我必须更新一些非常古老的MFC VC ++代码,以通过后台线程中的 SetWindowsHookEx function和 LowLevelMouseProc callback function捕获所有鼠标点击。然后,我必须向我的主线程发送一条消息,指示点击(这部分我已经可以做了)。这样做的目的是在应用程序中有一个定时锁定机制,如果用户暂时不与它交互。
我似乎无法让回调在其自己的线程中运行。单独我可以得到SetWindowsHookEx和LowLevelMouseProc来输出鼠标点击就好了,但是当我尝试在另一个线程中执行它时,我什么也得不到。我在MSDN上的LowLevelMouseProc上找到了这个引用:
"在安装它的线程的上下文中调用此钩子。通过向安装了挂钩的线程发送消息来进行调用。因此,安装钩子的线程必须有一个消息循环。"
我必须把它放在它自己的主题中,这样它就不会阻止程序的其余部分。
为简洁起见,我省略了错误检查。我没有做过很多C ++编码,所以任何指针都会非常感激。
void MouseMonitor::initialize()
{
theInstance_ = new MouseMonitor();
CWinThread* mouseThread = AfxBeginThread(WaitForPeek, NULL);
}
UINT MouseMonitor::WaitForPeek(LPVOID lp)
{
MSG msg;
DWORD status;
g_Hook = SetWindowsHookEx(WH_MOUSE_LL, &LowLevelMouseProc,
GetModuleHandle(0), 0);
while (1)
{
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK LowLevelMouseProc (int code, WPARAM wParam, LPARAM lParam)
{
if (code == HC_ACTION)
{
const char *msg;
char msg_buff[128];
msg = "";
switch (wParam)
{
case WM_LBUTTONDOWN: msg = "WM_LBUTTONDOWN"; break;
case WM_LBUTTONUP: msg = "WM_LBUTTONUP"; break;
case WM_MOUSEMOVE: break;
case WM_RBUTTONDOWN: msg = "WM_RBUTTONDOWN"; break;
case WM_RBUTTONUP: msg = "WM_RBUTTONUP"; break;
default:
sprintf(msg_buff, "Unknown msg: %u", wParam);
break;
}
if (msg != "")
{
TRACE("<<< MouseClick >>>\n");
cout << msg << endl;
}
}
return CallNextHookEx(g_Hook, code, wParam, lParam);
}