pyqt全局鼠标事件/钩子
2017-12-11 22:00
239 查看
之前我们用RegisterHotKey实现了全局热键。今天我们来学习一下全局钩子的知识。来结束我这几天的研究。笔者用的是python3.6
首先我们要明白一些关键的部分:
钩子分为线程钩子和系统钩子两种。
线程钩子是局部的,所以qt自带的事件已经可以实现了。我们来学习一下系统钩子的写法,因为系统钩子是全局的。ps.暂且原谅我这样描述。大概意思就是这样的,各位看官老爷们可以去百度详细的讲解。
系统钩子是注册进去以后系统帮忙调用回调事件。但这里注意啦。这个回调事件必须用c写成dll供python调用。这个无解。。具体原因可以查个大概。就是系统需要让所有程序执行这个事件(调用这个dll)。
我们用到的就是这个函数windll.user32.SetWindowsHookExA下面是代码:
ss是返回的钩子句柄,得到它有很多好处,我们暂且向下看。
SetWindowsHookExA这个函数在user32.dll里面,用dll函数查看器即可查看。
另外它里面还有SetWindowsHookA
SetWindowsHookExW
SetWindowsHookW
下面是这几个的区别。其实区别不大~~
http://bbs.csdn.net/topics/66391
http://blog.csdn.net/vlily/article/details/8129504
当
4000
然,必不可少的就是这个函数的参数了,这里我会详细讲解的:
http://baike.sogou.com/v7807464.htm?fromTitle=setwindowshookex
我们从它的第一个参数说起:
int idHook这是一个钩子类型。可以监管系统几乎所有事情,不只是鼠标键盘哦~~
http://blog.sina.com.cn/s/blog_547901e30102v6n0.html
这个是参数的大概意思,下面是参数的数值。因为python没法像c语言一样可以直接调用winuser.h
嘛,所以笔者在这里准备了下面这个。可以在python里面直接填数值哦。是不是很贴心~~
http://blog.csdn.net/acheld/article/details/53386347
HOOKPROC lpfn其实就是一个函数的指针。如果做系统钩子的话这个函数必须写在dll里面。以下是大概的写法。
http://blog.sina.com.cn/s/blog_4513dde60100o6od.html
上面这个介绍了一种用ctypes填这个参数的方法,他是用python里面的函数当做第二个参数。
很遗憾,我上面说的无解,所以必须把执行函数写在dll里面。
http://blog.csdn.net/qingdujun/article/details/25861615
这个是笔者编写dll的方法,其实笔者也不会c语言啦~哈哈哈
其实上面的SetHook和ShanHook函数完全不用写啦,在python里面写即可,唯有MouseProc函数必须写在这里面。返回0则放任系统,返回1则丢掉信息。鼠标将卡死。
CallNextHookEx这个函数被我注释掉了,使用它与不使用它没有影响,所以在这里不多说了。
http://baike.sogou.com/v10464092.htm?fromTitle=callnexthookex
如果有好奇的朋友可以在下面留言。
没错。。用ctypes调用dll就是这么简单。。。
如果做到以上步骤基本可以实现全局钩子了,另外推荐多研究一下钩子类型,不同的钩子效果是不同的。
下面我们再来用python试一下调用这个函数。
这样就是在python里面调用这个函数,大家可以和dll里面写的对比一下。
第三个参数的意思就是第二个参数所在的模块句柄。很简单的调用了GetModuleHandleA是不是?~~
这里有个小区别GetModuleHandle与GetModuleHandleA。如果在python里面搜不到的函数。一定要用dll函数查看器查看一下那个函数到底叫什么名字。略坑。。。
如果做系统钩子,第四个函数保持0即可。但俺还是要说两句。
第4个参数是python线程id。但是python的threading#多线程只有名字name,如果id的话需要调用win api里面的函数。返回当前线程的id,ps.注意不是进程id哦。
恕笔者无力,实在是没找到返回线程id的函数了,所以只能姑且填0了。
按理说,python调用的和dll调用的应该是一样的。但是
WH_MOUSE = 7
WH_MOUSE_LL = 14
在python里只有14成功,7会失败。在dll里面两个却都会成功。
大家可以尝试一下其他的类型。可能会有意想不到的收获哦。
大家也可以去研究一下按键精灵的钩子,应该也有很多人在讨论。
下面说一下遇到的问题:
1.无论什么钩子,我弄完以后都会爆卡无比,不知原因。可能是因为win7系统的问题吧。
2.python调用和dll调用显然是不一样的。
这个是俺写的python部分。dll部分上面也给出了。需要各位看官们自行编译。
首先我们要明白一些关键的部分:
钩子分为线程钩子和系统钩子两种。
线程钩子是局部的,所以qt自带的事件已经可以实现了。我们来学习一下系统钩子的写法,因为系统钩子是全局的。ps.暂且原谅我这样描述。大概意思就是这样的,各位看官老爷们可以去百度详细的讲解。
系统钩子是注册进去以后系统帮忙调用回调事件。但这里注意啦。这个回调事件必须用c写成dll供python调用。这个无解。。具体原因可以查个大概。就是系统需要让所有程序执行这个事件(调用这个dll)。
我们用到的就是这个函数windll.user32.SetWindowsHookExA下面是代码:
from ctypes import windll ss = windll.user32.SetWindowsHookExA() print(ss)
ss是返回的钩子句柄,得到它有很多好处,我们暂且向下看。
SetWindowsHookExA这个函数在user32.dll里面,用dll函数查看器即可查看。
另外它里面还有SetWindowsHookA
SetWindowsHookExW
SetWindowsHookW
下面是这几个的区别。其实区别不大~~
http://bbs.csdn.net/topics/66391
http://blog.csdn.net/vlily/article/details/8129504
当
4000
然,必不可少的就是这个函数的参数了,这里我会详细讲解的:
http://baike.sogou.com/v7807464.htm?fromTitle=setwindowshookex
我们从它的第一个参数说起:
int idHook这是一个钩子类型。可以监管系统几乎所有事情,不只是鼠标键盘哦~~
http://blog.sina.com.cn/s/blog_547901e30102v6n0.html
这个是参数的大概意思,下面是参数的数值。因为python没法像c语言一样可以直接调用winuser.h
嘛,所以笔者在这里准备了下面这个。可以在python里面直接填数值哦。是不是很贴心~~
http://blog.csdn.net/acheld/article/details/53386347
HOOKPROC lpfn其实就是一个函数的指针。如果做系统钩子的话这个函数必须写在dll里面。以下是大概的写法。
http://blog.sina.com.cn/s/blog_4513dde60100o6od.html
上面这个介绍了一种用ctypes填这个参数的方法,他是用python里面的函数当做第二个参数。
很遗憾,我上面说的无解,所以必须把执行函数写在dll里面。
http://blog.csdn.net/qingdujun/article/details/25861615
这个是笔者编写dll的方法,其实笔者也不会c语言啦~哈哈哈
#include <windows.h> HHOOK g_hMouse = NULL; bool cg = true; //鼠标钩子过程 LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) { //CallNextHookEx(g_hMouse, nCode, wParam, lParam); return 0; } //安装鼠标钩子过程的函数 HHOOK SetHook() { g_hMouse = SetWindowsHookEx(WH_MOUSE, MouseProc, GetModuleHandle("GHookDll"),0); return g_hMouse; } //删除鼠标钩子 bool ShanHook() { cg = UnhookWindowsHookEx(g_hMouse); return cg; }
其实上面的SetHook和ShanHook函数完全不用写啦,在python里面写即可,唯有MouseProc函数必须写在这里面。返回0则放任系统,返回1则丢掉信息。鼠标将卡死。
CallNextHookEx这个函数被我注释掉了,使用它与不使用它没有影响,所以在这里不多说了。
http://baike.sogou.com/v10464092.htm?fromTitle=callnexthookex
如果有好奇的朋友可以在下面留言。
from ctypes import CDLL zz = CDLL("GHookDll.dll") ss = zz.SetHook() dd = zz.ShanHook()
没错。。用ctypes调用dll就是这么简单。。。
如果做到以上步骤基本可以实现全局钩子了,另外推荐多研究一下钩子类型,不同的钩子效果是不同的。
下面我们再来用python试一下调用这个函数。
zz = CDLL("GHookDll.dll") ss = windll.user32.SetWindowsHookExA(3,zz.MouseProc,windll.kernel32.GetModuleHandleA("GHookDll"), 0)
这样就是在python里面调用这个函数,大家可以和dll里面写的对比一下。
第三个参数的意思就是第二个参数所在的模块句柄。很简单的调用了GetModuleHandleA是不是?~~
这里有个小区别GetModuleHandle与GetModuleHandleA。如果在python里面搜不到的函数。一定要用dll函数查看器查看一下那个函数到底叫什么名字。略坑。。。
如果做系统钩子,第四个函数保持0即可。但俺还是要说两句。
第4个参数是python线程id。但是python的threading#多线程只有名字name,如果id的话需要调用win api里面的函数。返回当前线程的id,ps.注意不是进程id哦。
恕笔者无力,实在是没找到返回线程id的函数了,所以只能姑且填0了。
按理说,python调用的和dll调用的应该是一样的。但是
WH_MOUSE = 7
WH_MOUSE_LL = 14
在python里只有14成功,7会失败。在dll里面两个却都会成功。
大家可以尝试一下其他的类型。可能会有意想不到的收获哦。
大家也可以去研究一下按键精灵的钩子,应该也有很多人在讨论。
下面说一下遇到的问题:
1.无论什么钩子,我弄完以后都会爆卡无比,不知原因。可能是因为win7系统的问题吧。
2.python调用和dll调用显然是不一样的。
from ctypes import CDLL, windll, c_int import time import threading#多线程 def kaishigouzi(): zz = CDLL("GHookDll.dll") ss = zz.SetHook() print(ss) time.sleep(1) print("删除钩子") zhende = zz.ShanHook() print(zhende) def kaishigouzi_2(): zz = CDLL("GHookDll.dll") SetWindowsHookExA = windll.user32.SetWindowsHookExA(3,zz.MouseProc, windll.kernel32.GetModuleHandleA("GHookDll"), 0) print(SetWindowsHookExA) time.sleep(10) ss = windll.user32.UnhookWindowsHookEx(c_int(SetWindowsHookExA)) print(ss) t1 = threading.Thread(target=kaishigouzi_2) #t1.setDaemon(True) t1.start()
这个是俺写的python部分。dll部分上面也给出了。需要各位看官们自行编译。
后记:
win32 api是一堆很强大的函数,如果有时间的话还是建议买一本偏向底层的书籍仔细学习一下。会对初学者的你有很大帮助的~~相关文章推荐
- 全局钩子监听键盘鼠标事件
- .NET使用钩子捕获全局鼠标和键盘事件
- 鼠标全局事件
- QT中监控全局键盘鼠标事件
- C#如何监听全局的事件-例如鼠标移动事件
- VC++全局钩子实现鼠标坐标值实时捕获
- 仿QQ悬挂窗口的实现(全局鼠标钩子)
- VC++ Hook截取鼠标点击窗口消息的问题!全局钩子
- osx获取全局键盘/鼠标事件
- VB.NET全局键盘鼠标钩子 [Vb.Net Hook](修正版)
- C#监测全局键盘与鼠标事件
- 使用钩子函数[3] - 建立一个全局的鼠标钩子
- C#钩子类 几乎捕获键盘鼠标所有事件
- .NET 实现线程键盘鼠标钩子和全局鼠标键盘钩子
- 全局鼠标键盘事件实现应用程序的自动锁定
- 全局钩子(hook鼠标键盘消息)
- C#监测全局键盘与鼠标事件
- 安装全局钩子程序(鼠标钩子)
- C#如何监听全局的事件-例如鼠标移动事件
- C#全局鼠标钩子