Intercept keyboard input using current keyboard layout

廉价感情. 提交于 2019-12-24 19:23:53

问题


I've implemented a low-level keyboard hook using SetWindowsHookEx() function. It works fine and returns a virtual key code for each keystroke. I can convert this virtual key code to a System.Windows.Input.Key using KeyInterop.KeyFromVirtualKey(). But the target is to get a symbol that corresponds to this virtual key code in current keyboard layout.

I.e. for German layout I want to get "Y" for Key.Z, "Z" for Key.Y.

Does anyone can help?

Thank you.


回答1:


call the GetKeyboardLayout to retrieve the active layout value, then, do some conditional loop to get the result you want.




回答2:


You should take a look at this methods GetKeyboardState, GetKeyboardLayout, MapVirtualKeyEx, ToUnicodeEx.

Solution should look something like

byte[] keyboardState = new byte[256];
GetKeyboardState(keyboardState);
IntPtr handle = GetKeyboardLayout(0);
uint scanCode = MapVirtualKeyEx(VirtualKeyCode, 0, handle);
StringBuilder stringBuilder = new StringBuilder(2);

int nResultLower = ToUnicodeEx(VirtualKeyCode, scanCode, keyboardState, stringBuilder,
                                       stringBuilder.Capacity, 0, handle);

string output= string.Empty;
if (nResultLower != 0)
{
  output = stringBuilder.ToString();
}



回答3:


Not quite sure we're talking about same scenario, but I recently encountered similar problem where ToUnicodeEx interrupted users' key strokes (when using modifiers like 'alt+numpad' or on German keyboard the '+' key modifier), causing unexpected letters to be printed into screen instead if the desired ones.

Solved my problem by combining @Nejchy's code with ClearKeyboardBuffer method right before running ToUnicodeEx:

private static bool ClearKeyboardBuffer(uint vk, uint sc, IntPtr hkl)
{
    StringBuilder sb = new StringBuilder(10);
    int rc = -1;
    bool isDeadKey = false;
    while (rc < 0)
    {
        rc = user32.ToUnicodeEx(vk, sc, new byte[256], sb, sb.Capacity, 0, hkl);
        if (!isDeadKey && rc == -1) isDeadKey = true;
        Console.Write(rc);
    }
    return isDeadKey;
}

In your code that does 'ToUnicodeEx':

var isDeadKey = ClearKeyboardBuffer((uint)aKey, 0, hKd);
if (isDeadKey) return;
user32.ToUnicodeEx((uint)aKey, vkCode, keyboardState, characters, 10, (uint)0, hKd);

Reference: http://www.siao2.com/2006/03/23/558658.aspx http://www.siao2.com/2006/04/06/569632.aspx

Also look at his code: https://stackoverflow.com/a/8705696/802848



来源:https://stackoverflow.com/questions/1164172/intercept-keyboard-input-using-current-keyboard-layout

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!