windows - How to obtain keyboard layout for Microsoft Edge and other windows hosted in ApplicationFrameHost.exe
问题描述
As we all know, Windows's keyboard layouts are thread-specific. When a layout changes, a message is dispatched to the foreground thread by the shell. So if one wants to obtain the most recent system-wide keyboard layout, one must do something like this:
const HWND foregroundWindow = ::GetForegroundWindow();
const DWORD foregroundThread = ::GetWindowThreadProcessId(foregroundWindow, NULL);
const HKL layout = ::GetKeyboardLayout(foregroundThread);
This works fine for most native Windows apps.
However, UWP applications, and several system apps including Microsoft Edge host their windows in the ApplicationFrameHost.exe
. This causes ::GetForegroundWindow()
to return the window of said process, leading to several curious problems, including misdetection of the foreground process and troubles detecting the actual keyboard layout.
The threads of ApplicationFrameHost.exe
simply don't react to the system-wide keyboard layout change. It seems that they are not hosting the actual focused UI element. ::GetForegroundWindow()
returns only the frame window, but the actual UI element has its own thread and maybe is hosted by its own process. Thus, the foreground framw window is simply not getting the respective layout change messages, and its thread has a stale HKL
associated with it.
How can I detect the correct HKL of the foreground process?
解决方案
诀窍是完全停止依赖该GetForegroundWindow()
方法。
相反,我通过利用古怪和违反直觉但记录了GetGUIThreadInfo()
.
如果您将零作为第一个参数传递给此函数,它将返回前台线程的信息——接收实际用户输入的线程!
该线程还将及时从 shell 接收与 HKL 相关的消息,因此键盘布局不会过时。
GUITHREADINFO gti = { sizeof(GUITHREADINFO) };
// fetching the foreground thread info
::GetGUIThreadInfo(0, >i);
// you may also fallback to other window handles in the GUITHREADINFO
// if the `hwndFocus == NULL`
const DWORD thread = ::GetWindowThreadProcessId(gti.hwndFocus, NULL);
const HKL layout = ::GetKeyboardLayout(thread);
推荐阅读
- android - 使用 Linkify 在 android 中更改链接的文本
- python - Issue a warning only once per program
- tensorflow - keras 和 keras-gpu 有什么区别?
- angular - 当响应为假时如何删除行数据,该行数据在 angular2 中添加为真作为响应
- javascript - Update on datachange on Angular 6
- selenium - Selenium chromedriver svg dom 抓取链接
- ios - Detect when the local video ended and move to another Scene
- android-studio - 我的 Android Studio 升级到 3.2.1,当我构建时出现错误
- c# - Error: Unexpected end of stream. Data might be corrupted
- atom-editor - Atom v1.32 stopped detecting matching tags and JavaScript syntax highlighting