在實(shí)際應(yīng)用中,有時(shí)程序需要在特定的鼠標(biāo)、按鍵事件后,執(zhí)行一些操作,比如:
1、點(diǎn)擊觸摸屏?xí)r觸發(fā)蜂鳴器。
2、在休眠狀態(tài)點(diǎn)擊觸摸屏后,讓程序結(jié)束休眠狀態(tài)。
3、設(shè)定全局的按鍵功能,如一鍵截圖或一鍵關(guān)機(jī)。
4、過濾一些鼠標(biāo)或鍵盤操作等等。
這時(shí),可以使用鍵盤鼠標(biāo)鉤子來實(shí)現(xiàn)這些功能。
鉤子是WINDOWS/WINCE系統(tǒng)獨(dú)有的消息處理機(jī)制。通過系統(tǒng)調(diào)用,將消息處理程序段掛入系統(tǒng),獲得消息處理優(yōu)先控制權(quán),在消息達(dá)到目的窗口前進(jìn)行處理。鉤子函數(shù)可以通過判斷決定是否加工處理(改變)消息,或不做處理繼續(xù)傳遞各消息,或強(qiáng)制結(jié)束消息傳遞。
鉤子有很多種,WINCE系統(tǒng)已精簡到只有4種鉤子。同時(shí)鉤子又可做局部鉤子或全局鉤子,局部鉤子僅在指定進(jìn)程內(nèi)生效,而全局鉤子在系統(tǒng)范圍內(nèi)都生效。一般的全局鉤子需要掛載到dll中使用,本文介紹的鼠標(biāo)鉤子和鍵盤鉤子較特殊,不需要掛載到dll中即可全局生效。
鉤子的運(yùn)行邏輯如下圖,每種鉤子可以掛入任意多個(gè)鉤子函數(shù),以鏈表方式存儲。系統(tǒng)優(yōu)先訪問鏈表首位的鉤子,然后依次傳遞消息給后面的鉤子處理。后掛入的鉤子位于鏈表的前端。
使用方法
添加鉤子分3步。
1、編寫鉤子函數(shù)處理代碼
2、調(diào)用API函數(shù)將鉤子函數(shù)掛入系統(tǒng)
3、創(chuàng)建消息循環(huán),使鉤子運(yùn)作起來
添加引用
使用鉤子需要用到函數(shù),SetWindowsHookEx,UnhookWindowsHookEx,CallNextHookEx。及鍵盤鉤子鼠標(biāo)鉤子的定義,及鍵盤消息,鼠標(biāo)消息的結(jié)構(gòu)體定義,均定義在pwinuser.h中。
#include "pwinuser.h"
創(chuàng)建需要掛入系統(tǒng)的消息處理函數(shù)
即鉤子函數(shù),鉤子函數(shù)定義必須為制定的格式。
鉤子函數(shù)根據(jù)實(shí)際應(yīng)用需求,決定是否調(diào)用CallNextHookEx,將消息傳遞給后面的鉤子處理。
首位的鉤子函數(shù)返回值決定該消息是丟棄,還是傳給系統(tǒng)消息處理函數(shù),再分發(fā)給各窗口。
以下為鍵盤及鼠標(biāo)鉤子函數(shù)的示例。
鍵盤鉤子函數(shù)
該鍵盤鉤子示例函數(shù)中,當(dāng)檢測到按鍵‘1’按下時(shí),調(diào)用Beep函數(shù)觸發(fā)蜂鳴器。
LRESULT CALLBACK KeyboardProc(intnCode,WPARAM wParam,LPARAM lParam)
{
KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *) lParam;
if(wParam == WM_KEYDOWN) //按鈕按下
{
switch(pkbhs->vkCode)
{
case0x31: //按鈕‘’
Beep();
break;
defaut:
break;
}
}
returnCallNextHookEx(NULL,nCode,wParam,lParam);
}
注:
1、WINCE鍵盤鉤子函數(shù)得到的WPARAM記錄的消息類別,如按鍵是按下消息WM_KEYDOWN還是彈起消息WM_KEYUP。
LPARAM指向鍵盤消息結(jié)構(gòu)體KBDLLHOOKSTRUCT,里面記錄有詳細(xì)信息,如觸發(fā)的按鍵是什么,有沒有輔助按下ALT鍵或者CTRL鍵,等等。
2、鉤子隊(duì)列第一個(gè)鉤子的返回值決定系統(tǒng)是否能接受到該消息。
返回0表示,將消息傳遞給系統(tǒng)消息處理函數(shù)繼續(xù)處理。
返回1表示,丟棄消息,系統(tǒng)將收不到該消息。
調(diào)用CallNextHookEx表示調(diào)用下一個(gè)鉤子消息處理函數(shù),如果不調(diào)用,那么后面的鉤子函數(shù)將不產(chǎn)生作用。
鼠標(biāo)(觸摸屏)鉤子函數(shù)
該鼠標(biāo)鉤子示例函數(shù)中,當(dāng)檢測到鼠標(biāo)或觸摸屏點(diǎn)擊時(shí),調(diào)用Beep函數(shù)觸發(fā)蜂鳴器。
LRESULT CALLBACK MouseHookProc(intnCode, WPARAM wParam, LPARAM lParam)
{
MSLLHOOKSTRUCT *pmshs = (MSLLHOOKSTRUCT *) lParam;
if(wParam == WM_LBUTTONDOWN) //鼠標(biāo)點(diǎn)擊處理代碼
{
Beep();
}
returnCallNextHookEx(NULL,nCode,wParam,lParam);
}
注:
1、WINCE鼠標(biāo)鉤子函數(shù)得到的WPARAM記錄的消息類別,如是鼠標(biāo)按下還是彈起,還是雙擊,移動(dòng),等等。
LPARAM記錄的詳細(xì)信息,如點(diǎn)擊坐標(biāo),滾輪參數(shù)等等。
2、觸摸屏消息和鼠標(biāo)消息是一樣的。
3、鉤子隊(duì)列第一個(gè)鉤子的返回值決定系統(tǒng)是否能接受到該消息。
返回0表示,將消息傳遞給系統(tǒng)消息處理函數(shù)繼續(xù)處理。
返回1表示,丟棄消息,系統(tǒng)將收不到該消息。
調(diào)用CallNextHookEx表示調(diào)用下一個(gè)鉤子消息處理函數(shù),如果不調(diào)用,那么后面的鉤子函數(shù)將不產(chǎn)生作用。
Beep函數(shù)
在本文示例中,將嵌入式板子GPIO15連接上一個(gè)蜂鳴器,通過設(shè)置GPIO電平觸發(fā)蜂鳴器。
在程序初始段打開GPIO,獲得GPIO句柄。
#include"isa_dio.h"
HANDLE hGpio;
hGpio = OpenGPIO( _T("PIO1:"));
添加Beep函數(shù),通過GPIO句柄操作GPIO15。
voidBeep()
{
GPIO_OutClear(hGpio, GPIO15);
Sleep(10);
GPIO_OutSet(hGpio, GPIO15);
}
添加鉤子
在主線程中調(diào)用SetWindowsHookEx函數(shù)向系統(tǒng)添加鉤子。
第一個(gè)參數(shù)為添加的鉤子類型,WH_KEYBOARD_LL為鍵盤鉤子,WH_MOUSE_LL為鼠標(biāo)鉤子。
第二個(gè)參數(shù)為注入的消息處理函數(shù)指針,即前面定義的鉤子函數(shù)。
第三個(gè)參數(shù)為鉤子程序的instance指針,本文介紹的鉤子并不需要掛載到dll中使用,所以簡單設(shè)置為NULL即可。
最后個(gè)參數(shù)為鉤子關(guān)聯(lián)的線程句柄,這里為0表示關(guān)聯(lián)所有線程,即全局鉤子。
函數(shù)返回NULL表示添加鉤子失敗,成功返回鉤子句柄。
示例代碼如下:
HINSTANCE hInstance = NULL;
HHOOK g_hKBDhook = NULL;
HHOOK g_hMouseHook = NULL;
g_hKBDhook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, hInstance, 0);
if(g_hKBDhook == NULL)
{
returnfalse;
}
g_hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, hInstance, 0);
if(g_hMouseHook == NULL)
{
returnfalse;
}
添加消息循環(huán)
鉤子機(jī)制是基于消息循環(huán)的,所以添加消息循環(huán)是必須的,如果沒有添加消息循環(huán),會導(dǎo)致系統(tǒng)消息進(jìn)入鉤子后卡死。
MFC框架的程序已經(jīng)自帶消息循環(huán)。
而命令行的程序則需要在主函數(shù)里添加以下代碼。
MSG msg;
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
刪除鉤子
當(dāng)不需要鉤子時(shí),應(yīng)當(dāng)主動(dòng)釋放鉤子。
UnhookWindowsHookEx(g_ hKBDhook);
UnhookWindowsHookEx(g_hMouseHook);
英創(chuàng)提供了例程及源代碼,有需要的客戶可以聯(lián)系英創(chuàng)工程師獲得。
-
WINDOWS
+關(guān)注
關(guān)注
4文章
3570瀏覽量
89312 -
嵌入式主板
+關(guān)注
關(guān)注
7文章
6086瀏覽量
35622
發(fā)布評論請先 登錄
相關(guān)推薦
龍芯中科榮獲2024年度信息技術(shù)應(yīng)用創(chuàng)新工作委員會卓越貢獻(xiàn)成員單位
芯盛智能榮獲2024年信息技術(shù)應(yīng)用創(chuàng)新工作委員會卓越貢獻(xiàn)成員單位
飛騰助力首屆教育信息技術(shù)應(yīng)用創(chuàng)新大賽圓滿落幕
有方科技參編的信息技術(shù)團(tuán)體標(biāo)準(zhǔn)發(fā)布
龍芯中科助力2024首屆教育信息技術(shù)應(yīng)用創(chuàng)新大賽成功舉辦
中科創(chuàng)達(dá)榮獲2024年軟件和信息技術(shù)服務(wù)優(yōu)秀企業(yè)
kvm切換器鼠標(biāo)鍵盤怎么設(shè)置
梯度科技入選2023年信息技術(shù)應(yīng)用創(chuàng)新解決方案名單
MSP430 FRAM技術(shù)–使用方法和最佳實(shí)踐
![MSP430 FRAM<b class='flag-5'>技術(shù)</b>–<b class='flag-5'>使用方法</b>和最佳實(shí)踐](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
esp-idf傳遞鼠標(biāo)數(shù)據(jù)延遲很大的原因?
USB口接鼠標(biāo)鍵盤可用,接U盤不能正常使用
翼輝信息入選2023年信息技術(shù)應(yīng)用創(chuàng)新解決方案名單
![翼輝<b class='flag-5'>信息</b>入選2023年<b class='flag-5'>信息技術(shù)</b>應(yīng)用創(chuàng)新解決方案名單](https://file1.elecfans.com/web2/M00/DF/08/wKgaomYtxPmAfMmRAAAXEv6laks393.jpg)
STM32F407 USB HOST HID部分鼠標(biāo)鍵盤無法讀取數(shù)據(jù)的原因?
龍芯中科三項(xiàng)信創(chuàng)方案入圍工信部2023年信息技術(shù)應(yīng)用創(chuàng)新應(yīng)用示范案例名單
![龍芯中科三項(xiàng)信<b class='flag-5'>創(chuàng)</b>方案入圍工信部2023年<b class='flag-5'>信息技術(shù)</b>應(yīng)用創(chuàng)新應(yīng)用示范案例名單](https://file1.elecfans.com/web2/M00/C3/19/wKgZomXpfwWAT16RAABpz-I0EpY201.png)
評論