1、问题。
最近遇到一个问题,就是项目软件需要捕获到Alt+Tab事件。一开始无从下手,查了查资料,才搞得定。
2、原理。
Windows中Alt + Tab组合键被用来在各个程序之间切换。因此,该键盘消息(WM_KEYDOWN/WM_KEYUP)是直接发给系统内核,在应用程序中的消息循环中截获不到。
一个常见问题是,可是有的应用程序想在被Alt+TAB 切换到后台之间做点事情,这时候该怎么办?
方案之一就是用底层的键盘钩子,截获整个系统的键盘输入。但这样做会导致一些效率以及稳定性问题。
另外一个比较方便安全的方案就是用Windows Accessbility API的SetWinEventHook 函数,监听 EVENT_SYSTEM_SWITCHSTART 和 EVENT_SYSTEM_SWITCHEND事件。他们分别对应用户按下Alt+Tab键以及松开 Alt+Tab键。
3、实现。
3.1 声明钩子对象、Hook函数和回调。
static HWINEVENTHOOK g_ChangeUIHook = NULL; //切换界面钩子
void InstallChangeUIEventHook();
static void CALLBACK HandleChangeUIEvent(
HWINEVENTHOOK hook,
DWORD eventWin, HWND hwnd,
LONG idObject, LONG idChild,
DWORD dwEventThread,
DWORD dwmsEventTime);
3.2 Hook及回调的实现。
void InstallChangeUIEventHook()
{
g_ChangeUIHook = ::SetWinEventHook(EVENT_SYSTEM_SWITCHSTART, EVENT_SYSTEM_SWITCHEND,
NULL,
HandleChangeUIEvent, 0, 0,
WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS
);
}
void CALLBACK HandleChangeUIEvent(
HWINEVENTHOOK hook,
DWORD eventWin, HWND hwnd,
LONG idObject, LONG idChild,
DWORD dwEventThread,
DWORD dwmsEventTime)
{
switch (eventWin)
{
case EVENT_SYSTEM_SWITCHSTART:
{
TRACE0("[EVENT_SYSTEM_MENUSTART] Alt +Tab 按下 \n");
break;
}
case EVENT_SYSTEM_SWITCHEND:
{
TRACE0("[EVENT_SYSTEM_MENUEND] Alt +Tab 松开\n");
break;
}
}
}
4、调用。
在程序初始化时候调用InstallChangeUIEventHook();
5、测试。
切换ALT+TAB,效果:
参考:https://blog.51cto.com/wingeek/273996