Sign in to follow this  
Followers 0
WoodGrain

How to detect Qwerty vs Dvorak layout?

11 posts in this topic

Hi guys,

I've seen the @kblayout macro, but the information I'm after is the keyboard layout (aka "Input Method") so I can detect if I'm using "US Keyboard" or "United States-Dvorak Keyboard" rather than 00000c09 or 00000409 which relate to languages such as EN AU or EN US for example.

For example I have 1 language set up (English Australia) in my regional settings, but then under the language I have "US Keyboard" and "United States-Dvorak Keyboard" setup, so that when I press WIN+SPACE I can toggle between them.

Effectively I want a way of determining if I'm running qwerty or dvorak.

Thanks guys!!

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

I think @kblayout macro calls GetKeyboardLayout API, but it retrieves only low order byte, so it gets only the language identifier, you need the device identifier (also known as device handle or physical layout) too that's contained in high order bytes.

 

EDIT: On second thought, @kblayout macro calls GetKeyboardLayoutName function, which retrieves by default only language ID.

Edited by j0kky

Share this post


Link to post
Share on other sites

Perhaps there' a registry key with the qwerty / dvorak state..?

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Don't you like GetKeyboardLayout?

#include <WinAPI.au3>

HotKeySet("{SPACE}", _GetKeyboardLayout)
HotKeySet("{ESC}", _Exit)

While 1
    Sleep(100)
WEnd

Func _GetKeyboardLayout()
    Local $aRet = DllCall("user32.dll", "HANDLE", "GetKeyboardLayout", "DWORD", 0)
    If @error Then
        ConsoleWrite("ERROR!" & @CRLF)
        Return
    EndIf
    ConsoleWrite("Language Identifier: " & Hex(_WinAPI_LoWord($aRet[0]), 4) & @CRLF & _
        "Device Identifier: " & Hex(_WinAPI_HiWord($aRet[0]), 4) & @CRLF & @CRLF)
EndFunc

Func _Exit()
    Exit
EndFunc

 

Edited by j0kky

Share this post


Link to post
Share on other sites

Result while in Qwerty:

Language Identifier: 0C09
Device Identifier: 0409

Result when using Dvorak:

Language Identifier: 0C09
Device Identifier: 0409

 

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

That's really strange... Try this switching between the two keyboard setup without closing the application (and mantaining it on the top level). 

#include <WinAPI.au3>

Global Const $WM_INPUTLANGCHANGE = 0x0051
$hGUI = GUICreate("My GUI")
GUIRegisterMsg($WM_INPUTLANGCHANGE, "_WM_INPUTLANGCHANGE")
GUISetState(@SW_SHOW)
HotKeySet("{ESC}", _Exit)
WinActivate($hGUI)

While 1
    Sleep(100)
WEnd

Func _WM_INPUTLANGCHANGE($hWnd, $iMsg, $wParam, $lParam)
    Local $aRet = DllCall("user32.dll", "HANDLE", "GetKeyboardLayout", "DWORD", 0)
    If @error Then
        ConsoleWrite("ERROR!" & @CRLF)
        Return
    EndIf
    ConsoleWrite("Handle: " & $aRet[0]  & @CRLF & _
        "Language Identifier: " & Hex(_WinAPI_LoWord($aRet[0]), 4) & @CRLF & _
        "Device Identifier: " & Hex(_WinAPI_HiWord($aRet[0]), 4) & @CRLF & _
        "wParam: " & $wParam & @CRLF & _
        "lParam: " & $lParam & @CRLF & @CRLF)
    Return 'GUI_RUNDEFMSG'
EndFunc

Func _Exit()
    Exit
EndFunc

Then post here full console output.

Edited by j0kky

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Sorry about the delay!

Here's the output from the script, changing to EN-AU Dvorak first, then changing back to EN-AU Qwerty.

Quote

Handle: 0xF0020C09
Language Identifier: 0C09
Device Identifier: F002
wParam: 0x00000000
lParam: 0xF0020C09

Handle: 0x04090C09
Language Identifier: 0C09
Device Identifier: 0409
wParam: 0x00000000
lParam: 0x04090C09

Looks like the device identifier has picked it up while running the gui! I tried a truncated version of your script without the gui in a loop and it doesn't return the same result.

Edited by WoodGrain

Share this post


Link to post
Share on other sites

Is it possible to do this without a GUI?
I'm want to use it to display an icon so I can see at a glance which layout it's in.

Cheers

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

What did you do to remove the GUI? You shouldn't need it for the code to run, you can start it and have it run in the tray with a hotkey or something.

EDIT: Upon further inspection it seems we need GuiRegisterMsg for this to work, so alternatively you could just try to make the GUI invisible in the background. I don't know if there is a non-GUI alternative to this function.

Edited by anthonyjr2

UHJvZmVzc2lvbmFsIENvbXB1dGVyZXI=

Share this post


Link to post
Share on other sites

#10 ·  Posted

Hehe, an invisible gui. I guess if there's not another option it's the best available way.

I've really done nothing with the gui before, does this create much overhead in the script?
I'm wanting to check the state of the keyboard layout every second.

Thanks.

Share this post


Link to post
Share on other sites

#11 ·  Posted

hmm, ok, well I'm going to abandon this prospect, thanks guys for your input.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • Tarakesh
      By Tarakesh
      I have a situation where the desktop is designed in java swings. The nodes JTree is not allowing me to do checkbox selection using "spacebar". I am able to navigate through the nodes using up, down arrow and a tab. When I reach to the desire node selection, mouse left click is not working due a flaw a JTree core. However since it is selected, if mouse cursor auto moved to the position of the selection and send a "click"  then it should be solved. Any ideas much appreciated. 
      the problem with having fixed coordinates are the main windows is divided to 2panels where right panel containing this JTree can be expanded or shrink-ed.

    • myspacee
      By myspacee
      Hello,
      need help to remap '<' button and SHIFT+'<'
      I made a little editor that allows to my users to write using proprietary codes.
      In production we have 2 keys/symbols that i want to 'emulate'. So, when is press on my keyboard :
      < = « SHIFT+< = » Try to use help example _IsPressed :
       
      #include <Misc.au3> #include <MsgBoxConstants.au3> Local $hDLL = DllOpen("user32.dll") While 1 If _IsPressed("10", $hDLL) Then ConsoleWrite("_IsPressed - Shift Key was pressed." & @CRLF) ; Wait until key is released. While _IsPressed("10", $hDLL) Sleep(250) WEnd ConsoleWrite("_IsPressed - Shift Key was released." & @CRLF) ElseIf _IsPressed("1B", $hDLL) Then MsgBox($MB_SYSTEMMODAL, "_IsPressed", "Close the application.") ExitLoop EndIf Sleep(250) WEnd DllClose($hDLL) but how manage keys combination ?
      thank you for any help,
      m.
    • Tarakesh
      By Tarakesh
      Hi,
      First of all I would like say infinite thanks to the team involved in designing this great tool.
      Here is my problem
      1. Press windows button
      2. ESC
      3. TAB
      4. It will take me to the first pinned icon in the taskbar
      5. If I I do SHIFT F10 which usually opens context menu like  right click of the mouse.
      6. For one of the application I am using it does not support  Shift + F10 context menu rather it listens to only mouse right click event.
      7. I do a search in a tree view of my application and the search item is selected or focused
      8. For eg

           User1

           User2
           User3
      Now if I search for User1 the tab or focus move to User 1 (Red)
           User1

           User2
           User3
      If I search for User3 the tab or focus moves to User 3
      Now my question is how can I move the mouse automatically go to the focused item on the window. Such that during automation I can issue MoveClick("{RIGHT}") as {SHIFT F10} is not working from the keyboard. It is a java app, unfortunately it is not honoring the right click events from keyboard to open the context

      WinMinimizeAll();
      Send("^{ESC}")
      Sleep(200)
      Send("{ESC}")
      Send("{TAB}")

      the above scripts take the tab to the first pinned icon in the taskbar. Now i want
      MouseMove( "move to tab" selection")

      Regards,
      Tarakesh
    • GreenSparks
      By GreenSparks
      Hi!
      I post here because i was wonderring if someone in this forum could help me with my script.
      What i'm trying to do, is to basically install a new keyboard layout in Windows and activate it. I want to acheive by the registry or the command line, but not with the autoit automation tools, i don't find it stable...
      Thanks for your help and have a good day!