1

Is there any way to programatically detect what keyboard layout a user is using?

For example if the user is using a QWERTY layout a message box should appear that the user is using a QWERTY keyboard, same with AZERTY, QWERTZ, etc... I have no idea where to start and how to accomplish this.

Joscplan
  • 1,024
  • 2
  • 15
  • 35
  • Have you tried using the information in [this answer](http://stackoverflow.com/questions/869609/keyboard-type-qwerty-or-dvorak-detection?rq=1)? Seems like it may be extendable to your uses. – FThompson May 12 '14 at 18:30
  • or this: http://stackoverflow.com/questions/661722/extracting-keyboard-layouts-from-windows – Stefan Falk May 12 '14 at 18:31
  • Why are you trying to tell the user something with a message box that he can trivially figure out himself by just looking at his keyboard? – Hans Passant May 12 '14 at 18:36
  • Is not for that use the message box is just an example. The use for this is key mapping. – Joscplan May 12 '14 at 18:40

2 Answers2

2

As from the answer suggested in that question Keyboard Type (Qwerty or Dvorak) detection here is what I came with:

public partial class Form1 : Form
{
    const int KL_NAMELENGTH = 9;

    [DllImport("user32.dll")]
    private static extern long GetKeyboardLayoutName(
          System.Text.StringBuilder pwszKLID);

private void Form1_Load(object sender, EventArgs e)
    {
        StringBuilder name = new StringBuilder(KL_NAMELENGTH);
        GetKeyboardLayoutName(name);
        String KeyBoardLayout = name.ToString();
        if (KeyBoardLayout == "00000407" || KeyBoardLayout == "00000807")
        {
            MessageBox.Show("Using QWERTZ");
        }
        else if (KeyBoardLayout == "0000040c" || KeyBoardLayout == "0000080c")
        {
            MessageBox.Show("Using AZERTY");
        }
        else if (KeyBoardLayout == "00010409")
        {
            MessageBox.Show("Using Dvorak");
        }
        else
        {
            MessageBox.Show("Using QWERTY");
        }
    }   
}

Keyboard Locale IDs taken from here: Locale IDs, Input Locales, and Language Collections for Windows XP and Windows Server 2003

Community
  • 1
  • 1
Joscplan
  • 1,024
  • 2
  • 15
  • 35
0

I thought there was an easy way to get the layout in the form "AZERTY" or "QWERTY", but apparently there isn't... However, you can cheat by requesting the names of the keys from their scan code. This code returns "AZERTY", "QWERTY" or "QWERTZ", depending on the current layout:

private static string GetKeyboardLayout()
{
    var layout = new StringBuilder();
    var buffer = new StringBuilder(64);
    for (int i = 0; i < 6; i++)
    {
        int scanCode = 0x10 + i;
        int lParam = scanCode << 16;
        GetKeyNameText(lParam, buffer, buffer.Capacity);
        layout.Append(buffer.ToString());
    }
    return layout.ToString();
}

[DllImport("user32.dll")]
private static extern int GetKeyNameText(int lParam, StringBuilder lpString, int cchSize);

But of course, it won't work for Dvorak keyboards, since the layout doesn't actually spell "DVORAK"... (and I suspect the returned value would be meaningless for non-latin keyboards too)

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758