WINCE勾子使用方法

作者:太阳下的泪

转自:http://blog.sina.com.cn/s/blog_5be1061c0100bhx6.html


wince下支持三种钩子:

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

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

WH_JOURNALPLAYBACKHook返回一个时间暂停值,它告诉系统,在处理当前回放的消息时,系统等待百分之几秒。这使得此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 DLLapplication.

//

 

#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;

    }

    returnTRUE;

}

 

 

// 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 beenexported.

// 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(intnCode, 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(BOOLbOnlySendOEM)

{

bOnlySendOEMMsg = bOnlySendOEM;

}

 

extern "C" KEYBOARDHOOK_API void SetNeedPassOnceMsg(BOOLbWhetherNeed)

{

bNeedPassOnceMsg = bWhetherNeed;

}

2.  建立头文件

 

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

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

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

// that uses this DLL. This way any other project whose sourcefiles 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(intnCode, WPARAM wParam, LPARAM lParam);

extern "C" KEYBOARDHOOK_API void SetAppHWND(HWNDhCurAppWnd);

extern "C" KEYBOARDHOOK_API void SetTopHWND(HWNDhCurTopWnd);

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

extern "C" KEYBOARDHOOK_API void SetOnlySendOEMMsg(BOOLbOnlySendOEM);

extern "C" KEYBOARDHOOK_API void SetNeedPassOnceMsg(BOOLbWhetherNeed);

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

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值