Windows Mobile 中的鍵盤鉤子實戰

來源:互聯網
上載者:User

在需要用到SOFT1和SOFT2兩個按鍵的時候, 也嘗試了各種方案, 最後還是選個鉤子函數, 但是在使用的過程中還是出現了一些問題的, 一些解決了一些還沒有。下面有以下網上很多的實現。 且看這個

winceKBhook.h

#ifndef _WINCE_KB_HOOK_H<br />#define _WINCE_KB_HOOK_H<br />//used for passing to SetWindowsHookEx funtion to set a Low level (LL) keyboard hook<br />#define WH_KEYBOARD_LL 20<br />// Define the function types used by hooks<br />typedef LRESULT(CALLBACK* HOOKPROC)(int code, WPARAM wParam, LPARAM lParam);<br />typedef HHOOK (WINAPI *_SetWindowsHookExW)(int, HOOKPROC, HINSTANCE, DWORD);<br />typedef LRESULT(WINAPI *_CallNextHookEx)(HHOOK, int, WPARAM, LPARAM);<br />typedef LRESULT(WINAPI *_UnhookWindowsHookEx)(HHOOK);<br />// For the low level keyboard hook, your keyboards procedures is passed a pointer to KBDLLHOOKSTRUCT instance<br />typedef struct {<br /> DWORD vkCode;<br /> DWORD scanCode;<br /> DWORD flags;<br /> DWORD time;<br /> ULONG_PTR dwExtraInfo;<br />} KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;<br />// Win32 Hook APIs<br />static _SetWindowsHookExW SetWindowsHookEx;<br />static _UnhookWindowsHookExUnhookWindowsHookEx;<br />static _CallNextHookEx CallNextHookEx;<br />bool ActivateKBHook(HINSTANCE hInstance, HOOKPROC LLKeyboardHookCallbackFunction);<br />bool DeactivateKBHook();<br />HRESULT DefHookProc(int, WPARAM, LPARAM);<br />#endif<br />

winceKBhook.cpp

#include "stdafx.h"<br />#include "winceKBhook.h"<br />//globals<br />HINSTANCE g_hHookApiDLL= NULL;//handle to coredll.dll, where all the hook related APIs are present<br />HHOOK g_hInstalledLLKBDhook = NULL;//g_hInstalledLLKBDhook represents handle to the installed KB hook<br />bool ActivateKBHook(HINSTANCE hInstance, HOOKPROC LLKeyboardHookCallbackFunction)<br />{<br />//we need to manually load these standard Win32 API calls<br />//MSDN states that these aren't supported in WinCE<br />SetWindowsHookEx= NULL;<br />CallNextHookEx= NULL;<br />UnhookWindowsHookEx= NULL;<br />//now load the coredll.dll<br />g_hHookApiDLL = LoadLibrary(_T("coredll.dll"));<br />if(g_hHookApiDLL == NULL)<br />{<br />//something is awfully wrong<br />//the dll has to be present<br />return false;<br />}<br />else<br />{<br />//load the SetWindowsHookEx API call<br />//the SetWindowsHookEx function installs an application-defined hook procedure into a hook chain.<br />//You would install a hook procedure to monitor the system for certain types of events.<br />//here we use use the hook to monitor kyeboard events<br />SetWindowsHookEx = (_SetWindowsHookExW)GetProcAddress(g_hHookApiDLL, _T("SetWindowsHookExW"));<br />if(SetWindowsHookEx == NULL)<br />{<br />//this means that MS has really stopped supporting this API in WinCE<br />return false;<br />}<br />else<br />{<br />//install the KB hook<br />//the hande needs to be saved for default processing of the events and to uninstall the hook, once we are done with it<br />g_hInstalledLLKBDhook = SetWindowsHookEx(WH_KEYBOARD_LL, LLKeyboardHookCallbackFunction, hInstance, 0);<br />if(g_hInstalledLLKBDhook == NULL)<br />{<br />return false;<br />}<br />}<br />//load CallNextHookEx() API call<br />//the CallNextHookEx function passes the hook information to the next hook procedure in the current hook chain.<br />//we use this call for default processing of events.<br />CallNextHookEx = (_CallNextHookEx)GetProcAddress(g_hHookApiDLL, _T("CallNextHookEx"));<br />if(CallNextHookEx == NULL)<br />{<br />return false;<br />}<br />//load UnhookWindowsHookEx() API<br />//the UnhookWindowsHookEx function removes a hook procedure installed in a hook chain by the SetWindowsHookEx function.<br />//we use this call to unistall the hook.<br />UnhookWindowsHookEx = (_UnhookWindowsHookEx)GetProcAddress(g_hHookApiDLL, _T("UnhookWindowsHookEx"));<br />if(UnhookWindowsHookEx == NULL)<br />{<br />return false;<br />}<br />}<br />//all the APIs are loaded and the application is hooked<br />return true;<br />}<br />bool DeactivateKBHook()<br />{<br />//unload the hook<br />if(g_hInstalledLLKBDhook != NULL)<br />{<br />UnhookWindowsHookEx(g_hInstalledLLKBDhook);<br />g_hInstalledLLKBDhook = NULL;<br />}<br />//unload the coredll.dll<br />if(g_hHookApiDLL != NULL)<br />{<br />FreeLibrary(g_hHookApiDLL);<br />g_hHookApiDLL = NULL;<br />}</p><p>//we have terminated gracefully<br />return true;<br />}<br />HRESULT DefHookProc(int nCode, WPARAM wParam, LPARAM lParam)<br />{<br />return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);<br />}

這個類似的實現網上一抄一大把。 我也搞了一個來實現, 還搞了一個DefHookProc函數, 因為懶得把CallNextHookEx時候要用的HHOOK公開了,所以一樣的, hook filter裡面就調用DefHookProc就好, 不需要調用CallNextHookEx了,一個參數我幫忙填寫好了。

末了, 我嘗試的實現了一下filter 函數:

int BlockKeyList[] = {VK_F1,VK_F2};<br />#ifndef HC_ACTION<br />#define HC_ACTION 0<br />#endif //HC_ACTION<br />LRESULT CALLBACK LLKeyboardHookCallbackFunction(int nCode, WPARAM wParam, LPARAM lParam)<br />{<br /> KBDLLHOOKSTRUCT* pHook = (KBDLLHOOKSTRUCT*)lParam;<br /> if(nCode >= HC_ACTION)<br /> {<br /> if( wParam == WM_KEYDOWN && pHook->vkCode == VK_F1)<br /> {<br /> g_App.onKeyEvent(KEY_EVENT_KEY_PRESS, SL_KEY_SOFT1, lParam);<br /> return 1;<br /> }<br /> else if (wParam == WM_KEYUP && pHook->vkCode == VK_F1)<br /> {<br /> g_App.onKeyEvent(KEY_EVENT_KEY_RELEASE, SL_KEY_SOFT1, lParam);<br /> return 1;<br /> }<br /> else if (wParam == WM_KEYDOWN && pHook->vkCode == VK_F2)<br /> {<br /> g_App.onKeyEvent(KEY_EVENT_KEY_PRESS, SL_KEY_SOFT2, lParam);<br /> return 1;<br /> }<br /> else if (wParam == WM_KEYUP && pHook->vkCode == VK_F2)<br /> {<br /> g_App.onKeyEvent(KEY_EVENT_KEY_RELEASE, SL_KEY_SOFT2, lParam);<br /> return 1;<br /> }<br /> }<br /> return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);<br />}


己看了應該沒有什麼問題, 但是實際上跑的是時候發現幾次都crash了。 當然這些crash都和Messagebox有關係, 都是彈出Messagebox的時候就程式再沒有響應了!!! 糊塗了,難道是messagebox是不同的線程¥%¥……%, 想來想去還是至少有點, g_App.onKeyEvent如果裡面彈出Messagebox這裡豈不是阻塞了?? 可能這樣的函數是不允許你阻塞在這裡的。 所以決定改了, 用PostMessage發個非同步訊息看看。

if (code >= 0)<br /> {<br /> HWND hWnd;<br /> TCHAR szTitle[MAX_LOADSTRING]; // title bar text<br /> TCHAR szWindowClass[MAX_LOADSTRING]; // main window class name<br /> LoadString(g_hInst, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);<br /> LoadString(g_hInst, IDC_SCANLIFE, szWindowClass, MAX_LOADSTRING);<br /> //If it is already running, then focus on the window, and exit<br /> hWnd = FindWindow(szWindowClass, szTitle);<br /> if (hWnd)<br /> {<br /> if (pHook->vkCode == VK_F1 && wParam == WM_KEYDOWN)<br /> {<br /> PostMessage(hWnd, WM_KEYDOWN, VK_F1, 0);<br /> return true;<br /> }<br /> else if (pHook->vkCode == VK_F1 && wParam == WM_KEYUP)<br /> {<br /> PostMessage(hWnd, WM_KEYUP, VK_F1, 0);<br /> return true;<br /> }<br /> else if (pHook->vkCode == VK_F2 && wParam == WM_KEYDOWN)<br /> {<br /> PostMessage(hWnd, WM_KEYDOWN, VK_F2, 0);<br /> return true;<br /> }<br /> else if (pHook->vkCode == VK_F2 && wParam == WM_KEYUP)<br /> {<br /> PostMessage(hWnd, WM_KEYUP, VK_F2, 0);<br /> return true;<br /> }<br /> }<br /> }<br /> return DefHookProc(code, wParam, lParam);

果然一把通過了:) 當然就像開始就說的一樣, 還是有問題沒有解決, 在Smartphone上有的手機直接SetWindowsHookEx失敗! 這個除了程式簽名估計沒有什麼辦法。 anyway 繼續探索吧。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.