[CLASS] Lyt - Keyboard layout (language) operation

Post a reply

Confirmation code
Enter the code exactly as it appears. All letters are case insensitive.
Smilies
:D :) ;) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :!: :?: :idea: :| :mrgreen: :geek: :ugeek: :arrow: :angel: :clap: :crazy: :eh: :lolno: :problem: :shh: :shifty: :sick: :silent: :think: :thumbup: :thumbdown: :salute: :wave: :wtf: :yawn: :facepalm: :bravo: :dance: :beard: :morebeard: :xmas: :HeHe: :trollface: :cookie: :rainbow: :monkeysee: :monkeysay: :happybday: :headwall: :offtopic: :superhappy: :terms: :beer:
View more smilies

BBCode is ON
[img] is OFF
[flash] is OFF
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: [CLASS] Lyt - Keyboard layout (language) operation

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by popobawa » 20 Aug 2018, 22:28

It does not work on Run windows (win+r) on windows 10
:(

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by antoniy » 30 Apr 2018, 01:37

Morning Drugwash, stealzy!

Nice that you support this discussion! :)

Experiment 1:

This snipped produces "hwn mismatch" message box, when I press CapsLock on the desktop. I also tried to close screen captures and screen drawers to minimize risk of hidden windows -> same effect.

Code: [Select all] [Expand]GeSHi © Codebox Plus



AHK version v1.1.28.02 - April 7, 2018
Script is executed with AutoHotkeyU64.exe process.
Windows 10 version 1709 (05 Build 16299.371)

AHK Windows Spy reports:
Program Manager
ahk_class Progman
ahk_exe Explorer.EXE


Experiment 2:
Set just before loading the Lyt class. No change of keyboard layout on the desktop.

Experiment 3:
On Windows 7, x64, same script - does not work either!

Experiment 4 (to check interference with other code):
Closed all AHK processes. Extracted just Lyt code with CapsLock hook and started it -> does not work on the desktop.

Thank you!
Anton

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by stealzy » 29 Apr 2018, 15:38

Drugwash wrote:add that directive

I don't think this is enough, because it will not have an effect on WinExist("A") id return.
Btw, I try send PostMessage, 0x50 message directly to window with id hDesk := DllCall("user32\GetDesktopWindow", "Ptr"),
it not change layout while I renaming file on desktop.
Anton, could you please specify your OS version. Have you tried use x64 AutoHotkey interpreter?

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by Drugwash » 29 Apr 2018, 11:56

antoniy wrote:Hi @Drugwash,

Thank you for your prompt reply!

I inserted the code, however it fires a message box in any cases - whether it is a desktop or an application window.
The beginning of the Set() function looks now like:

Code: [Select all]GeSHi © Codebox Plus

        Set(arg := "switch", win := "") {
hDesk := DllCall("user32\GetDesktopWindow", "Ptr")
If (hWnd != hDesk)
msgbox, hwnd mismatch!

IfEqual win, 0, Return "Window not found"


Kind regards,
Anton Golubev

That's not correct, Anton, the Set() function should have been:

Code: [Select all] [Expand]GeSHi © Codebox Plus

However, since according to stealzy's reply there is another window that should take the message, the whole issue may lie in a missing directive: DetectHiddenWindows, On. Please add that directive to the autoexec section of your script and see if the code then works.

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by stealzy » 29 Apr 2018, 10:03

On my OS (Win7x64) Lyt code can switch layout while I renaming the file located on the desktop :think:.
In my case WinExist("A") return ID of window with class "WorkerW", so it take a message.

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by antoniy » 29 Apr 2018, 10:01

Hi @Drugwash,

Thank you for your prompt reply!

I inserted the code, however it fires a message box in any cases - whether it is a desktop or an application window.
The beginning of the Set() function looks now like:

Code: [Select all]GeSHi © Codebox Plus

        Set(arg := "switch", win := "") {
hDesk := DllCall("user32\GetDesktopWindow", "Ptr")
If (hWnd != hDesk)
msgbox, hwnd mismatch!

IfEqual win, 0, Return "Window not found"


Kind regards,
Anton Golubev

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by Drugwash » 29 Apr 2018, 08:20

Just for a short test, please try to add this code in the Set() function right before IfEqual hWnd, 0, Return "Window not found" and try again:

Code: [Select all]GeSHi © Codebox Plus

hDesk := DllCall("user32\GetDesktopWindow", "Ptr")
If (hWnd != hDesk)
msgbox, hwnd mismatch!

If you get the 'hwnd mismatch' message then that may be the problem.
Next, try to bypass the hWnd detection and use directly the handle retrieved by GetDesktopWindow(). If it works that way then you'll know for sure where the problem lies. I'm not sure how to fix this however.

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by antoniy » 29 Apr 2018, 07:02

Hi,

The script/class lyt from stealzy otherwise perfectly working, fails to switch keyboard layout if just a desktop is selected. Use-case: I want to rename the file located on the desktop, press the trigger button (CaseLock in my case), but nothing happens. AHK correctly sends the event to the script (checked with the msgbox), but the layout stays in the old position. If I do file rename in Explorer window, I can switch layout normally.

I think the problem happening because there is actually "no process" to switch the layout. The problem lies somewhere in the mechanism of Lyt class, how it selects the processes to switch the layout. In this case I think the explorer.exe must be manipulated, although its process window is not active.

Could anybody check my assumptions and fix idea please? I will be glad to try the fix and write back if it worked.

That's the script I use:

Code: [Select all]GeSHi © Codebox Plus

toggle=1
Capslock::
if (toggle:=!toggle)
Lyt.Set(0x4070409)
else
Lyt.Set("RU")
SoundBeep 999,1
Return


Kind regards,
Anton

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by Drugwash » 06 Feb 2018, 11:01

Yeah, I managed to fix a few things since posting that code above, the offline version now correctly detects Default User Layout and System User Layout, but it wasn't easy to find out the proper way. At least I think it's the proper way, but it's possible a a user with limited rights may not be able to retrieve System Default Layout. Dunno, haven't checked - I always give admin rights to users on my machines. Someday I'll post the code in a new topic, maybe someone will offer feedback.

HKLs seem to be 8 bytes even on XP, I found that out during tests. Actually, truncating them to 4 bytes will yield the wrong result when they're in the form of 0xFFFFffffXXXXYYYY.

Hex2Str() is just for prettifying the display but it erroneously interfered with the HKLs in GetHKL(). It allows for some fine customization of the output. The Format() function is so weird I can never understand it, besides I prefer basic syntax as one day I may go back to my 98SE machine after I fix it and don't wanna get bad habits in the mean time. :)

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by stealzy » 06 Feb 2018, 05:35

Hi all!
@formicant, you're right, thanks, fix all my codeboxes :facepalm:.
I think you need hook on window message to monitor the layout changing. Also, hook on window activate and creating, such every window has it's own layout.

@Drugwash, thanks for fix my hardcode :thumbup:! Update top post just now, btw feel free to modify it, i go to the forum at least once a week.
GetKLIDfromHKL() works such because WinAPI GetKeyboardLayoutName works this way. I don't like it, but it work fast (I checked it with A_TickCount) and right way.
I test it on my x64 OS with both AutoHotkeyA32.exe and AutoHotkeyU64.exe.
Drugwash wrote:It seems to have trouble with those long negative pointers

Pointer is not negative, just 8-bytes against 4, but there is nothing to worry unless you convert it to decimal view wrong way.
GetKeyboardLayout() always return full size HKL for your system, but in PostMessage you must use 4-byte HKL if AutoHotkey process is 32-byte.
Dvorak on OSx64 0xfffffffff0020409 -> 0xf0020409 Dvorak on OSx86. It's already works fine with pointers, so don't worry ;).

@Drugwash, look throw your code, DllCall("GetUserDefaultLangID") != system default layout :HeHe:.
It is system locale (time format, etc). Try change default layout in lang bar if you want proof.
Actually system default layout KLID written in registry: HKCU\Keyboard Layout\Preload\1.
Don't know why Hex2Str() look this way, maybe you find usefull this function:

Code: [Select all]GeSHi © Codebox Plus

hex(n) {
Return Format("{:#0" 2 + 2*A_PtrSize "x}", n)
}

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by Drugwash » 01 Feb 2018, 10:01

Latest version should work fine without any modification. We should stop here until I polish it a little and start a new topic, then a moderator will hopefully move relevant posts there to remove this hijacking.

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by burque505 » 01 Feb 2018, 09:06

Here's some results with 2*A_PtrSize, 8, and then 16.
LytDW2.png
LytDW2.png (27.43 KiB) Viewed 1157 times

LytDW_8.png
LytDW_8.png (25.74 KiB) Viewed 1157 times

LytDW_16.png
LytDW_16.png (23.6 KiB) Viewed 1157 times

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by Drugwash » 01 Feb 2018, 03:14

Dang, I desperately need an x64 machine for testing! :(
Thank you, burque. It seems to have trouble with those long negative pointers. Could you please try what's suggested above in the striked out text, that is replacing 2*A_PtrSize with 8?
But first, are you sure you redownloaded the code above? I modified it a bit after initial posting, maybe you got the old version.

Regarding images, my understanding is that images over a certain width are being attached as files rather than being rendered inline, to avoid board misalignment.

[EDIT] Code above was modified twice, should work correctly in x64 now without any modification whatsoever.

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by burque505 » 31 Jan 2018, 18:45

Here's what showed up for the same 7 keyboards as above.
(Having trouble getting the forum to display images at the moment ...)

LytDW2.png
(40.93 KiB) Not downloaded yet

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by Drugwash » 31 Jan 2018, 11:54

Yep, that is the correct output. :)

Now, since you use an x64 system (I see the long HKLs), could you please test the script below and see if it yields the same results (or better)? I don't have any x64 machines in the house.

Found a couple bugs, fixed below, and also cleaned up a bit. Edited twice since first posted. Please redownload, should work fine now in x64.

Code: [Select all] [Expand]GeSHi © Codebox Plus

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by burque505 » 31 Jan 2018, 11:31

Thanks, @Drugwash! Here's how it looks on my system after your fixes:

LytDW.PNG
LytDW.PNG (21.46 KiB) Viewed 1230 times

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by Drugwash » 31 Jan 2018, 04:27

The info about console language is useful, thank you.

There is a gotcha in the code though: the script assumes the default system shell is Explorer, which may not always be the case (there were/are replacements such as BlackBox/BBLean etc). In such case it may be better to use GetShellWindow(), GetProgmanWindow(), maybe even GetDesktopWindow() - all in user32.dll.

I see each KLID is being retrieved by temporarily activating the respective layout, which even if very brief may interfere with user's typing or automation. The alternative would be to parse the Preload and Substitutes lists in registry, matching against the HKLs (and there's a trick there too) to get to the real KLIDs.

@burque505: There's a slight mistake in your code too: it should be LayoutName, not DisplayName. That will show the layout name after the language name. ;)

[EDIT] Oh shoot, just noticed one language/layout is completely missing from the list, the Swedish one:
LangLayoutList.png
(26.46 KiB) Not downloaded yet


[EDIT2] …and I know why: because you assumed five would be more than enough installed layouts, so you hardcoded that value instead of getting the real one. ;) Here's the correct function:

Code: [Select all] [Expand]GeSHi © Codebox Plus

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by burque505 » 30 Jan 2018, 19:16

Hi stealzy, thanks, I like it.
I changed the example above as shown (or hidden) :) below so it would work (thanks formicant!).

Spoiler


Lyt.PNG
Lyt.PNG (21.69 KiB) Viewed 1279 times

Re: [CLASS] Lyt - Keyboard layout (language) operation

Post by formicant » 30 Jan 2018, 13:03

Great! Thanks.
(Please note that the method names in the examples differ from the ones in the class. E.g. GetLng ~ GetLocaleName.)

BTW, what is the best way to monitor the layout changing?

Top