前二章我们讲述了ime和imm函数,二者之间是靠下列结构通讯的。
1、IMEINFO struct tagIMEInfo { //输入法的接口信息 用于ImeInquire函数中 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 typedef tagCOMPOSITIONFORM { //窗口位置、大小信息: //由IMC_SETCOMPOSITIONWINDOW和IMC_SETCANDIDATEPOS消息使用 DWORD dwStyle; //管理窗口方式 //=CFS_DEFAULT 将编码窗口显示到隐含的位置 //=CFS_FORCE_POSITION // 以给定的坐标显示窗口,不受IME控制 //=CFS_POINT // 以给定的坐标显示窗口,受IME控制 //=CFS_RECT //以给定的大小显示窗口 POINT ptCurrentPos; //给定坐标 RECT rcArea; //给定窗口的小 }COMPOSITIONFORM; 7、CANDIDATEFORM The CANDIDATEFORM structure is used for IMC_GETCANDIDATEPOS and IMC_SETCANDIDATEPOS messages. typedef tagCANDIDATEFORM { //列表窗口信息 //由IMC_GETCANDIDATEPOS和IMC_SETCANDIDATEPOS消息处理 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 typedef struct _tagRECONVERTSTRING { //用于W98和2000 DWOPD dwSize; DWORD dwVersion; DWORD dwStrLen; DWORD dwStrOffset; DWORD dwCompStrLen; DWORD dwCompStrOffset; DWORD dwTargetStrLen; DWORD dwTargetStrOffset; } RECONVERTSTRING; 11、IMEMENUITEMINFO typedef _tagIMEMENUITEMINFO { //输入法菜单结构,W98/2000 UINT cbSize; UINT fType; UINT fState; UINT wID; HBITMAP hbmpChecked; HBITMAP hbmpUnchecked; DWORD dwItemData; TCHAR szString[48]; HBITMAP hbmpItem; } 12、INPUTCONTEXT The INPUTCONTEXT structure is an internal data structure that stores Input Context data. typedef struct tagINPUTCONTEXT { //IMC 数据存放区 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;