快捷键(加速键),系统热键,键盘钩子的不同
昨天剛剛了解到系統(tǒng)熱鍵的API: RegisterHotKey(),當(dāng)時(shí)很感慨,因?yàn)檫@些年來(lái),經(jīng)常用到的是【快捷鍵】或用【鍵盤(pán)鉤子】實(shí)現(xiàn)的全局快鍵鍵,因?yàn)槲也恢烙鞋F(xiàn)成的系統(tǒng)熱鍵的API可用,有點(diǎn)丟人了。
現(xiàn)在想想,系統(tǒng)的快捷鍵,系統(tǒng)熱鍵,鍵盤(pán)鉤子他們各有各的特點(diǎn),簡(jiǎn)單做個(gè)總結(jié):
1. 快捷鍵(Accelerator:加速鍵),特點(diǎn)是:窗口必須在獲得焦點(diǎn)(激活的狀態(tài))下,才能響應(yīng)快捷鍵。
我一般都是在 res.rc 中添加:
//
// Accelerator resources 加速鍵
// 詳細(xì)介紹: https://docs.microsoft.com/en-us/windows/win32/menurc/accelerators-resource
//
LANGUAGE 0, SUBLANG_NEUTRAL
IDR_ACCELERATOR1 ACCELERATORS
{
/*
//快捷鍵的映射關(guān)系
"^C", ID_ACCELERATOR_DELETE // control C
"K", ID_ACCELERATOR_DELETE // shift K
"k", ID_ACCELERATOR_DELETE, ALT // alt k
98, ID_ACCELERATOR_DELETE, ASCII // b
66, ID_ACCELERATOR_DELETE, ASCII // B (shift b)
"g", ID_ACCELERATOR_DELETE // g
"G", ID_ACCELERATOR_DELETE // G (shift G)
VK_F1, ID_ACCELERATOR_DELETE, VIRTKEY // F1
VK_F1, ID_ACCELERATOR_DELETE, CONTROL, VIRTKEY // control F1
VK_F1, ID_ACCELERATOR_DELETE, SHIFT, VIRTKEY // shift F1
VK_F1, ID_ACCELERATOR_DELETE, ALT, VIRTKEY // alt F1
VK_F2, ID_ACCELERATOR_DELETE, ALT, SHIFT, VIRTKEY // alt shift F2
VK_F2, ID_ACCELERATOR_DELETE, CONTROL, SHIFT, VIRTKEY // ctrl shift F2
VK_F2, ID_ACCELERATOR_DELETE, ALT, CONTROL, VIRTKEY // alt control F2
*/
//"H", ID_ACCELERATOR_SCREENSHOT_STATIC, ALT, CONTROL, VIRTKEY // ctrl + alt + h, 注意, 前面必須使用大寫(xiě)的 "H"
VK_DELETE, ID_ACCELERATOR_DELETE, VIRTKEY
}
然后在主程序中 main() 中添加:
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1)); // 加載加速鍵表
//printf("hAccelTable:%ld
", hAccelTable);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
//參考 - http://dec3.jlu.edu.cn/webcourse/T000024/files/bjjx/bjjx3.htm 和 http://itzone.hk/article/article.php?aid=200406211205229426
//TranslateAccelerator()函數(shù)確定存放在msg消息結(jié)構(gòu)中的消息是不是鍵盤(pán)消息。
//如果是,該函數(shù)將查找句柄為hAccel的加速鍵表。如果找到了一個(gè)匹配,則調(diào)用句桶為hwnd的窗口的窗口過(guò)程。
//如果加速鍵ID與系統(tǒng)菜單的菜單項(xiàng)一致,則消息就是WM_SYSCOMMAND;否則,消息為WM_COMMAND。
if(!TranslateAccelerator(hwnd, hAccelTable, &messages)) //啟用加速鍵
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
else
{
//printf("按下了加速鍵...
");
}
}
2. 系統(tǒng)熱鍵,特點(diǎn):窗口不激活也能接收到鍵盤(pán)消息。使用RegisterHotKey() 注冊(cè),操作上很簡(jiǎn)單,但由于是全局性的,容易和別的軟件發(fā)生熱鍵沖突,導(dǎo)致熱鍵注冊(cè)失敗。
3. 鍵盤(pán)鉤子,特點(diǎn):窗口不激活也能接收到鍵盤(pán)消息。使用上有點(diǎn)麻煩,但是這玩意一般情況下不會(huì)因與別軟件沖突,而無(wú)法接收鍵盤(pán)消息。當(dāng)然如果別的軟件也有鍵盤(pán)鉤子,同時(shí)禁止了鍵盤(pán)消息向下傳遞,會(huì)不會(huì)也無(wú)法接收鍵盤(pán)消息,我沒(méi)測(cè)試)
//全局鍵盤(pán)鉤子 //參考 - http://blog.csdn.net/one_six_mix/article/details/52044406 hook_keyboard = SetWindowsHookExA(WH_KEYBOARD_LL, keyboardHook, GetModuleHandleA(0), 0); //GetModuleHandleA(0)或 NULL, 都行
//鉤子回調(diào) - 全局鍵盤(pán)鉤子
LRESULT CALLBACK keyboardHook(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode == HC_ACTION) //當(dāng) nCode等于HC_ACTION時(shí),要求得到處理
{
//參考 - http://bbs.csdn.net/topics/320236776
//參考 - http://www.51hei.com/bbs/dpj-30393-1.html
//BOOL bControlKeyDown = GetAsyncKeyState(VK_CONTROL) >> ((sizeof(SHORT) * 8 ) - 1);// 檢查是否Ctrl鍵被按下
KBDLLHOOKSTRUCT *ks = (KBDLLHOOKSTRUCT*)lParam;
//printf("是否Ctrl鍵被按下:%d
", bControlKeyDown);
//printf("ks->vkCode:%c
", ks->vkCode);
if(ks->vkCode == VK_ESCAPE)
{
//printf("esc
");
if(currentMouseLocationTarget == TARGET_NULL)
{
}
else
{
...
if(hook_keyboard)
{
UnhookWindowsHookEx(hook_keyboard); //解鎖
hook_keyboard = NULL;
}
return 1; //屏蔽掉, 不再向下傳遞
}
}
}
return CallNextHookEx(hook_keyboard, nCode, wParam, lParam); //返回給下一個(gè)鉤子子程處理 (==不屏蔽)
}
總結(jié)
以上是生活随笔為你收集整理的快捷键(加速键),系统热键,键盘钩子的不同的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 凹凸相对论
- 下一篇: IAX协议简化VoIP部署(转)