Jump to content

Recommended Posts

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!!

Link to post
Share on other sites

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
Link to post
Share on other sites

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
Link to post
Share on other sites

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
Link to post
Share on other sites
  • 2 weeks later...

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
Link to post
Share on other sites
  • 3 weeks later...

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=

Link to post
Share on other sites
  • 2 weeks later...

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.

Link to post
Share on other sites
  • 3 months later...

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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By LWC
      If you like to launch a game that has uncomfortable key combination, can you use AutoIt to map better keys just for that game without affecting the entire system?
      For the sake of example, let's say your game's executable is notepad.exe and you'd like the letter / to actually type \, but only inside Notepad.
    • By Colduction
      Hi AutoIt Programmers!, I just looking for a way to change entered keys in English to Russian keys and reverse, i must clear for you to understand. For example:
       
      I write keys on keyboard and i forgot to change input language and then the result will be: Dkflbvbh (Thing we write in fact) ====> Владимир (Thing we want)
       
      And reverse: Владимир  ====> Dkflbvbh

      Is there any solution without writing constant for each words? for example dlls or WinAPIs.
    • By matwachich
      DEPRECATED: see this new UDF
       
    • By Fenzik
      Hello,
      i searched the forum for something near, but with no success...
      I have Combobox control with $CBS_DROPDOWNLIST style with some items (for example (one, two, nine).
      When i want to select the item, using keyboard, the items are selected only on First letter base (for example when i type "on", Nine is selected).
      Is there some trick to force the combobox with $CBS_DROPDOWNLIST style to accept more than the First letter during selecting the items from the list?
      Mi wanted result is the same as for example - when you type "fir" on the desktop, Firefox is automatically selected.
      Thank you so much.
      Fenzik
    • By WoodGrain
      Hi All,
      I've bought a Ergodox EZ programmable keyboard with layers of key maps (eg, layer 0 = dvorak, layer 1 = numberpad & nav, layer 2 = qwerty, etc), I've also got a small USB screen that can pull information from the registry. What I would like to determine is a way to pull the value of each current key from the keyboard, I can then write the values to the registry and pull them into my USB screen so I can see the keyboard key layout.
      I'm stuck with retrieving the key values, I've looked at _IsPressed(), _WinAPI_GetKeyState(), _WinAPI_GetKeyboardState(), _WinAPI_GetKeyboardType(), _WinAPI_GetKeyNameText(), but none of them appear to be able to pull the keyboard key values without user interaction.
      The idea being, in pseudo code, bear in mind no error checking etc in this code, "GetKeyValue()" is what I'm needing help with and is a made up function, as is "HardwareKey1" etc:
      $keyOnePrev = "" $numOfKeys = 76 While 1 $keyOneCurrent = GetKeyValue(HardwareKey1) If $keyOneCurrent <> $keyOnePrev Then For $key = 1 To $numOfKeys $keyToWrite = GetKeyValue(HardwareKey & $key) RegWrite("HKEY_CURRENT_USER\Software\myKeyboard", "key" & $key, "REG_SZ", $keyToWrite) Next EndIf $keyOnePrev = $keyOneCurrent Sleep(5000) WEnd Thanks guys!
×
×
  • Create New...