如何在 ctypes 中使用来自鼠标/键盘挂钩的结构信息
所以我有一些看起来像这样的c代码:
#pragma comment(linker, "/SECTION:.SHARED,RWS")
#pragma data_seg(".SHARED")
HMODULE hInstance = 0;
HHOOK hKeyboardHook = 0;
int lastKey = 0;
int keyFlags = 0;
HHOOK hMouseHook = 0;
int mouseMsgID = 0;
MOUSEHOOKSTRUCT *mHookPt;
MOUSEHOOKSTRUCT mHookStruct;
#pragma data_seg()
BOOL WINAPI DllMain(HANDLE hModule, DWORD dwFunction, LPVOID lpNot)
{
hInstance = hModule;
return TRUE;
}
LRESULT CALLBACK KeyboardProc(int hookCode, WPARAM vKeyCode, LPARAM flags)
{
if(hookCode < 0)
{
return CallNextHookEx(hKeyboardHook, hookCode, vKeyCode, flags);
}
if(!hookCode)
{
lastKey = (int)vKeyCode;
keyFlags = (int)flags;
}
return CallNextHookEx(hKeyboardHook, hookCode, vKeyCode, flags);
}
LRESULT CALLBACK MouseProc(int hookCode, WPARAM msgID, LPARAM pMouseHookStruct)
{
if(hookCode < 0)
{
return CallNextHookEx(hMouseHook, hookCode, msgID, pMouseHookStruct);
}
if(!hookCode)
{
mouseMsgID = (int)msgID;
mHookPt = (MOUSEHOOKSTRUCT *)pMouseHookStruct;
mHookStruct = *mHookPt;
}
return CallNextHookEx(hMouseHook, hookCode, msgID, pMouseHookStruct);
}
__declspec(dllexport) int getLastKey(void)
{
if(!lastKey)
return 0;
return lastKey;
}
__declspec(dllexport) int getLastFlags(void)
{
if(!keyFlags)
return 0;
return keyFlags;
}
__declspec(dllexport) int getMsgID(void)
{
if(!mouseMsgID)
return 0;
return mouseMsgID;
}
__declspec(dllexport) MOUSEHOOKSTRUCT getMouseStruct(void)
{
return mHookStruct;
}
__declspec(dllexport) void InstallHooks(void)
{
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hInstance, 0);
hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc, hInstance, 0);
}
__declspec(dllexport) void UninstallHooks(void)
{
UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook = 0;
lastKey = 0;
keyFlags = 0;
UnhookWindowsHookEx(hMouseHook);
mouseMsgID = 0;
mHookPt = NULL;
}
它被编译成一个dll,使用ctypes.CDLL('blah.dll')
加载到python中:
class MouseHookStruct(ctypes.wintypes.Structure):
_fields_ = [("pt", ctypes.wintypes.POINT),
("hwnd", ctypes.wintypes.HWND),
("dwExtraInfo", ctypes.wintypes.POINTER(ctypes.wintypes.c_ulong))]
dll = ctypes.CDLL('blah.dll')
dll.getMouseStruct.restype = MouseHookStruct
try:
dll.InstallHooks()
mStruct = MouseHookStruct()
while True:
mStruct = dll.getMouseStruct()
print mStruct.pt.x, mStruct.pt.y
except KeyboardInterrupt:
pass
finally:
dll.UninstallHooks()
所有这一切都是打印出来< code>0 0 无论鼠标在哪里。键盘钩子很好,因为它的回调过程不使用结构。但是,如果我尝试 WH_KEYBOARD_LL 我会遇到同样的问题(结构的所有值都是 0)。在操作系统、C 和 Python ctypes 之间传递结构时我缺少什么?
So I've got some c code that looks like this:
#pragma comment(linker, "/SECTION:.SHARED,RWS")
#pragma data_seg(".SHARED")
HMODULE hInstance = 0;
HHOOK hKeyboardHook = 0;
int lastKey = 0;
int keyFlags = 0;
HHOOK hMouseHook = 0;
int mouseMsgID = 0;
MOUSEHOOKSTRUCT *mHookPt;
MOUSEHOOKSTRUCT mHookStruct;
#pragma data_seg()
BOOL WINAPI DllMain(HANDLE hModule, DWORD dwFunction, LPVOID lpNot)
{
hInstance = hModule;
return TRUE;
}
LRESULT CALLBACK KeyboardProc(int hookCode, WPARAM vKeyCode, LPARAM flags)
{
if(hookCode < 0)
{
return CallNextHookEx(hKeyboardHook, hookCode, vKeyCode, flags);
}
if(!hookCode)
{
lastKey = (int)vKeyCode;
keyFlags = (int)flags;
}
return CallNextHookEx(hKeyboardHook, hookCode, vKeyCode, flags);
}
LRESULT CALLBACK MouseProc(int hookCode, WPARAM msgID, LPARAM pMouseHookStruct)
{
if(hookCode < 0)
{
return CallNextHookEx(hMouseHook, hookCode, msgID, pMouseHookStruct);
}
if(!hookCode)
{
mouseMsgID = (int)msgID;
mHookPt = (MOUSEHOOKSTRUCT *)pMouseHookStruct;
mHookStruct = *mHookPt;
}
return CallNextHookEx(hMouseHook, hookCode, msgID, pMouseHookStruct);
}
__declspec(dllexport) int getLastKey(void)
{
if(!lastKey)
return 0;
return lastKey;
}
__declspec(dllexport) int getLastFlags(void)
{
if(!keyFlags)
return 0;
return keyFlags;
}
__declspec(dllexport) int getMsgID(void)
{
if(!mouseMsgID)
return 0;
return mouseMsgID;
}
__declspec(dllexport) MOUSEHOOKSTRUCT getMouseStruct(void)
{
return mHookStruct;
}
__declspec(dllexport) void InstallHooks(void)
{
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hInstance, 0);
hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc, hInstance, 0);
}
__declspec(dllexport) void UninstallHooks(void)
{
UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook = 0;
lastKey = 0;
keyFlags = 0;
UnhookWindowsHookEx(hMouseHook);
mouseMsgID = 0;
mHookPt = NULL;
}
It's compiled into a dll, which is loaded into python using ctypes.CDLL('blah.dll')
:
class MouseHookStruct(ctypes.wintypes.Structure):
_fields_ = [("pt", ctypes.wintypes.POINT),
("hwnd", ctypes.wintypes.HWND),
("dwExtraInfo", ctypes.wintypes.POINTER(ctypes.wintypes.c_ulong))]
dll = ctypes.CDLL('blah.dll')
dll.getMouseStruct.restype = MouseHookStruct
try:
dll.InstallHooks()
mStruct = MouseHookStruct()
while True:
mStruct = dll.getMouseStruct()
print mStruct.pt.x, mStruct.pt.y
except KeyboardInterrupt:
pass
finally:
dll.UninstallHooks()
All this does is print out 0 0
regardless of where the mouse is. The keyboard hook is fine because its callback proc does not make use of a struct. However, if I try a WH_KEYBOARD_LL I have the same issue (all values of the struct are 0). What am I missing with passing structs between the OS, C and Pythons ctypes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论