none
Compact 2013: keybd_eventEx Usage RRS feed

  • Question

  • Hi all,

    In CE6 I can send the the 'e' character to the currently active window using the following code:

    keybd_event('E',0,0,0);
    keybd_event('E',0,KEYEVENTF_KEYUP,0);

    In WEC7 and WEC2013 this code snippet no longer works. The MSDN webpage 'https://msdn.microsoft.com/en-us/library/ee504289.aspx' tells me that keybd_event has been deprecated and to use keybd_eventEx instead. Unfortunately keybd_eventEx doesn't work either. I suspect this is because I need to specify a valid GUID for the new 'guidPDD' argument. Does anybody know where I can find the GUID of my device's default keyboard?

    Thanks!

    Monday, January 2, 2017 10:35 PM

Answers

  • Hi Jared,

    I think you might be missing some complexity in your call.  Remember there is Key up key down and some routines act on the up and others on the down.

    I happen to be in my CE 7 tree but it should be the same for CE 8... here is a sample app "Pegterm" that uses this method located at \\wce700\public\COMMON\oak\drivers\netsamp\pegterm\termctrl\termime.c

        for(; offset > 0; offset-- )
        {
            nShiftState = KeyStateDownFlag  | KeyShiftNoCharacterFlag;
            PostKeybdMessage(pTCI->hTermWnd, uCharacter, nShiftState,
                1, &nShiftState, &uCharacter);
            
            nShiftState &= ~KeyStateDownFlag;
            nShiftState |= KeyStatePrevDownFlag;
            
            PostKeybdMessage(pTCI->hTermWnd, uCharacter, nShiftState,
                1, &nShiftState, &uCharacter);
        }

    So you really need two messages to accomplish a full keypress.

    Sincerely,

    IoTGirl

     
    • Marked as answer by Jared Hagel Friday, January 6, 2017 6:06 PM
    Thursday, January 5, 2017 12:12 AM
    Moderator

All replies

  • Hi Jared,

    Have you looked at using Windows Messages? Like WM_CHAR & WM_KEYDOWN and such? I think those would free you from needing to know about hardware guids.

    Sincerely,

    IoTGirl

    Tuesday, January 3, 2017 7:37 AM
    Moderator
  • Thanks for the fast reply IoTGirl,

    The problem I'll have with sending Windows Messages is I believe I need to have a windows handle. It will likely be difficult to get the handle of the currently active window in our application. Our application is the remote display server for our device.

    Is there a GUID for the keypad on the Software Input Panel?

    Tuesday, January 3, 2017 4:58 PM
  • Hi Jared,

    From MSDN docs: WM_CHAR = This message is posted to the window with the keyboard focus when a WM_KEYDOWN message is translated by the TranslateMessage function.

    I don't know how you get the keyboard message not to go to the active window.  I guess you could shim the keyboard driver and decide which you want to inject or filter.

    Sincerely,

    IoTGirl

    Tuesday, January 3, 2017 6:11 PM
    Moderator
  • Hello and thanks for the quick reply again!

    I do want the keyboard message to go to the active window. It seems like sending keystrokes to the active window is no simple task (see http://stackoverflow.com/questions/11890972/simulating-key-press-with-postmessage-only-works-in-some-applications). Unfortunately this stackoverlow post won't work for me because the function 'GetGUIThreadInfo' isn't supported in Windows CE. It's a shame that a simple call to keybd_event no longer works.

    Thanks IoTGirl for pointing me in the right direction!

    Tuesday, January 3, 2017 7:19 PM
  • Hmmm, again I am unsure why you need to find the active window or gui thread as the OS already knows it. Have you tried PostKeybdMessage with a NULL Window handle?  https://msdn.microsoft.com/en-us/library/ee501918.aspx
    Tuesday, January 3, 2017 11:12 PM
    Moderator
  • Hi IoTGirl. Thank you very much - PostKeybdMessage actually sends keyboard messages to the currently active window when I specify -1 as the windows handle. However this function doesn't work as I would expect. For example, I would expect that 'Shift+1' should send a '!' character, but instead it sends the character '1'. I have a feeling that I'm using this function incorrectly. My code is shown below. I haven't found many usage examples for PostKeybdMessage.

    UINT uStates[] = { KeyShiftAnyShiftFlag | KeyStateDownFlag };
    UINT uChars[] = { '1' };
    if (!PostKeybdMessage((HWND)-1, 0, uStates[0], 1, uStates, uChars))
    RETAILMSG(1, (L"Can't send char (%u)", GetLastError()));

    Any obvious flaws in the code snippet I used above?

    Thanks!

    Wednesday, January 4, 2017 11:39 PM
  • Hi Jared,

    I think you might be missing some complexity in your call.  Remember there is Key up key down and some routines act on the up and others on the down.

    I happen to be in my CE 7 tree but it should be the same for CE 8... here is a sample app "Pegterm" that uses this method located at \\wce700\public\COMMON\oak\drivers\netsamp\pegterm\termctrl\termime.c

        for(; offset > 0; offset-- )
        {
            nShiftState = KeyStateDownFlag  | KeyShiftNoCharacterFlag;
            PostKeybdMessage(pTCI->hTermWnd, uCharacter, nShiftState,
                1, &nShiftState, &uCharacter);
            
            nShiftState &= ~KeyStateDownFlag;
            nShiftState |= KeyStatePrevDownFlag;
            
            PostKeybdMessage(pTCI->hTermWnd, uCharacter, nShiftState,
                1, &nShiftState, &uCharacter);
        }

    So you really need two messages to accomplish a full keypress.

    Sincerely,

    IoTGirl

     
    • Marked as answer by Jared Hagel Friday, January 6, 2017 6:06 PM
    Thursday, January 5, 2017 12:12 AM
    Moderator
  • That worked for me. Thanks for your quick and knowledgeable feedback IoTGirl!
    Friday, January 6, 2017 6:07 PM
  • You are very welcome and thank you for confirming the solution!
    Friday, January 6, 2017 6:16 PM
    Moderator
  • For anybody else that has trouble finding a replacement for the 'keybd_event' function in WEC2013, one other thing that helped me was taking a look at the IM_PressKey function in the WEC2013 sample code found here: C:\WINCE800\public\common\sdk\samples\LargeKB\im.cpp. This function uses Windows calls 'SendVirtualKey' and 'SendCharEvents', which I substituted for 'keybd_event' (which partially works as before) and 'PostKeybdMessage'. 
    Friday, March 24, 2017 3:01 PM