Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Keyboard layout switcher for many layouts


  • Please log in to reply
6 replies to this topic
Alqualos
  • Members
  • 1 posts
  • Last active: Aug 08 2011 05:30 PM
  • Joined: 08 Aug 2011
If your native language is not English, you probably have two keyboard layouts installed and switch between them using Alt+Shift. This is fine, but if you're learning some third language or you just need to type in yet another layout occasionally, this becomes rather annoying because Alt+Shift doesn't work like Alt+Tab, so if you press it once to switch from English to your native language, then press it once more, you end up with third layout instead of going back to English.

This script aims to fix that issue, allowing to switch between two layouts no matter how many of them you have enabled in Windows:

; This should be replaced by whatever your native language is. See 
; http://msdn.microsoft.com/en-us/library/dd318693%28v=vs.85%29.aspx
; for the language identifiers list.
ru := DllCall("LoadKeyboardLayout", "Str", "00000419", "Int", 1)
en := DllCall("LoadKeyboardLayout", "Str", "00000409", "Int", 1)

!Shift::
w := DllCall("GetForegroundWindow")
pid := DllCall("GetWindowThreadProcessId", "UInt", w, "Ptr", 0)
l := DllCall("GetKeyboardLayout", "UInt", pid)
if (l = en)
{
    PostMessage 0x50, 0, %ru%,, A
}
else
{
    PostMessage 0x50, 0, %en%,, A
}

Known problems:

[*:okyfdnxp]The code above works only if you press Alt first, then Shift. If you press Shift first then Alt, normal layout switching mechanism is used. If you don't like this behavior, it is quite easy to change it to work for Shift-Alt too.
[*:okyfdnxp]The layout is switched as soon as Shift is pressed. This is different from the way Windows handles it, when switching occurs when you release one of the keys, provided you didn't press anything else in-between. This could be annoying if you use some shortcuts like Alt+Shift+V somewhere. A workaround is to press Shift+Alt+V instead, but it requires some practice to get used to it.

lixo1
  • Guests
  • Last active:
  • Joined: --
It works fine but I would like to expand the code to do it on existing windows and I am newbie w/ this tool.
How to loop through all the present windows ?

lixo1
  • Guests
  • Last active:
  • Joined: --
I did not how to switch all the windows at once but I found how to do it when the window is raised (become active)

The script change the keyboard automatically based on the user's setup choose through F12:

;
;Title  : Switch Keyboard to the wished Keyboard/language when the window is raised
;Date   : 6.01.2012
;Release: 1.0
;Author : JDacosta
;

fr := DllCall("LoadKeyboardLayout", "Str", "0000100c", "Int", 1)
en := DllCall("LoadKeyboardLayout", "Str", "00000409", "Int", 1)

Loop
{
  #IfWinActive
  {

    w := DllCall("GetForegroundWindow")
    pid := DllCall("GetWindowThreadProcessId", "UInt", w, "Ptr", 0)
    l := DllCall("GetKeyboardLayout", "UInt", pid)

    if (keysw_status_en AND l <> en)
    {
      PostMessage 0x50, 0, %en%,, A
      Sleep 1000
    }

    if (not keysw_status_en AND l <> fr)
    {
      PostMessage 0x50, 0, %fr%,, A
      Sleep 1000
    }

    Sleep 1000
  }
}

keysw_status_en := true
keysw_update_status()

f12::
  keysw_status_en := not keysw_status_en
  keysw_update_status()
  return

keysw_update_status()
{
  global keysw_status_en
  if (keysw_status_en)
    text := "En"
  else
    text := "Fr"
   
  x := A_ScreenWidth - 260
  y := A_ScreenHeight - 20
  tooltip %text%, %x%, %y%
}


nicolai
  • Guests
  • Last active:
  • Joined: --
Can you tell me, please, is it possible in AHK to make switching between layouts by HOLDING a key? I mean, for example, typing in Russian I press CAPS and hold it. While holding CAPS I'm typing in English. When I release CAPS, the layout switches back to Russian. (AFAIK this behavior is also supported in linux.)

  • Guests
  • Last active:
  • Joined: --

Can you tell me, please, is it possible in AHK to make switching between layouts by HOLDING a key? I mean, for example, typing in Russian I press CAPS and hold it. While holding CAPS I'm typing in English. When I release CAPS, the layout switches back to Russian. (AFAIK this behavior is also supported in linux.)

Did that, thanks for the useful example!
; This should be replaced by whatever your native language is. See
; http://msdn.microsoft.com/en-us/library/dd318693%28v=vs.85%29.aspx
; for the language identifiers list.
ru := DllCall("LoadKeyboardLayout", "Str", "00000419", "Int", 1)
en := DllCall("LoadKeyboardLayout", "Str", "00000409", "Int", 1)

*CapsLock::
w := DllCall("GetForegroundWindow")
pid := DllCall("GetWindowThreadProcessId", "UInt", w, "Ptr", 0)
l := DllCall("GetKeyboardLayout", "UInt", pid)
if (l = en)
{
    PostMessage 0x50, 0, %ru%,, A
}
else
{
    PostMessage 0x50, 0, %en%,, A
}

*CapsLock UP::
w := DllCall("GetForegroundWindow")
pid := DllCall("GetWindowThreadProcessId", "UInt", w, "Ptr", 0)
l := DllCall("GetKeyboardLayout", "UInt", pid)
if (l = en)
{
    PostMessage 0x50, 0, %ru%,, A
}
else
{
    PostMessage 0x50, 0, %en%,, A
}


duburlan
  • Members
  • 1 posts
  • Last active: Sep 09 2014 08:51 PM
  • Joined: 09 Sep 2014

Hi guys,

 

Is there any way to directly switch keyboard in Autohotkey? Like, left Win for the first layout and right Win for the second one.

 

I gues it also implies moving the Win keys somewhere else.

 

Thanks!



aleksandr
  • Members
  • 1 posts
  • Last active: Mar 03 2015 09:34 AM
  • Joined: 03 Mar 2015

Hi,

 

does anybody here use Dvorak Programmer keyboard (http://kaufmann.no/d...i386-calc.exe)? 

 

If so then how to make the trick in thread to work with that layout?

 

R. Kaufmann (the author of layout) told me magic constants as follows:

 

dvp := DllCall("LoadKeyboardLayout", "Str", "19360419", "Int", 17)

// the latter parameter should at least include KLF_REPLACELANG (= 0x10, i.e. the sum in the last parameter should at least be 16+1 = 17) see: https://msdn.microso...5(v=vs.85).aspx

// one could experiment by passing INPUTLANGCHANGE_FORWARD (= 2) as the second parameter to PostMessage (WM_INPUTLANGCHANGEREQUEST (= 0x50))

 

But nothing worked out. Any ideas on how to make it work?