Ste*_* Lu 13 c++ winapi multithreading
我正在尝试捕获全局鼠标和键盘输入.
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode >= 0) {
if (wParam == WM_RBUTTONDOWN) printf("right mouse down\n");
if (wParam == WM_RBUTTONUP) printf("right mouse up\n");
}
return CallNextHookEx(0, nCode, wParam, lParam);
}
HHOOK mousehook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, NULL, 0);
while(true) {
MSG msg;
if (PeekMessage(&msg,0,0,0,PM_REMOVE)) {
printf("msg recvd\n");
TranslateMessage(&msg);
DispatchMessage(&msg);
}
#ifdef TEST
Sleep(50);
#endif
}
Run Code Online (Sandbox Code Playgroud)
所以一切都在这里工作,除非我#define TEST放入Sleep,鼠标变得非常迟钝,如果我突然只允许鼠标每秒更新20次,可能会出现这种情况.没有睡眠,我将CPU固定在100%.但是现在这没关系(如果我使用的话就会消失GetMessage).
根据我的理解,低级钩子通过上下文切换到安装它的进程,然后发送进程某种消息让它执行钩子回调.令我困惑的是,为什么我的程序永远不会打印"msg recvd",但只要我点击鼠标右键,就会打印"鼠标右键/向上".这使我得出结论,我MouseHookProc在PeekMessage呼叫期间被调用.它恰好是某种特殊的消息,并PeekMessage返回0.但我仍然需要打电话PeekMessage或一些等价物.
由于我的程序需要做很多事情,我显然不能通过PeekMessage调用另一个函数来减轻我的消息循环(调用的那个),比如50ms返回.我怎样才能多线程化我的程序以保持鼠标响应能力,同时做一些繁重的工作?在多线程win32程序中,仍然只有一个消息队列,对吧?
更新:在阅读了MS的文档后,我想我知道对我来说正确的做法是什么.我应该在我的应用程序中生成一个线程,该线程调用SetWindowsHookEx注册鼠标钩子,然后在它自己的消息循环中坐下来,系统将负责将鼠标更新发送到该线程.它可以随意做任何想做的事情MouseHookProc,我的应用程序的其余部分将独立运行.
Han*_*ant 11
问题是你的消息循环,因为你使用PeekMessage()会烧掉100%的CPU周期.Windows知道如何保持挂钩活动,即使您不轮询消息,使用GetMessage()来解决您的问题.使用Sleep(1)也可以解决您的问题,但这里没有必要.
为什么必须将SetWindowsHookEx与Windows消息队列一起使用
我问你是否将这个地方MouseHookProc放在DLL中,因为试图将它放在EXE中这是一个典型的错误.我多年前也做过.
首先,您如何阅读http://msdn.microsoft.com/en-us/library/ms644990.aspx:
SetWindowsHookEx可用于将DLL注入另一个进程.32位DLL无法注入64位进程,64位DLL无法注入32位进程.如果应用程序需要在其他进程中使用钩子,则需要32位应用程序调用SetWindowsHookEx将32位DLL注入32位进程,并且64位应用程序调用SetWindowsHookEx注入64位DLL进入64位进程.32位和64位DLL必须具有不同的名称.
所以你必须放在DLL中.确切地说,如果您想要支持32位和64位平台,则必须实现两个dll:一个32位和64位DLL.但为什么?怎么SetWindowsHookEx运作?
如果您在EXE中执行如下代码
HINSTANCE hinstDLL = LoadLibrary(TEXT("c:\\myapp\\syshook.dll"));
HOOKPROC hkprcMouse = (HOOKPROC)GetProcAddress(hinstDLL, "MouseHookProc");
HHOOK hhookMouse = SetWindowsHookEx(
WH_MOUSE_LL,
hkprcMouse,
hinstDLL,
0);
Run Code Online (Sandbox Code Playgroud)
你给user32.dll请求在同一个windows工作站的所有其他进程中注入你的syshook.dll(dll不会注入通过快速用户切换记录的其他用户的服务和进程).然后user32.dll中调用LoadLibrary的syshook.dll在不同的进程.然后,如果MouseHookProc将调用该函数,则将在处理鼠标消息的进程的上下文中调用in.如果进程不是控制台应用程序的代码就好
printf("right mouse down\n");
Run Code Online (Sandbox Code Playgroud)
无法工作.
所以我希望你现在不会想到为什么你必须放在MouseHookProcDLL中.
| 归档时间: |
|
| 查看次数: |
19458 次 |
| 最近记录: |