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

效果图windows

实例.gif

前言api

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

贪吃蛇效果函数

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

实例.gif

实现思路code

说到这,真的很后悔之前没第一个学c语言,反而学了vb,如今被其余语言搞得没有精力去学了,并无说vb很差,它也很强大,只是它封装了不少,让不少人接触底层得知识更少了,好比窗体,归根到底,全部窗体都是用CreateWindow 函数来建立,可是学了vb,谁会傻到在用CreateWindow来建立窗口呢?orm

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

上面所说的CreateWindow,当它成功建立一个窗口后,它的返回值就是一个句柄,你拿到这个句柄后,你就能够对它作你想作的事了,好比用SetWindowText 给它设置一个标题.对象

明白了句柄,如今就要拿到桌面的句柄,对它进行控制,用spy++能够分析一下它blog

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

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

相关文章
相关标签/搜索