aardio 文档

输入法与键盘状态检测

aardio 标准库 key.ime 提供输入法相关函数。
key.ime.state 函数则用于检测输入法与键盘状态,标准库 key.ime.stateBar 用于创建显示输入法状态的工具界面。基于 key.ime.stateBar 实现的开源软件 ImTip 目前已经成为了流行的桌面软件。

一、输入法状态检测原理与规则

我们先了解两个用于表示输入法状态的变量:

opened 用于表示当前是否打开输入法。
convMode 则用于指示输入法的转换模式(中、英、标点符号、全角、半角等)。

基本规则:

convMode 还有一些其他状态,中文输入法一般用不到。

ImTip 检测输入法的实现源码

二、输入法兼容性

至于第三方输入法工具则更为混乱,早年我写过文章,在 ImTip 发布之前网上流传的代码基本都是错的。例如有的开发者看到中文状态下 convMode 是某个数值就以为这个固定的数值就表示中文输入状态,其实这是未经过严谨测试望文生义,别人切换几个状态或者换个输入法你的程序就乱套了。

三、key.ime.state 函数 #

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;
    }       
}

Markdown 格式