none
Keyboard hooks, ToUnicodeEx, MapVirtrualKeyEx

    Question

  • Hello, I need help with ToUnicodeEx function from user32.dll.I'm working on keyboard hook and I want to get char from virtual key code. For this issue I'm using ToUnicodeEx function from user32.dll. But I'm having a problem with dead keys. I'm using Czech keyboard layout and when I want to write some of the czech char which is composed by "line mark" which is clasified as dead key and some regular letter. And when I write "line mark", use ToUnicodeEx in my hooks, it automaticly writes two "line marks" instead of waiting for next input. I really don't know why. Also I tried to use MapVirtualKeyEx instead of ToUnicodeEx and it was fine, but it returns me wrong char for special chars. Thanks!
    Thursday, November 27, 2008 9:10 AM

Answers

  • Hi,

    As I learnt from your post ,when you use ToUnicodeEx to extract dead keys and other chars,the method does not work properly.The issue is that the API method(ToUnicodeEx) works with the state of the keyboard buffer. So when the user types a dead key and you use the ToUnicode API, the two are combined and thus the next keystroke the user types will no longer work with the given dead key at all.

    ToUnicodeEx returns -1 if a dead key was sent. The dead key is then in the buffer, and a second call to ToUnicodeEx with the base character will  return the actual character. 

    When the return key is -1 ,The specified virtual key is a dead-key character (accent or diacritic). This value is returned regardless of the keyboard layout, even if several characters have been typed and are stored in the keyboard state. If possible, even with Unicode keyboard layouts, the function has written a spacing version of the dead-key character to the buffer specified by pwszBuff. For example, the function writes the character SPACING ACUTE (0x00B4), rather than the character NON_SPACING ACUTE (0x0301).(http://msdn.microsoft.com/en-us/library/ms646322(VS.85).aspx)

    You can call the following code snippet in your hook call back method:

    private static void ClearKeyboardBuffer(uint vk, uint sc, IntPtr hkl) {  
        StringBuilder sb = new StringBuilder(10);  
        do {  
            rc = ToUnicodeEx(vk, sc, lpKeyStateNull, sb, sb.Capacity, 0, hkl);  
        } while(rc < 0);  

    And more information about this issue,please see:http://blogs.msdn.com/michkap/archive/2005/01/19/355870.aspx

    Best regards,
    Harry
    • Marked as answer by Harry Zhu Friday, December 05, 2008 1:34 AM
    Tuesday, December 02, 2008 8:52 AM

All replies

  • Hi,

    As I learnt from your post ,when you use ToUnicodeEx to extract dead keys and other chars,the method does not work properly.The issue is that the API method(ToUnicodeEx) works with the state of the keyboard buffer. So when the user types a dead key and you use the ToUnicode API, the two are combined and thus the next keystroke the user types will no longer work with the given dead key at all.

    ToUnicodeEx returns -1 if a dead key was sent. The dead key is then in the buffer, and a second call to ToUnicodeEx with the base character will  return the actual character. 

    When the return key is -1 ,The specified virtual key is a dead-key character (accent or diacritic). This value is returned regardless of the keyboard layout, even if several characters have been typed and are stored in the keyboard state. If possible, even with Unicode keyboard layouts, the function has written a spacing version of the dead-key character to the buffer specified by pwszBuff. For example, the function writes the character SPACING ACUTE (0x00B4), rather than the character NON_SPACING ACUTE (0x0301).(http://msdn.microsoft.com/en-us/library/ms646322(VS.85).aspx)

    You can call the following code snippet in your hook call back method:

    private static void ClearKeyboardBuffer(uint vk, uint sc, IntPtr hkl) {  
        StringBuilder sb = new StringBuilder(10);  
        do {  
            rc = ToUnicodeEx(vk, sc, lpKeyStateNull, sb, sb.Capacity, 0, hkl);  
        } while(rc < 0);  

    And more information about this issue,please see:http://blogs.msdn.com/michkap/archive/2005/01/19/355870.aspx

    Best regards,
    Harry
    • Marked as answer by Harry Zhu Friday, December 05, 2008 1:34 AM
    Tuesday, December 02, 2008 8:52 AM
  • I found someone who found a way around it:

    http://www.docdroppers.org/wiki/index.php?title=Writing_Keyloggers

    This does NOT remove dead keys.

    Wednesday, March 24, 2010 1:20 PM
  • I found someone who found a way around it:

    http://www.docdroppers.org/wiki/index.php?title=Writing_Keyloggers

    This does NOT remove dead keys.

    Wednesday, March 24, 2010 1:20 PM
  • I have the same problem, and the link no longer exist, can you please direct me to right place, Thanks,
    Thursday, October 20, 2011 11:11 AM
  • Google for "Get modification number for Shift key" and you'll find the article ;) For example: http://debtnews.net/index.php/article/debtor/2008-09-08/1088.html Good luck! Christian
    Thursday, October 20, 2011 11:33 AM