最近在玩咸鱼之王,为了方便挂机的时候加快点通关进程,所以想用Python写个模拟鼠标点击脚本。
需求:
- Python调用鼠标事件
- 找到咸鱼之王的窗口
- 模拟鼠标点击,在后台工作,不能占用鼠标事件,不能影响其他的正常操作。
开始解决问题
随便Bing搜索一下,可以看到直接有Python调用Windows函数发送鼠标模拟事件。
# 鼠标操作
import win32api
import win32gui
import win32con
'''通过spy++拿到应用程序主窗口的类名和窗口标题'''
mainHnd=win32gui.FindWindow("窗口类名","窗口标题(全)")
'''根据GetWindowRect拿到主窗口的左顶点的位置坐标(x,y)和窗口的宽高(w*h)'''
rect = win32gui.GetWindowRect(mainHnd)
x,y=rect[0],rect[1]
w,h=rect[2] - x,rect[3] - y
模拟鼠标指针, 传送到指定坐标
long_position = win32api.MAKELONG(x, y)
# 模拟鼠标按下
win32api.SendMessage(hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, long_position)
# 模拟鼠标弹起
win32api.SendMessage(hwnd, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, long_position)
————————————————
版权声明:本文为CSDN博主「aydolt」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/aydolt/article/details/127389848
首先上面有一些错误
SendMessage 需要传入窗口句柄,正确句柄应该是mainHnd。
接下来问题就来了,你怎么获取到正确的窗口类名和标题名?
于是乎
你需要来一个 Spy++
【怎么下载,你们自己解决】
接下来是怎么用Spy++
注意事项:
-
你需要找到是哪个窗口对象响应了鼠标点击事件,
建议你右键点击子窗口对象,选择message
-
打开message窗口后,鼠标移动到咸鱼之王的窗口,点击一下,你就可以看到数据了。
看到了么
圈出来的部分,就是左键点击的事件,包括key,和坐标
所以,需要SendMessage到这个窗口对象。 -
回到窗口列表,右键查看Properties
用这里的General 里的Window Caption和Class里的 Class Name获取不到正确的窗口句柄。代码运行的时候报错了。
于是,换了个思路,我取父窗口看看行不行
OK 没有问题 - 设置点击位置
positionX = int(173)
positionY = int(452)
long_position = win32api.MAKELONG(positionX, positionY)
win32api.SendMessage(mainHnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, long_position)
win32api.SendMessage(mainHnd, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, long_position)
项目跑起来之后,正确的点击了窗口
不过,问题还没有完全解决
因为代码占用了鼠标事件,其他工作做不了啦...
最后扒一下
SendMessage,发现还有一个 PostMessage函数
1、SendMessage()和PostMessage().这两个函数几乎是一样的,它们的区别是:
SendMessage()直接把一个消息发给窗口过程,等消息被处理后才返回。Postmessage()只是把消息发送到消息队列,完成后即返回。
行啊...再测试一波
完美解决
最后代码:
import win32api
import win32gui
import win32con
import time
'''通过spy++拿到应用程序主窗口的类名和窗口标题'''
FrameClass = "Chrome_WidgetWin_0"
FrameTitle = "咸鱼之王"
mainHnd = win32gui.FindWindow(FrameClass, FrameTitle)
'''根据GetWindowRect拿到主窗口的左顶点的位置坐标(x,y)和窗口的宽高(w*h)'''
# rect 取到左上和右下坐标
rect = win32gui.GetWindowRect(mainHnd)
print(rect)
x,y=rect[0],rect[1]
w,h=rect[2] - x,rect[3] - y
# 模拟鼠标指针, 传送到指定坐标
positionX = int(173)
positionY = int(452)
countTime = 0
while(countTime<500):
print(countTime)
long_position = win32api.MAKELONG(positionX, positionY)
# 模拟鼠标按下
win32api.PostMessage(mainHnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, long_position)
time.sleep(0.05)
# 模拟鼠标弹起
win32api.PostMessage(mainHnd, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, long_position)
countTime=countTime+1
time.sleep(0.05)
参考资料
Win32 API消息函数:SendMessage(发送消息)win32api.sendmessage意念586的博客-CSDN博客
Python:PostMessage后台发送鼠标消息给模拟器无效的解决办法_python 后台鼠标_Yaadon的博客-CSDN博客
【Python】win32gui.Findwindow(parm1,parm2)窗口句柄获取_ztmajor的博客-CSDN博客