用代码移动桌面图标(贪吃蛇)

效果图

实例.gif

前言

记得上高二的时候,闲来无事,上b站搜电脑病毒的视频看(不要问我为什么会搜这个),看到一个很有意思的"病毒",其实也不算病毒,它会控制桌面图标形成一个人形,并跳舞,跳完之后电脑就蓝屏了.之后下定决心也要整一个,埋头研究了两个星期吧,写了一个贪吃蛇,此贪吃蛇非彼贪吃蛇,它当然是控制的桌面图标来玩啦,还写了个网络版的,通过手机去控制.

贪吃蛇效果

本文章只介绍如何移动图标,不介绍贪吃蛇实现(源码太多),可以评价私信要源码

实例.gif

实现思路

首先要了解什么是句柄,通俗得讲它就是一个整数,具体它标识窗口、位图、画笔等对象,并且是不变得整数,就像身份证一样,当人出生后,必定会有一个18位的身份证号,并且是不变得,通过它,可以知道某人得姓名,地址,年龄等信息,句柄也是如此.

比如CreateWindow高数,当它成功创建一个窗口后,它的返回值就是一个句柄,你拿到这个句柄后,就可以对它做你想做的事了,比如用SetWindowText 给它设置一个标题.

明白了句柄,现在就要拿到桌面的句柄,对它进行控制,用spy++可以分析一下它

image.png

这里有一点不一样,在windows7中,它的父窗口类名是Program Manage,但是在windows10中,它的类名是WorkerW,并且有多个WorkerW.下图是windows 7中

image.png

但是这不影响我们.从中可以看到,桌面就是一个ListView,我们只要拿到它的句柄,就可以对他进行控制.

获取桌面句柄

需要用到api:
FindWindow:根据窗口的类名和窗口名称匹配指定的窗口,并且返回这个窗口的句柄
FindWindowEx:根据所在的父窗口中查找类名和窗口名称匹配的窗口,并且返回这个窗口的句柄

查找桌面句柄如下.
注:在win7下可就不这么写了,

Private Function getDesktopHwnd() As Long
Dim hwndWorkerW As Long, hwndShelldll As Long, hwndDesktop As Long

Do While (hwndDesktop = 0)
    hwndWorkerW = FindWindowEx(0, hwndWorkerW, "WorkerW", vbNullString)
        If (hwndWorkerW <> 0) Then
            hwndShelldll = FindWindowEx(hwndWorkerW, 0, "SHELLDLL_DefView", vbNullString)
   
            hwndDesktop = FindWindowEx(hwndShelldll, 0, "SysListView32", vbNullString)
        End If
Loop
getDesktopHwnd = hwndDesktop
End Function

移动图标

知道了桌面的句柄,然后就是移动图标了
既然桌面就是一个ListView,那么只需要给ListView发送一个LVM_SETITEMPOSITION消息来设置item的位置.
如果你对windows机制不太了解的话,可能不明白为何要这样做,简单说一下,windows是根据消息来驱动程序运行的,例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序,应用程序会在一个叫窗口过程函数的地方处理消息,windows定义了大量的消息,列入:WM_CLOSE,对这个窗口发送WM_CLOSE,如果应用程序不做特殊处理的话,窗口就会关闭,

如果对ListView操作的话,就需要发送以LVM开头的消息,WM开头的是窗口消息,还有对列表框的消息LB_xxx

发送消息可以用SendMessage函数或PostMessage,区别在于使用PostMessage是立即返回,SendMessage需要等待应用程序处理完之后返回,在这里我们也不需要等待程序返回,所以用PostMessage.

看一下PostMeeage的定义

image.png

参数hwnd:消息接收的窗口句柄
参数msg:具体消息
参数wparam和lparam:其他特定于消息的信息。

在看一下LVM_SETITEMPOSITION消息的定义

image.png

也就是说,使用PostMeeage投递LVM_SETITEMPOSITION消息的时候,参数wparam是某个图标的索引,lparam是位置.
但是如何用一个整数标识一个坐标呢,在c中可以用MAKELPARAM来获取,vb中可没有这样的方法,那就自己写一个

Public Function MAKELPARAM(ByVal l As Integer, ByVal h As Integer) As Long
Dim ll As String
Dim lh As String
Dim r As String
ll = Format(Hex(l), "@@@@")
lh = Format(Hex(h), "@@@@")
Dim result As Long

result = CLng("&h" & Replace(lh & ll, " ", "0"))
 MAKELPARAM = result
 
End Function

全部代码

Private Const LVM_FIRST As Long = &H1000

Private Declare Function GetDesktopWindow Lib "user32.dll" () As Long

Private Const LVM_SETITEMPOSITION32 As Long = (LVM_FIRST + 49)
Private Declare Function PostMessage Lib "user32.dll" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Declare Function EnumWindows Lib "user32.dll" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long

Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

Private Const LVM_SETITEMPOSITION As Long = (LVM_FIRST + 15)

Private Type POINTAPI
    x As Long
    y As Long
End Type

Dim curPoint As POINTAPI

Dim listViewhwnd As Long

Public Function MAKELPARAM(ByVal l As Integer, ByVal h As Integer) As Long
Dim ll As String
Dim lh As String
Dim r As String
ll = Format(Hex(l), "@@@@")
lh = Format(Hex(h), "@@@@")
Dim result As Long

result = CLng("&h" & Replace(lh & ll, " ", "0"))
 MAKELPARAM = result
 
End Function


Private Function getDesktopHwnd() As Long
Dim hwndWorkerW As Long, hwndShelldll As Long, hwndDesktop As Long

Do While (hwndDesktop = 0)
    hwndWorkerW = FindWindowEx(0, hwndWorkerW, "WorkerW", vbNullString)
        If (hwndWorkerW <> 0) Then
            hwndShelldll = FindWindowEx(hwndWorkerW, 0, "SHELLDLL_DefView", vbNullString)
   
            hwndDesktop = FindWindowEx(hwndShelldll, 0, "SysListView32", vbNullString)
        End If
Loop
getDesktopHwnd = hwndDesktop
End Function
Private Sub Form_Load()
listViewhwnd = getDesktopHwnd()

End Sub

Private Sub Timer1_Timer()
curPoint.x = curPoint.x + 10

PostMessage listViewhwnd, LVM_SETITEMPOSITION, 10, MAKELPARAM(curPoint.x, 110)
End Sub

注:右击桌面--->查看---->自动排列图标 、将图标和网格对齐 需要取消勾选

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 226,979评论 6 528
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 97,750评论 3 412
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 174,647评论 0 373
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 62,299评论 1 307
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 71,104评论 6 405
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 54,623评论 1 320
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,716评论 3 434
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 41,873评论 0 285
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 48,380评论 1 330
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 40,344评论 3 354
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 42,496评论 1 365
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,055评论 5 355
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,756评论 3 343
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,146评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 35,410评论 1 281
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 51,072评论 3 386
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,485评论 2 370

推荐阅读更多精彩内容