• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            君子性非異也,善假于物也。

            如有恒,何須三更起,半夜眠;最怕莫,三天打魚(yú)兩天曬網(wǎng),竹籃打水一場(chǎng)空!
            posts - 31, comments - 23, trackbacks - 0, articles - 30
              C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
            一、在WINDOWS鍵盤(pán)事件上掛接監(jiān)控函數(shù)的方法

            WINDOW下可進(jìn)行掛接的過(guò)濾函數(shù)包括11種:

            WH_CALLWNDPROC 窗口函數(shù)的過(guò)濾函數(shù)

            WH_CBT 計(jì)算機(jī)培訓(xùn)過(guò)濾函數(shù)

            WH_DEBUG 調(diào)試過(guò)濾函數(shù)

            WH_GETMESSAGE 獲取消息過(guò)濾函數(shù)

            WH_HARDWARE 硬件消息過(guò)濾函數(shù)

            WH_JOURNALPLAYBACK 消息重放過(guò)濾函數(shù)

            WH_JOURNALRECORD 消息記錄過(guò)濾函數(shù)

            WH_MOUSE 鼠標(biāo)過(guò)濾函數(shù)

            WH_MSGFILTER 消息過(guò)濾函數(shù)

            WH_SYSMSGFILTER 系統(tǒng)消息過(guò)濾函數(shù)

            WH_KEYBOARD 鍵盤(pán)過(guò)濾函數(shù)

            其中鍵盤(pán)過(guò)濾函數(shù)是最常用最有用的過(guò)濾函數(shù)類(lèi)型,不管是哪一種類(lèi)型的過(guò)濾函數(shù),其掛接的基本方法都是相同的。
            WINDOW調(diào)用掛接的反調(diào)函數(shù)時(shí)總是先調(diào)用掛接鏈?zhǔn)椎哪莻€(gè)函數(shù),因此必須將鍵盤(pán)掛鉤函數(shù)利用函數(shù)SetWindowsHookEx()將其掛接在函數(shù)鏈?zhǔn)住V劣谙⑹欠駛鬟f給函數(shù)鏈的下一個(gè)函數(shù)是由每個(gè)具體函數(shù)功能確定的,如果消息需要傳統(tǒng)給下一個(gè)函數(shù),可調(diào)用API函數(shù)的CallNextHookEx()來(lái)實(shí)現(xiàn),如果不傳遞直接返回即可。掛接函數(shù)可以是用來(lái)監(jiān)控所有線(xiàn)程消息的全局性函數(shù),也可以是單獨(dú)監(jiān)控某一線(xiàn)程的局部性函數(shù)。如果掛接函數(shù)是局部函數(shù),可以將它放到一個(gè).DLL動(dòng)態(tài)鏈接庫(kù)中,也可以放在一個(gè)局部模塊中;如果掛接函數(shù)是全局的,那么必須將其放在一個(gè).DLL動(dòng)態(tài)鏈接庫(kù)中。掛接函數(shù)必須嚴(yán)格按照下述格式進(jìn)行聲明,以鍵盤(pán)掛鉤函數(shù)為例:

            int FAR PASCAL KeyboardProc(int nCode,WORD wParam,DWORD lParam)

            其中KeyboardProc為定義掛接函數(shù)名,該函數(shù)必須在模塊定義文件中利用EXPORTS命令進(jìn)行說(shuō)明;nCode決定掛接函數(shù)是否對(duì)當(dāng)前消息進(jìn)行處理;wParam和lParam為具體的消息內(nèi)容。



            二、鍵盤(pán)事件掛接函數(shù)的安裝與下載

            在程序中可以利用函數(shù)SetWindowsHookEx()來(lái)掛接過(guò)濾函數(shù),在掛接函數(shù)時(shí)必須指出該掛接函數(shù)的類(lèi)型、函數(shù)的入口地址以及函數(shù)是全局性的還是局部性的,掛接函數(shù)的具體調(diào)用格式如下:

            SetWindowsHookEx(iType,iProc,hInst,iCode)

            其中iType為掛接函數(shù)類(lèi)型,鍵盤(pán)類(lèi)型為WH_KEYBOARD,iProc為掛接函數(shù)地址,hInst為掛接函數(shù)鏈接庫(kù)實(shí)例句柄,iCode為監(jiān)控代碼-0表示全局性函數(shù)。如果掛接函數(shù)需要將消息傳遞給下一個(gè)過(guò)濾函數(shù),則在該掛接函數(shù)返回前還需要調(diào)用一次CallNextHookEx()函數(shù),當(dāng)需要下載掛接函數(shù)時(shí),只要調(diào)用一次UnhookWindowsHookEx(iProc)函數(shù)即可實(shí)現(xiàn)。如果函數(shù)是全局性的,那么它必須放在一個(gè).DLL動(dòng)態(tài)鏈接庫(kù)中,這時(shí)該函數(shù)調(diào)用方法可以和其它普通.DLL函數(shù)一樣有三種:

            1.在DEF定義文件中直接用函數(shù)名或序號(hào)說(shuō)明:

            EXPORTS

            WEP @1 RESIDENTNAME

            InitHooksDll @2

            InstallFilter @3

            KeyboardProc @4

            用序號(hào)說(shuō)明格式為:鏈接庫(kù)名.函數(shù)名(如本例中說(shuō)明方法為KEYDLL.KeyboardProc)。

            2.在應(yīng)用程序中利用函數(shù)直接調(diào)用:

            首先在應(yīng)用程序中利用LoadLibrary(LPSTR "鏈接庫(kù)名")將動(dòng)態(tài)鏈接庫(kù)裝入,并取得裝載庫(kù)模塊句柄hInst,然后直接利用GetProcAddress(HINSTANCE hInst,LPSTR "函數(shù)過(guò)程名")獲取函數(shù)地址,然后直接調(diào)用該地址即可,程序結(jié)束前利用函數(shù)FreeLibrary( )釋放裝入的動(dòng)態(tài)鏈接庫(kù)即可。

            3.利用輸入庫(kù).LIB方法

            利用IMPLIB.EXE程序在建立動(dòng)態(tài)鏈接庫(kù)的同時(shí)建立相應(yīng)的輸入庫(kù).LIB,然后直接在項(xiàng)目文件中增加該輸入庫(kù)。



            三、WINDOWS掛鉤監(jiān)控函數(shù)的實(shí)現(xiàn)步驟

            WINDOWS掛鉤函數(shù)只有放在動(dòng)態(tài)鏈接庫(kù)DLL中才能實(shí)現(xiàn)所有事件的監(jiān)控功能。在.DLL中形成掛鉤監(jiān)控函數(shù)基本方法及其基本結(jié)構(gòu)如下:

            1、首先聲明DLL中的變量和過(guò)程;

            2、然后編制DLL主模塊LibMain(),建立模塊實(shí)例;

            3、建立系統(tǒng)退出DLL機(jī)制WEP()函數(shù);

            4、完成DLL初始化函數(shù)InitHooksDll(),傳遞主窗口程序句柄;

            5、編制掛鉤安裝和下載函數(shù)InstallFilter();

            6、編制掛鉤函數(shù)KeyboardProc(),在其中設(shè)置監(jiān)控功能,并確定繼續(xù)調(diào)下一個(gè)鉤

            子函數(shù)還是直接返回WINDOWS應(yīng)用程序。

            7、在WINDOWS主程序中需要初始化DLL并安裝相應(yīng)掛鉤函數(shù),由掛接的鉤子函數(shù)負(fù)

            責(zé)與主程序通信;

            8、在不需要監(jiān)控時(shí)由下載功能卸掉掛接函數(shù)。

            四、WINDOWS下鍵盤(pán)掛鉤監(jiān)控函數(shù)的應(yīng)用技術(shù)



            目前標(biāo)準(zhǔn)的104 鍵盤(pán)上都有兩個(gè)特殊的按鍵,其上分別用WINDOW程序徽標(biāo)和鼠標(biāo)下拉列表標(biāo)識(shí),本文暫且分別稱(chēng)為Micro左鍵和Micro右鍵,前者用來(lái)模擬鼠標(biāo)左鍵激活開(kāi)始菜單,后者用來(lái)模擬鼠標(biāo)右鍵激活屬性菜單。這兩個(gè)特殊按鍵只有在按下后立即抬起即完成 CLICK過(guò)程才能實(shí)現(xiàn)其功能,并且沒(méi)有和其它按鍵進(jìn)行組合使用。由于WINDOWS 系統(tǒng)中將按鍵劃分得更加詳細(xì),使應(yīng)用程序中很難靈活定義自己的專(zhuān)用快捷鍵,比如在開(kāi)發(fā).IME等應(yīng)用程序時(shí)很難找到不與WORD8.0等其它應(yīng)用程序沖突的功能按鍵。如果將標(biāo)準(zhǔn)104鍵盤(pán)中的這兩個(gè)特殊按鍵作為模擬CTRL和ALT 等專(zhuān)用按鍵,使其和其它按鍵組合,就可以在自己的應(yīng)用程序中自由地設(shè)置專(zhuān)用功能鍵,為應(yīng)用程序?qū)崿F(xiàn)各種功能快捷鍵提供靈活性。正常情況下WINDOWS 鍵盤(pán)事件驅(qū)動(dòng)程序并不將這兩個(gè)按鍵的消息進(jìn)行正常解釋?zhuān)@就必須利用鍵盤(pán)事件的掛鉤監(jiān)控函數(shù)來(lái)實(shí)現(xiàn)其特定的功能。其方法如下:

            1、首先編制如下一個(gè)簡(jiǎn)單動(dòng)態(tài)鏈接庫(kù)程序,并編譯成DLL文件。

            #include "windows.h"

            int FAR PASCAL LibMain(HANDLE hModule,UINT wDataSeg,UINT cbHeapSize,LPSTR lpszCmdLine);

            int WINAPI WEP(int bSystemExit);

            int WINAPI InitHooksDll(HWND hwndMainWindow);

            int WINAPI InstallFilter(BOOL nCode);

            LRESULT CALLBACK KeyHook(int nCode,WORD wParam,DWORD lParam);

            static HANDLE hInstance; // 全局句柄

            static HWND hWndMain; // 主窗口句柄

            static int InitCalled=0; // 初始化標(biāo)志

            static HHOOK hKeyHook;

            FARPROC lpfnKeyHook=(FARPROC)KeyHook;

            BOOL HookStates=FALSE;

            int FAR PASCAL LibMain(

            HANDLE hModule,

            UINT wDataSeg,

            UINT cbHeapSize,

            LPSTR lpszCmdLine)

            {

            if (cbHeapSize!=0) UnlockData(0);

            hInstance = hModule;

            return 1;

            }

            int WINAPI WEP (int bSystemExit)

            { return 1;}

            int WINAPI InitHooksDll(HWND hwndMainWindow)

            { hWndMain = hwndMainWindow;

            InitCalled = 1;

            return (0);

            }

            int WINAPI InstallFilter(BOOL nCode)

            { if (InitCalled==0) return (-1);

            if (nCode==TRUE) {

            hKeyHook=SetWindowsHookEx(WH_KEYBOARD,

            (HOOKPROC)lpfnKeyHook,hInstance,0);

            HookStates=TRUE;

            } else {

            UnhookWindowsHookEx(hKeyHook);

            HookStates=FALSE;

            }

            return(0);

            }

            LRESULT CALLBACK KeyHook(int nCode,WORD wParam,DWORD lParam)

            {

            static BOOL msflag=FALSE;

            if(nCode>=0) {

            if(HookStates==TRUE){

            if((wParam==0xff)|| //WIN3.X下按鍵值

            (wParam==0x5b)||(wParam==0x5c)){//WIN95下按鍵值

            if((i==0x15b)||(i==0x15c)){ //按鍵按下處理

            msflag=TRUE;

            PostMessage(hWndMain,0x7fff,0x1,0x3L);

            } else if((i==0xc15b)||(i==0xc15c)){//按鍵抬起處理

            msflag=FALSE;

            PostMessage(hWndMain,0x7fff,0x2,0x3L);

            }

            }

            }

            }

            return((int)CallNextHookEx(hKeyHook,nCode,wParam,lParam));

            }

            該程序的主要功能是監(jiān)控鍵盤(pán)按鍵消息,將兩個(gè)特殊按鍵Micro按下和抬起消息轉(zhuǎn)換成自定義類(lèi)型的消息,并將自定義消息發(fā)送給應(yīng)用程序主窗口函數(shù)。

            2、在應(yīng)用程序主函數(shù)中建立窗口后,調(diào)用InitHooksDll()函數(shù)來(lái)初始化動(dòng)態(tài)鏈接庫(kù),并將應(yīng)用程序主窗口句柄傳遞給鏈接庫(kù),然后調(diào)用InstallFilter()函數(shù)掛接鍵盤(pán)事件監(jiān)控回調(diào)函數(shù)。

            InitHooksDll(hIMEWnd); //初始化DLL

            InstallFilter(TRUE); //安裝鍵盤(pán)回調(diào)函數(shù)

            3、在應(yīng)用程序主窗口函數(shù)處理自定義消息時(shí),保存Micro按鍵的狀態(tài),供組合按鍵處理時(shí)判斷使用。

            switch (iMessage) {

            case 0x7fff: //自定義消息類(lèi)型

            if(lParam==0x3L){//設(shè)置Micro鍵的狀態(tài)

            if(wParam==0x1) MicroFlag=TRUE;

            else if(wParam==0x2) MicroFlag=FALSE;

            }

            break;

            4、在進(jìn)行按鍵組合處理時(shí),首先判斷Micro鍵是否按下,然后再進(jìn)行其它按鍵的判斷處理。

            case WM_KEYDOWN: // 按鍵按下處理

            if(MicroFlag==TRUE){//Micro鍵按下

            if((BYTE)HIBYTE(wParam)==0x5b){

            //Micro+"["組合鍵

            ......//按鍵功能處理

            } else if((BYTE)HIBYTE(wParam)==0x5d){

            //Micro+"]"組合鍵

            ......//按鍵功能處理

            }

            }

            break;

            5、當(dāng)應(yīng)用程序退出時(shí)應(yīng)注意下載鍵盤(pán)監(jiān)控函數(shù),即調(diào)用InstallFilter(FALSE)函數(shù)一次。

            6、利用本文提供的方法設(shè)置自己的應(yīng)用程序功能按鍵,在保證程序功能按鍵不會(huì)與其它系統(tǒng)發(fā)生沖突的同時(shí),有效地利用了系統(tǒng)中現(xiàn)有資源,而且在實(shí)現(xiàn)應(yīng)用程序功能的同時(shí)靈活應(yīng)用了系統(tǒng)中提供的各種功能調(diào)用。
            久久天天躁狠狠躁夜夜躁2O2O| 2021精品国产综合久久| 99久久er这里只有精品18| 亚洲午夜无码久久久久小说 | 国产精品久久久久一区二区三区| 一本一本久久aa综合精品| 亚洲人成无码www久久久| 亚洲国产成人久久一区WWW| 热久久国产欧美一区二区精品| 国产精品日韩深夜福利久久 | 亚洲国产精品无码久久久久久曰| 久久久久九九精品影院| 欧美性大战久久久久久| 亚洲精品美女久久久久99小说| 久久亚洲精品国产精品婷婷| 一级a性色生活片久久无少妇一级婬片免费放 | 久久久久99精品成人片试看| 久久免费的精品国产V∧| 亚洲人成网亚洲欧洲无码久久| 人妻无码αv中文字幕久久| 69SEX久久精品国产麻豆| AA级片免费看视频久久| 久久国产精品一区| 无码任你躁久久久久久老妇App| 久久99久国产麻精品66| 久久99国产综合精品免费| 成人精品一区二区久久| 久久只有这里有精品4| 久久超乳爆乳中文字幕| 久久久久久久久久免免费精品 | 无码国内精品久久人妻蜜桃| 国产精品视频久久久| 无码人妻久久一区二区三区蜜桃| 无码AV中文字幕久久专区| 国产AⅤ精品一区二区三区久久| 久久精品免费全国观看国产| 久久精品人人做人人妻人人玩| 开心久久婷婷综合中文字幕| 东京热TOKYO综合久久精品| 性做久久久久久久久久久| 狠狠色丁香婷综合久久|