V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
lon91ong
V2EX  ›  Python

pywin32 实现的鼠标后台点击功能略有不足

  •  1
     
  •   lon91ong · 2023-09-12 20:05:44 +08:00 · 1644 次点击
    这是一个创建于 430 天前的主题,其中的信息可能已经有所发展或是发生改变。

    主要参考, 使用 pywin32 的 SendMessage 函数实现,函数定义如下:

    from win32.win32gui import SendMessage
    # 定义鼠标事件的参数
    MK_LBUTTON = 1 # 鼠标左键, 右键为 2
    MOUSE_MOVE = 512 #0x0001  # 鼠标移动
    MOUSE_LEFTDOWN = 513 #0x0002  # 左键按下
    MOUSE_LEFTUP = 514 #0x0004  # 左键释放
    def bkg_click(hWnd, coord, count = 1, drag = False, delta = 0):
    	# hWnd 窗口句柄,coord 相对坐标,drag 拖动与否,delta 拖动量,count 点击次数
    	x, y = int(coord[0]), int(coord[1])
    	while count > 0:
    		lParam = x | y <<16
    		SendMessage(hWnd, MOUSE_LEFTDOWN, MK_LBUTTON, lParam)
    		if drag:
    			lParam = x | (y + delta) <<16
    			SendMessage(hWnd,MOUSE_MOVE, MK_LBUTTON, lParam)
    		SendMessage(hWnd, MOUSE_LEFTUP, None, lParam)
    		sleep(0.3)
    		count -= 1
    

    美中不足之处在于,点击事件发送时会激活窗口,会抢夺活动窗口权限,影响电脑的其它操作

    请教大侠有没有更完美的 后台 鼠标事件发送方法

    第 1 条附言  ·  2023-09-19 21:16:54 +08:00

    stackoverflow参考

    Not take focus, but allow interaction?

    How to use setWindowLongPtr?

    根据上面的参考,试着设置窗口属性使其无法激活

    from win32con import GWL_EXSTYLE, WS_EX_NOACTIVATE
    from win32gui import SetWindowLong
    
    #执行时用具体窗口句柄数值替换下面的hwnd参数
    SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_NOACTIVATE) 
    

    经过测试,原本不抢焦点的窗口会变成无法接收键盘输入

    抢焦点的窗口毫无影响,照抢不误 用spyxx查看窗口属性,WS_EX_NOACTIVATE已经加上了,但毫无作用

    感觉不是我代码的问题,似乎是窗口本身有问题

    游戏是PC端的微信小程序,双开PC端微信(选择快捷方式后,快速双击回车键两次)

    登录两个微信号然后各自开一个游戏窗口

    这样打开的窗口会有什么“畸形”的bug吗?

    17 条回复    2024-04-10 20:29:18 +08:00
    zictos
        1
    zictos  
       2023-09-12 20:40:19 +08:00 via Android
    大漠插件
    kkk9
        2
    kkk9  
       2023-09-12 21:04:47 +08:00
    调用驱动后台
    ysc3839
        3
    ysc3839  
       2023-09-12 21:27:16 +08:00 via Android
    PostMessage 呢? LockSetForegroundWindow 呢?
    GeekGao
        4
    GeekGao  
       2023-09-12 21:45:11 +08:00
    PostMessage
    owen800q
        5
    owen800q  
       2023-09-12 21:47:36 +08:00 via iPhone
    用大漠插件
    lon91ong
        6
    lon91ong  
    OP
       2023-09-13 13:13:22 +08:00
    根据上面几位的回复进行了一番搜索,结果如下:

    > 大漠插件限制 32 为 python ,我的 python 环境迁移到 64 位平台已经很久了,不想再折腾回去

    > PostMessage 试过了,直接替换 SendMessage 函数,其它都不变,然后鼠标乱点,似乎坐标错乱了,不明白跟 SendMessage 的坐标换算有啥不兼容的地方

    > LockSetForegroundWindow 根据[微软的介绍]( https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-locksetforegroundwindow)是给前台程序用的,跟我这个要求不符
    ohmyhaha
        7
    ohmyhaha  
       2023-09-13 13:26:16 +08:00
    我插个眼。蹲一个方案
    lon91ong
        8
    lon91ong  
    OP
       2023-09-13 14:38:40 +08:00
    更新一下反馈信息,上面关于 PostMessage 替换 SendMessage 的反馈有误,用 PostMessage 替换后程序表现不是坐标错乱,而是跟 SendMessage 一样会抢活动窗口权限

    另外补充一点,用两个脚本进程分别监控两个窗口,只有一个进程会抢活动窗口权限,另外一个不抢,同样的代码,好奇怪
    lon91ong
        9
    lon91ong  
    OP
       2023-09-13 15:04:45 +08:00
    再补充一点,没有使用多线程,就是直接打开了两个命令行窗口,分别运行两个脚本实例,一个抢一个不抢
    zaw
        10
    zaw  
       2023-09-13 16:03:20 +08:00
    以前也研究过,太麻烦了,最后还是选大漠插件,虽然只能 32 位 python ,但影响不大,电脑上多版本 python 外加 env 独立环境
    lon91ong
        11
    lon91ong  
    OP
       2023-09-15 14:13:43 +08:00
    今天为了测试兼容性把代码复制了一份整了两个文件夹( 3.10 和 3.11 各一个),脚本分开跑之后不抢窗口焦点了
    用的是 PostMessage 方法
    lon91ong
        12
    lon91ong  
    OP
       2023-09-16 09:56:57 +08:00
    一切都是幻觉,今天又抢焦点了
    lon91ong
        13
    lon91ong  
    OP
       2023-09-18 20:14:18 +08:00
    用多进程(multiprocessing)解决了
    很奇怪的毛病,开两个命令行窗口分别运行就会有一个抢焦点,同样的代码用 multiprocessing 就不抢了
    lon91ong
        14
    lon91ong  
    OP
       2023-09-19 13:51:25 +08:00
    然并卵,就昨天一会儿好用,今天重开依旧是一个抢一个不抢

    控制变量,折腾了半天,现在不抢了,还是一头雾水
    lon91ong
        16
    lon91ong  
    OP
       220 天前
    https://bbs.125.la/thread-14804647-2-1.html
    问题归结于浏览器窗口的问题,小程序也是 Chrome 核心的,凡是 Chrome 核心的都不行
    换用 Firefox 就可以完全后台了
    lon91ong
        17
    lon91ong  
    OP
       219 天前 via Android
    还有用 Python 服务油猴 js 提供键鼠输入的思路,在吾爱破解那边,1734053
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2651 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 04:30 · PVG 12:30 · LAX 20:30 · JFK 23:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.