我想在python中使用win32api模块安装一个hook,并捕获wm_activate消息,以便对其进行进一步处理,然后将消息发布给其他应用程序进行处理。基本上我想检测用户是否更改了活动的前景窗口。我已经使用 PySide2 模块中的 QTimer 每 25 毫秒检查活动前景窗口是否已更改,但这不是最佳解决方案。
这是我的尝试,但我没有从中得到任何消息,因为从不执行 low_level_handler 回调函数。它适用于低级鼠标钩子。我错过了什么?
# Some of this adapted from BoppreH's answer here:http://stackoverflow.com/questions/9817531/applying-low-level-keyboard-hooks-with-python-and-setwindowshookexa
import win32con, win32gui
from ctypes import wintypes
from ctypes import windll, CFUNCTYPE, POINTER, c_int, c_void_p, byref, WINFUNCTYPE
import atexit
Handlers=[]
def listener(yo):
def low_level_handler(nCode, wParam, lParam):
print("reach")
print(nCode,wParam, lParam)
#Be nice, return next hook
return windll.user32.CallNextHookEx(hook_id, nCode, wParam, lParam)
# Our low level handler signature.
CMPFUNC = WINFUNCTYPE(c_int, c_int, c_int, POINTER(c_void_p))
# Convert the Python handler into C pointer.
pointer = CMPFUNC(low_level_handler)
windll.kernel32.GetModuleHandleW.restype = wintypes.HMODULE
windll.kernel32.GetModuleHandleW.argtypes = [wintypes.LPCWSTR]
windll.user32.SetWindowsHookExA.argtypes = (c_int, wintypes.HANDLE, wintypes.HMODULE, wintypes.DWORD)
print(yo)
hwnd = windll.kernel32.GetModuleHandleW(None)
hook_id = windll.user32.SetWindowsHookExA(win32con.WH_CALLWNDPROC, pointer, hwnd, 0)
HOOK_ID = hook_id
# Register to remove the hook when the interpreter exits.
atexit.register(windll.user32.UnhookWindowsHookEx, hook_id)
while True:
windll.user32.PostThreadMessageW(hook_id, win32con.WM_ACTIVATE, 0, 0)
msg = win32gui.GetMessage(None, 0, 0)
win32gui.TranslateMessage(byref(msg))
win32gui.DispatchMessage(byref(msg))
WM_QUIT = 0x0012
HOOK_ID = None
def installHook():
listener("yo")
def removeHook():
windll.user32.UnhookWindowsHookEx(HOOK_ID)
HOOK_ID = None
installHook()