The 'in' process for out of process keyboard work

by Michael S. Kaplan, published on 2007/01/14 03:01 -05:00, original URI: http://blogs.msdn.com/b/michkap/archive/2007/01/14/1463873.aspx


The question that came in from zafer was:

i have a problem to switch e.g. "notepad" keyboard layout with C# and interop WinAPI. If i used "ActiveKeyboardLayout" this switch only my application keyboard layout. I have writen a virtualkeyboard. In this program i switch the keyboard input over "SetForegroundWindow" with the handle of active window for example "notepad". What should i do for switching keyboard layout on other process. Can you help me. Thanks for this issue.

This question actually comes up quite often, but the answer is probably not going to make the person asking happy.

There is no way to change the active keyboard layout in another process or thread. This is why apps like the Language Bar have to have a presence in every thread in order to be able to get enough information to display the current layout as one moves among the various threads and processes.

Which sort of suggests the solution -- a SetWindowsHookEx call and so on, to inject code into the thread so that you can have code  running where it will have the right context.

But I would really recommend thinking quite carefully before going down that road since it certainly brings your code to a whole new level in terms of exposure and risk. Like making an unintended security bug into your code into something with system-wide availability? Or at a minimum putting a bit of managed code into every thread and process? Scary!

If you really wanted to go down that road, I would highly recommend creating a minimally sized DLL in C or C++ with as few dependencies as possible, one that has no job except to communicate specific changes back and forth with the larger managed application that is acting as the virtual keyboard. Less to go wrong, less to burden all of the other processes with, and so on. If your final DLL is more than 10-20k then you should go back and try again....

And for the sake of everyone on the Internet, try to be at least 1000 times more careful than you would usually be, from a security standpoint. :-)

 

This post brought to you by  (U+ff01, a.k.a. FULLWIDTH EXCLAMATION MARK)


# Skip on 14 Jan 2007 9:53 AM:

You definitely shouldn't use c# for anything you inject into another process.  Since only one version of the CLR can be loaded per process this can cause all sorts of bad dependencies.

Old New Thing had a post on it awhile back, in the context of managed code for shell extensions, but the same warnings should apply here.

# Haali on 14 Jan 2007 10:51 AM:

Actually you can (ab)use WM_INPUTLANGCHANGEREQUEST. The documentation for that message says that DefWindowProc will do the needed changes, and indeed it works fine most of the time (I know it doesn't work for some input fields in Outlook).

# Michael S. Kaplan on 14 Jan 2007 4:46 PM:

Ah, problems with that message, though (like the fact that it is kind of broken now and not all apps will respect it anyway, as you pointed out). A globally (in the scope sense) relevant app/tool like a virtual keyboard can'r afford to only work sometimes....


referenced by

2007/10/11 Rumor as prophecy in Win32

go to newer or older post, or back to index or month or day