zoukankan      html  css  js  c++  java
  • Hook编程

    SetWindowsHookEx

    UnhookWindowsHookEx

    LRESULT CALLBACK HookProc( int nCode , WPARAM wParam , LPARAM lParam )
    {
       // process event
       ...
    
       return CallNextHookEx(NULL, nCode, wParam, lParam);
    }
    HOOKPROC hkprcSysMsg;
    static HINSTANCE hinstDLL; 
    static HHOOK hhookSysMsg; 
     
    hinstDLL = LoadLibrary(TEXT("c:\myapp\sysmsg.dll")); 
    hkprcSysMsg = (HOOKPROC)GetProcAddress( hinstDLL , "SysMessageProc" ); 
    
    hhookSysMsg = SetWindowsHookEx( WH_SYSMSGFILTER , hkprcSysMsg , hinstDLL , 0 );
    #include <windows.h>
    #include <strsafe.h>
    #include "app.h"
    
    #pragma comment( lib, "user32.lib") 
    #pragma comment( lib, "gdi32.lib")
    
    #define NUMHOOKS 7 
     
    // Global variables 
     
    typedef struct _MYHOOKDATA 
    { 
        int nType; 
        HOOKPROC hkprc; 
        HHOOK hhook; 
    } MYHOOKDATA; 
     
    MYHOOKDATA myhookdata[NUMHOOKS]; 
    
    HWND gh_hwndMain;
    
    // Hook procedures
    
    LRESULT WINAPI CallWndProc(int, WPARAM, LPARAM);
    LRESULT WINAPI CBTProc(int, WPARAM, LPARAM);
    LRESULT WINAPI DebugProc(int, WPARAM, LPARAM);
    LRESULT WINAPI GetMsgProc(int, WPARAM, LPARAM);
    LRESULT WINAPI KeyboardProc(int, WPARAM, LPARAM);
    LRESULT WINAPI MouseProc(int, WPARAM, LPARAM);
    LRESULT WINAPI MessageProc(int, WPARAM, LPARAM);
    
    void LookUpTheMessage(PMSG, LPTSTR);
     
    LRESULT WINAPI MainWndProc(HWND hwndMain, UINT uMsg, WPARAM wParam, LPARAM lParam) 
    { 
        static BOOL afHooks[NUMHOOKS]; 
        int index; 
        static HMENU hmenu; 
     
        gh_hwndMain = hwndMain;
        
        switch (uMsg) 
        { 
            case WM_CREATE: 
     
                // Save the menu handle
     
                hmenu = GetMenu(hwndMain); 
     
                // Initialize structures with hook data. The menu-item identifiers are 
                // defined as 0 through 6 in the header file app.h. They can be used to 
                // identify array elements both here and during the WM_COMMAND message. 
     
                myhookdata[IDM_CALLWNDPROC].nType = WH_CALLWNDPROC; 
                myhookdata[IDM_CALLWNDPROC].hkprc = CallWndProc; 
                myhookdata[IDM_CBT].nType = WH_CBT; 
                myhookdata[IDM_CBT].hkprc = CBTProc; 
                myhookdata[IDM_DEBUG].nType = WH_DEBUG; 
                myhookdata[IDM_DEBUG].hkprc = DebugProc; 
                myhookdata[IDM_GETMESSAGE].nType = WH_GETMESSAGE; 
                myhookdata[IDM_GETMESSAGE].hkprc = GetMsgProc; 
                myhookdata[IDM_KEYBOARD].nType = WH_KEYBOARD; 
                myhookdata[IDM_KEYBOARD].hkprc = KeyboardProc; 
                myhookdata[IDM_MOUSE].nType = WH_MOUSE; 
                myhookdata[IDM_MOUSE].hkprc = MouseProc; 
                myhookdata[IDM_MSGFILTER].nType = WH_MSGFILTER; 
                myhookdata[IDM_MSGFILTER].hkprc = MessageProc; 
     
                // Initialize all flags in the array to FALSE. 
     
                memset(afHooks, FALSE, sizeof(afHooks)); 
     
                return 0; 
     
            case WM_COMMAND: 
                switch (LOWORD(wParam)) 
                { 
                     // The user selected a hook command from the menu. 
     
                    case IDM_CALLWNDPROC: 
                    case IDM_CBT: 
                    case IDM_DEBUG: 
                    case IDM_GETMESSAGE: 
                    case IDM_KEYBOARD: 
                    case IDM_MOUSE: 
                    case IDM_MSGFILTER: 
     
                        // Use the menu-item identifier as an index 
                        // into the array of structures with hook data. 
     
                        index = LOWORD(wParam); 
     
                        // If the selected type of hook procedure isn't 
                        // installed yet, install it and check the 
                        // associated menu item. 
     
                        if (!afHooks[index]) 
                        { 
                            myhookdata[index].hhook = SetWindowsHookEx( 
                                myhookdata[index].nType, 
                                myhookdata[index].hkprc, 
                                (HINSTANCE) NULL, GetCurrentThreadId()); 
                            CheckMenuItem(hmenu, index, 
                                MF_BYCOMMAND | MF_CHECKED); 
                            afHooks[index] = TRUE; 
                        } 
     
                        // If the selected type of hook procedure is 
                        // already installed, remove it and remove the 
                        // check mark from the associated menu item. 
     
                        else 
                        { 
                            UnhookWindowsHookEx(myhookdata[index].hhook); 
                            CheckMenuItem(hmenu, index, 
                                MF_BYCOMMAND | MF_UNCHECKED); 
                            afHooks[index] = FALSE; 
                        } 
     
                    default: 
                        return (DefWindowProc(hwndMain, uMsg, wParam, 
                            lParam)); 
                } 
                break; 
     
                //
                // Process other messages. 
                //
     
            default: 
                return DefWindowProc(hwndMain, uMsg, wParam, lParam); 
        } 
        return NULL; 
    } 
     
    /**************************************************************** 
      WH_CALLWNDPROC hook procedure 
     ****************************************************************/ 
     
    LRESULT WINAPI CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) 
    { 
        CHAR szCWPBuf[256]; 
        CHAR szMsg[16]; 
        HDC hdc; 
        static int c = 0; 
        size_t cch;
        HRESULT hResult; 
     
        if (nCode < 0)  // do not process message 
            return CallNextHookEx(myhookdata[IDM_CALLWNDPROC].hhook, nCode, wParam, lParam); 
     
        // Call an application-defined function that converts a message 
        // constant to a string and copies it to a buffer. 
     
        LookUpTheMessage((PMSG) lParam, szMsg); 
     
        hdc = GetDC(gh_hwndMain); 
     
        switch (nCode) 
        { 
            case HC_ACTION:
                hResult = StringCchPrintf(szCWPBuf, 256/sizeof(TCHAR),  
                   "CALLWNDPROC - tsk: %ld, msg: %s, %d times   ", 
                    wParam, szMsg, c++);
                if (FAILED(hResult))
                {
                // TODO: writer error handler
                }
                hResult = StringCchLength(szCWPBuf, 256/sizeof(TCHAR), &cch);
                if (FAILED(hResult))
                {
                // TODO: write error handler
                } 
                TextOut(hdc, 2, 15, szCWPBuf, cch); 
                break; 
     
            default: 
                break; 
        } 
     
        ReleaseDC(gh_hwndMain, hdc); 
        
        return CallNextHookEx(myhookdata[IDM_CALLWNDPROC].hhook, nCode, wParam, lParam); 
    } 
     
    /**************************************************************** 
      WH_GETMESSAGE hook procedure 
     ****************************************************************/ 
     
    LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) 
    { 
        CHAR szMSGBuf[256]; 
        CHAR szRem[16]; 
        CHAR szMsg[16]; 
        HDC hdc; 
        static int c = 0; 
        size_t cch; 
        HRESULT hResult;
     
        if (nCode < 0) // do not process message 
            return CallNextHookEx(myhookdata[IDM_GETMESSAGE].hhook, nCode, 
                wParam, lParam); 
     
        switch (nCode) 
        { 
            case HC_ACTION: 
                switch (wParam) 
                { 
                    case PM_REMOVE:
                        hResult = StringCchCopy(szRem, 16/sizeof(TCHAR), "PM_REMOVE");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                        break; 
     
                    case PM_NOREMOVE:
                        hResult = StringCchCopy(szRem, 16/sizeof(TCHAR), "PM_NOREMOVE");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                        break; 
     
                    default:
                        hResult = StringCchCopy(szRem, 16/sizeof(TCHAR), "Unknown");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                        break; 
                } 
     
                // Call an application-defined function that converts a 
                // message constant to a string and copies it to a 
                // buffer. 
     
                LookUpTheMessage((PMSG) lParam, szMsg); 
     
                hdc = GetDC(gh_hwndMain);
                hResult = StringCchPrintf(szMSGBuf, 256/sizeof(TCHAR), 
                    "GETMESSAGE - wParam: %s, msg: %s, %d times   ", 
                    szRem, szMsg, c++);
                if (FAILED(hResult))
                {
                // TODO: write error handler
                }
                hResult = StringCchLength(szMSGBuf, 256/sizeof(TCHAR), &cch);
                if (FAILED(hResult))
                {
                // TODO: write error handler
                } 
                TextOut(hdc, 2, 35, szMSGBuf, cch); 
                break; 
     
            default: 
                break; 
        } 
     
        ReleaseDC(gh_hwndMain, hdc); 
        
        return CallNextHookEx(myhookdata[IDM_GETMESSAGE].hhook, nCode, wParam, lParam); 
    } 
     
    /**************************************************************** 
      WH_DEBUG hook procedure 
     ****************************************************************/ 
     
    LRESULT CALLBACK DebugProc(int nCode, WPARAM wParam, LPARAM lParam) 
    { 
        CHAR szBuf[128]; 
        HDC hdc; 
        static int c = 0; 
        size_t cch; 
        HRESULT hResult;
     
        if (nCode < 0)  // do not process message 
            return CallNextHookEx(myhookdata[IDM_DEBUG].hhook, nCode, 
                wParam, lParam); 
     
        hdc = GetDC(gh_hwndMain); 
     
        switch (nCode) 
        { 
            case HC_ACTION:
                hResult = StringCchPrintf(szBuf, 128/sizeof(TCHAR),   
                    "DEBUG - nCode: %d, tsk: %ld, %d times   ", 
                    nCode,wParam, c++);
                if (FAILED(hResult))
                {
                // TODO: write error handler
                }
                hResult = StringCchLength(szBuf, 128/sizeof(TCHAR), &cch);
                if (FAILED(hResult))
                {
                // TODO: write error handler
                } 
                TextOut(hdc, 2, 55, szBuf, cch); 
                break; 
     
            default: 
                break; 
        } 
     
        ReleaseDC(gh_hwndMain, hdc); 
        
        return CallNextHookEx(myhookdata[IDM_DEBUG].hhook, nCode, wParam, lParam); 
    } 
     
    /**************************************************************** 
      WH_CBT hook procedure 
     ****************************************************************/ 
     
    LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam) 
    { 
        CHAR szBuf[128]; 
        CHAR szCode[128]; 
        HDC hdc; 
        static int c = 0; 
        size_t cch; 
        HRESULT hResult;
     
        if (nCode < 0)  // do not process message 
            return CallNextHookEx(myhookdata[IDM_CBT].hhook, nCode, wParam, 
                lParam); 
     
        hdc = GetDC(gh_hwndMain); 
     
        switch (nCode) 
        { 
            case HCBT_ACTIVATE:
                hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), "HCBT_ACTIVATE");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                break; 
     
            case HCBT_CLICKSKIPPED:
                hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), "HCBT_CLICKSKIPPED");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                break; 
     
            case HCBT_CREATEWND:
                hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), "HCBT_CREATEWND");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                break; 
     
            case HCBT_DESTROYWND:
                hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), "HCBT_DESTROYWND");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                break; 
     
            case HCBT_KEYSKIPPED:
                hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), "HCBT_KEYSKIPPED");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                break; 
     
            case HCBT_MINMAX:
                hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), "HCBT_MINMAX");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                break; 
     
            case HCBT_MOVESIZE:
                hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), "HCBT_MOVESIZE");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                break; 
     
            case HCBT_QS:
                hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), "HCBT_QS");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                break; 
     
            case HCBT_SETFOCUS:
                hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), "HCBT_SETFOCUS");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                break; 
     
            case HCBT_SYSCOMMAND:
                hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), "HCBT_SYSCOMMAND");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                break; 
     
            default:
                hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), "Unknown");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                break; 
        } 
        hResult = StringCchPrintf(szBuf, 128/sizeof(TCHAR), "CBT -  nCode: %s, tsk: %ld, %d times   ",
            szCode, wParam, c++);
        if (FAILED(hResult))
        {
        // TODO: write error handler
        }
        hResult = StringCchLength(szBuf, 128/sizeof(TCHAR), &cch);
        if (FAILED(hResult))
        {
        // TODO: write error handler
        } 
        TextOut(hdc, 2, 75, szBuf, cch); 
        ReleaseDC(gh_hwndMain, hdc); 
        
        return CallNextHookEx(myhookdata[IDM_CBT].hhook, nCode, wParam, lParam); 
    } 
     
    /**************************************************************** 
      WH_MOUSE hook procedure 
     ****************************************************************/ 
     
    LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) 
    { 
        CHAR szBuf[128]; 
        CHAR szMsg[16]; 
        HDC hdc; 
        static int c = 0; 
        size_t cch; 
        HRESULT hResult;
     
        if (nCode < 0)  // do not process the message 
            return CallNextHookEx(myhookdata[IDM_MOUSE].hhook, nCode, 
                wParam, lParam); 
     
        // Call an application-defined function that converts a message 
        // constant to a string and copies it to a buffer. 
     
        LookUpTheMessage((PMSG) lParam, szMsg); 
     
        hdc = GetDC(gh_hwndMain);
        hResult = StringCchPrintf(szBuf, 128/sizeof(TCHAR), 
            "MOUSE - nCode: %d, msg: %s, x: %d, y: %d, %d times   ", 
            nCode, szMsg, LOWORD(lParam), HIWORD(lParam), c++); 
        if (FAILED(hResult))
        {
        // TODO: write error handler
        }
        hResult = StringCchLength(szBuf, 128/sizeof(TCHAR), &cch);
        if (FAILED(hResult))
        {
        // TODO: write error handler
        }
        TextOut(hdc, 2, 95, szBuf, cch); 
        ReleaseDC(gh_hwndMain, hdc); 
        
        return CallNextHookEx(myhookdata[IDM_MOUSE].hhook, nCode, wParam, lParam); 
    } 
     
    /**************************************************************** 
      WH_KEYBOARD hook procedure 
     ****************************************************************/ 
     
    LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 
    { 
        CHAR szBuf[128]; 
        HDC hdc; 
        static int c = 0; 
        size_t cch; 
        HRESULT hResult;
     
        if (nCode < 0)  // do not process message 
            return CallNextHookEx(myhookdata[IDM_KEYBOARD].hhook, nCode, 
                wParam, lParam); 
     
        hdc = GetDC(gh_hwndMain);
        hResult = StringCchPrintf(szBuf, 128/sizeof(TCHAR), "KEYBOARD - nCode: %d, vk: %d, %d times ", nCode, wParam, c++);
        if (FAILED(hResult))
        {
        // TODO: write error handler
        } 
        hResult = StringCchLength(szBuf, 128/sizeof(TCHAR), &cch);
        if (FAILED(hResult))
        {
        // TODO: write error handler
        } 
        TextOut(hdc, 2, 115, szBuf, cch); 
        ReleaseDC(gh_hwndMain, hdc); 
        
        return CallNextHookEx(myhookdata[IDM_KEYBOARD].hhook, nCode, wParam, lParam); 
    } 
     
    /**************************************************************** 
      WH_MSGFILTER hook procedure 
     ****************************************************************/ 
     
    LRESULT CALLBACK MessageProc(int nCode, WPARAM wParam, LPARAM lParam) 
    { 
        CHAR szBuf[128]; 
        CHAR szMsg[16]; 
        CHAR szCode[32]; 
        HDC hdc; 
        static int c = 0; 
        size_t cch; 
        HRESULT hResult;
     
        if (nCode < 0)  // do not process message 
            return CallNextHookEx(myhookdata[IDM_MSGFILTER].hhook, nCode, 
                wParam, lParam); 
     
        switch (nCode) 
        { 
            case MSGF_DIALOGBOX:
                hResult = StringCchCopy(szCode, 32/sizeof(TCHAR), "MSGF_DIALOGBOX");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                break; 
     
            case MSGF_MENU:
                hResult = StringCchCopy(szCode, 32/sizeof(TCHAR), "MSGF_MENU");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                break; 
     
            case MSGF_SCROLLBAR:
                hResult = StringCchCopy(szCode, 32/sizeof(TCHAR), "MSGF_SCROLLBAR");
                        if (FAILED(hResult))
                        {
                        // TODO: write error handler
                        } 
                break; 
     
            default:
                hResult = StringCchPrintf(szCode, 128/sizeof(TCHAR), "Unknown: %d", nCode);
        if (FAILED(hResult))
        {
        // TODO: write error handler
        }
                break; 
        } 
     
        // Call an application-defined function that converts a message 
        // constant to a string and copies it to a buffer. 
     
        LookUpTheMessage((PMSG) lParam, szMsg); 
     
        hdc = GetDC(gh_hwndMain);
        hResult = StringCchPrintf(szBuf, 128/sizeof(TCHAR),  
            "MSGFILTER  nCode: %s, msg: %s, %d times    ", 
            szCode, szMsg, c++);
        if (FAILED(hResult))
        {
        // TODO: write error handler
        } 
        hResult = StringCchLength(szBuf, 128/sizeof(TCHAR), &cch);
        if (FAILED(hResult))
        {
        // TODO: write error handler
        } 
        TextOut(hdc, 2, 135, szBuf, cch); 
        ReleaseDC(gh_hwndMain, hdc); 
        
        return CallNextHookEx(myhookdata[IDM_MSGFILTER].hhook, nCode, wParam, lParam); 
    }

    You can release a global hook procedure by using UnhookWindowsHookEx, but this function does not free the DLL containing the hook procedure. This is because global hook procedures are called in the process context of every application in the desktop, causing an implicit call to the LoadLibrary function for all of those processes. Because a call to the FreeLibrary function cannot be made for another process, there is then no way to free the DLL. The system eventually frees the DLL after all processes explicitly linked to the DLL have either terminated or called FreeLibrary and all processes that called the hook procedure have resumed processing outside the DLL.

    An alternative method for installing a global hook procedure is to provide an installation function in the DLL, along with the hook procedure. With this method, the installing application does not need the handle to the DLL module. By linking with the DLL, the application gains access to the installation function. The installation function can supply the DLL module handle and other details in the call to SetWindowsHookEx. The DLL can also contain a function that releases the global hook procedure; the application can call this hook-releasing function when terminating.

  • 相关阅读:
    cmake学习笔记之add_library、target_link_libraries和link_directories
    Linux的.a、.so和.o文件及链接时的命名
    【CH2401】送礼物
    【POJ1011】Sticks
    【CH2101】可达性统计
    【CH2201】小猫爬山
    【HNOI2002】营业额统计
    【洛谷P3128】最大流
    【JLOI2014】松鼠的新家
    【洛谷P4552】IncDec Sequence
  • 原文地址:https://www.cnblogs.com/cnstalker/p/7157770.html
Copyright © 2011-2022 走看看