经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » Windows » 查看文章
用代码移动桌面图标(贪吃蛇)
来源:cnblogs  作者:听风逝夜blog  时间:2019/6/24 8:45:13  对本文有异议

效果图

实例.gif

前言

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

贪吃蛇效果

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

实例.gif

实现思路

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

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

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

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

image.png

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

image.png

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

获取桌面句柄

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

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

  1. Private Function getDesktopHwnd() As Long
  2. Dim hwndWorkerW As Long, hwndShelldll As Long, hwndDesktop As Long
  3. Do While (hwndDesktop = 0)
  4. hwndWorkerW = FindWindowEx(0, hwndWorkerW, "WorkerW", vbNullString)
  5. If (hwndWorkerW <> 0) Then
  6. hwndShelldll = FindWindowEx(hwndWorkerW, 0, "SHELLDLL_DefView", vbNullString)
  7. hwndDesktop = FindWindowEx(hwndShelldll, 0, "SysListView32", vbNullString)
  8. End If
  9. Loop
  10. getDesktopHwnd = hwndDesktop
  11. 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中可没有这样的方法,那就自己写一个

  1. Public Function MAKELPARAM(ByVal l As Integer, ByVal h As Integer) As Long
  2. Dim ll As String
  3. Dim lh As String
  4. Dim r As String
  5. ll = Format(Hex(l), "@@@@")
  6. lh = Format(Hex(h), "@@@@")
  7. Dim result As Long
  8. result = CLng("&h" & Replace(lh & ll, " ", "0"))
  9. MAKELPARAM = result
  10. End Function

全部代码

  1. Private Const LVM_FIRST As Long = &H1000
  2. Private Declare Function GetDesktopWindow Lib "user32.dll" () As Long
  3. Private Const LVM_SETITEMPOSITION32 As Long = (LVM_FIRST + 49)
  4. 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
  5. Private Declare Function EnumWindows Lib "user32.dll" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
  6. Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
  7. 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
  8. Private Const LVM_SETITEMPOSITION As Long = (LVM_FIRST + 15)
  9. Private Type POINTAPI
  10. x As Long
  11. y As Long
  12. End Type
  13. Dim curPoint As POINTAPI
  14. Dim listViewhwnd As Long
  15. Public Function MAKELPARAM(ByVal l As Integer, ByVal h As Integer) As Long
  16. Dim ll As String
  17. Dim lh As String
  18. Dim r As String
  19. ll = Format(Hex(l), "@@@@")
  20. lh = Format(Hex(h), "@@@@")
  21. Dim result As Long
  22. result = CLng("&h" & Replace(lh & ll, " ", "0"))
  23. MAKELPARAM = result
  24. End Function
  25. Private Function getDesktopHwnd() As Long
  26. Dim hwndWorkerW As Long, hwndShelldll As Long, hwndDesktop As Long
  27. Do While (hwndDesktop = 0)
  28. hwndWorkerW = FindWindowEx(0, hwndWorkerW, "WorkerW", vbNullString)
  29. If (hwndWorkerW <> 0) Then
  30. hwndShelldll = FindWindowEx(hwndWorkerW, 0, "SHELLDLL_DefView", vbNullString)
  31. hwndDesktop = FindWindowEx(hwndShelldll, 0, "SysListView32", vbNullString)
  32. End If
  33. Loop
  34. getDesktopHwnd = hwndDesktop
  35. End Function
  36. Private Sub Form_Load()
  37. listViewhwnd = getDesktopHwnd()
  38. End Sub
  39. Private Sub Timer1_Timer()
  40. curPoint.x = curPoint.x + 10
  41. PostMessage listViewhwnd, LVM_SETITEMPOSITION, 10, MAKELPARAM(curPoint.x, 110)
  42. End Sub

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

原文链接:http://www.cnblogs.com/HouXinLin/p/11072503.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号