输入法编程

最近打算研究一下CE下的输入法,找到了李振春先生写的自由拼音来学习。

在学习之前,先学习一下PC上输入法有基础知识。 

 

一般汉字输入法都由三个窗口组成:
状态窗口(Status Windows):显示当前的输入法状态;
编码输入窗口(Composition Windows):显示当前击键情况;
汉字选择窗口(Candidates Windows):列出当前编码的全部汉字(串),供用户选择或查询。

用Dumpbin.exe打开微软提供的拼音输入法(WINDOWS/SYSTEM/WINPY.IME)看看它有什么组成。
dumpbin c:/WINDOWS/system32/winpy.ime /EXPORTS
Microsoft (R) COFF Binary File Dumper Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


Dump of file c:/WINDOWS/system32/winpy.ime

File Type: DLL

  Section contains the following exports for WINPY.dll

           0 characteristics
    48023831 time date stamp Mon Apr 14 00:43:29 2008
        0.00 version
           1 ordinal base
          19 number of functions
          19 number of names

    ordinal    hint RVA      name

          1    0    0000AF24 CandWndProc    //"选择汉字窗口"
          2    1    0000C9D9 CompWndProc    //"输入编码窗口"
          3    2    0000E433 ImeConfigure   //配置当前ime参数函数
          4    3    0000D0FF ImeConversionList  //将字符或字符串转换成目标字符
          5    4    0000D190 ImeDestroy     //退出当前使用的IME
          6    5    0000F026 ImeEnumRegisterWord
          7    6    0000D1A6 ImeEscape      //应用软件访问输入法的接口函数
          8    7    0000EFEB ImeGetRegisterWordStyle
          9    8    0000CC94 ImeInquire     //启动并初始化当前IME输入法
         10    9    0001210A ImeProcessKey  //IME输入键盘事件管理函数
         11    A    0000EDD7 ImeRegisterWord    //向输入法字典注册字符串
         12    B    0000D92B ImeSelect      //启动当前IME输入法
         13    C    0000D966 ImeSetActiveContext    //设置当前的输入处于活动状态
         14    D    0000E856 ImeSetCompositionString    //由应用程序设置输入法编码
         15    E    00012696 ImeToAsciiEx   //将输入的键盘事件转换为汉字编码事件
         16    F    0000EE3C ImeUnregisterWord  ////删除被注册的字符串
         17   10    0000EA0B NotifyIME      //IME事件管理函数
         18   11    0000FE7F StatusWndProc  //状态窗口注册函数
         19   12    0001406F UIWndProc      //用户界面接口函数

  Summary

        8000 .ShareDa
        6000 .data
        2000 .reloc
        5000 .rsrc
        3000 .sgroup
       16000 .text
      
从上述可以看出,IME程序共有19个出口函数组成,每一个函数都有特定的格式,它们担负着与windows 系统传递信息的作用,这些函数是供Windows系统调用的。

-----------------
输入法的函数简介
1. 初始化IME
BOOL ImeInquire(LPIMEINFO lpIMEInfo, //用于初始化该输入法的结构地址
    LPTSTR lpszWndClass, //当前输入法的名称
    LPCTSTR或者dword lpszData //系统信息,9X系列值为0,NT/2000下有实际值
    );
如果该函数初始化成功,返回TURE,否则为FALSE
用户应该搞清楚IMEINFO结构,它关系着你设计的输入法是否成功。

2.将某字符或字符串转换成目标字符串
DWORD IMEConversionList(HIMC hIMC, // 与当前输入法相关的应用程序句柄
    LPCTSTRlpSrc, // 要转换的字符串 (也可能是结果串,可由uFlag指定)
    LPCANDIDATELIST lpDst, /// 转换后的字符串(也可能是源串,可由uFlag指定)
    DWORD dwBufLen, //转换后有几个字符
    UINT uFlag //指定结果的存放位置
    );
如果成功,返回转换后的字符串长度

3.用户设置输入法接口
BOOL ImeConfigure(HKL hKL, //当前输入法句柄
    HWND hWnd, //配置窗口的父窗口
    DWORD dwMode, //配置什么
    LPVOID lpData //用户设置的数据
    );
该函数的功能是提供给输入法使用者一个可以更改某些隐含设置的能力.
如果你用过别人的输入法,其中的"配置输入法..."功能既是也!
对于一个初写输入法的人,可以不予理它.

4.关闭当前输入法
BOOL ImeDestroy(UINT uReserved //无用 (0)
    );
成功返回TURE,否则为FALSE

5.用户软件访问输入法内部信息的接口
LRESULT ImeEscape(HIMC hIMC, //当前的应用程序句柄
    UINT uEscape,   //设置函数功能
                    //=IME_ESC_QUERY _SUPPORT
                    //=IME_ESC_RESERVED_LAST IME_ESC_RESERVED_FIRST
                    //=IME_ESC_PRIVATE_FIRST IME_ESC_PRIVATE_LAST
                    //=IME_ESC_SEQUENCE_TO_ INTERNAL
                    //=IME_ESC_GET_EUDC_ DICTIONARY
                    //=IME_ESC_SET_EUDC_ DICTIONARY
                    //=IME_ESC_MAX_KEY
                    //=IME_ESC_IME_NAME
                    //=IME_ESC_SYNC_HOTKEY
                    //=IME_ESC_HANJA_MODE
                    //=IME_ESC_GETHELPFILENAME(只适应 Windows 98和Windows 2000)
                    //=IME_ESC_PRIVATE_HOTKEY(w95下不可用)
    LPVOID lpData   //当前功能所需的数据
    );
如果失败,返回0,否则有个功能决定
有时,人们可以用此函数怀区输入法的名称、帮助文件名称等。当然,我们可以不提供这些功能。

6.激活或搁置当前的输入法
BOOL ImeSetActiveContext(HIMC hIMC, //当前用户程序句柄
    BOOL fFlag //激活或搁置:=TRUE 激活 =FALSE 搁置
    );
成功返回TRUE,否则为FALSE

7.处理应用程序传入的所有击键事件,监测是否是当前输入法所需的
BOOL ImeProcessKey(HIMC hIMC, //应用程序句柄
    UINT uVirKey, //需处理的虚键
    DWORD lParam, //击键消息参数
    CONST LPBYTE lpbKeyState //当前键盘状态(256字节)
    );
如果此键是该输入法需要的,则返回TRUE,否则为FALSE
只有返回true的击键,IME才去处理

8.输入法选择窗口状态管理函数
BOOL NotifyIME(HIMC hIMC, //当前的应用程序句柄
    DWORD dwAction, //状态值
    DWORD dwIndex, //与状态值有关的序号
    DWORD dwValue //与状态值有关的值
    );
状态值说明:
=NI_OPENCANDIDATE 打开编码选择窗口
=NI_CLOSECANDIDATE 关闭当前的编码选择窗
=NI_SELECTCANDIDATESTR 选摘编码
此时:dwIndex 被选择的编码列表序号.
dwValue 被选中的编码在当前的编码列表中的序号
=NI_CHANGECANDIDATELIST 改变当前的编码列表(按pageup等键操作)
此时:dwIndex 被选择的编码列表序号.
dwValue 不用
=NI_SETCANDIDATE_PAGESTART 设置编码开始页号
此时: dwIndex 被改变的编码列表序号
dwValue 新页的开始序号.
=NI_SETCANDIDATE_PAGESIZE 改变编码列表页的大小
此时:dwIndex 当前编码页序号
dwValue 新的页大小
=NI_CONTEXTUPDATED 更新应用程序的信息的输入法的信息:移动位置,设置模式,设置编码窗口,字体。
此时:dwIndex 只用于 dwValue=IMC_SETCONVERSIONMODE, IMC_SETSENTENCEMODE
dwValue 可取由 WM_IME_CONTROL 发送的下列值:
IMC_SETCANDIDATEPOS
IMC_SETCOMPOSITIONFONT
IMC_SETCOMPOSITIONWINDOW
IMC_SETCONVERSIONMODE
IMC_SETSENTENCEMODE
IMC_SETOPENSTATUS
=NI_COMPOSITIONSTR 改变编码窗口中的编码
此时:dwIndex 取下列值:CPS_COMPLETE 完成编码转换
CPS_CONVERT 转换编码
CPS_REVERT 取消当前的编码
CPS_CANCEL 清除编码,并关闭编码窗
dwValue 不用
此函数成功,返回TRUE,否则为FALSE

9.初始化输入法
BOOL ImeSelect(HIMC hIMC, //当前应用程序句柄
    BOOL fSelect //是否初始化当前输入法,TRUE表示初始化
    );
返回:成功返回true,否则为FALSE
The ImeSetCompositionString function is used by an application to set the IME composition string structure with the data contained in the lpComp or lpRead parameters. The IME then generates a message.

10.将编码窗口中输入的编码保存的编码结构中,发送编码完成的消息WM_IME_COMPOSITION给系统,
BOOL WINAPI ImeSetCompositionString(HIMC hIMC, //当前的应用程序句柄
    DWORD dwIndex, //设置此函数功能
                    //=SCS_SETSTR
                    //=SCS_CHANGEATTR
                    //=SCS_CHANGECLAUSE
                    //= SCS_QUERYRECONVERTSTRING
                    //=SCS_RECONVERTSTRING
                    //=SCS_SETRECONVERTSTRING
    LPCVOID lpComp, //编码数据区
    DWORD dwCompLen, //编码数据区长度
    LPCVOID lpRead, //读入的编码数据
    DWORD dwReadLen //读入的编码数据长度
    );

11.转换编码为汉字(串)
UINT ImeToAsciiEx(UINT uVirKey, //虚键
    UINT uScanCode, //扫描码
    CONST LPBYTE lpbKeyState, //用户定义的键盘状态
    LPDWORD lpdwTransBuf, //转换后的数据存放区
    UINT fuState, //活动菜单标志
    HIMC hIMC //当前的应用程序句柄
    );
返回:返回值表示有几个消息,可理解为:本编码对应的汉字串有几个汉字组成(当然,这并不相等)。

12.BOOL WINAPI ImeRegisterWord(LPCTSTR lpszReading,
    DWORD dwStyle,
    LPCTSTR lpszString
    );

13.BOOL WINAPI ImeUnregisterWord(LPCTSTR lpszReading,
    DWORD dwStyle,
    LPCTSTR lpszString
    );

14.UINT WINAPI ImeGetRegisterWordStyle(UINT nItem,LPSTYLEBUF lpStyleBuf);

15.UINT WINAPI ImeEnumRegisterWord(hKL,
    REGISTERWORDENUMPROC lpfnEnumProc,
    LPCTSTR lpszReading,
    DWORD dwStyle,
    LPCTSTR lpszString,
    LPVOID lpData
    );

16.DWORD WINAPI ImeGetImeMenuItems(HIMC hIMC,
    DWORD dwFlags,
    DWORD dwType,
    LPIMEMENUITEMINFO lpImeParentMenu,
    LPIMEMENUITEMINFO lpImeMenu,
    DWORD dwSize
    );

------------------
上面介绍了ime文件中必须设计的函数,要完成这些函数的设计,需用到windows系统提供的管理函数(Input Method Manager,简称IMM)。
IMM函数可以被IME函数使用,也可用于应用软件直接管理IME。
相关术语:
(1)input method context(简称IMC):输入法相关部分,在这里解释为:相关连的应用程序(进程)
(2)component of the input context(简称IMCC):IMC的部件,是INPUTCONTEXT 结构的成员。

一.IME中使用的IMM函数清单
ImmGetCompositionWindow //取编码窗口信息
ImmSetCompositionWindow //设置编码窗口信息
ImmGetCandidateWindow //取选择窗口信息
ImmSetCandidateWindow //设置选择窗口信息
ImmGetCompositionString //取编码窗口的某一信息
ImmSetCompositionString //设置编码窗口的某一信息
ImmGetCompositionFont //取编码字体
ImmSetCompositionFont //设置编码字体
ImmGetNumCandidateList //取选择区中编码数
ImmGetCandidateList //取选择区中编码
ImmGetGuideLine
ImmGetConversionStatus //取当前输入法的状态(ACSII,SHAPE,FULL等)
ImmGetConversionList //重新获得选择区转换表
ImmGetOpenStatus //取输入法打开属性
ImmSetConversionStatus //设置输入法状态
ImmSetOpenStatus //设置输入法打开状态
ImmNotifyIME //通报IME,输入法状态被改变
ImmGenerateMessage //将我们的汉字串法发送到与当前输入法相关联的应用软件中
ImmRequestMessage //向应用程序发送WM_IME_REQUEST
ImmLockIMC //获取当前IMC的INPUTCONTEXT结构信息,增加IMC 计数器
ImmUnlockIMC //释放IMC计数器
ImmGetIMCLockCount //取计数器值
ImmCreateIMCC //创建INPUTCONTEXT结构的一个成员
ImmDestroyIMCC //删除IMC成员缓冲区
ImmLockIMCC //取IMCC缓冲地址,同时使IMCC的计数器值增加
ImmUnlockIMCC //递减IMCC计数器
ImmReSizeIMCC //重新设置IMC的成员的缓冲区大小
ImmGetIMCCSize //取IMC成员的缓冲区大小
ImmGetIMCCLockCount //返回IMC计数器值
ImmGetHotKey //取输入法状态键,该函数供控制面板使用
ImmSetHotKey //设置输入法的热键
ImmCreateSoftKeyboard //产生一个软键盘
ImmDestroySoftKeyboard //销毁软键盘
ImmShowSoftKeyboard //显示或隐藏软键盘

二.IMM函数使用格式说明
1.将汉字串法发送到与当前输入法相关联的应用软件中
BOOL WINAPI ImmGenerateMessage(HIMC hIMC //与当前输入法相关联的应用软件的句柄,
                                            //该结构的hMsgBuf项即为汉字串消息
    );
成功为TRUE,否则为FALSE

2.向应用程序发送WM_IME_REQUEST,只是用于w98及w2000
LRESULT WINAPI ImmRequestMessage(HIMC hIMC, //与当前输入法相关联的应用软件的句柄
    WPARAM wParam, //与WM_IME_REQUEST相关的wP
    LPARAM lParam  //与WM_IME_REQUEST相关的LP
                    //=IMR_COMPOSITIONWINOW
                    //=IMR_CANDIDATEWINDOW
                    //=IMR_COMPOSITIONFONT
                    //=IMR_RECONVERTSTRING
                    //=IMR_CONFIRMRECONVERTSTRING
                    //=IMR_QUERYCHARPOSITION
                    //=IMR_DOCUMENTFEED
    );

3.获取当前IMC的INPUTCONTEXT结构信息,增加IMC 计数器
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC //当前应用程序句柄
    );
成功返回INPUTCONTEXT 结构指针,否则为NULL

4.释放IMC计数器
BOOL WINAPI ImmUnlockIMC(HIMC hIMC //当前应用程序句柄
    );
返回:如果IMC计数器被减少到0了,返回FALSE,否则为TRUE.
注意:ImmLockIMC与ImmUnlockIMC必须成对出现,必须是相同的HIMC

5.取计数器值
HIMCC WINAPI ImmGetIMCLockCount(HIMC hIMC //当前应用程序句柄
    );
如果成功返回HIMC的计数器值,否则为NULL.

6.创建INPUTCONTEXT结构的一个成员
HIMCC WINAPI ImmCreateIMCC(DWORD dwSize //成员的缓冲区长度
    );
如果成功返回IMC的成员句柄,否则为NULL

7.删除IMC成员缓冲区
HIMCC WINAPI ImmDestroyIMCC(HIMCC hIMCC //被删除的IMC的成员
    );
如果成功返回NULL,否则等于该HIMCC.

8.取IMCC缓冲地址,同时使IMCC的计数器值增加
LPVOID WINAPI ImmLockIMCC(HIMCC hIMCC //IMC成员句柄
    );
If the function is successful, the return value is the pointer for the IMC component. Otherwise, the return value is NULL.

9.递减IMCC计数器
BOOL WINAPI ImmUnlockIMCC(HIMCC hIMCC //IMC成员句柄
    );
如果IMCC的计数器值为零,则返回 FALSE,否则为TRUE.

10.重新设置IMC的成员的缓冲区大小
HIMCC WINAPI ImmReSizeIMCC(HIMCC hIMCC, //IMC的成员句柄
    DWORD dwSize //新缓冲区大小
    );
如果成功,返回新的HIMCC,否则为 NULL.

11.取IMC成员的缓冲区大小
DWORD WINAPI ImmGetIMCCSize(HIMCC hIMCC //IMC成员句柄
    );
返回IMC成员的缓冲区大小

12.返回IMC计数器值
DWORD WINAPI ImmGetIMCCLockCount(HIMCC hIMCC //IMC成员的句柄
    );
成功返回该IMCC的计数器值,否则为0

13.取输入法状态键,该函数供控制面板使用
BOOL WINAPI ImmGetHotKey(DWORD dwHotKeyID,
    LPUINT lpuModifiers,
    LPUINT lpuVKey,
    LPHKL lphKL
    );

14.设置输入法的热键
BOOL WINAPI ImmSetHotKey(DWORD dwHotKeyID,
    UINT uModifiers,
    UINT uVKey,
    hKL hKL
    );

15.产生一个软键盘
HWND WINAPI ImmCreateSoftKeyboard(UINT uType, //软件盘上的键码含义的定义方式
                //=SOFTKEYBOARD_TYPE_T1
                //=SOFTKEYBOARD_TYPE_C1
    UINT hOwner, //该输入法的UI窗口
    int x, //定位坐标
    int y //定位坐标
    );
成功返回软键盘的窗口句柄

16.销毁软键盘
BOOL WINAPI ImmDestroySoftKeyboard(HWND hSoftKbdWnd //软年盘窗口句柄
    );
成功为TRUE,法哦则为FALSE.

17.显示或隐藏软键盘
BOOL WINAPI ImmShowSoftKeyboard(HWND hSoftKbdWnd, //软年盘窗口句柄
    int nCmdShow //窗口状态=SW_HIDE 表示隐藏,=SW_SHOWNOACTIVATE表示显示
    );
如构成功返回 TRUE. 否则为 FALSE.

------------------
使用的结构
1.IMEINFO : 输入法的接口信息 用于ImeInquire函数中
struct tagIMEInfo {
    DWORD dwPrivateDataSize;//用户设计的数据结构的字节数
    DWORD fdwProperty; //输入法对键盘事件的相应特性
        //其中其高字可为下列字节位的组合:
            //=IME_PROP_AT_CARET 转换窗口是否放置在需插入字符的位置
            //=IME_PROP_SPECIAL_UI 该输入法具有特殊用户接口
            //=IME_PROP_CANDLIST_START_FROM_1 输入法的选择窗口中汉字串的起始序号为1
            //=IME_PROP_UNICODE 支持UNICODE字符
        //其中其低字可为下列字节位的组合:
            //=IME_PROP_END_UNLOAD
            //=IME_PROP_KBD_CHAR_FIRST 首先由键盘转换字符
            //=IME_PORP_NEED_ALTKEY 将ALT键盘事件传送到IME输入法内
            //=IME_PROP_IGNORE_UPKEYS 禁止上位键事件进入输入法内
            //=IME_PROP_COMPLETE_ON_UNSELECT 当关闭输入法时,完成编码的转换
            // 用于 W98及2000 中
    DWORD fdwConversionCaps;//当前输入法具有的功能特性,如有软键、标点、中西文切换等功能
        //=IME_CMODE_NATIVE 设置活动模式
        //=IME_CMODE_FULLSHAPE 设置全角模式
        //=IME_CMODE_CHARCODE 设置为字符模式
        //=IME_CMODE_SOFTKBD //设置软键盘模式
        //=IME_CMODE_NOCONVERSION //不支持模式变换
        //=IME_CMODE_EUDC //
        //=IME_CMODE_SYMBOL //设置标点字符模式
    DWORD fdwSentenceCaps; //
        //=IME_SMODE_PLAURALCLAUSE
        //=IME_SMODE_SINGLECONVERT
        //=IME_SMODE_AUTOMETIC
        //=IME_SMODE_CONVERSATION
    DWORD fdwUICaps; // 用户界面能力:支持软键盘等
        //=UI_CAP_2700
        //=UI_CAP_ROT90
        //=UI_CAP_ROTANY
        //=UI_CAP_SOFKBD
    DWORD fdwSCSCaps; // 用户设置编码串的能力
        //=SCS_CAP_COMPSTR
        //=SCS_CAP_MAKEREAD
    DWORD fdwSelectCaps; // 输入法切换时是否使用以前输入法的模式
        //=SELECT_CAP_CONVMODE
        //=SELECT_CAP_SENTENCE
} IIMEINFO;

2.COMPOSITIONSTR : 用于编码管理,用于存放编码信息的信息:所有的实际信息放在本结构的后面
typedef struct tagCOMPOSITIONSTR {
    DWORD dwSize; //当前编码信息需要的存储空间=读入的编码+属性+子串+属性+编码+属性+结果+属性
    DWORD dwCompReadAttrLen; //读入的编码属性长度
    DWORD dwCompReadAttrOffset; //存放在内存的位置
    DWORD dwCompReadClsLen; //读入的子串长度
    DWORD dwCompReadClsOffset; //存放在内存的位置
    DWORD dwCompReadStrLen; //读入的编码长度
    DWORD dwCompReadStrOffset; //存放在内存的位置
    DWORD dwCompAttrLen; //编码属性长度
    DWORD dwCompAttrOffset; //存放在内存的位置
    DWORD dwCompClsLen; //编码子串长度
    DWORD dwCompClsOffset; //存放在内存的位置
    DWORD dwCompStrLen; //编码串长度
    DWORD dwCompStrOffset; //存放在内存的位置
    DWORD dwCursorPos; //当前光标位置
    DWORD dwDeltaStart; //被修改编码的位置
    DWORD dwResultReadClsLen; //读入结果子串长度
    DWORD dwResultReadClsOffset; //存放在内存的位置
    DWORD dwResultReadStrLen; //读入的编码长度
    DWORD dwResultReadStrOffset; //存放在内存的位置
    DWORD dwResultClsLen; //结果子串长度
    DWORD dwResultClsOffset; //存放在内存的位置
    DWORD dwResultStrLen; //结果串长度
    DWORD dwResultStrOffset; //存放在内存的位置
    DWORD dwPrivateSize; //用户自定义数据长度
    DWORD dwPrivateOffset; //存放在内存的位置
}COMPOSITIONSTR;

3.CANDIDATEINFO : 用于编码选择管理,编码选择信息的信息,其后为实际编码列表数据
typedef struct tagCANDIDATEINFO {
    DWORD dwSize; //数据所占内存大小
    DWORD dwCount; //表马列表个数
    DWORD dwOffset[32]; //各个编码列表的内存位置
    DWORD dwPrivateSize; //自定义数据尺寸
    DWORD dwPrivateOffset; //缓冲区位置
} CANDIDATEINFO;

4.GUIDELINE
typedef struct tagGUIDELINE {
    DWORD dwSize;
    DWORD dwLevel; // the error level.
        // GL_LEVEL_NOGUIDELINE,
        // GL_LEVEL_FATAL,
        // GL_LEVEL_ERROR,
        // GL_LEVEL_WARNNING,
        // GL_LEVEL_INFORMATION
    DWORD dwIndex; // GL_ID_NODICTIONARY and so on.
    DWORD dwStrLen; // Error Strings, if this is 0, there is no error string.
    DWORD dwStrOffset;
    DWORD dwPrivateSize;
    DWORD dwPrivateOffset;
} GUIDELINE;

5.CANDIDATELIST : 编码选择列表信息 =〉管理编码窗口中的列表信息
The CANDIDATELIST structure contains information about a candidate list.

typedef struct tagCANDIDATELIST {
    DWORD dwSize; // 用字节表示的内存大小:=sizeof(CANDIDATELIST)+选择字符数据
    DWORD dwStyle; // 列表串的取值方式
        //=IME_CAND_UNKNOWN 列表数据的格式无定义
        //=IME_CAND_READ 读到什么数据即为什么数据,一般我们使用该属性
        //=IME_CAND_CODE 如果dwCount=1,dwOffset不是地址,而是实际数据,
        // >1 dwOffset 表示地址
        //=IME_CAND_MEANING
        //=IME_CAND_RADICAL
        //=IME_CAND_STROKES
    DWORD dwCount; // 当前列表个数
    DWORD dwSelection; // 当前选择的列表序号
    DWORD dwPageStart; // 在列表窗口中所显示的列表的起始序号(上下翻页时用)
    DWORD dwPageSize; // 一页显示的列表个数
    DWORD dwOffset[]; // 列表数据存放区地址:[阿];[大]。。。。
} CANDIDATELIST;

6.COMPOSITIONFORM : 窗口位置、大小信息,由IMC_SETCOMPOSITIONWINDOW和IMC_SETCANDIDATEPOS消息使用
typedef tagCOMPOSITIONFORM {
    DWORD dwStyle; //管理窗口方式
        //=CFS_DEFAULT 将编码窗口显示到隐含的位置
        //=CFS_FORCE_POSITION // 以给定的坐标显示窗口,不受IME控制
        //=CFS_POINT // 以给定的坐标显示窗口,受IME控制
        //=CFS_RECT //以给定的大小显示窗口
    POINT ptCurrentPos; //给定坐标
    RECT rcArea; //给定窗口的小
}COMPOSITIONFORM;

7.CANDIDATEFORM : 列表窗口信息,由IMC_GETCANDIDATEPOS和IMC_SETCANDIDATEPOS消息处理
The CANDIDATEFORM structure is used for IMC_GETCANDIDATEPOS and IMC_SETCANDIDATEPOS messages.

typedef tagCANDIDATEFORM {
    DWORD dwIndex; //列表窗口序号
    DWORD dwStyle; //属性:
        //=CFS_CANDIDATEPOS 指定显示位置
        //=CFS_EXCLUDE 不可显示
        //=CFS_DEFAULT 根据需要显示
    POINT ptCurrentPos; //坐标位置
    REC rcArea; //不可显示区
} CANDIDATEFORM;

8.STYLEBUF : 注册字结构
typedef struct tagSTYLEBUF {
    DWORD dwStyle;
    TCHAR szDes cription[32]
} STYLEBUF;

9.SOFTKBDDATA : 软键盘中各键对应的汉字
typedef struct tagSOFTKBDDATA {
    UINT uCount; //键码数组个数(可以为1,2,当区分SHIFT键时为2,即:一组带SHIFT,一组不带SHIFT)
    WORD wCode[][256] //对应的键码数据
} SOFTKBDDATA;

10.RECONVERTSTRING : 用于W98和2000
typedef struct _tagRECONVERTSTRING {
    DWOPD dwSize;
    DWORD dwVersion;
    DWORD dwStrLen;
    DWORD dwStrOffset;
    DWORD dwCompStrLen;
    DWORD dwCompStrOffset;
    DWORD dwTargetStrLen;
    DWORD dwTargetStrOffset;
} RECONVERTSTRING;

11.IMEMENUITEMINFO : 输入法菜单结构,W98/2000
typedef _tagIMEMENUITEMINFO {
    UINT cbSize;
    UINT fType;
    UINT fState;
    UINT wID;
    HBITMAP hbmpChecked;
    HBITMAP hbmpUnchecked;
    DWORD dwItemData;
    TCHAR szString[48];
    HBITMAP hbmpItem;
}

12.INPUTCONTEXT : IMC 数据存放区
The INPUTCONTEXT structure is an internal data structure that stores Input Context data.

typedef struct tagINPUTCONTEXT {
    HWND hWnd; //使用该IMC的窗口
    BOOL fOpen; //IME的打开与关闭状态
    POINT ptStatusWndPos; //状态窗口的位置
    POINT ptSoftKbdPos; //软键盘的位置
    DWORD fdwConversion; //IME状态(活动、不活动,全角等)
    DWORD fdwSentence; //编码方式
    union {
        LOGFONTA A;
        LOGFONTW W;
    } lfFont; //字体
    COMPOSITIONFORM cfCompForm; //编码格式结构
    CANDIDATEFORM cfCandForm[4]; //列表选择结构
    HIMCC hCompStr; //
    HIMCC hCandInfo;
    HIMCC hGuideLine
    HIMCC hPrivate;
    DWORD dwNumMsgBuf; //存放在hMsgBuf中的消息数
    HIMCC hMsgBuf; //存放的消息,格式: [消息1] [wParam1] [lParam1] {[消息] [wParam2] [lParam2]...
    //注意:我们输入的汉字串存放在这里
    DWORD fdwInit //系统根据此值来初始本结构相应的信息
        //=INIT_STATUSWNDPOS 初始化ptStatusWndPos
        //=INIT_CONVERSION 初始化fdwConversion
        //=INIT_SENTENCE 初始化fdwSentence
        //=INIT_LOGFONT 初始化lfFont
        //=INIT_COMPFORM 初始化cfCompForm
        //=INIT_SOFTKBDPOS 初始化ptSoftKbdPos
    DWORD dwReserve[3]; //将来版本扩展的信息
} INPUTCONTEXT;

------------------
在UI窗口下需要处理下列windows消息
1.WM_IME_SETCONTEXT : 激活或休眠输入法
LRESULT CALLBACK UIWndProc(HWND hUIWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{

    case WM_IME_SETCONTEXT:
    fSet= (BOOL) wParam;
   
    lISCBits = lParam;
}
如果fSet为TRUE,系统将激活当前输入法的某个窗口(状态窗、列表窗等),为FALSE时休眠当前输入法.
其中lISCBits中指出对哪个窗口操作。

数值                        含义
ISC_SHOWUICOMPOSITIONWINDOW 显示编码窗口
ISC_SHOWUIGUIDWINDOW 显示信息窗口
ISC_SHOWUICANDIDATEWINDOW 显示0号列表窗口
(ISC_SHOWUICANDIDATEWINDOW << 1) 显示1号列表窗口.
(ISC_SHOWUICANDIDATEWINDOW << 2) 显示2号列表窗口.
(ISC_SHOWUICANDIDATEWINDOW << 3) 显示3号列表窗口.

2.WM_IME_CONTROL : 管理当前输入法
wSubMessage= wParam; 受WM_IME_CONTROL 控制的消息
lpData = (LPVOID) lParam; 对应的数据
其中子消息有下列消息:
1) IMC_GETCANDIDATEPOS: 获取列表窗口的位置.此时lParam传送的是CANDIDATEFORM结构地址。
    如果此消息成功返回0,否则非零。
    通常如果你设计此部分了,返回0。否则返回1。

2) IMC_GETCOMPOSITONFONT: 获取编码窗口字体结构, lParam为LOGFONT结构地址
    如果此消息成功返回0,否则非零。
    通常如果你设计此部分了,返回0。否则返回1。

3) IMC_GETCOMPOSITONWINDOW: 获取编码窗口位置,lParam为COMPOSITIONFORM结构地址。
    如果此消息成功返回0,否则非零。
    通常如果你设计此部分了,返回0。否则返回1。

4) IMC_GETSOFTKBDFONT: 获取软键盘字体。 lParam字体结构LOGFONT地址。

5) IMC_GETSOFTKBDPOS: 获取软键盘位置,lParam = 0;
    返回软键盘在屏幕窗口中的坐标结构POINTS。

6) IMC_GETSOFTKBDSUBTYPE
    wSubMessage= IMC_GETSOFTKBDSUBTYPE;
    lParam = 0;

7) IMC_GETSTATUSWINDOWPOS: 获取状态窗口位置
    wSubMessage= IMC_GETSTATUSWINDOWPOS;
    lParam = 0;
    返回状态窗口坐标原点在屏幕窗口中的坐标结构POINTS。

8) IMC_SETCANDIDATEPOS
    wSubMessage= IMC_SETCANDIDATEPOS;
    lpCANDIDATEFORM= (LPCANDIDATEFORM) lParam;
    设置列表窗口的位置.此时lParam传送的是CANDIDATEFORM结构地址。
    如果此消息成功返回0,否则非零。
    注意:UI窗口不接受此消息,它的管理函数是NotifyIME。

9) IMC_SETCOMPOSITONFONT: 设置编码窗口的字体.此时lParam传送的是LOGFONT结构地址。
    wSubMessage= IMC_SETCOMPOSITIONFONT;
    lpLogFont= (LPLOGFONT) lParam;
    注意:UI窗口不接受此消息,它的管理函数是NotifyIME。

10) IMC_SETCOMPOSITONWINDOW: 设置编码窗口属性,此时lParam传送的是COMPOSITIONFORM结构地址。
    wSubMessage= IMC_SETCOMPOSITIONWINDOW;
    lpCOMPOSITIONFORM= (LPCOMPOSITIONFORM) lParam;
    如果此消息成功返回0,否则非零。
    注意:UI窗口不接受此消息,它的管理函数是NotifyIME。

11) IMC_SETSOFTKBDDATA: 设置软键盘数据,此时lParam传送的是SOFTKBDDATA结构地址,用户设定自己的软键盘字符。
    wSubMessage= IMC_SETSOFTKBDDATA;
    lpSoftKbdData= (LPSOFTKBDDATA) lParam;
    如果此消息成功返回0,否则非零。
    注意:UI窗口不接受此消息,它的管理函数是NotifyIME。

12) IMC_SETSOFTKBDSUBTYPE: 设置软键盘类型
    wSubMessage= IMC_SETSOFTKBDSUBTYPE;
    lSubType= lParam;
    成功返回subtype,否则返回-1.
    注意:UI窗口不接受此消息,它的管理函数是NotifyIME。

13) IMC_SETSOFTKBDFONT: 设置软键盘字体,此时lParam传送的是LOGFONT结构地址
    wSubMessage= IMC_SETSOFTKBDFONT;
    lpLogFont= (LPLOGFONT)lParam;
    如果此消息成功返回0,否则非零。
    注意:UI窗口不接受此消息,它的管理函数是NotifyIME。

14) IMC_SETSOFTKBDPOS: 设置软件位置,此时lParam传送的是POINTS结构
    wSubMessage= IMC_SETSOFTKBDPOS;
    ptsPt= (POINTS)lParam;
    如果此消息成功返回0,否则非零。

15) IMC_SETSTATUSWINDOWPOS: 设置状态窗口位置,此时lParam传送的是POINTS结构
    wSubMessage= IMC_SETSTATUSWINDOWPOS;
    ptsPt= (POINTS)lParam;
    如果此消息成功返回0,否则非零。

3.WM_IME_COMPOSITION
当用户改变了编码状态时,发送此消息WM_IME_COMPOSITION
应用程序可以通过调用ImmGetCompositionString获取新的编码状态。
wChar= wParam; 最后输入到编码窗口的2字节的DBCS字符
lAttribute= lParam; 当前编码的含义。
lAttribute可取下列值得组合:

值 含义
GCR_ERRORSTR 修正错误
GCR_INFORMATIONSTR 修正信息串
GCS_COMPATTR 修正编码串属性.
GCS_COMPCLAUSE 修正编码信息.
GCS_COMPREADATTR 修正读入串的属性
GCS_COMPREADCLAUSE 修正读入串的属性.
GCS_COMPREADSTR 修正读入串。
GCS_COMPSTR 修正当前的编码
GCS_CURSORPOS 修正当前编码的光标位置.
GCS_DELTASTART 修正当前编码的开始位置
GCS_RESULTCLAUSE 修正结果串的信息.
GCS_RESULTREADCLAUSE 修正读入串的信息.
GCS_RESULTREADSTR 修正读入串.
GCS_RESULTSTR 修正编码结果串.
CS_INSERTCHAR 在当前位置插入一个字符
CS_NOMOVECARET 替换结果串

4.WM_IME_COMPOSITIONFULL
用户接口窗口不能增加编码窗口的尺寸时,ime用户接口窗口将发送WM_IME_COMPOSITIONFULL消息,可不处理。
wParam = 0
lParam= 0

5.WM_IME_ENDCOMPOSITION
当编码结束时ime发送此消息WM_IME_ENDCOMPOSITION
wParam = 0
lParam= 0
用户程序可以接受此消息,以便自己显示用户输入的编码。

6.WM_IME_SELECT
系统发出WM_IME_SELECT以便选择一个新的ime。
fSelect= (BOOL)wParam; TRUE表示新的IME已选择,FALSE表示不被选择或关闭该输入法。
hKL= lParam;
系统利用这个消息产生或关闭老的输入法用户窗口。

7.WM_IME_STARTCOMPOSITION
当用户开始输入编码时,系统立即发送该消息到IME中,IME打开编码窗口。
wParam = 0
lParam= 0

8.WM_IME_NOTIFY
IME消息组:
wSubMessage= wParam;
lParam= lParam;
各消息说明:
1) IMN_CLOSESTATUSWINDOW : 关闭状态窗口时,系统发送IMN_CLOSESTATUSWINDOW消息。
wSubMessage = IMN_CLOSESTATUSWINDOW;
lParam= 0;
当用户接口窗口接收到此消息时,将关闭状态窗口。
2) IMN_OPENSTATUSWINDOW : 产生或打开状态窗口
wSubMessage = IMN_OPENSTATUSWINDOW;
lParam= 0;
当ime接收到此消息时,将产生状态窗口.
有关状态串口的信息可用ImmGetConversionStatus获取,设置状态窗口的信息可用ImmSetConversionStatus.
3) IMN_OPENCANDIDATE : 打开或产生列表选择窗口
wSubMessage = IMN_OPENCANDIDATE;
lCandidateList= lParam;
4) IMN_CHANGECANDIDATE : 更新当前的列表选择窗口
WM_IME_NOTIFY
wSubMessage = IMN_CHANGECANDIDATE;
lCandidateList= lParam;
5) IMN_CLOSECANDIDATE : 关闭选择窗口
wSubMessage = IMN_CLOSECANDIDATE;
lCandidateList= lParam;
UI窗口接收此消息后,将销毁列表选择窗口

IMN_SETCONVERSIONMODE: 改变输入法状态模式管理
wSubMessage = IMN_SETCONVERSIONMODE;
lParam= 0;

IMN_SETOPENSTATUS: 设置输入法状态
wSubMessage = IMN_SETOPENSTATUS;
lParam= 0;

IMN_SETCANDIDATEPOS: 设置列表窗口位置
wSubMessage = IMN_SETCANDIDATEPOS;
lCandidateList= lParam;
Parameters

IMN_SETCOMPOSITIONFONT: 设置编码窗口字体
wSubMessage = IMN_SETCOMPOSITIONFONT;
lParam= 0;

IMN_SETCOMPOSITIONWINDOW: 设置编码窗口
wSubMessage = IMN_SETCOMPOSITIONWINDOW;
lParam= 0;

IMN_GUIDELINE: 错误信息处理
wSubMessage = IMN_GUIDELINE;
lParam= 0;

IMN_SOFTKBDDESTROYED: 关闭软键盘
wSubMessage = IMN_SOFTKBDDESTROYED;
lParam= 0;

你可能感兴趣的:(EVC4,编程)