I have an application that logs everything that the user clicks, but when I click special characters like ´ with a to get á , I get ´´a ; the same thing when I want to get à , then I get ``a , so all special characters are printed twice, and then after that a regular character is typed.
I always searched and can’t find anything. But I noticed that the problem lies in the ToAscii method, without which characters print correctly.
public string GetString(IntPtr lParam, int vCode) { try { bool shift = Keys.Shift == Control.ModifierKeys || Console.CapsLock; string value = ""; KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure( lParam, typeof(KeyboardHookStruct)); byte[] keyState = new byte[256]; byte[] inBuffer = new byte[2]; DllClass.GetKeyboardState(keyState); var ascii= DllClass.ToAscii( MyKeyboardHookStruct.vkCode, MyKeyboardHookStruct.scanCode, keyState, inBuffer, MyKeyboardHookStruct.flags ); if (ascii == 1) { char key = (char)inBuffer[0]; if ((shift) && Char.IsLetter(key)) key = Char.ToUpper(key); value = key.ToString(); } return value; } catch (Exception) { return ""; } }
Am I missing something or did something wrong? All other characters work fine, but these are special characters that appear as double characters.
EDIT:
Try instead of ToUnicode .
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)] public static extern int ToUnicode( uint virtualKey, uint scanCode, byte[] keyStates, [MarshalAs(UnmanagedType.LPArray)] [Out] char[] chars, int charMaxCount, uint flags); public string GetString(IntPtr lParam, int vCode) { try { bool shift = Keys.Shift == Control.ModifierKeys || Console.CapsLock; string value = ""; KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure( lParam, typeof(KeyboardHookStruct)); byte[] keyState = new byte[256]; byte[] inBuffer = new byte[2]; char[] chars = new char[2]; DllClass.GetKeyboardState(keyState); int val = 0; val = ToUnicode( (uint)MyKeyboardHookStruct.vkCode, (uint)MyKeyboardHookStruct.scanCode, keyState, chars, chars.Length, 0 ); val = ToUnicode( (uint)MyKeyboardHookStruct.vkCode, (uint)MyKeyboardHookStruct.scanCode, keyState, chars, chars.Length, 0 ); if (val == 1) { char key = (char)chars[0]; if ((shift) && Char.IsLetter(key)) key = Char.ToUpper(key); value = key.ToString(); } return value; } catch (Exception) { return ""; } }
Someone PLEASE help me, I really need to understand this =/ .
EDIT:
int val = -1; if (IsDeadKey((uint)vCode)) { while (val == -1) { val = ToUnicode( (uint)MyKeyboardHookStruct.vkCode, (uint)MyKeyboardHookStruct.scanCode, keyState, chars, chars.Length, 0 ); } } else val = ToUnicode( (uint)MyKeyboardHookStruct.vkCode, (uint)MyKeyboardHookStruct.scanCode, keyState, chars, chars.Length, 0 );
So, now I tried calling ToAscii or ToUnicode several times to reset the real character, but to no avail. Am I doing it wrong?
As for ASCII, first call ´ , I get -1 , so I call it again, then I get 1 ; and then I press as a to get á , but then I get only a . The same thing, if I use ToUnicode twice after each other, I get only a instead of á and so on ...