对于windows应用程序的某个独立窗口,一种常见的全局热键处理的方法为:注册自定义全局热键,通过消息WM_HOTKEY的响应函数处理热键事件,并在结束时删除已注册的自定义热键。由于win+D组合键为windows系统自带热键,无法注册为应用程序独立窗口的全局热键,但可以单独注册win键为全局热键,因此,本文采用了一种特殊的设计方法,实现了应用程序独立窗口对win+D组合键的响应和处理。
首先,在创建窗口时,注册win键为全局热键:
1 LRESULT CWnd::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) 2 { 3 ... 4 BOOL bRegRes = RegisterHotKey(m_hWnd, SELF_DEFINED_HOTKEY1, MOD_WIN, VK_LWIN); 5 if (!bRegRes) 6 { 7 //左win键注册失败日志打印 8 } 9 bRegRes = RegisterHotKey(m_hWnd, SELF_DEFINED_HOTKEY2, MOD_WIN, VK_RWIN); 10 if (!bRegRes) 11 { 12 //右win键注册失败日志打印 13 } 14 return S_OK; 15 }
那么,当按下win键时,独立窗口会收到消息WM_HOTKEY,通过MESSAGE_HANDLE,调用接口OnHotKey处理该消息:
1 LRESULT CWnd::OnHotKey(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL /*bHandled*/) 2 { 3 if (SELF_DEFINED_HOTKEY1 == wParam || SELF_DEFINED_HOTKEY2 == wParam) 4 { 5 //启动事件响应定时器ON_ACTION_TIMER 6 } 7 }
定时器中,通过windows API GetAsyncKeyState()检测按键实时状态,判断是否需要执行win+D热键响应事件:
1 LRESULT CWnd::OnTimer(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) 2 { 3 if (ON_ACTION_TIMER == wParam) 4 { 5 if (任意win键按下) 6 { 7 if (D键没有按下) 8 { 9 break; 10 } 11 //关闭定时器ON_ACTION_TIMER并处理win+D热键响应事件 12 } 13 else 14 { 15 //关闭定时器ON_ACTION_TIMER 16 } 17 } 18 }
最后,在窗口销毁时,不要忘了把自定义的热键给删除掉:
1 LRESULT CWnd::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) 2 { 3 if (!UnregisterHotKey(m_hWnd, SELF_DEFIEND_HOTKEY1) || !UnregisterHotKey(m_hWnd, SELF_DEFIEND_HOTKEY2)) 4 { 5 uint32 nError = GetLastError(); 6 //错误信息打印 7 } 8 return S_OK; 9 }