c# - 如何使用模态窗口将 WM_INPUTLANGCHANGEREQUEST 发送到应用程序?
问题描述
我写了一个键盘切换器,效果很好,但是如果当前应用程序打开了模式窗口,则会失败。在键盘开关上,我执行以下操作
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();
但语言没有改变。
我将如何做到这一点?
添加 get root owner 改善了情况,但并没有完全帮助。
添加调用GetDesktopWindow
没有帮助:
hwnd = GetDesktopWindow();
InputLangChangeRequest(hwnd, language);
hwnd = GetRootOwner();
InputLangChangeRequest(hwnd, language);
解决方案
通过遍历 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);
}
}
推荐阅读
- python - 如何解决 AttributeError:“NoneType”对象没有属性“CONTENT_TYPE”
- javascript - 嵌入指向最新 YouTube 视频的链接
- asp.net - 我第一次启动 Visual Studio 时没有 IIS Express 按钮
- python - 从需求文件中的私人仓库进行 pip 安装时避免 git clone
- ios - Facebook SDK 警告我设置“FacebookAdvertiserIDCollectionEnabled”标志。如何解决这个问题?
- c# - 本地计算机上的自托管 WebAPI,支持 https
- google-cloud-firestore - Firestore 触发器函数的跟踪上下文(分布式跟踪)
- android - 如何取消 Firebase 存储元数据下载任务?
- c# - 我无法检查玩家是否在冲刺
- r - glmnet 包中的“standardize =”选项