aardio 标准库 key.ime 提供输入法相关函数。
key.ime.state 函数则用于检测输入法与键盘状态,标准库 key.ime.stateBar 用于创建显示输入法状态的工具界面。基于 key.ime.stateBar 实现的开源软件 ImTip 目前已经成为了流行的桌面软件。
我们先了解两个用于表示输入法状态的变量:
opened 用于表示当前是否打开输入法。
convMode 则用于指示输入法的转换模式(中、英、标点符号、全角、半角等)。
基本规则:
convMode 还有一些其他状态,中文输入法一般用不到。
个别输入法会返回错误的状态,主要分为以下三种情况:#
可尝试在不同窗口切换一下英文全半角、中英文标点等并查看 ImTip 能否正确显示状态,多切换几个窗口如果出错就是有问题。第 1、第 2 种情况可以在 ImTip 中勾选怪异模式解决( 不能同时安装多个有问题的输入法,因为 ImTip 会检测输入法列表并自动切换不同的兼容模式 ),第 3 种情况可能是该输入法问题比较严重,勾选怪异模式无法解决。
至于第三方输入法工具则更为混乱,早年我写过文章,在 ImTip 发布之前网上流传的代码基本都是错的。例如有的开发者看到中文状态下 convMode 是某个数值就以为这个固定的数值就表示中文输入状态,其实这是未经过严谨测试望文生义,别人切换几个状态或者换个输入法你的程序就乱套了。
ImTip 检测输入法状态的功能由 aardio 标准库的 key.ime.state 函数提供,此函数的关键源码如下:
namespace key.ime{
conversionLangIds = {[0x804] = 0x409;[0x404] = 0x409;[0xC04] = 0x409;[0x1404] = 0x409;[0x412] = 0x409;[0x0411] = 0x409} ;
state = function(hwnd){
if(!hwnd) {
hwnd = ::User32.GetForegroundWindow();
if(..winex) hwnd = ..winex.getFocus(hwnd,true) : hwnd;
}
var opened = getOpenStatus(hwnd);
var convMode = getConversionMode(hwnd);
var langId = getCurrentLangIdByHwnd(hwnd);
if (opened && langId==0x409) opened = false;
if(convMode === null) return false,,langId;
var symbolMode = 1/*_IME_SYMBOLMODE_HALFSHAPE*/;
if(!opened && (convMode==1 || convMode==0 ) && ! conversionLangIds[langId] ) symbolMode = 0;
elseif( (convMode & 0x400/*_IME_CMODE_SYMBOL*/) && opened ) symbolMode = 3/*_IME_SYMBOLMODE_SYMBOL*/;
elseif(convMode & 8/*_IME_CMODE_FULLSHAPE*/) symbolMode = 2/*_IME_SYMBOLMODE_FULLSHAPE*/;
elseif(convMode & 0x100/*_IME_CMODE_NOCONVERSION*/) opened = false;
/*
首个返回值为是否启用输入转换(例如输入中、日、韩等文字),false 为英文输入状态,
第二个返回值 symbolMode 用一个数值表示标点模式:
1. 英文半角标点
2. 英文全角标点
3. 中文标点
0. 或 null 已关闭输入转换
*/
return opened && (convMode & 3/*_IME_CMODE_LANGUAGE*/),symbolMode,langId,convMode;
}
}