Использование GetAncestor
Извлекает собственное корневое окно, пройдя по цепочке родительского окна и
окна владельца, возвращаемые GetParent.
Это должно вернуть главное окно пользовательского интерфейса, если есть модальное окно или цепочка модального окна.
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);
}
}