zoukankan      html  css  js  c++  java
  • WINCE勾子使用方法(转)

    wince下支持三种钩子:

    1.#define WH_JOURNALRECORD 0使应用程序可以监视输入事件。典型地,应用程序使用该HOOK记录鼠标、键盘输入事件以供以后回放。该HOOK是全局HOOK,并且不能在指定线程中使用。

    2.#define WH_JOURNALPLAYBACK 1使应用程序可以向系统消息队列中插入消息。该HOOK可以回放以前由WH_JOURNALRECORD HOOK录制的鼠标、键盘输入事件。在WH_JOURNALPLAYBACK Hook安装到系统时,鼠标、键盘输入事件将被屏蔽。该HOOK同样是一个全局HOOK,不能在指定线程中使用。

    WH_JOURNALPLAYBACK Hook返回一个时间暂停值,它告诉系统,在处理当前回放的消息时,系统等待百分之几秒。这使得此HOOK可以控制在回放时的时间事件

    3.#define WH_KEYBOARD_LL 20 

     

    其中最常用的是键盘钩子,其它两个偶没有用过。

    1.  设置钩子
    通过SetWindowsHookEx ()函数。

    2.  释放钩子
    UnhookWindowsHookEx()函数。

    3.  钩子进程
    函数HookProc。

    4.  调用下一个钩子函数
    CallNexHookEx()函数。

     

    钩子的建立

    1.  建立一个动态连接库的.cpp文件。

    // KeyBoardHook.cpp : Defines the entry point for the DLL application.

    //

     

    #include "stdafx.h"

    #include "KeyBoardHook.h"

    #include <Pwinuser.h>

    #include "BasalMessage.h"

    //#include "FileManage.h"

     


    //告诉编译器将变量放入它自己的数据共享节中

    #pragma data_seg("KeyHookData")

    HINSTANCE hInst = NULL;

    #pragma data_seg()

     

    //告诉编译器设置共享节的访问方式为:读,写,共享

    #pragma comment(linker, "/SECTION:KeyHookData,RWS")

     

    BOOL APIENTRY DllMain( HANDLE hModule,

                           DWORD  ul_reason_for_call,

                           LPVOID lpReserved

                                  )

    {

        switch (ul_reason_for_call)

    {

            case DLL_PROCESS_ATTACH:

                   hInst = (HINSTANCE)hModule;

                   break;

            case DLL_THREAD_ATTACH:

            case DLL_THREAD_DETACH:

            case DLL_PROCESS_DETACH:

                   break;

        }

        return TRUE;

    }

     

     

    // This is an example of an exported variable

    KEYBOARDHOOK_API int nKeyBoardHook=0;

     

    // This is an example of an exported function.

    KEYBOARDHOOK_API int fnKeyBoardHook(void)

    {

    return 42;

    }

     

    // This is the constructor of a class that has been exported.

    // see KeyBoardHook.h for the class definition

    CKeyBoardHook::CKeyBoardHook()

    {

    return;

    }

     

    extern "C" KEYBOARDHOOK_API void InstallHook(void)

    {

    if (hInst)

    {

            hKeyHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyBoardProc, hInst, 0);

    }

    }

     

    extern "C" KEYBOARDHOOK_API void UnHook(void)

    {

    if (hKeyHook)

    {

            UnhookWindowsHookEx(hKeyHook);

            hKeyHook = NULL;

    }

     

    hInst = NULL;

    }

     

    extern "C" KEYBOARDHOOK_API LRESULT CALLBACK KeyBoardProc(int nCode, WPARAM wParam, LPARAM lParam)

    {

    TCHAR t_WndClassName[50] = { 0 };

    HWND hCurActiveWnd = NULL;

    HWND hCurForegroundWnd = NULL;

    BOOL bIsTaskBarMsg = FALSE;

    BOOL bIsOEMmsg = FALSE;

     

    PKBDLLHOOKSTRUCT pkbhs = (PKBDLLHOOKSTRUCT)lParam;

     

    if (WM_KEYDOWN == wParam)

    {

            uCount++;

            RETAILMSG(1, (TEXT("WM_KEYDOWN vk %d \r\n"),pkbhs->vkCode));

            //响应按键声,并限制需要向上Post的vkCode

            switch (pkbhs->vkCode)

            {

            case VK_UP:

                   break;

            case VK_DOWN:

                   break;

            case VK_LEFT:

                   break;

            case VK_RIGHT:

                   break;

            case VK_OEM_SELECT:

                   bIsOEMmsg = TRUE;

                   break;

            case VK_OEM_OK:

                   bIsOEMmsg = TRUE;

                   break;

            case VK_OEM_BACK:

                   bIsOEMmsg = TRUE;

                   break;

            case VK_OEM_DIAL:

                   bIsOEMmsg = TRUE;

                   break;

            case VK_NUMPAD1:

    case 0x31:

                   break;

            case VK_NUMPAD2:

    case 0x32:

                   break;

            case VK_NUMPAD3:

    case 0x33:

                   break;

            case VK_NUMPAD4:

    case 0x34:

                  break;

            case VK_NUMPAD5:

    case 0x35:

                   break;

            case VK_NUMPAD6:

    case 0x36:

                   break;

            case VK_NUMPAD7:

    case 0x37:

                   break;

            case VK_NUMPAD8:

    case 0x38:

                   break;

            case VK_NUMPAD9:

    case 0x39:

                   break;

            case VK_NUMPAD0:

    case 0x30:

                   break;

            case VK_OEM_ASTERISK:

                   bIsOEMmsg = TRUE;

                   break;

            case VK_OEM_POUND:

                   bIsOEMmsg = TRUE;

                   break;

            case VK_OEM_SIDEUP:

                   bIsOEMmsg = TRUE;

                   break;

            case VK_OEM_SIDEDOWN:

                   bIsOEMmsg = TRUE;

                   break;

            case VK_OEM_CAMERA:

                   bIsOEMmsg = TRUE;

                   break;

            default:

                   uCount = 0;

                   return CallNextHookEx(hKeyHook, nCode, wParam, lParam);    //继续传递消息

            }

     

            if (bNeedPassOnceMsg)

            {

                   return TRUE;

            }

     

            //只发送OEM消息,其它消息并不拦截。

            //拦截原消息,发送自定义消息。

            //限制需要向上Post的vkCode

            switch (pkbhs->vkCode)

            {

                          return CallNextHookEx(hKeyHook, nCode, wParam, (LPARAM)pkbhs);   //转换为回车消息传递(未测试)

    }

            case VK_OEM_OK:

            case VK_OEM_BACK:

            case VK_OEM_DIAL:

            case VK_OEM_DISCONNECT:

                   bIsOEMmsg = TRUE;

                   break;

            case VK_NUMPAD1:

            case VK_NUMPAD2:

            case VK_NUMPAD3:

            case VK_NUMPAD4:

            case VK_NUMPAD5:

           case VK_NUMPAD6:

            case VK_NUMPAD7:

            case VK_NUMPAD8:

            case VK_NUMPAD9:

            case VK_NUMPAD0:

    case 0x30:

    case 0x31:

    case 0x32:

    case 0x33:

    case 0x34:

    case 0x35:

    case 0x36:

    case 0x37:

    case 0x38:

    case 0x39:

                   break;

            case VK_OEM_ASTERISK:

            case VK_OEM_POUND:

            case VK_OEM_SIDEUP:

            case VK_OEM_SIDEDOWN:

            case VK_OEM_CAMERA:

                   bIsOEMmsg = TRUE;

                   break;

            default:

                   return CallNextHookEx(hKeyHook, nCode, wParam, lParam);    //继续传递消息

            }

     

            //只发送OEM消息,其它消息并不拦截。

            if (bOnlySendOEMMsg)

            {

                   if (bIsOEMmsg)

                   {

                          PostMessage(hTopWnd, WM_USER_KEYUP, (WPARAM)(pkbhs->vkCode), (LPARAM)uCount);

                          return TRUE;  //拦截OEM消息,不再向上传递此消息。                    

                   }

                   else

                   {

                          return CallNextHookEx(hKeyHook, nCode, wParam, lParam);    //继续传递其它消息

                   }

            }

     

            //拦截原消息,发送自定义消息。

            if (bHoldUpMsg)

            {//菜单未弹出的情况

                   PostMessage(hTopWnd, WM_USER_KEYUP, (WPARAM)(pkbhs->vkCode), 0L);

                   return TRUE;  //拦截消息,不再向上传递此消息。

            }

    }

    else

    {

            uCount = 0;

    }

     

    return CallNextHookEx(hKeyHook, nCode, wParam, lParam);    //继续传递消息

    }

     

    extern "C" KEYBOARDHOOK_API void SetAppHWND(HWND hCurAppWnd)

    {

    hAppWnd = hCurAppWnd;

    }

     

    extern "C" KEYBOARDHOOK_API void SetTopHWND(HWND hCurTopWnd)

    {

    hTopWnd = hCurTopWnd;

    }

     

    extern "C" KEYBOARDHOOK_API void SetHoldUpMsg(BOOL bHoldUp)

    {

    bHoldUpMsg = bHoldUp;

    }

     

    extern "C" KEYBOARDHOOK_API void SetOnlySendOEMMsg(BOOL bOnlySendOEM)

    {

    bOnlySendOEMMsg = bOnlySendOEM;

    }

     

    extern "C" KEYBOARDHOOK_API void SetNeedPassOnceMsg(BOOL bWhetherNeed)

    {

    bNeedPassOnceMsg = bWhetherNeed;

    }

    2.  建立头文件

     

    // The following ifdef block is the standard way of creating macros which make exporting

    // from a DLL simpler. All files within this DLL are compiled with the KEYBOARDHOOK_EXPORTS

    // symbol defined on the command line. this symbol should not be defined on any project

    // that uses this DLL. This way any other project whose source files include this file see

    // KEYBOARDHOOK_API functions as being imported from a DLL, wheras this DLL sees symbols

    // defined with this macro as being exported.

    #ifdef KEYBOARDHOOK_EXPORTS

    #define KEYBOARDHOOK_API __declspec(dllexport)

    #else

    #define KEYBOARDHOOK_API __declspec(dllimport)

    #endif

     

    // This class is exported from the KeyBoardHook.dll

    class KEYBOARDHOOK_API CKeyBoardHook {

    public:

    CKeyBoardHook(void);

    // TODO: add your methods here.

    };

     

    extern KEYBOARDHOOK_API int nKeyBoardHook;

     

    KEYBOARDHOOK_API int fnKeyBoardHook(void);

     

    extern "C" KEYBOARDHOOK_API void InstallHook(void);

    extern "C" KEYBOARDHOOK_API void UnHook(void);

    extern "C" KEYBOARDHOOK_API LRESULT CALLBACK KeyBoardProc(int nCode, WPARAM wParam, LPARAM lParam);

    extern "C" KEYBOARDHOOK_API void SetAppHWND(HWND hCurAppWnd);

    extern "C" KEYBOARDHOOK_API void SetTopHWND(HWND hCurTopWnd);

    extern "C" KEYBOARDHOOK_API void SetHoldUpMsg(BOOL bHoldUp);

    extern "C" KEYBOARDHOOK_API void SetOnlySendOEMMsg(BOOL bOnlySendOEM);

    extern "C" KEYBOARDHOOK_API void SetNeedPassOnceMsg(BOOL bWhetherNeed);

    3.  建立程序主文件

    if (hModule)

        {

            InHook = (pInstallHook)GetProcAddress(hModule, L"InstallHook");

            UnHook = (pUnHook)GetProcAddress(hModule, L"UnHook");

            SetAppHWND = (pSetAppHWND)GetProcAddress(hModule, L"SetAppHWND");

            SetTopHWND = (pSetTopHWND)GetProcAddress(hModule, L"SetTopHWND");

            SetHoldUpMsg = (pSetHoldUpMsg)GetProcAddress(hModule, L"SetHoldUpMsg");

            SetOnlySendOEMMsg = (pSetOnlySendOEMMsg)GetProcAddress(hModule, L"SetOnlySendOEMMsg");

            SetNeedPassOnceMsg = (pSetNeedPassOnceMsg)GetProcAddress(hModule, L"SetNeedPassOnceMsg");

     

            if (!InHook || !UnHook || !SetAppHWND || !SetTopHWND || !SetHoldUpMsg || !SetOnlySendOEMMsg || !SetNeedPassOnceMsg)

            {

                MessageBoxEx(hWnd, L"KeyboardHook.dll加载失败,程序被终止。", L"Info", MB_OK);

                PostQuitMessage(0);

            }

        }

        else

        {

            MessageBoxEx(hWnd, L"KeyboardHook.dll加载失败,程序被终止。", L"Info", MB_OK);

            PostQuitMessage(0);

        }

     

    InHook();

     

     

    DLL的编写,也可以参考以下网址中的内容:

    http://www.bc-cn.net/Article/kfyy/cyy/jszl/200709/6328_2.html

     

     

    WinCE上支持三种类型的Hook

    #define WH_JOURNALRECORD 0
    #define WH_JOURNALPLAYBACK 1
    #define WH_KEYBOARD_LL 20

    不过前两个使用的时候是使用如下函数:
    QASetWindowsJournalHook
    QAUnhookWindowsJournalHook

    后者使用SetWindowsHookExW和UnhookWindowsHookEx

  • 相关阅读:
    Web服务器推送技术【转】
    [转]vs2010 中文版下载地址及可用CDKEY
    [php] sae上的一个应用框架申请通过了
    [linux] ssh WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 问题解决
    [php] 调试利器
    [javascript] 邮箱&&电话正则
    [erlang] Erlang比较运算符 (Term Comparisons)
    [vim] gvim 折行
    [linux] 查看内存型号
    [linux] mtu查看&&设置
  • 原文地址:https://www.cnblogs.com/Jade2009/p/1454903.html
Copyright © 2011-2022 走看看