问题
I wrote a keyboard switcher, which works well, but fails if current application has modal window opened. On keyboard switch I do the following
hwnd = GetForegroundWindow();
PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, IntPtr.Zero, handle);
where
[DllImport("User32.dll", EntryPoint = "PostMessage")]
private static extern int PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
but the language does not change.
How would I accomplish this?
Adding get root owner improved situation, but didn't help completely.
Adding call for GetDesktopWindow
didn't help:
hwnd = GetDesktopWindow();
InputLangChangeRequest(hwnd, language);
hwnd = GetRootOwner();
InputLangChangeRequest(hwnd, language);
Code is here https://github.com/dims12/NormalKeyboardSwitcher
回答1:
Use GetAncestor
Retrieves the owned root window by walking the chain of parent and owner windows returned by GetParent.
This should return the main UI window if there is a modal window, or a chain of modal window.
hwnd = GetForegroundWindow();
hwnd = GetAncestor(hwnd, GA_ROOTOWNER); //#define GA_ROOTOWNER 3
Apparently
WM_INPUTLANGCHANGEREQUEST
fails if the target itself is a dialog based application (I don't know why!) To solve the problem you can post WM_INPUTLANGCHANGEREQUEST
message to dialog's descendants (in addition to WM_INPUTLANGCHANGEREQUEST
message to the dialog itself)
static bool MyEnumProc(IntPtr hwnd, IntPtr lParam)
{
PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, IntPtr.Zero, lParam);
return true;
}
static void Foo()
{
//Greek input for testing:
var hkl = LoadKeyboardLayout("00000408", KLF_ACTIVATE);
var hwnd = GetForegroundWindow();
if (hwnd != null)
{
hwnd = GetAncestor(hwnd, GA_ROOTOWNER);
PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, IntPtr.Zero, (IntPtr)hkl);
StringBuilder buf = new StringBuilder(100);
GetClassName(hwnd, buf, 100);
//if this is a dialog class then post message to all descendants
if (buf.ToString() == "#32770")
EnumChildWindows(hwnd, MyEnumProc, (IntPtr)hkl);
}
}
来源:https://stackoverflow.com/questions/51117874/how-to-send-wm-inputlangchangerequest-to-app-with-modal-window