【发布时间】:2021-11-18 15:18:59
【问题描述】:
我正在尝试在第三方应用窗口中收听事件,我不拥有其中的源。
我不明白documentation 的这部分内容:
调用 SetWinEventHook 的客户端线程必须有一个消息循环才能接收事件。
我如何“定义”这个消息循环?
在我的钩子代码中,它永远不会到达switch:
void CALLBACK WinEventProc(
HWINEVENTHOOK hWinEventHook,
DWORD event,
HWND hwnd,
LONG idObject,
LONG idChild,
DWORD dwEventThread,
DWORD dwmsEventTime
)
{
switch (event) {
case EVENT_SYSTEM_MINIMIZESTART:
...
break;
case EVENT_SYSTEM_MINIMIZEEND:
...
break;
}
}
HWINEVENTHOOK hWinEventHook;
int EventHook() {
hWinEventHook = SetWinEventHook(
EVENT_SYSTEM_MINIMIZESTART, // eventMin
EVENT_SYSTEM_MINIMIZEEND, // eventMax
NULL, // hmodWinEventProc
WinEventProc, // pfnWinEventProc
4834, // idProcess
0, // idThread
WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); //dwFlags
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
std::thread t1(EventHook);
...
}
我按照cmets中的建议修改了代码,但是现在我的程序崩溃了;
到达线路时崩溃:
while (GetMessage(&msg, NULL, 0, 0))
【问题讨论】:
-
“消息循环”是及时重复调用
GetMessage和DispatchMessage的简写。您示例中的while循环实际上是一个消息循环。就问题而言,它在别处。你检查SetWinEventHook调用是否成功?4834是某个进程的有效ID吗?您是否最小化或恢复了属于该进程的某些窗口? -
@IgorTandetnik 你的意思是如果
hWinEventHook正在返回一个值?确实如此。 -
你有一个消息循环,但是当你使用 std::async 时它还不够好。要求是消息循环在设置挂钩的同一线程上运行。轻松修复,您根本不需要它是异步的。
-
您可能还需要为 Windows 而不是控制台进行编译,以便主线程是 UI 线程,并且代码可能应该从主线程或至少是 STA 线程运行。我认为钩子有点难以理解和正确,如果做得不好可能会极大地影响系统的稳定性。除非您别无选择并且愿意大量阅读,否则最好避免使用它们...