我写了一个键盘切换器,它工作正常,但是如果当前应用程序已打开模式窗口,则会失败。在键盘开关上,执行以下操作
hwnd = GetForegroundWindow();
PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, IntPtr.Zero, handle);
其中
[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();
,但语言不变。
我该怎么做?
添加使root所有者的情况有所改善,但并没有完全解决问题。
添加对GetDesktopWindow
的呼叫没有帮助:
hwnd = GetDesktopWindow();
InputLangChangeRequest(hwnd, language);
hwnd = GetRootOwner();
InputLangChangeRequest(hwnd, language);
答案 0 :(得分:1)
通过遍历父级和子级链来检索拥有的根窗口 GetParent返回的所有者窗口。
如果存在模态窗口或模态窗口链,则应该返回主UI窗口。
hwnd = GetForegroundWindow();
hwnd = GetAncestor(hwnd, GA_ROOTOWNER); //#define GA_ROOTOWNER 3
WM_INPUTLANGCHANGEREQUEST
会失败(我不知道为什么!)要解决此问题,您可以向对话框的后代(除了WM_INPUTLANGCHANGEREQUEST
之外,向对话框的后代发布WM_INPUTLANGCHANGEREQUEST
消息消息发送到对话框本身)
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);
}
}