Hooking the keyboard message queue in compact framework code

Print This Post Print This Post

Here is some nice code to use a keyboard hook implemented in C# for compact framework.

You can use this to catch the funny OS asigned keys like F1, F2, F3, F4, F6 and F7 (Softkey 1 and 2, Phone, End, Volume Up, Volume Down); and last but not least catch the Win Key press.

The hooking class:

using System;
using System.Runtime.InteropServices;
In order to use this class in your program, just declare the varialble and hook up into HookEvent:
HookKeys hook = new HookKeys();
hook.HookEvent += new HookKeys.HookEventHandler(HookEvent);
public class HookKeys
#region delegates
    public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
    public delegate void HookEventHandler(HookEventArgs e, KeyBoardInfo keyBoardInfo);
    public HookEventHandler HookEvent;
#region fields
    private HookProc hookDeleg;
    private static int hHook = 0;

    public HookKeys()
    #region public methods
    /// Starts the hook
    public void Start()
        if (hHook != 0)
            //Unhook the previouse one
        hookDeleg = new HookProc(HookProcedure);
        hHook = SetWindowsHookEx(WH_KEYBOARD_LL, hookDeleg, GetModuleHandle(null), 0);
        if (hHook == 0)
            throw new SystemException("Failed acquiring of the hook.");
    /// Stops the hook
    public void Stop()
    #region protected and private methods
    protected virtual void OnHookEvent(HookEventArgs hookArgs, KeyBoardInfo keyBoardInfo)
        if (HookEvent != null)
            HookEvent(hookArgs, keyBoardInfo);

    private int HookProcedure(int code, IntPtr wParam, IntPtr lParam)
       KBDLLHOOKSTRUCT hookStruct =  (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
       if (code < 0)
            return CallNextHookEx(hookDeleg, code, wParam, lParam);
       // Let clients determine what to do
       HookEventArgs e = new HookEventArgs();
       e.Code = code;
       e.wParam = wParam;
       e.lParam = lParam;
       KeyBoardInfo keyInfo = new KeyBoardInfo();
       keyInfo.vkCode = hookStruct.vkCode;
       keyInfo.scanCode = hookStruct.scanCode;
       OnHookEvent(e, keyInfo);
       // Yield to the next hook in the chain
       return CallNextHookEx(hookDeleg, code, wParam, lParam);
   #region P/Invoke declarations

   private static extern int AllKeys(bool bEnable);

   private static extern int SetWindowsHookEx(int type, HookProc hookProc, IntPtr hInstance, int m);
   private static extern IntPtr GetModuleHandle(string mod);
   private static extern int CallNextHookEx(
           HookProc hhk,
           int nCode,
           IntPtr wParam,
           IntPtr lParam
   private static extern int GetCurrentThreadId();
   [DllImport("coredll.dll", SetLastError = true)]
   private static extern int UnhookWindowsHookEx(int idHook);
   private struct KBDLLHOOKSTRUCT
       public int vkCode;
       public int scanCode;
       public int flags;
       public int time;
       public IntPtr dwExtraInfo;
   const int WH_KEYBOARD_LL = 20;
#region event arguments

    public class HookEventArgs : EventArgs
        public int Code;    // Hook code
        public IntPtr wParam;   // WPARAM argument
        public IntPtr lParam;   // LPARAM argument
    public class KeyBoardInfo
        public int vkCode;
        public int scanCode;
        public int flags;
        public int time;

Here is the download of the Visual Studio 2005 Windows Mobile 6 SDK targeting source code:

[Download not found]


  1. Bernd says:

    Thanks, this little Class saved my day!

  2. adi says:

    Thanks allot,
    The behavior is not consistent, some times one press on keyboard is being interpreted as two clicks, do you know what could be the reason?


  3. admin says:


    The hook code simply enables you to see keyboard messages. You have to look for WM_KEYDOWN and/or WM_KEYUP yourself in the hookeventhandler. Every keypress on the hardware keyboard may produce two and more messages depending on the key pressed. If you press the(a) key and CAPS lock is on, you will get wm_keydown+shift; wm_keydown+’a’;(wm_char(‘A’);wm_keyup+’a’;wm_keyup+shift

    Sorry, but without any code I cant say what you are doing wrong.



  4. Raj says:

    I’ve just download this code and trying to run it in Windows7, VS2010 but it showing me an Error : “Unable to load coredll.dll.

    Please help me…

  5. admin says:

    The code will run on Windows Mobile up to version 6.5.3 and Pocket PC. It is not for Windows Phone or Desktop PC.

  6. andrea says:

    in the event handler, when a key is pressed:

    void HookEventProc(HookEventArgs hookArgs, KeyBoardInfo keyBoardInfo)


    is there a way to detect from hookargs members or keyboardInfo members if ctrl key was held down?
    I mean how can I detect for example the CTRL + 1 ckey combination?

    many thanks in advance


  7. admin says:


    no, the modifier keys are not handled in a special way. In the event subscriber code you can watch for VK_CONTROL, VK_SHIFT, VK_LSHIFT and VK_ALT and other modifier keys and set flags when you get a WM_KEYDOWN for a modifier key and unset the flag, when you get a WM_KEYUP with a modifier VK_ value. HookEventArgs and KeyInfo transport all necessary info about the key.


  8. Jose Incera says:

    it works great on the first form, but when i try to use it on another form y shows “Failed acquiring of the hook”

  9. josef says:

    Hello Jose

    that is normal if you do not use that as “singleton”. Although MS makes us believe we could chain multiple hooks, it is not supported on Windows CE based devices.

    You have to ensure you install only one keyboard hook or unhook before you instantiate another keyboard hook.



  10. Mikael says:


    I’m just trying this out.. However, i’m not successfull in getting this to stop the LWin buttons actions.

    I’ve tried converting it to a KeyEventArgs and set handled to true, but that did not help. The start menu of the device still pops open when the windows key is pressed on the keyboard.
    If i add a MessageBox, i can see that it recognizes the keypress, but doesn’t halt it.

    How should i do that?

    static void HookEventProc(HookEventArgs hookArgs, KeyBoardInfo keyBoardInfo)

    if (vkMap.vkValues[keyBoardInfo.vkCode].s == "VK_LWIN")
    Keys key = (Keys)keyBoardInfo.vkCode;
    KeyEventArgs kea = new KeyEventArgs(key);
    kea.Handled = true;
    MessageBox.Show("Key: " + kea.KeyCode.ToString());



    (This is for Windows CE, 6)

  11. josef says:

    Hello Mikael

    I did not test it in WinCE6 (no device here). But I have some comments:
    1. Do NOT call a blocking function like MessageBox.Show() in a event handler, here HookEventProc!
    2. You create a new KeyEventArgs. KeyEventArgs as used by you is OK for a keyevent handler, but HookEvent is not a managed KeyEventHandler as On_KeyPress, On_KeyDown/UP.
    3. To supress the key press to be signaled to the system you need to handle that in HookProcedure. You may add a “return TRUE;” for VK_LWIN instead of return “CallNextHookEx(hookDeleg, code, wParam, lParam);”. That way the key is not forwarded. The OnHookEvent(e, keyInfo); is to signal the key to managed code but the next line (return CallNextHookEx(hookDeleg, code, wParam, lParam);) forwards the pressed key to the next listener (the System).

    See also http://www.hjgode.de/wp/2012/09/20/windows-mobile-cf-how-to-catch-f1-and-f2-in-weh/



  12. Josué says:

    Hi Josef
    First: your code did helpme a lot, so thank you so much
    Second: My english is very bad but i do my best
    How can i modify this code to let the listener hit some keys?
    a mean, just unhook some keys like volumeUP and volumeDOWN
    please help me again.


  13. josef says:

    Hello Josué

    the hook uses AllKeys(True) API and therefor the OS does not see F6/F7 (Volume Up/Down) any more. But you can watch for F6/F7 and if youre code sees that codes, it could fire VKEY_F6, VKEY_F7 using keybd_event API call. That will possibly handled by the OS.
    If the code starts to call itself using keybd_event, you need to set/reset a flag to avoid a loop.

    Within a hookproc in C++ I had an option to forward keys (CallNextHook…) that let some keys get back to the OS. That worked fine.


  14. Josué says:

    Thanks for responding,
    meaby im lost… please check my code.
    Just for now i am testing whith returno key

    //Para interceptar teclas propias del dispositivo
    public delegate void HookEvent(HookEventArgs hookArgs, KeyBoardInfo keyBoardInfo);

    //Para activar tecla volumenUP volumenDOWN
    public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags,
    UIntPtr dwExtraInfo);

    const byte VK_RETURN = 0x0D;
    const uint KEYEVENTF_KEYUP = 0x0002;

    static void HookEventProc(HookEventArgs hookArgs, KeyBoardInfo keyBoardInfo)

    byte bScan = 0;
    uint eventKey = 0;
    UIntPtr otro = UIntPtr.Zero;

    if ((keyBoardInfo.vkCode == 117) || (keyBoardInfo.vkCode == 118)) {
    keybd_event(VK_RETURN, bScan, eventKey, otro);
    keybd_event(VK_RETURN, bScan, KEYEVENTF_KEYUP, otro);

    //System.Diagnostics.Debug.WriteLine(“Hook called”);
    string s = “0x” + HexEncoding.ToString(hookArgs.lParam.ToInt32());
    s += “\t0x” + HexEncoding.ToString(hookArgs.wParam.ToInt32());
    s += “\t0x” + HexEncoding.ToString(keyBoardInfo.scanCode);
    s += “\t0x” + HexEncoding.ToString(keyBoardInfo.flags);
    s += “\t0x” + HexEncoding.ToString(keyBoardInfo.vkCode);
    s += “\t” + vkMap.vkValues[keyBoardInfo.vkCode].s;
    //s += “\r\n”;


  15. josef says:

    Hello Josué

    what is the purpose of using hook for your application? What do you want to program?


Leave a Reply