c++钩子函数

    技术2026-08-25  7

    c++系统钩子应用实现步骤

    最近在学习c++钩子函数,在学习过程中得到了许多好友的帮助.特别是bdmh,daniel在此万分感谢.深深感到在学习c++的路上,知己很多,我不是一个人在战斗.结合自定义消息映射方面,作为学习的一个总结.Step1:创建win32动态链接库(an empty project DLL),命名为HookDLL

    1:增加一个类,命名为DLL.cpp

    2:增加头文件

    #include <windows.h>

    #include "DLL.h"

    3:创建全局变量

    #pragma data_seg("Shared")

    HHOOK mHook=NULL;

    HINSTANCE hInstance=NULL;

    #pragma data_seg()

    4:在DLL.cpp中增加实现几个函数

    a.钩子回调函数 LRESULT WINAPI KeyProc(int code,WPARAM wParam,LPARAM lParam)

    b. 入口函数

    BOOL APIENTRY DllMain( HANDLE hModule,

                               DWORD ul_reason_for_call,

                               LPVOID lpReserved)

    c. 供外界调用的启动与停止钩子函数

    extern "C" __declspec(dllexport) BOOL WINAPI Start()

    extern "C" __declspec(dllexport) void WINAPI Stop()

    d.自定义消息:#define WM_Hook WM_USER+100

    具体代码如下:

    LRESULT WINAPI KeyProc(int code,WPARAM wParam,LPARAM lParam)

    {

     if(code==HC_ACTION && (lParam & 0xc000ffff) ==1)

     {

      char *sName;

      BOOL b_sft=::GetAsyncKeyState (VK_SHIFT)>>((sizeof(short)*8)-1);

     if(b_sft)

     {

        switch(wParam)

        {

            case '1':sName="!"; break;

            case '2':sName="@"; break;

            case '3':sName = "#";break;

            case '4':sName = "$";break;

            case '5':sName = "%";break;

            case '6':sName = "^";break;

            case '7':sName = "&";break;

            case '8':sName = "*";break;

            case '9':sName = "(";break;

            case '0':sName = ")";break;

            case 'A':sName = "A";break;

            case 'B':sName = "B";break;

            case 'C':sName = "C";break;

            case 'D':sName = "D";break;

            case 'E':sName = "E";break;

            case 'F':sName = "F";break;

            case 'G':sName = "G";break;

            case 'H':sName = "H";break;

            case 'I':sName = "I";break;

            case 'J':sName = "J";break;

            case 'K':sName = "K";break;

            case 'L':sName = "L";break;

            case 'M':sName = "M";break;

            case 'N':sName = "N";break;

            case 'O':sName = "O";break;

            case 'P':sName = "P";break;

            case 'Q':sName = "Q";break;

            case 'R':sName = "R";break;

            case 'S':sName = "S";break;

            case 'T':sName = "T";break;

            case 'U':sName = "U";break;

            case 'V':sName = "V";break;

            case 'W':sName = "W";break;

            case 'X':sName = "X";break;

            case 'Y':sName = "Y";break;

            case 'Z':sName = "Z";break;

        }

     }

     else

     {

            switch(wParam)

            {

            /*0~9*/

            case '1': sName="1"; break;

            case '2':sName = "2";break;

            case '3':sName = "3";break;

            case '4':sName = "4";break;

            case '5':sName = "5";break;

            case '6':sName = "6";break;

            case '7':sName = "7";break;

            case '8':sName = "8";break;

            case '9':sName = "9";break;

            case '0':sName = "0";break;

            /*A~Z*/

            case 'A':sName = "a";break;

            case 'B':sName = "b";break;

            case 'C':sName = "c";break;

            case 'D':sName = "d";break;

            case 'E':sName = "e";break;

            case 'F':sName = "f";break;

            case 'G':sName = "g";break;

            case 'H':sName = "h";break;

            case 'I':sName = "i";break;

            case 'J':sName = "j";break;

            case 'K':sName = "k";break;

            case 'L':sName = "l";break;

            case 'M':sName = "m";break;

            case 'N':sName = "n";break;

            case 'O':sName = "o";break;

            case 'P':sName = "p";break;

            case 'Q':sName = "q";break;

            case 'R':sName = "r";break;

            case 'S':sName = "s";break;

            case 'T':sName = "t";break;

            case 'U':sName = "u";break;

            case 'V':sName = "v";break;

            case 'W':sName = "w";break;

            case 'X':sName = "x";break;

            case 'Y':sName = "y";break;

            case 'Z':sName = "z";break;

            }

     }

    switch(wParam) //数字键

    {

        case VK_BACK:sName="~"; break;

        case VK_NUMPAD1:sName="1";break;

        case VK_NUMPAD3:sName = "3";break;

        case VK_NUMPAD4:sName = "4";break;

        case VK_NUMPAD5:sName = "5";break;

        case VK_NUMPAD6:sName = "6";break;

        case VK_NUMPAD7:sName = "7";break;

        case VK_NUMPAD8:sName = "8";break;

        case VK_NUMPAD9:sName = "9";break;

        case VK_NUMPAD0:sName = "0";break;

        case VK_MULTIPLY:sName = "*";break;

        case VK_ADD:

        sName="+";

        break;

        case VK_SUBTRACT:

        sName="-";

        break;

        case VK_DECIMAL:

        sName=".";

        break;

        case VK_DIVIDE:

        sName="/";

        break;

    }

     HWND H_wnd=::GetForegroundWindow ();

     //自定义消息发送

    ::SendMessage (H_wnd,WM_Hook,wParam, (LPARAM)(LPCSTR)sName);

     MessageBox(H_wnd,sName,"键盘提示",MB_OK);

     

     }

     return CallNextHookEx( mHook, code, wParam, lParam );

    }

    BOOL APIENTRY DllMain(HANDLE hModule,

           DWORD ul_reason_for_call,

           LPVOID lpReserved)

    {

        switch(ul_reason_for_call)

        {

        case DLL_PROCESS_ATTACH:

        hInstance=(HINSTANCE)hModule;

        break;

        case DLL_THREAD_ATTACH:

        case DLL_THREAD_DETACH:

        case DLL_PROCESS_DETACH:

        break;

        }

    return TRUE;

    }

    extern "C" __declspec(dllexport) BOOL WINAPI Start()

    {

        if(mHook!=NULL)   return FALSE;

        //WH_KEYBOARD值为2,键盘消息钩子

        //KeyProc 为回调函数

        //hInstance:实例

        //0:表示全局钩子

        mHook=::SetWindowsHookEx (WH_KEYBOARD,KeyProc,hInstance,0);

        return mHook!=NULL;

    }

    extern "C" __declspec(dllexport) void WINAPI Stop()

    {

      //要卸载的钩子

     ::UnhookWindowsHookEx (mHook);

    }

    5.在DLL.h中加入如下函数定义

    extern "C" __declspec(dllexport) BOOL WINAPI Start();

    extern "C" __declspec(dllexport) void WINAPI Stop();

    编译生成HookDll.dll和HookDll.lib

    Step 2:

    1.新建MFC基本对话框应用程序,命名为HookTest,在其工作目录加入HookDll.dll和HookDll.lib

    2.在CHookTestDlg.cpp中加入如下引用

     

    //加入动态链接库的引用

    #include "DLL.h"

     

    //隐式调用库文件

    #pragma comment(lib,"HookDLL")

     

    3.加入自定义消息

    #define WM_Hook WM_USER+100

     

    4.加入消息映射

    BEGIN_MESSAGE_MAP(CHookTestDlg, CDialog) ON_MESSAGE(WM_Hook,OnReceive)  //增加部分END_MESSAGE_MAP()

     

    5.在CHookTestDlg.h中加入消息声明

    afx_msg void OnReceive(WPARAM wParam,LPARAM lParam);

     

    6.在对话框另加入两个按钮btnStart,btnStop,相应的代码为:

    void CHookTestDlg::OnbtnStartHook()

    {

        // TODO: Add your control notification handler code here

        Start();

    }

     

    void CHookTestDlg::OnbtnStopHook()

    {

        // TODO: Add your control notification handler code here

        Stop();

    }

     

    7.增加映射函数OnReceive的实现代码

     

    void CHookTestDlg::OnReceive (WPARAM wParam,LPARAM lParam){  CEdit * mEdit=(CEdit *)GetDlgItem(IDC_EDIT1); mEdit->SetWindowText ((LPCSTR)lParam); }

     

    Step 3:

    运行程序,点btnStart,按键盘上任意键如A,,将弹出一对话框,并且文本显示回传的A

     

     

    源代码URL:

     

     http://download.csdn.net/source/3035667

     

    最新回复(0)