SetWinEventHook监听EVENT_SYSTEM_SWITCHSTART不生效问题排查
问题代码
#define UNICODE #define _UNICODE #include <iostream> #include <Windows.h> #include <fstream> using namespace std; void CALLBACK Wineventproc(HWINEVENTHOOK hWinEventHook,DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD idEventThread, DWORD dwmsEventTime ){ cout<<"EventId:"<<idEventThread<<endl; } int main() { CoInitialize(nullptr); HWINEVENTHOOK hEventHook = SetWinEventHook(EVENT_SYSTEM_SWITCHSTART, EVENT_SYSTEM_SWITCHEND, nullptr, Wineventproc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); if(hEventHook==NULL){ cout<<"hook fail"<<endl; return 0; } MSG mess; BOOL bRet; cout<<"1"<<endl; while ((bRet=GetMessage(&mess, nullptr,0,0))!=0){ cout<<"2"<<endl; if(bRet == -1){ }else { TranslateMessage(&mess); DispatchMessage(&mess); } } if(!UnhookWinEvent(hEventHook)){ return 0; } CoUninitialize(); return 0; }
问题现象
调用SetWinEventHook()接口尝试捕获窗口切换事件,实际按下Alt+Tab组合键(对应EVENT_SYSTEM_SWITCHSTART事件)时,程序内的GetMessage()始终处于阻塞状态,无法触发事件回调。
问题原因与修复方案
你的代码踩了三个WinEvent钩子在控制台程序下的典型坑,按影响大小排序:
- 控制台主线程消息队列未完整初始化
控制台程序主线程默认不会初始化支持全局跨进程WinEvent回调的消息队列结构,仅靠GetMessage()触发的轻量初始化不足以支持跨进程事件投递,系统根本没法把其他进程发出的事件通知传到你的线程队列里,直接导致GetMessage()永久阻塞。
修复方式很简单,在安装完钩子、进入消息循环之前,调用一次PeekMessage强制完成消息队列的完整初始化:MSG dummy; PeekMessage(&dummy, nullptr, 0, 0, PM_NOREMOVE); - UIPI(用户界面特权隔离)拦截系统进程的事件通知
Alt+Tab对应的窗口切换事件是由explorer.exe、dwm.exe这类系统级进程发出的,这类进程运行的完整性级别远高于普通双击启动的用户程序,Windows默认的UIPI机制会拦截高权限进程发往低权限进程的事件消息,自然收不到回调。
修复方式是创建一个隐藏的仅消息窗口作为消息接收载体,把WinEvent对应的消息加入过滤白名单:// 获取WinEvent使用的注册消息号 UINT winEventMsg = RegisterWindowMessageW(L"WinEventHook"); // 创建不可见的仅消息窗口 HWND hMsgWnd = CreateWindowExW(0, L"STATIC", L"", 0, 0,0,0,0, HWND_MESSAGE, nullptr, GetModuleHandle(nullptr), nullptr); // 放开对应消息的权限过滤 ChangeWindowMessageFilterEx(hMsgWnd, winEventMsg, MSGFLT_ALLOW, nullptr); - 回调逻辑存在错误
你在回调中输出的idEventThread是触发事件的线程ID,不是事件ID,要判断当前触发的是切换开始还是结束事件,需要输出回调第二个参数event的值。另外不建议在回调里用cout打日志,控制台输出的缓冲机制很容易在高频回调场景下卡住主线程,调试阶段用OutputDebugString输出日志更稳定,不会干扰消息循环运行。
以上几个问题修改完成后,按下Alt+Tab即可正常捕获对应的窗口切换事件。
内容的提问来源于stack exchange,提问作者user19021341
相关产品推荐
相关产品推荐

