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

你可能感兴趣的:(WinCE)