我正在尝试用Python(3.4.3)后台应用程序(windows7/8)全局跟踪鼠标。这涉及到设置一个WindowsHook,它应该向我返回该特定钩子的有效句柄,但是我的句柄总是0。在
使用GetCursorPos只跟踪鼠标位置非常简单(作为替代方案,GetCursorInfo也可以):from ctypes.wintypes import *
ppoint = ctypes.pointer(POINT())
ctypes.windll.user32.GetCursorPos(ppoint)
print('({}, {})'.format(ppoint[0].x, ppoint[0].y))
还可以方便地只跟踪位置^{},它跟踪最后64个鼠标位置:
^{pr2}$
不过,我想也能跟踪点击,拖动等。
一个好的解决方案似乎是^{}。(可能还有另一种方法有待探索:Raw Input)
为了能够使用LealLealMouthPro,文档告诉我们使用^{},它也覆盖在{a5}(C++)tutorials(c ^)中,以及一些有趣的projects(也C ^)。在<>文件在C++中定义如下:HHOOK WINAPI SetWindowsHookEx(
_In_ int idHook,
_In_ HOOKPROC lpfn,
_In_ HINSTANCE hMod,
_In_ DWORD dwThreadId
);
在python中,以下值应该是我的正确值:idHook:^{}
hMod:HINSTANCE(0)(基本上是一个空指针)
dwThreadId:ctypes.windll.kernel32.GetCurrentThreadId()
对于lpfn,我需要一些实现^{}的回调函数,这里是LLMouseProc:def _LLMouseProc (nCode, wParam, lParam):
return ctypes.windll.user32.CallNextHookEx(None, nCode, wParam, lParam)
LLMouseProcCB = ctypes.CFUNCTYPE(LRESULT, ctypes.c_int, WPARAM, LPARAM)
LLMouseProc = LLMouseProcCB(_LLMouseProc)
综上所述,我希望这能奏效:from ctypes.wintypes import *
LONG_PTR = ctypes.c_long
LRESULT = LONG_PTR
WH_MOUSE_LL = 14
def _LLMouseProc(nCode, wParam, lParam):
print("_LLMouseProc({!s}, {!s}, {!s})".format(nCode, wParam, lParam))
return ctypes.windll.user32.CallNextHookEx(None, nCode, wParam, lParam)
LLMouseProcCB = ctypes.CFUNCTYPE(LRESULT, ctypes.c_int, WPARAM, LPARAM)
LLMouseProc = LLMouseProcCB(_LLMouseProc)
threadId = ctypes.windll.kernel32.GetCurrentThreadId()
# register callback as hook
print('hook = SetWindowsHookExW({!s}, {!s}, {!s}, {!s})'.format(WH_MOUSE_LL, LLMouseProc,
HINSTANCE(0), threadId))
hook = ctypes.windll.user32.SetWindowsHookExW(WH_MOUSE_LL, LLMouseProc,
HINSTANCE(0), threadId)
print('Hook: {}'.format(hook))
import time
try:
while True:
time.sleep(0.2)
except keyboardInterrupt:
pass
但是输出显示hook == 0:hook = SetWindowsHookExW(14, , c_void_p(None), 5700)
Hook: 0
我认为回调函数的最后一个参数,名称lParam与LPARAM(即ctypes.c_long)不太正确,因为我假设实际需要的是指向这个结构的指针:class MSLLHOOKSTRUCT(ctypes.Structure):
_fields_ = [
("pt", POINT),
("mouseData", DWORD),
("flags", DWORD),
("time", DWORD),
("dwExtraInfo", ULONG_PTR)
]
但是将签名改为LLMouseProcCB = ctypes.CFUNCTYPE(LRESULT, ctypes.c_int, WPARAM, ctypes.POINTER(MSLLHOOKSTRUCT))并不能解决问题,我仍然有一个0的钩子。在
这是追踪鼠标的正确方法吗?我需要做些什么才能正确注册Windows钩子?在