• <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>

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

            如有恒,何須三更起,半夜眠;最怕莫,三天打魚兩天曬網,竹籃打水一場空!
            posts - 31, comments - 23, trackbacks - 0, articles - 30
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            [轉]WINDOWS鍵盤事件監控原理及應用

            Posted on 2006-10-15 12:37 neter 閱讀(345) 評論(0)  編輯 收藏 引用 所屬分類: 程序設計
            一、在WINDOWS鍵盤事件上掛接監控函數的方法

            WINDOW下可進行掛接的過濾函數包括11種:

            WH_CALLWNDPROC 窗口函數的過濾函數

            WH_CBT 計算機培訓過濾函數

            WH_DEBUG 調試過濾函數

            WH_GETMESSAGE 獲取消息過濾函數

            WH_HARDWARE 硬件消息過濾函數

            WH_JOURNALPLAYBACK 消息重放過濾函數

            WH_JOURNALRECORD 消息記錄過濾函數

            WH_MOUSE 鼠標過濾函數

            WH_MSGFILTER 消息過濾函數

            WH_SYSMSGFILTER 系統消息過濾函數

            WH_KEYBOARD 鍵盤過濾函數

            其中鍵盤過濾函數是最常用最有用的過濾函數類型,不管是哪一種類型的過濾函數,其掛接的基本方法都是相同的。
            WINDOW調用掛接的反調函數時總是先調用掛接鏈首的那個函數,因此必須將鍵盤掛鉤函數利用函數SetWindowsHookEx()將其掛接在函數鏈首。至于消息是否傳遞給函數鏈的下一個函數是由每個具體函數功能確定的,如果消息需要傳統給下一個函數,可調用API函數的CallNextHookEx()來實現,如果不傳遞直接返回即可。掛接函數可以是用來監控所有線程消息的全局性函數,也可以是單獨監控某一線程的局部性函數。如果掛接函數是局部函數,可以將它放到一個.DLL動態鏈接庫中,也可以放在一個局部模塊中;如果掛接函數是全局的,那么必須將其放在一個.DLL動態鏈接庫中。掛接函數必須嚴格按照下述格式進行聲明,以鍵盤掛鉤函數為例:

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

            其中KeyboardProc為定義掛接函數名,該函數必須在模塊定義文件中利用EXPORTS命令進行說明;nCode決定掛接函數是否對當前消息進行處理;wParam和lParam為具體的消息內容。



            二、鍵盤事件掛接函數的安裝與下載

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

            SetWindowsHookEx(iType,iProc,hInst,iCode)

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

            1.在DEF定義文件中直接用函數名或序號說明:

            EXPORTS

            WEP @1 RESIDENTNAME

            InitHooksDll @2

            InstallFilter @3

            KeyboardProc @4

            用序號說明格式為:鏈接庫名.函數名(如本例中說明方法為KEYDLL.KeyboardProc)。

            2.在應用程序中利用函數直接調用:

            首先在應用程序中利用LoadLibrary(LPSTR "鏈接庫名")將動態鏈接庫裝入,并取得裝載庫模塊句柄hInst,然后直接利用GetProcAddress(HINSTANCE hInst,LPSTR "函數過程名")獲取函數地址,然后直接調用該地址即可,程序結束前利用函數FreeLibrary( )釋放裝入的動態鏈接庫即可。

            3.利用輸入庫.LIB方法

            利用IMPLIB.EXE程序在建立動態鏈接庫的同時建立相應的輸入庫.LIB,然后直接在項目文件中增加該輸入庫。



            三、WINDOWS掛鉤監控函數的實現步驟

            WINDOWS掛鉤函數只有放在動態鏈接庫DLL中才能實現所有事件的監控功能。在.DLL中形成掛鉤監控函數基本方法及其基本結構如下:

            1、首先聲明DLL中的變量和過程;

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

            3、建立系統退出DLL機制WEP()函數;

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

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

            6、編制掛鉤函數KeyboardProc(),在其中設置監控功能,并確定繼續調下一個鉤

            子函數還是直接返回WINDOWS應用程序。

            7、在WINDOWS主程序中需要初始化DLL并安裝相應掛鉤函數,由掛接的鉤子函數負

            責與主程序通信;

            8、在不需要監控時由下載功能卸掉掛接函數。

            四、WINDOWS下鍵盤掛鉤監控函數的應用技術



            目前標準的104 鍵盤上都有兩個特殊的按鍵,其上分別用WINDOW程序徽標和鼠標下拉列表標識,本文暫且分別稱為Micro左鍵和Micro右鍵,前者用來模擬鼠標左鍵激活開始菜單,后者用來模擬鼠標右鍵激活屬性菜單。這兩個特殊按鍵只有在按下后立即抬起即完成 CLICK過程才能實現其功能,并且沒有和其它按鍵進行組合使用。由于WINDOWS 系統中將按鍵劃分得更加詳細,使應用程序中很難靈活定義自己的專用快捷鍵,比如在開發.IME等應用程序時很難找到不與WORD8.0等其它應用程序沖突的功能按鍵。如果將標準104鍵盤中的這兩個特殊按鍵作為模擬CTRL和ALT 等專用按鍵,使其和其它按鍵組合,就可以在自己的應用程序中自由地設置專用功能鍵,為應用程序實現各種功能快捷鍵提供靈活性。正常情況下WINDOWS 鍵盤事件驅動程序并不將這兩個按鍵的消息進行正常解釋,這就必須利用鍵盤事件的掛鉤監控函數來實現其特定的功能。其方法如下:

            1、首先編制如下一個簡單動態鏈接庫程序,并編譯成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; // 初始化標志

            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));

            }

            該程序的主要功能是監控鍵盤按鍵消息,將兩個特殊按鍵Micro按下和抬起消息轉換成自定義類型的消息,并將自定義消息發送給應用程序主窗口函數。

            2、在應用程序主函數中建立窗口后,調用InitHooksDll()函數來初始化動態鏈接庫,并將應用程序主窗口句柄傳遞給鏈接庫,然后調用InstallFilter()函數掛接鍵盤事件監控回調函數。

            InitHooksDll(hIMEWnd); //初始化DLL

            InstallFilter(TRUE); //安裝鍵盤回調函數

            3、在應用程序主窗口函數處理自定義消息時,保存Micro按鍵的狀態,供組合按鍵處理時判斷使用。

            switch (iMessage) {

            case 0x7fff: //自定義消息類型

            if(lParam==0x3L){//設置Micro鍵的狀態

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

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

            }

            break;

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

            case WM_KEYDOWN: // 按鍵按下處理

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

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

            //Micro+"["組合鍵

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

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

            //Micro+"]"組合鍵

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

            }

            }

            break;

            5、當應用程序退出時應注意下載鍵盤監控函數,即調用InstallFilter(FALSE)函數一次。

            6、利用本文提供的方法設置自己的應用程序功能按鍵,在保證程序功能按鍵不會與其它系統發生沖突的同時,有效地利用了系統中現有資源,而且在實現應用程序功能的同時靈活應用了系統中提供的各種功能調用。
            精品久久久久久亚洲精品| 久久精品国产99久久久| 精品多毛少妇人妻AV免费久久| 狠狠干狠狠久久| 久久国产乱子伦精品免费午夜| 色综合久久夜色精品国产| 色综合久久久久无码专区| 国产精品一区二区久久不卡| 国产2021久久精品| 色青青草原桃花久久综合| 国产精品国色综合久久| 久久高潮一级毛片免费| 久久精品亚洲一区二区三区浴池| 99热都是精品久久久久久| 亚洲日韩欧美一区久久久久我| www久久久天天com| 色综合久久夜色精品国产| 国产福利电影一区二区三区久久久久成人精品综合 | 久久人人爽人人爽AV片| 精品综合久久久久久98| 品成人欧美大片久久国产欧美... 品成人欧美大片久久国产欧美 | 综合久久久久久中文字幕亚洲国产国产综合一区首| 亚洲欧美成人久久综合中文网| 久久99国产精品99久久| 久久久一本精品99久久精品88| 久久这里有精品| 久久综合精品国产一区二区三区| A狠狠久久蜜臀婷色中文网| 超级97碰碰碰碰久久久久最新| 久久久WWW成人免费毛片| 久久99精品国产99久久| 99久久精品日本一区二区免费| 久久久久久久久久久久久久| 亚洲另类欧美综合久久图片区| 久久综合久久鬼色| 久久天天躁狠狠躁夜夜2020老熟妇| 亚洲国产精品久久久久| 国产伊人久久| 久久成人永久免费播放| 欧美午夜A∨大片久久| 日本亚洲色大成网站WWW久久 |