• EVC编程点滴四


    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文件。

      1 // KeyBoardHook.cpp : Defines the entry point for the DLL application.
      2 //
      3  
      4 #include "stdafx.h"
      5 #include "KeyBoardHook.h"
      6 #include <Pwinuser.h>
      7 #include "BasalMessage.h"
      8 //#include "FileManage.h"
      9  
     10 //告诉编译器将变量放入它自己的数据共享节中
     11 #pragma data_seg("KeyHookData")
     12 HINSTANCE hInst = NULL;
     13 #pragma data_seg()
     14  
     15 //告诉编译器设置共享节的访问方式为:读,写,共享
     16 #pragma comment(linker, "/SECTION:KeyHookData,RWS") 
     17  
     18 BOOL APIENTRY DllMain( HANDLE hModule,
     19                        DWORD  ul_reason_for_call,
     20                        LPVOID lpReserved
     21                               )
     22 {
     23     switch (ul_reason_for_call)
     24 {
     25         case DLL_PROCESS_ATTACH:
     26                hInst = (HINSTANCE)hModule;
     27                break;
     28         case DLL_THREAD_ATTACH:
     29         case DLL_THREAD_DETACH:
     30         case DLL_PROCESS_DETACH:
     31                break;
     32     }
     33     return TRUE;
     34 }
     35  
     36  
     37 // This is an example of an exported variable
     38 KEYBOARDHOOK_API int nKeyBoardHook=0;
     39  
     40 // This is an example of an exported function.
     41 KEYBOARDHOOK_API int fnKeyBoardHook(void)
     42 {
     43 return 42;
     44 }
     45  
     46 // This is the constructor of a class that has been exported.
     47 // see KeyBoardHook.h for the class definition
     48 CKeyBoardHook::CKeyBoardHook()
     49 {
     50 return;
     51 }
     52   
     53 extern "C" KEYBOARDHOOK_API void InstallHook(void)
     54 {
     55 if (hInst)
     56 {
     57         hKeyHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyBoardProc, hInst, 0);
     58 }
     59 }
     60  
     61 extern "C" KEYBOARDHOOK_API void UnHook(void)
     62 {
     63 if (hKeyHook)
     64 {
     65         UnhookWindowsHookEx(hKeyHook);
     66         hKeyHook = NULL;
     67 }
     68  
     69 hInst = NULL;
     70 }
     71  
     72 extern "C" KEYBOARDHOOK_API LRESULT CALLBACK KeyBoardProc(int nCode, WPARAM wParam, LPARAM lParam)
     73 {
     74 TCHAR t_WndClassName[50] = { 0 };
     75 HWND hCurActiveWnd = NULL;
     76 HWND hCurForegroundWnd = NULL;
     77 BOOL bIsTaskBarMsg = FALSE;
     78 BOOL bIsOEMmsg = FALSE;
     79  
     80 PKBDLLHOOKSTRUCT pkbhs = (PKBDLLHOOKSTRUCT)lParam;
     81  
     82 if (WM_KEYDOWN == wParam)
     83 {
     84         uCount++;
     85         RETAILMSG(1, (TEXT("WM_KEYDOWN vk %d /r/n"),pkbhs->vkCode));
     86         //响应按键声,并限制需要向上Post的vkCode
     87         switch (pkbhs->vkCode)
     88         {
     89         case VK_UP:
     90                break;
     91         case VK_DOWN:
     92                break;
     93         case VK_LEFT:
     94                break;
     95         case VK_RIGHT:
     96                break;
     97         case VK_OEM_SELECT:
     98                bIsOEMmsg = TRUE;
     99                break;
    100         case VK_OEM_OK:
    101                bIsOEMmsg = TRUE;
    102                break;
    103         case VK_OEM_BACK:
    104                bIsOEMmsg = TRUE;
    105                break;
    106         case VK_OEM_DIAL:
    107                bIsOEMmsg = TRUE;
    108                break;
    109         case VK_NUMPAD1:
    110 case 0x31:
    111                break;
    112         case VK_NUMPAD2:
    113 case 0x32:
    114                break;
    115         case VK_NUMPAD3:
    116 case 0x33:
    117                break;
    118         case VK_NUMPAD4:
    119 case 0x34:
    120               break;
    121         case VK_NUMPAD5:
    122 case 0x35:
    123                break;
    124         case VK_NUMPAD6:
    125 case 0x36:
    126                break;
    127         case VK_NUMPAD7:
    128 case 0x37:
    129                break;
    130         case VK_NUMPAD8:
    131 case 0x38:
    132                break;
    133         case VK_NUMPAD9:
    134 case 0x39:
    135                break;
    136         case VK_NUMPAD0:
    137 case 0x30:
    138                break;
    139         case VK_OEM_ASTERISK:
    140                bIsOEMmsg = TRUE;
    141                break;
    142         case VK_OEM_POUND:
    143                bIsOEMmsg = TRUE;
    144                break;
    145         case VK_OEM_SIDEUP:
    146                bIsOEMmsg = TRUE;
    147                break;
    148         case VK_OEM_SIDEDOWN:
    149                bIsOEMmsg = TRUE;
    150                break;
    151         case VK_OEM_CAMERA:
    152                bIsOEMmsg = TRUE;
    153                break;
    154         default:
    155                uCount = 0;
    156                return CallNextHookEx(hKeyHook, nCode, wParam, lParam);    //继续传递消息
    157         }
    158  
    159         if (bNeedPassOnceMsg)
    160         {
    161                return TRUE;
    162         }
    163  
    164         //只发送OEM消息,其它消息并不拦截。
    165         //拦截原消息,发送自定义消息。
    166         //限制需要向上Post的vkCode
    167         switch (pkbhs->vkCode)
    168         {
    169                       return CallNextHookEx(hKeyHook, nCode, wParam, (LPARAM)pkbhs);   //转换为回车消息传递(未测试)
    170 }
    171         case VK_OEM_OK:
    172         case VK_OEM_BACK:
    173         case VK_OEM_DIAL:
    174         case VK_OEM_DISCONNECT:
    175                bIsOEMmsg = TRUE;
    176                break;
    177         case VK_NUMPAD1:
    178         case VK_NUMPAD2:
    179         case VK_NUMPAD3:
    180         case VK_NUMPAD4:
    181         case VK_NUMPAD5:
    182        case VK_NUMPAD6:
    183         case VK_NUMPAD7:
    184         case VK_NUMPAD8:
    185         case VK_NUMPAD9:
    186         case VK_NUMPAD0:
    187 case 0x30:
    188 case 0x31:
    189 case 0x32:
    190 case 0x33:
    191 case 0x34:
    192 case 0x35:
    193 case 0x36:
    194 case 0x37:
    195 case 0x38:
    196 case 0x39:
    197                break;
    198         case VK_OEM_ASTERISK:
    199         case VK_OEM_POUND:
    200         case VK_OEM_SIDEUP:
    201         case VK_OEM_SIDEDOWN:
    202         case VK_OEM_CAMERA:
    203                bIsOEMmsg = TRUE;
    204                break;
    205         default:
    206                return CallNextHookEx(hKeyHook, nCode, wParam, lParam);    //继续传递消息
    207         }
    208  
    209         //只发送OEM消息,其它消息并不拦截。
    210         if (bOnlySendOEMMsg)
    211         {
    212                if (bIsOEMmsg)
    213                {
    214                       PostMessage(hTopWnd, WM_USER_KEYUP, (WPARAM)(pkbhs->vkCode), (LPARAM)uCount);
    215                       return TRUE;  //拦截OEM消息,不再向上传递此消息。                    
    216                }
    217                else
    218                {
    219                       return CallNextHookEx(hKeyHook, nCode, wParam, lParam);    //继续传递其它消息
    220                }
    221         }
    222  
    223         //拦截原消息,发送自定义消息。
    224         if (bHoldUpMsg)
    225         {//菜单未弹出的情况
    226                PostMessage(hTopWnd, WM_USER_KEYUP, (WPARAM)(pkbhs->vkCode), 0L);
    227                return TRUE;  //拦截消息,不再向上传递此消息。
    228         }
    229 }
    230 else
    231 {
    232         uCount = 0;
    233 }
    234  
    235 return CallNextHookEx(hKeyHook, nCode, wParam, lParam);    //继续传递消息
    236 }
    237  
    238 extern "C" KEYBOARDHOOK_API void SetAppHWND(HWND hCurAppWnd)
    239 {
    240 hAppWnd = hCurAppWnd;
    241 }
    242  
    243 extern "C" KEYBOARDHOOK_API void SetTopHWND(HWND hCurTopWnd)
    244 {
    245 hTopWnd = hCurTopWnd;
    246 }
    247  
    248 extern "C" KEYBOARDHOOK_API void SetHoldUpMsg(BOOL bHoldUp)
    249 {
    250 bHoldUpMsg = bHoldUp;
    251 }
    252  
    253 extern "C" KEYBOARDHOOK_API void SetOnlySendOEMMsg(BOOL bOnlySendOEM)
    254 {
    255 bOnlySendOEMMsg = bOnlySendOEM;
    256 }
    257  
    258 extern "C" KEYBOARDHOOK_API void SetNeedPassOnceMsg(BOOL bWhetherNeed)
    259 {
    260 bNeedPassOnceMsg = bWhetherNeed;
    261 }

    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.  建立程序主文件

     1 if (hModule)
     2     {
     3         InHook = (pInstallHook)GetProcAddress(hModule, L"InstallHook");
     4         UnHook = (pUnHook)GetProcAddress(hModule, L"UnHook");
     5         SetAppHWND = (pSetAppHWND)GetProcAddress(hModule, L"SetAppHWND");
     6         SetTopHWND = (pSetTopHWND)GetProcAddress(hModule, L"SetTopHWND");
     7         SetHoldUpMsg = (pSetHoldUpMsg)GetProcAddress(hModule, L"SetHoldUpMsg");
     8         SetOnlySendOEMMsg = (pSetOnlySendOEMMsg)GetProcAddress(hModule, L"SetOnlySendOEMMsg");
     9         SetNeedPassOnceMsg = (pSetNeedPassOnceMsg)GetProcAddress(hModule, L"SetNeedPassOnceMsg");
    10  
    11         if (!InHook || !UnHook || !SetAppHWND || !SetTopHWND || !SetHoldUpMsg || !SetOnlySendOEMMsg || !SetNeedPassOnceMsg)
    12         {
    13             MessageBoxEx(hWnd, L"KeyboardHook.dll加载失败,程序被终止。", L"Info", MB_OK);
    14             PostQuitMessage(0);
    15         }
    16     }
    17     else
    18     {
    19         MessageBoxEx(hWnd, L"KeyboardHook.dll加载失败,程序被终止。", L"Info", MB_OK);
    20         PostQuitMessage(0);
    21     }
    22  
    23 InHook();
    24  

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

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

  • 相关阅读:
    android如何隐藏通知栏和禁止横屏竖屏切换
    android webview加载网页,文字listview和image混合listview的实现
    PHP加密3DES报错 Call to undefined function: mcrypt_module_open() 的解决方法
    http和HTTPS的区别及SSL介绍
    android SQLite数据库 一次性存储多条数据
    两个android程序间的相互调用(apk互调)
    android在学习——activity关闭和dialog.dismiss冲突的解决(Activity has leaked window com.android.internal.policy.impl.PhoneWindow)
    【android】解决因为图片太大引起的内存不足问题,Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
    android数据库操作 sqlite returned: error code = 14, msg = cannot open file at source line 25502
    android实现对SQLite数据库的增、删、改、查
  • 原文地址:https://www.cnblogs.com/91program/p/5255606.html
Copyright © 2020-2023  润新知