vc++基础班[12]---注册全局系统热键

vc++基础班[12]---注册全局系统热键
------------------------------------------ Begin ----------------------------------------
①、注册全局系统热键的优点:
即使程序的窗口不是当前活动窗口、或者窗口最小化、隐藏后,也都可以响应热键;
比如QQ软件的默认呼出热键:Ctrl+Alt+Z 就是注册了全局系统热键;

②、注册窗口全局系统热键的步骤:

1> 调用 RegisterHotKey 函数注册全局系统热键;
BOOL RegisterHotKey(
    HWND hWnd,
    int id,
    UINT fsModifiers,
    UINT vk
);
hWnd : 指定响应该热键的窗口句柄;
id : 热键的标识,有点类似于 SetTimer 中的标识,作用域为线程内;
fsModifiers : 指定组合键,这个值可以由 MOD_ALT、MOD_CONTROL、MOD_SHIFT、MOD_WIN 中的一个或几个组成; 
vk : 指定热键的虚拟键盘码,如:'A' 
备注:这里的 Ctrl+Alt+A 这个组合键的作用域是全局的;

示例:RegisterHotKey(m_hWnd, 1000, MOD_CONTROL|MOD_ALT, 'Q');

2> 响应目标窗口的 WM_HOTKEY 消息;
3> 调用 UnregisterHotKey 卸载热键:
BOOL UnregisterHotKey(
    HWND hWnd,
    int id
);
hWnd : 热键关联的窗口句柄;
id : 热键的标识;
可以放到对话框类的 OnDestroy() 函数中进行调用,这样模态与非模态对话框都可以成功的进行卸载;

==============================================
③、热键提高篇:注册线程全局热键,没有窗口;

④、线程全局热键的步骤:
1> 声明线程函数:static UINT __cdecl ThreadProc(LPVOID pParam);
成员函数作为线程函数:http://www.cctry.com/thread-19591-1-1.html

2> 调用MFC中的 AfxBeginThread 函数进行新工作线程的创建: AfxBeginThread(ThreadProc, this);
3> 线程函数的实现://跟大家说明一下id和key作用域的问题
UINT CMFCTestDlg::ThreadProc(LPVOID pParam)
{
CMFCTestDlg *pThis = (CMFCTestDlg *)pParam;
BOOL bRet = RegisterHotKey(NULL, pThis->hotkey_n, MOD_CONTROL|MOD_ALT, 'E');
int err = GetLastError();
LPARAM lpa = MAKELPARAM(MOD_CONTROL|MOD_ALT, 'E');

MSG stMsg = {0};
while(GetMessage(&stMsg, NULL, 0, 0))
{
switch(stMsg.message)
{
case WM_HOTKEY:
::MessageBox(NULL, _T("您按下了:Ctrl+Alt+E 热键!"), _T("友情提示"), MB_OK);
break;
default:break;
}
}
UnregisterHotKey(NULL, pThis->hotkey_n);

return 0;
}

3> 线程函数的退出:
因为 GetMessage 是阻塞的,没有消息的话,那么就会一直等待,直到返回为止,所以我们要加一个“后门”,让其可以退出;
使用的方法就是把 GetMessage 换成 PeekMessage,这个函数是异步的,所以没有消息也可以返回:
UINT CMFCTestDlg::ThreadProc(LPVOID pParam)
{
CMFCTestDlg *pThis = (CMFCTestDlg *)pParam;
BOOL bRet = RegisterHotKey(NULL, pThis->hotkey_n, MOD_CONTROL|MOD_ALT, 'E');
int err = GetLastError();
LPARAM lpa = MAKELPARAM(MOD_CONTROL|MOD_ALT, 'E');

MSG stMsg = {0};
while(TRUE)
{
if (PeekMessage(&stMsg, NULL, 0, 0, PM_REMOVE)){
switch(stMsg.message)
{
case WM_HOTKEY:
::MessageBox(NULL, _T("您按下了:Ctrl+Alt+E 热键!"), _T("友情提示"), MB_OK);
break;
default:break;
}
}
Sleep(100); //防止CPU过高
}
UnregisterHotKey(NULL, pThis->hotkey_n);

return 0;
}

原文链接: vc++基础班[12]---注册全局系统热键 版权所有,转载时请注明出处,违者必究。
注明出处格式:流沙团 ( https://gyarmy.com/post-280.html )

发表评论

0则评论给“vc++基础班[12]---注册全局系统热键”