如何让全屏游戏的文本编辑框支持IME和TSF输入法
本文主要解决游戏在全屏状态下文本编辑框无法显示组词窗口和候选词窗口的问题
文章首发:http://blog.csdn.net/goodboychina/article/details/52067561
导致这个问题的原因是TSF与IME不兼容,且从Win7开始TSF(高级文字服务)默认是开启状态,并且无法关闭。这个情况在Win8下更严重。
要解决这个问题要从TSF框架的引入导致的兼容性问题入手。首先先了解下文本编辑框用到的IME相关的API和相关概念。
HKL:键盘布局,最初的含义就是单纯的键盘布局,能够将键盘的扫描码转换成设备无关的虚键码。现在HKL的含义更广泛,表示本地化标识符。
HKL名字:键盘布局编号,设备码和语言代码组成。前四位是设备码,后四位是语言码。注册表项HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts中列出了所有键盘布局。项名就是HKL名称。
- “00000804” 表示 中文(简体) - 默认键盘
- “E0220804” 表示 中文(简体) - 搜狗输入法
- “E0230804” 表示 中文(简体) – 必应Bing输入法
API与消息
BOOL WINAPI GetKeyboardLayoutName(_Out_ LPTSTR pwszKLID);
可以获得当前键盘布局或输入法的HKL名字WM_INPUTLANGCHANGE
消息可以获知输入法切换情况
组词窗口 组词窗口显示了当前已经键入的字符序列
WM_IME_STARTCOMPOSITION
:输入法进入组词模式,程序会收到这个消息。WM_IME_ENDCOMPOSITION
:输入法结束组词模式,程序会收到这个消息。WM_IME_COMPOSITION
:组词发生改变,程序会收到这个消息
候选词窗口 候选词窗口列出可以选择的字或词
WM_IME_NOTIFY wParam==IMN_CHANGECANDIDATE
:候选词发生变动WM_IME_NOTIFY wParam==IMN_CLOSECANDIDATE
:关闭候选词窗口WM_IME_NOTIFY wParam==IMN_OPENCANDIDATE
:打开候选词窗口
TSF对输入框架重新进行了设计,基于COM组件实现,部分原有的消息与API已不能正常工作
ITfTextInputProcessor
:TIP 文字输入处理器ITfInputProcessorProfiles
:管理系统范围内的TIPITfInputProcessorProfileMgr
:管理程序当前的TIPITfUIElementSink
:接口类,实现此接口可以监听组词窗口和候选词窗口相关事件ITfInputProcessorProfileActivationSink
:接口类,实现此接口可以得知TIP的切换
程序需要作调整,能够同时支持TIP和IME
获取输入法名字示例代码
/* 获取HKL的显示名字
*/
bool GetLayoutName(const wchar_t* kl, wchar_t* nm )
{
long lRet;
HKEY hKey;
static wchar_t tchData[64];
DWORD dwSize;
wchar_t keypath[200];
wsprintfW(keypath, L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s", kl);
lRet = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
keypath,
0,
KEY_QUERY_VALUE,
&hKey
);
if (lRet == ERROR_SUCCESS)
{
dwSize = sizeof(tchData);
lRet = RegQueryValueExW(
hKey,
L"Layout Text",
NULL,