Windows Mobile上使用钩子(转)

wince系统对于钩子技术的支持,显然不及windows。有一些技术文档干脆说wince不支持钩子。其实,不尽然。我们还是可以从coredll.dll中,得到一些有用的接口,来实现拦截一些简单的键盘或鼠标的动作。

还是代码最有说服力:

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

#define HC_ACTION            0

typedef LRESULT    (CALLBACK* HOOKPROC)(int code, WPARAM wParam, LPARAM lParam);
typedef HHOOK      (WINAPI *_SetWindowsHookExW)(int, HOOKPROC, HINSTANCE, DWORD);
typedef LRESULT    (WINAPI *_CallNextHookEx)(HHOOK, int, WPARAM, LPARAM);
typedef LRESULT    (WINAPI *_UnhookWindowsHookEx)(HHOOK);

static _SetWindowsHookExW      SetHook;
static _UnhookWindowsHookEx    UnhookHook;
static _CallNextHookEx         CallNextHook;

HINSTANCE g_hHookApiDll    = NULL;
HHOOK     g_hKbdHook       = NULL;
HHOOK     g_hMouseHook     = NULL;

LRESULT CALLBACK KbdHookCallback(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam);

BOOL ActivateHook(HINSTANCE hInstance, HOOKPROC HookCallback);
BOOL DeactivateHook();

BOOL ActivateHook(HINSTANCE hInstance, HOOKPROC hookProc)
{
    SetHook        = NULL;
    CallNextHook   = NULL;
    UnhookHook     = NULL;

   EVENTMSG msg = {HC_ACTION};
    g_hMouseHook = QASetWindowsJournalHook(WH_JOURNALRECORD, MouseHookCallback, &msg);//这个是针对鼠标的

 if(NULL == g_hMouseHook )
 {
  return FALSE;
 }

 g_hHookApiDll = LoadLibrary(_T("coredll.dll"));
 if(NULL == g_hHookApiDll)
 {
  return FALSE;
 }

 SetHook = (_SetWindowsHookExW)GetProcAddress(g_hHookApiDll, _T("SetWindowsHookExW"));
    if(NULL == SetHook)
 {
  return FALSE;
 }

 g_hKbdHook = SetHook(WH_KEYBOARD_LL, hookProc, hInstance, 0);
 if(NULL == g_hKbdHook)
 {
  return FALSE;
 }

 CallNextHook = (_CallNextHookEx)GetProcAddress(g_hHookApiDll, _T("CallNextHookEx"));
 if(NULL == CallNextHook)
 {
  return FALSE;
 }

 UnhookHook = (_UnhookWindowsHookEx)GetProcAddress(g_hHookApiDll, _T("UnhookWindowsHookEx"));
 if(NULL == UnhookHook)
 {
  return FALSE;
 }

 return TRUE;
}

BOOL DeactivateHook()
{
 if(g_hMouseHook != NULL)
 {
  QAUnhookWindowsJournalHook(WH_JOURNALRECORD);
  g_hMouseHook = NULL;
 }

 if(g_hKbdHook != NULL)
 {
  UnhookHook(g_hKbdHook);
  g_hKbdHook = NULL;
 }

 if(g_hHookApiDll != NULL)
 {
  FreeLibrary(g_hHookApiDll);
  g_hHookApiDll = NULL;
 }

 return TRUE;
}

LRESULT CALLBACK KbdHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
 if(nCode >= HC_ACTION)
 {
  if(wParam == WM_KEYUP)
  {
   DWORD dwKey = ((KBDLLHOOKSTRUCT*)lParam)->vkCode;

   if(dwKey == VK_UP || dwKey == VK_DOWN || dwKey == VK_LEFT || dwKey == VK_RIGHT)
   {
    //Do Something
   }
  }
 }

    return CallNextHook(g_hKbdHook, nCode, wParam, lParam);
}

LRESULT CALLBACK MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
 if(nCode >= HC_ACTION)
 {
  PEVENTMSGMSG pMsg = (PEVENTMSGMSG)lParam;
  if(pMsg)
  {
   if(pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONUP)
   {
    //Do Something
   }
  }
 }

 return CallNextHook( g_hMouseHook, nCode, wParam, lParam );
}

如果在一个程序中启动了钩子,其他的程序使用钩子将无效。

由于使用了微软未公开的函数,可能会有潜在的问题,建议慎用。另,据说WM6.5以上,已经不支持鼠标钩子。

posted on 2010-01-05 16:41  老孙  阅读(571)  评论(0编辑  收藏  举报

导航