Click here to Skip to main content
13,590,079 members
Click here to Skip to main content
Add your own
alternative version

Tagged as


2 bookmarked
Posted 8 Sep 2011
Licenced CPOL

KeyToggleStart: Yet Another Usage for Keyboard Hook

, 8 Sep 2011
Rate this:
Please Sign up or sign in to vote.
How to start an application by just hitting some keys in sequence? The answer: Just use a keyboard hook.

Hello Windows Mobile Users! Recently, the following was requested: How can I start an application by just hitting some keys in sequence? The answer: Just use a keyboard hook.

So I started to code this hook tool based on my KeyToggleBoot2 code. There was not too much to change. The new tool is called KeyToggleStart and it is configured by the Registry:


      72 73 00
;max 10 keys!

Reg Keys Meaning

Forbiddenkeys is just an add-on feature: key codes entered in this list will not be processed any more by your Windows Mobile device. For example, to disable the use of the F3 (VK_TTALK) and F4 (VK_TEND) keys, you have to enter a binary list of 0×72,0×73,0×00 (the zero is needed to terminate the list).

KeySeq lists the char sequence you want to use to start an application. For example, if this is the string123″, every time you enter 123 in sequence within the given time, the application defined will be started.

TimeOut is the time in seconds you have to enter the sequence. So do not use a long key sequence as “starteiexplorenow” and a short timeout (except if you are a very fast type writer). The timeout is started with the first char matching and ends after the time or when you enter a non-matching char of the sequence.

With LEDid, you can specify a LED index number. LEDs on Windows Mobile are controlled by an index number, each LED has one or more ID assigned to it. So, with LEDid, you can control which LED will lit, when the matching process is running. You can even find an ID to control a vibration motor, if your Windows Mobile device is equipped with one.

The Exe registry string value is used to specify which application will be started when the key sequence is matched.

If the application you want to be started needs some arguments, you can enter these using the Arg registry value.

When you start the KeyToggleStart tool, you will not see any window except for a notification symbol on your Start/Home screen of the device.

If you tap this icon (redirection sign), you have the chance to end the hook tool.

The code itself is nothing special. Only the sequence matching code is a little bit special. As the chars in the sequence do not match keystrokes in a one-to-one manner, I have to check the shift state of the keyboard and if the current char of the sequence is a char needing a shift. For example: the asterisk char (“*”) is a combination of the “8″ key plus the Shift key. So, if you have the “*” in the char sequence, the code has to check for the “8″ key and if the keyboard is in shift state:

// The command below tells the OS that this EXE has an export
// function so we can use the global hook without a DLL
__declspec(dllexport) LRESULT CALLBACK g_LLKeyboardHookCallback(
   int nCode,      // The hook code
   WPARAM wParam,  // The window message (WM_KEYUP, WM_KEYDOWN, etc.)
   LPARAM lParam   // A pointer to a struct with information about the pressed key
    /*    typedef struct {
        DWORD vkCode;
        DWORD scanCode;
        DWORD flags;
        DWORD time;
        ULONG_PTR dwExtraInfo;
    // Get out of hooks ASAP; no modal dialogs or CPU-intensive processes!
    // UI code really should be elsewhere, but this is just a test/prototype app
    // In my limited testing, HC_ACTION is the only value nCode is ever set to in CE
    static int iActOn = HC_ACTION;
    static bool isShifted=false;
#ifdef DEBUG
    static TCHAR str[MAX_PATH];
    //DWORD vKey;
    if (nCode == iActOn)
        //only process unflagged keys
        if (pkbhData->flags != 0x00)
            return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);
        //check vkCode against forbidden key list
            BOOL bForbidden=false;
            int j=0;
                    DEBUGMSG(1, (L"suppressing forbidden key: 0x%0x\n",pkbhData->vkCode));
            }while(!bForbidden && pForbiddenKeyList[j]!=0x00);
                return true;
        SHORT sShifted = GetAsyncKeyState(VK_SHIFT);
        if((sShifted & 0x800) == 0x800)
            isShifted = true;
            isShifted = false;
        //check and toggle for Shft Key
        //do not process shift key
        if (pkbhData->vkCode == VK_SHIFT){
            DEBUGMSG(1, (L"Ignoring VK_SHIFT\n"));
            return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);
        //check if the actual key is a match key including the shift state
        if ((byte)pkbhData->vkCode == (byte)szVKeySeq[iMatched]){
            DEBUGMSG(1 , (L"==== char match\n"));
            if (bCharShiftSeq[iMatched] == isShifted){
                DEBUGMSG(1 , (L"==== shift match\n"));
                DEBUGMSG(1 , (L"==== shift not match\n"));
        if( wParam == WM_KEYUP ){
            DEBUGMSG(1, (L"---> szVKeySeq[iMatched] = 0x%02x\n", (byte)szVKeySeq[iMatched]));
            if ( ((byte)pkbhData->vkCode == (byte)szVKeySeq[iMatched]) && 
                         (isShifted == bCharShiftSeq[iMatched]) ) {
                //the first match?
                    //start the timer and lit the LED
                    tID=SetTimer(NULL, 0, matchTimeout, (TIMERPROC)Timer2Proc);
                DEBUGMSG(1, (L"iMatched is now=%i\n", iMatched));
                //are all keys matched
                if (iMatched == iKeyCount){
                    //show modeless dialog
                    DEBUGMSG(1, (L"FULL MATCH, starting ...\n"));
                    PostMessage(g_hWnd, WM_SHOWMYDIALOG, 0, 0);
                    //reset match pos and stop timer
                    DEBUGMSG(1, (L"FULL MATCH: Reset matching\n"));
                    iMatched=0; //reset match pos
                    KillTimer(NULL, tID);
                    //return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);
                //return -1; //do not forward key?
                KillTimer(NULL, tID);
                iMatched=0; //reset match pos
                DEBUGMSG(1, (L"FULL MATCH missed. Reseting matching\n"));
        } //if wParam == WM_KEY..
    return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);

Enjoy the code!


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


About the Author

Germany Germany
No Biography provided

You may also be interested in...

Comments and Discussions

-- There are no messages in this forum --
Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web01-2016 | 2.8.180618.1 | Last Updated 8 Sep 2011
Article Copyright 2011 by hjgode
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid