StrokesPlus Forum
                       
StrokesPlus Forum
Home | Profile | Register | Active Topics
Members | Search | FAQ
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 Lua Scripts
 General Action Scripts
 Keyboard language
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic  

Dimka

Russia
5 Posts

Posted - 11/22/2012 :  22:27:30  Show Profile  Reply with Quote
First of all, many, many thanks for S+.

Is there a way, trick, to display via acDisplayText() the keyboard input language, which is becoming active? (I use SendAlt & SendShift combination to switch between them, and it would be very good to bring info to the screen for some little time).

Rob

USA
2479 Posts

Posted - 11/23/2012 :  00:59:51  Show Profile  Visit Rob's Homepage  Reply with Quote
Since I don't have an international setup, it's difficult for me to field these types of requests.

However, I have been able to display the language ID for my system (409) by putting this into the Global Lua tab:
aliencore = alien.core
user32 = aliencore.load("user32.dll")

-- ************ GetKeyboardLayoutName ************

gGetKeyboardLayoutName = user32.GetKeyboardLayoutNameA
gGetKeyboardLayoutName:types{ ret = 'long', abi = 'stdcall', 'pointer'}

function aGetKeyboardLayoutName()
	sLayout = ""
	gGetKeyboardLayoutName(sLayout)
	return sLayout
end


And this into an action:
acDisplayText(aGetKeyboardLayoutName(), "Arial", 42, 1500, 0, 0, 455, 100, 100)


The sLayout receives the layout byref and seems to be lost if you do anything to the string, and it doesn't like matching in a comparison...I'll dig a little deeper when I have some time as (oddly enough) I'm not a Lua expert at all

Hopefully this does something for you.
Go to Top of Page

Dimka

Russia
5 Posts

Posted - 11/23/2012 :  01:29:26  Show Profile  Reply with Quote
Yes, that's completely enough for me. Thank you, Rob.

Update.
With your's script example I always get 409, no correlation with actual input language. Maybe some another Get... from user32.dll?

Edited by - Dimka on 11/23/2012 02:29:36
Go to Top of Page

Rob

USA
2479 Posts

Posted - 11/23/2012 :  08:06:31  Show Profile  Visit Rob's Homepage  Reply with Quote
Honestly, it was a complete stab in the dark in hoping it would show something different for another language

I'll have to look around some more.
Go to Top of Page

Rob

USA
2479 Posts

Posted - 11/23/2012 :  08:08:42  Show Profile  Visit Rob's Homepage  Reply with Quote
Judging by the name, perhaps it's only the keyboard's layout, nothing to do with the language selected. Meaning, the physical keyboard hasn't changed in any way, which may be what that function is retrieving. Again, pure speculation at this point.
Go to Top of Page

Rob

USA
2479 Posts

Posted - 11/23/2012 :  08:36:39  Show Profile  Visit Rob's Homepage  Reply with Quote
Actually, I think it's because input language is per thread. So Notepad can have one language, Word another, etc. The call is returning the language of the action thread in S+, which would likely be 409.

This may be a tricky thing to accomplish since applications can have many threads, which makes it very difficult to put this into an action as you don't know what thread to specify. For example, getting the foreground window we can determine the process ID easily (since there's only one per instance of a program); but internally, the app can potentially have dozens of threads, and I can't (thus far) find a way to programmatically determine the thread which is handling the input for a program.

The only way it seems would be to register a system-wide Windows message hook and capture the WM_INPUTLANGCHANGE message (which the program with focus receives when the input language is changed). However, that's something we can't do in a Lua script and isn't something I want to add to S+ as it just adds constant overhead for only a single use.
Go to Top of Page

Dimka

Russia
5 Posts

Posted - 11/23/2012 :  21:07:36  Show Profile  Reply with Quote
Understood, Rob.

Edited by - Dimka on 11/23/2012 21:10:13
Go to Top of Page

Rob

USA
2479 Posts

Posted - 11/24/2012 :  11:37:04  Show Profile  Visit Rob's Homepage  Reply with Quote
Ah ha! Thanks to some folks over at stackoverflow.com, I think I've got something. Now, it's not guaranteed to work as there may be some circumstances where the thread that created the window is not the one that is processing input, but there's a pretty good chance it will work most of the time. I've tested it in a few apps (installed the Simplified Chinese keyboard layout, and using the Alt+Shift to switch) and it's working fine.

Ok, so in the Global Lua tab:
aliencore = alien.core
user32 = aliencore.load("user32.dll")

-- ************ GetKeyboardLayout ************

gGetKeyboardLayout = user32.GetKeyboardLayout
gGetKeyboardLayout:types{ ret = 'long', abi = 'stdcall', 'long'}

function aGetKeyboardLayout(threadID)
	return gGetKeyboardLayout(threadID)
end

-- ************ GetWindowThreadProcessId ************

gGetWindowThreadProcessId = user32.GetWindowThreadProcessId
gGetWindowThreadProcessId:types{ ret = 'long', abi = 'stdcall', 'long', 'pointer'}

function aGetWindowThreadProcessId(hwnd)
	local threadID = 0
	threadID = gGetWindowThreadProcessId(hwnd, threadID)
	return threadID
end


The action:
local iLangID = bit32.rshift(aGetKeyboardLayout(aGetWindowThreadProcessId(acGetOwnerWindowByPoint(gsx,gsy))),16)
if iLangID == 1033 then
	sLang = "English - United States"
elseif iLangID == 2052 then
	sLang = "Chinese - People's Republic of China"
end
acDisplayText(sLang, "Arial", 42, 255, 0, 0, 1200, 100, 100)


See this link for the list of locale IDs (the 1033 and 2052 above) for the language(s) you need:
http://msdn.microsoft.com/en-us/goglobal/bb964664.aspx

Note that this is setup to get the language of the window that's under the mouse cursor where the gesture began. I can help you change that if you need to, but test it out as-is to see if it works for you.
Go to Top of Page

Dimka

Russia
5 Posts

Posted - 11/24/2012 :  14:58:06  Show Profile  Reply with Quote
Wonderful, it works now. Thanks.
One thing I have to mention: execution of acDisplayText() makes whole screen to flick once. Is there a way to prevent flickering (OS is XP)?
Go to Top of Page

Rob

USA
2479 Posts

Posted - 11/24/2012 :  15:32:05  Show Profile  Visit Rob's Homepage  Reply with Quote
Unfortunately not on XP. The overlay window which displays the text message is a full screen transparent window which is created when you call acDisplayText and is destroyed when the duration has passed. On XP, this causes a flicker when Windows blends and refreshes certain UI elements below the (mostly) transparent window.

The gesture draw window can be set to stay on top to prevent the flicker when drawing gestures, but the display text window doesn't stay running and thus there's no way around it. Clearly there could be a better way to handle this, and I've tried many times (without rewriting major sections of the code), but that's just the way it is for the time being.

At some point, I will likely end up rewriting S+ from the ground up, now that I have much more experience and a better idea of many use cases/issues/requests I hadn't thought of when I started writing S+.
Go to Top of Page

Dimka

Russia
5 Posts

Posted - 11/24/2012 :  15:57:33  Show Profile  Reply with Quote
I see.
Also text comes out white outlined. Maybe you can modify acDisplayText() with one more input param and make it able to draw colored background under chars?
Go to Top of Page

Rob

USA
2479 Posts

Posted - 11/24/2012 :  19:50:10  Show Profile  Visit Rob's Homepage  Reply with Quote
Well, since specifying a BG color of the text will draw a full rectangle of the color behind the text, I've decided to set the color key of the window to match the BG of the text, which will both be only a single tick off from the specified text color. This eliminates the white outline but doesn't affect anything else.

I'll release that in 2.4.3.
Go to Top of Page

babakm

58 Posts

Posted - 04/19/2014 :  02:18:23  Show Profile  Reply with Quote
Thanks
Second script is very good.
Other Language code:
http://www.robvanderwoude.com/languagecodes.php

Edited by - babakm on 04/19/2014 02:18:47
Go to Top of Page

perpleks

2 Posts

Posted - 03/28/2018 :  10:12:15  Show Profile  Reply with Quote
Unfortunately, StrokesPlus crashes under Windows 10 with this code :( Is it possible to resolve this issue somehow?
Go to Top of Page

perpleks

2 Posts

Posted - 03/28/2018 :  11:03:38  Show Profile  Reply with Quote
It seems like problem is in GetWindowThreadProcessId function, so I've simply omitted it, since in Windows 10 language change is system-wide by default.

My objective was to use strokes plus with Firefox instead of mouse gestures addon (they do not work with some tabs since webextensions disaster, e.g. new empty tab) and I was having problems with "Close tab" gesture due to S+ lack of proper multilanguage support. In the end I've came up with this gesture code:

local iLangID = bit32.rshift(aGetKeyboardLayout(0),16)

if iLangID == 1049 then
	acSendKeys("^")
elseif iLangID == 1033 then
	acSendKeys("^w")
end


Works nicely

Edited by - perpleks on 03/28/2018 11:05:08
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
StrokesPlus Forum © 2011-2018 Rob Yapchanyk Go To Top Of Page
Snitz Forums 2000