Windows Mobile: redirect function keys into Internet Explorer Mobile browser

iHookIE6

this small tool enables you to use Function keys within Internet Explorer Mobile (IEM) web sites.

Normally, most function keys are catched and used by the OS (GWES) to perfom special actions like menu softkeys, phone call, end phone, volume up, volume down and more.

Using a keyboard hook we can catch the function key presses, or better say WM_KEYDOWN and WM_KEYUP messages before the OS can catch them.

One challenge was to find the window that processes normal key presses. The keyboard windows messages are not send to the top level window. Using the Remote Spy Tool I found the Window inside Internet Explorer window that finally processes keyboard messages. Now the tool can hook the keyboard, catch F key presses (F1 to F24) and send them directly to the browser window (class name = “Internet Explorer_Server”). The tool simply uses FindWindow and GetWindow to locate the window handle of this window and then does a PostMessage with WM_KEYDOWN and WM_KEYUP directly to the browser window.

The hook function:

__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
) 
{
    static int iActOn = HC_ACTION;
    bool processed_key=false;
    int iResult=0;
    if (nCode == iActOn) 
    { 
        HWND hwndBrowserComponent=getIEMBrowserWindow();    //get the browser window
        if(getIEMWindow(&iResult)==NULL || hwndBrowserComponent==NULL)    // if IE is not loaded or not in foreground or browser window not found
            return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);

        PKBDLLHOOKSTRUCT pkbhData = (PKBDLLHOOKSTRUCT)lParam;
        //we are only interested in FKey press/release
        if(pkbhData->vkCode >= VK_F1 && pkbhData->vkCode <=VK_F24){
            DEBUGMSG(1,(L"found function key 0x%08x ...\n", pkbhData->vkCode));
            if(processed_key==false){
                if (wParam == WM_KEYUP)
                {
                    //synthesize a WM_KEYUP
                    DEBUGMSG(1,(L"posting WM_KEYUP 0x%08x to 0x%08x, lParam=0x%08x...\n", pkbhData->vkCode, hwndBrowserComponent, g_lparamCodeUp[pkbhData->vkCode - 0x70]));
                    PostMessage(hwndBrowserComponent, WM_KEYUP, pkbhData->vkCode, g_lparamCodeUp[pkbhData->vkCode - 0x70]);
                    processed_key=true;
                }
                else if (wParam == WM_KEYDOWN)
                {
                    //synthesize a WM_KEYDOWN
                    DEBUGMSG(1,(L"posting WM_KEYDOWN 0x%08x to 0x%08x, lParam=0x%08x...\n", pkbhData->vkCode, hwndBrowserComponent, g_lparamCodeDown[pkbhData->vkCode - 0x70]));
                    PostMessage(hwndBrowserComponent, WM_KEYDOWN, pkbhData->vkCode, g_lparamCodeDown[pkbhData->vkCode - 0x70]);
                    processed_key=true;
                }
            }
        }
    }
    else
        DEBUGMSG(1, (L"Got unknwon action code: 0x%08x\n", nCode));
    //shall we forward processed keys?
    if (processed_key)
    {
        processed_key=false; //reset flag
        if (bForwardKey){
            return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);
        }
        else
            return true;
    }
    else
        return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);
}

You will see, that the web site code in IEM can now process these function key presses using the body onKeyDown event.

the browser window with a javascript key demo:


(see also onkey.htm in http://www.hjgode.de/wp/2009/05/14/internet-explorer-mobile-handles-key-events/)

The same will not work, if you switched the browser engine from IE6 (or MSHTML) to PocketIE using the HKLM\Security\Internet Explorer\MSHTML=”0″ entry.

Screenshot shows that function keys are sent to the browser window. But you will see no reaction inside the web site.

Only the newer engine, started with Windows Mobile AKU 6.1.4, supports keyboard events inside the javascript object model.

To find the browser window, you normally would use EnumChildWindows(), but this API is not available on Windows CE based devices. So I re-used some code to scan a window for child and sibling windows to find the nested browser window:

//search for a child window with class name
static BOOL bStopScan=FALSE;
BOOL scanWindow(HWND hWndStart, TCHAR* szClass){
    HWND hWnd = NULL;
    HWND hWnd1 = NULL;    
    hWnd = hWndStart;
    TCHAR cszWindowString [MAX_PATH]; // = new TCHAR(MAX_PATH);
    TCHAR cszClassString [MAX_PATH]; //= new TCHAR(MAX_PATH);
    TCHAR cszTemp [MAX_PATH]; //= new TCHAR(MAX_PATH);
    BOOL bRet=FALSE;
    while (hWnd!=NULL && !bStopScan){
        //do some formatting
        GetClassName(hWnd, cszClassString, MAX_PATH);
        GetWindowText(hWnd, cszWindowString, MAX_PATH);
        wsprintf(cszTemp, L"\"%s\"  \"%s\"\t0x%08x\n", cszClassString, cszWindowString, hWnd);//buf);
        //DEBUGMSG(1, (cszTemp));
        if(wcsicmp(cszClassString, szClass)==0){
            DEBUGMSG(1 , (L"\n################### found target window, hwnd=0x%08x\n\n", hWnd));
            //set global hwnd
            g_hWndIEM6=hWnd;    //store in global var
            hWnd=NULL;
            hWndStart=NULL;
            bRet=TRUE;
            bStopScan=TRUE;
            return TRUE;    //exit loop
        }
        // Find next child Window
        hWnd1 = GetWindow(hWnd, GW_CHILD);
        if( hWnd1 != NULL ){ 
            scanWindow(hWnd1, szClass);
        }
        hWnd=GetWindow(hWnd,GW_HWNDNEXT);        // Get Next Window
    }
    return bRet;
}

Thanks to all the code providers in the internet. Keep coding and publishing.

Download (VS2008/WM5 SDK C++ project and binary)

[Download not found]

3 Comments

  1. Francesc Sanz says:

    Hi Josef,

    I want to run SAP web console on a WM 6.5 with Internet Explorer Mobile 6.
    I have changed the IEM6 behaviour to PIE changing the registry with
    HKLM\Security\Internet Explorer\MSHTML=”0″

    If not, the screen size behaviour is awful.
    But I have also problems with the function keys.
    How can I solve that?

  2. josef says:

    Hello

    SAP Webconsole has special javascript for Intermec Browser. Per default, the PIE internet browser does NOT support ANY keyboard handling within javascript. Intermec Browser runs in kiosk mode and adds support for keyboard handling via javascript, as SAP web console needs.

    There are many posts at http://community.intermec.com/t5/forums/searchpage/tab/message?allow_punctuation=true&q=web+function+keys#message-list about function keys and web browser.

    As you switched the new Internet Explorer (IE6) back to PIE using MSHTML reg key, you loose any javascript keyboard handling.

    Either you switch back to IE6 and correct the issues with page design or you use Intermec Browser (or another industrial browser, for example Naurtech).

    You may also test Intermec HTML5 browser (or ZetaKey browser).

    regards

    Josef

  3. Francesc Sanz says:

    Thank you. Best regards,

    Francesc

Leave a Reply