Python 2.7 windows钩子必须与消息泵注册在同一线程上吗?
我试图利用Windows钩子在应用程序发送自己的gui事件时拦截和阻止击键 我提出了以下清单:Python 2.7 windows钩子必须与消息泵注册在同一线程上吗?,python-2.7,winapi,pyhook,Python 2.7,Winapi,Pyhook,我试图利用Windows钩子在应用程序发送自己的gui事件时拦截和阻止击键 我提出了以下清单: import pythoncom import pyHook import threading import time def on_keyboard_event(event): print 'MessageName:',event.MessageName print 'Message:',event.Message print 'Time:',event.Time
import pythoncom
import pyHook
import threading
import time
def on_keyboard_event(event):
print 'MessageName:',event.MessageName
print 'Message:',event.Message
print 'Time:',event.Time
print 'Window:',event.Window
print 'WindowName:',event.WindowName
print 'Ascii:', event.Ascii, chr(event.Ascii)
print 'Key:', event.Key
print 'KeyID:', event.KeyID
print 'ScanCode:', event.ScanCode
print 'Extended:', event.Extended
print 'Injected:', event.Injected
print 'Alt', event.Alt
print 'Transition', event.Transition
print '---'
return False
class WindowsHooksWrapper:
def __init__(self):
self.started = False
self.thread = threading.Thread(target=self.thread_proc)
self.hook_manager = pyHook.HookManager()
def start(self):
if self.started:
self.stop()
# Register hook
self.hook_manager.KeyDown = on_keyboard_event
self.hook_manager.KeyUp = on_keyboard_event
self.hook_manager.HookKeyboard()
# Start the windows message pump
self.started = True
self.thread.start()
def stop(self):
if not self.started:
return
self.started = False
self.thread.join()
self.hook_manager.UnhookKeyboard()
def thread_proc(self):
print "Thread started"
while self.started:
pythoncom.PumpWaitingMessages()
print "Thread exiting..."
class WindowsHooksWrapper2:
def __init__(self):
self.started = False
self.thread = threading.Thread(target=self.thread_proc)
def start(self):
if self.started:
self.stop()
self.started = True
self.thread.start()
def stop(self):
if not self.started:
return
self.started = False
self.thread.join()
def thread_proc(self):
print "Thread started"
# Evidently, the hook must be registered on the same thread with the windows msg pump or
# it will not work and no indication of error is seen
# Also note that for exception safety, when the hook manager goes out of scope, it
# unregisters all outstanding hooks
hook_manager = pyHook.HookManager()
hook_manager.KeyDown = on_keyboard_event
hook_manager.KeyUp = on_keyboard_event
hook_manager.HookKeyboard()
while self.started:
pythoncom.PumpWaitingMessages()
print "Thread exiting..."
self.hook_manager.UnhookKeyboard()
def main():
# hook_manager = pyHook.HookManager()
# hook_manager.KeyDown = on_keyboard_event
# hook_manager.KeyUp = on_keyboard_event
# hook_manager.HookKeyboard()
# pythoncom.PumpMessages()
hook_wrapper = WindowsHooksWrapper2()
hook_wrapper.start()
time.sleep(30)
hook_wrapper.stop()
if __name__ == "__main__":
main()
主要的注释部分来自pyhook wiki教程,效果很好
然后我尝试将其集成到一个类中,即“WindowsHooksRapper”类。如果我使用该类,它将不起作用,键盘消息将传递到它们的预期目标
凭直觉,我尝试了“WindowsHooksRapper2”,我将钩子的注册移动到消息泵的同一个线程。它现在起作用了
我的直觉正确吗?注册要求与泵在同一螺纹上?若然,原因为何
注意到,这是Windows 32 API的要求,而不是Python或PyHoover库本身,因为我在C++中使用了,并且使用“StWistWORSRead”直接得到了相同的结果。
< p>您创建了一个线程范围钩子。 这些钩子事件要么与特定线程相关联,要么与调用线程所在桌面上的所有线程相关联 Python中的pythoncom.PumpWaitingMessages()
和Win32中的GetMessage
/PeekMessage
是从“特定线程或与调用线程位于同一桌面上的所有线程”获取消息的方法
要创建全局钩子,为了让所有进程都可以访问键盘钩子,必须将其放置在DLL中,然后将其加载到每个进程的地址空间中。有关如何制作全局键盘挂钩的详细信息,请参见此