Click here to Skip to main content
15,888,454 members
Articles / Programming Languages / C#

Hooking the keyboard message queue in compact framework code

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
4 Jan 2010CPOL 59K   5   27
Hooking the keyboard message queue in CF2
  • Download KbdHookCS - Keyboard hooking in compact framework

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 assigned 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:

C#
using System;
using System.Runtime.InteropServices;
/*
In order to use this class in your program, just declare the variable 
and hook up into HookEvent:
HookKeys hook = new HookKeys();
hook.HookEvent += new HookKeys.HookEventHandler(HookEvent);
hook.Start();
*/
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;
#endregion
#region fields
    private HookProc hookDeleg;
    private static int hHook = 0;
#endregion
 
    public HookKeys()
    {
    }
    ~HookKeys(){
        if(hHook!=0)
            this.Stop();
    }
    #region public methods
    ///
    /// Starts the hook
    ///
    public void Start()
    {
        if (hHook != 0)
        {
            //Unhook the previous one
            this.Stop();
        }
        hookDeleg = new HookProc(HookProcedure);
        hHook = SetWindowsHookEx(WH_KEYBOARD_LL, hookDeleg, GetModuleHandle(null), 0);
        if (hHook == 0)
        {
            throw new SystemException("Failed acquiring of the hook.");
        }
        AllKeys(true);
    }
    ///
    /// Stops the hook
    ///
    public void Stop()
    {
        UnhookWindowsHookEx(hHook);
        AllKeys(false);
    }
    #endregion
    #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);
   }
   #endregion
   #region P/Invoke declarations
 
   [DllImport("coredll.dll")]
   private static extern int AllKeys(bool bEnable);
 
   [DllImport("coredll.dll")]
   private static extern int SetWindowsHookEx
	(int type, HookProc hookProc, IntPtr hInstance, int m);
   [DllImport("coredll.dll")]
   private static extern IntPtr GetModuleHandle(string mod);
   [DllImport("coredll.dll")]
   private static extern int CallNextHookEx(
           HookProc hhk,
           int nCode,
           IntPtr wParam,
           IntPtr lParam
           );
   [DllImport("coredll.dll")]
   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;
   #endregion
}
#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;
    }
#endregion

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

<!-- Social Bookmarks BEGIN -->

<!-- Social Bookmarks END -->

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionWon't work if the application loses focus (WM6.5) Pin
tgz833-Jan-12 5:30
tgz833-Jan-12 5:30 
AnswerRe: Won't work if the application loses focus (WM6.5) Pin
hjgode3-Jan-12 6:46
hjgode3-Jan-12 6:46 
QuestionRe: Won't work if the application loses focus (WM6.5) Pin
tgz833-Jan-12 22:33
tgz833-Jan-12 22:33 
AnswerRe: Won't work if the application loses focus (WM6.5) Pin
hjgode4-Jan-12 5:37
hjgode4-Jan-12 5:37 
GeneralRe: Won't work if the application loses focus (WM6.5) Pin
tgz835-Jan-12 2:55
tgz835-Jan-12 2:55 
GeneralUsing without form Pin
Campese28-Mar-11 5:01
Campese28-Mar-11 5:01 
GeneralRe: Using without form Pin
hjgode28-Mar-11 18:31
hjgode28-Mar-11 18:31 
GeneralAfter a messagebox hangs Pin
mamm98998-Mar-11 22:49
mamm98998-Mar-11 22:49 
GeneralRe: After a messagebox hangs Pin
hjgode9-Mar-11 5:43
hjgode9-Mar-11 5:43 
GeneralRe: After a messagebox hangs Pin
mamm98999-Mar-11 21:16
mamm98999-Mar-11 21:16 
GeneralRe: After a messagebox hangs Pin
apcsi15-Jan-13 21:41
apcsi15-Jan-13 21:41 
GeneralSetWindowsHookEx returns 87 Pin
Member 769177121-Feb-11 1:58
Member 769177121-Feb-11 1:58 
GeneralRe: SetWindowsHookEx returns 87 Pin
hjgode21-Feb-11 2:23
hjgode21-Feb-11 2:23 
GeneralRe: SetWindowsHookEx returns 87 Pin
Member 769177121-Feb-11 2:29
Member 769177121-Feb-11 2:29 
GeneralRe: SetWindowsHookEx returns 87 Pin
Member 769177121-Feb-11 2:36
Member 769177121-Feb-11 2:36 
QuestionHTC HD2 incoming call don´t lock Green Button/Answer Key? [modified] Pin
ths18015-Dec-10 8:44
ths18015-Dec-10 8:44 
AnswerRe: HTC HD2 incoming call don´t lock Green Button/Answer Key? Pin
hjgode15-Dec-10 21:20
hjgode15-Dec-10 21:20 
AnswerRe: HTC HD2 incoming call don´t lock Green Button/Answer Key? Pin
ths18016-Dec-10 1:38
ths18016-Dec-10 1:38 
GeneralGreat code Pin
James P Grady13-Nov-10 10:57
James P Grady13-Nov-10 10:57 
QuestionAllKeys? Pin
Steven Richardson28-Sep-10 1:03
Steven Richardson28-Sep-10 1:03 
AnswerRe: AllKeys? Pin
hjgode28-Sep-10 17:51
hjgode28-Sep-10 17:51 
Hello

in this code we call a delegate to handle the key:

OnHookEvent(e, keyInfo);
// Yield to the next hook in the chain
return CallNextHookEx(hookDeleg, code, wParam, lParam);

if you return TRUE from the Hook funcion, the key message is marked as handled and removed from the message queue. If you return false or better return the CallNextHookEx function, the key will remain in the msg queue and can be handled by other windows.

You are talking about a KeyPreview/KeyPress/Key_UP/Key_Down dotnet function, where e.cancel=true signals the Compact Framework runtime, that you like to remove the key message. If you just use e.cancel=false, the key should be forwarded (remain in message queue) to other windows.

AFAIK, the scan button to trigger the barcode scanner do not use key message. On Intermec the scanner key does fire two named events and you cannot catch the key press with keyboard hooks or using the windows message queue.

regards

Josef

BTW: AllKeys and the KeyboardHooking described here are totally independent. AllKeys(true) just ensures that your dotnet application will get the keyboard messages delivered for Phone Keys (like VK_TEND) by the message queue and not consumed by the OS (ie phone app).
GeneralGreat code!! Pin
Sabrina Hope31-May-10 5:00
Sabrina Hope31-May-10 5:00 
GeneralRe: Great code!! Pin
Sabrina Hope31-May-10 5:37
Sabrina Hope31-May-10 5:37 
GeneralRe: Great code!! Pin
hjgode31-May-10 7:08
hjgode31-May-10 7:08 
GeneralRe: Great code!! Pin
Member 769177121-Feb-11 19:32
Member 769177121-Feb-11 19:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.