IME输入法编程

第一章 Windows9x系统下汉字输入法的基本原理

  Windows系统下汉字输入法实际上是将输入的标准ascii字符串按照一定的编码规则转换为汉字或汉字串,进入到目的地。由于应用程序各不相同,用户不可能自己去设计转换程序,因此,汉字输入自然而然落到WINDOWS系统管理中。

一、输入法与系统的关系

     键盘事件  应用程序
       |    |
      Windows的USER.EXE
         |
       输入法管理器
         |
        输入法 

  系统的键盘事件有windows的user.exe软件接收后,user.exe在将键盘事件传导输入法管理器(Input Method Manager,简称IMM)中,管理器 再将键盘事件传到输入法中,输入法根据用户编码字典,翻译键盘事件为对应的汉字(或汉字串),然后再反传到user.exe中,user.exe再将翻译后的键盘事件传给当前正运行的应用程序,从而完成汉字的输入。

二、汉字输入法的组成

微软Windows9x系统中汉字输入法的名称是"Input Method Editor" ,简称IME,输入法的程序名称为:*.ime,数据文件名称为*.MB,即通常说的输入法编码表(字典).

实际上IME文件是一个动态连接库程序(DLL),它与dll文件没有区别,只是名称不同而已。

一般汉字输入法都由三个窗口组成:

状态窗口(Status Windows)-显示当前的输入法状态(中文还是英文等站环信息);

编码输入窗口(Composition Windows)-显示当前击键情况;

汉字选择窗口(Candidates Windows)-列出当前编码的全部汉字(串),供用户选择或查询。

上述三个窗口由基本的用户接口(User Interface )函数管理着。

现在我们用Dumpbin.exe打开微软提供的拼音输入法(WINDOWS/SYSTEM/WINPY.IME)看看它有什么组成(这里一WINDOWS98为例,并假定windows系统安装在c:盘下):

C:/Dumpbin c:/windows/system/winpy.ime

Microsoft (R) COFF Binary File Dumper Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


Dump of file WINPY.IME

File Type: DLL       //IME 实际为dll程序

Section contains the following exports for WINPY.ime

0 characteristics
34A37323 time date stamp Fri Dec 26 17:04:35 1997
0.00 version
1 ordinal base
19 number of functions //共有19个函数
19 number of names     // 对应19个名称 

ordinal hint RVA name

1 0 0000A010 CandWndProc  //"选择汉字窗口"注册函数
2 1 0000E750 CompWndProc  //"输入编码窗口"注册函数
3 2 0000FB50 ImeConfigure  //配置当前ime参数函数 
4 3 0000FEC0 ImeConversionList//将字符或字符串转换成目标字符
5 4 0000FFA0 ImeDestroy   //退出当前使用的IME
6 5 000030D0 ImeEnumRegisterWord
7 6 0000FFB0 ImeEscape //应用软件访问输入法的接口函数.
8 7 00003080 ImeGetRegisterWordStyle
9 8 0000E9A0 ImeInquire      //启动并初始化当前IME输入法
10 9 0000A800 ImeProcessKey    //IME输入键盘事件管理函数
11 A 00002C20 ImeRegisterWord //向输入法字典注册字符串
12 B 000109A0 ImeSelect //启动当前IME输入法
13 C 000109E0 ImeSetActiveContext //设置当前的输入处于活动状态.
14 D 0000C850 ImeSetCompositionString 由应用程序设置输入法编码
15 E 0000AEE0 ImeToAsciiEx    //将输入的键盘事件转换为汉字编码事件
16 F 00002F40 ImeUnregisterWord //删除被注册的字符串.
17 10 0000CA90 NotifyIME   //IME事件管理函数
18 11 00005160 StatusWndProc //状态窗口注册函数
19 12 00002350 UIWndProc   //用户界面接口函数

Summary

5000 .ShareDa
7000 .data
2000 .idata
1000 .rdata
3000 .reloc
5000 .rsrc
2000 .sgroup
18000 .text


从上述可以看出,IME程序共有19个出口函数组成,每一个函数都有特定的格式,它们担负着与windows 系统传递信息的作用,这些函数是供Windows系统调用的。

三、输入法的函数简介

下面我们将介绍上述各个函数的功能及接口格式。

1. BOOL ImeInquire( //初始化IME
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、BOOL WINAPI ImeSetCompositionString( //将编码窗口中输入的编码保存的编码结构中,

//同志发送编码完成的消息

//( WM_IME_COMPOSITION)给系统,
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的版本信息(与普通DLL的区别)

VS_VERSION_INFO VERSIONINFO 代表字符 含义
FILEVERSION 4,0,0,950 //4.00.950 95版
PRODUCTVERSION 4,0,0,950 //4.00.950 95版
FILEFLAGSMASK 0x3fL
FILEFLAGS 0xaL
FILEOS 0x10004L //VOS_DOS_WINDOWS32 WIN32软件,可在DOS下运行
FILETYPE 0x3L //VFT_DRV 驱动程序
FILESUBTYPE 0xbL //VFT2_DRV_INPUTMETHOD 输入法驱动程序
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080403a8"
BEGIN
VALUE "Comments", "/0"
VALUE "CompanyName", "唐码软件开发工作室/0"
VALUE "FileDes cription", "唐码输入法 版本1.0/0"
VALUE "FileVersion", "4.00.950/0"
VALUE "InternalName", "唐码输入法 版本1.0/0"
VALUE "LegalCopyright", "Copyright (C) 唐码软件开发工作室 1999-1999/0"
VALUE "LegalTrademarks", "/0"
VALUE "OriginalFilename", "TM.IME/0"
VALUE "PrivateBuild", "/0"
VALUE "ProductName", "唐码输入法 版本1.0/0"
VALUE "ProductVersion", "4.00.950/0"
VALUE "SpecialBuild", "/0"
END

第二章 Windows9x系统提供的ime管理函数

  上一章,我们介绍了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、LRESULT WINAPI ImmRequestMessage( //向应用程序发送WM_IME_REQUEST

//只是用于w98及w2000
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、LPINPUTCONTEXT WINAPI ImmLockIMC( //获取当前IMC的INPUTCONTEXT结构信息,增加IMC 计数器
HIMC hIMC //当前应用程序句柄
)

成功返回INPUTCONTEXT 结构指针,否则为NULL

4、BOOL WINAPI ImmUnlockIMC( //释放IMC计数器
HIMC hIMC //当前应用程序句柄
)

返回:如果IMC计数器被减少到0了,返回FALSE,否则为TRUE.

注意:ImmLockIMC与ImmUnlockIMC必须成对出现,必须是相同的HIMC

5、HIMCC WINAPI ImmGetIMCLockCount( //取计数器值
HIMC hIMC //当前应用程序句柄
)

如果成功返回HIMC的计数器值,否则为NULL.

6、HIMCC WINAPI ImmCreateIMCC( //创建INPUTCONTEXT结构的一个成员
DWORD dwSize //成员的缓冲区长度
)

如果成功返回IMC的成员句柄,否则为NULL

7、HIMCC WINAPI ImmDestroyIMCC( //删除IMC成员缓冲区
HIMCC hIMCC //被删除的IMC的成员
)

如果成功返回NULL,否则等于该HIMCC.

8、LPVOID WINAPI ImmLockIMCC( //取IMCC缓冲地址,同时使IMCC的计数器值增加
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、BOOL WINAPI ImmUnlockIMCC( //递减IMCC计数器
HIMCC hIMCC //IMC成员句柄
)

如果IMCC的计数器值为零,则返回 FALSE,否则为TRUE.

10、HIMCC WINAPI ImmReSizeIMCC( //重新设置IMC的成员的缓冲区大小
HIMCC hIMCC, //IMC的成员句柄
DWORD dwSize //新缓冲区大小
)

如果成功,返回新的HIMCC,否则为 NULL.

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

返回IMC成员的缓冲区大小

12、DWORD WINAPI ImmGetIMCCLockCount( //返回IMC计数器值
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.

第三章 ime文件中必须使用的结构

前二章我们讲述了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;
IMETool 已经推出有几年了,因为我一向比较懒,没有写过必要的说明,至今有许多朋友不能正确使用它功能(看起来是我设计得比较烂,让人看不明白 )。下面我就几个常见问题做些说明。 1、问:Windows 系统本身就自带输入法管理功能,要 IMETool 何用? 答: ⑴系统自带输入法管理功能无法调整各输入法顺序,而 IMETool 可以实时调整。 ⑵系统自带输入法管理功能只能设置 Ctrl + Alt + 1 之类有限的热键,且有时无法恢复初始设置,删除输入法时无法自动将其热键一并删除。IMETool 大大突破了热键设置局限性,可以实现 1092 种不同的热键组合。这是 IMETool 独一无二的功能。 ⑶系统自带输入法管理功能没有从注册表删除输入法功能。 ⑷另外 IMETool 还支持丰富的命令行参数和脚本,可以通过命令行完成图形界面中的所有功能,非常灵活方便。 2、问:启动系统后总是会默认打开某一输入法,如何才能将其关闭? 答:在 IMETool 的输入法列表中,处在第一位的输入法即为默认输入法。如图一中①处,将“中文 (简体) – 美式键盘”设在第一位,系统启动时就不会再自动打开某输入法了。 3、问:如何才能用一个热键(如 Ctrl + 空格)快速地打开/关闭我最常用的输入法? 答:大家知道,默认的打开/关闭输入法热键是“Ctrl + 空格”,它其实就是来回切换位于输入法列表中前两位的输入法。所以只须将最常用的输入法排在列表中第二位即可,比如我最常用极点五笔输入法,就将其放在图一中②处。 4、问:如何快速打开某输入法的属性或热键对话框? 答:在输入法列表“名称”一列上双击,即可快速打开输入法属性设置对话框;即热键一列双击则打开热键设置对话框。 5、问:“键盘”按钮有何作用? 答:此功能极少用到。一些中文输入法在安装后使用系统默认的英文键盘定义,对于使用其它国别键盘的用户,会产生键位错误的情况。此时可使用 IMETool 的键盘布局重定义功能将其设置为正确的国别即可。注意:在点击“键盘”按钮打开的对话框中选择“确定”后,会立即修改注册表中的相应项目,请谨慎使用。 6、问:输入法风格中的“输入法指示器”和“高级文字服务”有什么区别? 答:在 Office XP 未出现之前,Win 9X 和 Windows 2000 中一直使用输入法指示器(internat.exe),即在任务栏系统托盘区中显示输入法列表的蓝色 En 或 CH 图标(不同配色方案下图标颜色可能不同)。 从 Office XP 开始,微软使用高级文字服务(ctfmon.exe)来代替输入法指示器,其特点是其输入法列表可在屏幕上任意移动,并可缩小至任务栏(但不在系统托盘区)。在 Windows XP/2003 系统中已经用高级文字服务完全取代了输入法指示器,所以要想使用输入法指示器,只能从 Windows 2000 系统中复制出 Internat.exe 和 indicdll.dll(前者必须的库文件)来使用。 7、问:调整输入法顺序为何有时不起作用? 答:此功能主要适用于使用输入法指示器的情况,在高级文字服务模式下,系统往往会记住你上次使用的输入法,并动态调整。另外在 Win95/NT 系统下,调整顺序需要重启系统方可生效。 8、问:使用 IMETool 进行一些设置后,默认的 Ctrl + Shift 切换输入法热键不能用了? 答:这是反映最多的一个问题,在此详细说明一下。 在高级文字服务模式下(ctfmon.exe),有“切换输入语言”和“切换键盘布局”两种热键,两者的热键必须为Ctrl + Shift 和 Alt + Shift 中的一个,即如果前者的热键是 Ctrl + Shift,后者的热键就必须是 Alt + Shift,其设置保存在注册表中。“切换输入语言”是指即在安装的不同语言间切换,如中文(中国)、美国英语等。“切换键盘布局”是指切换不同的输入法。 而在输入法指示器模式下(internat.exe),只有切换输入法这一种功能,而其从注册表读取的热键配置正好是高级文字服务模式下的“切换输入语言”的配置。由此可知,同样的注册表配置,高级文字服务和输入法指示器两种模式下切换输入法的热键正好是 相反的。 所以这个问题并不是 Ctrl + Shift 热键不能用了,而是默认变成了 Alt + Shift,可在设置中改回。 注:在 2.6.5 版本中,已经解决了这个问题,无须再手工切换。 9、问:在使用 IMETool 后,有时输入法的指示条会消失。 答:在 IMETool 的其它设置中,有一个打开/关闭输入法指示条的选项,是调用了一个 API 函数来实现的。不知何故,其只对当前打开的输入法有效,对其它输入法可能会起到相反的作用,不过在系统重启后会恢复正常。此问题有待于以后研究解决。 建议:在使用 IMETool 之前,关闭所有打开的输入法,因为已运行的不同程序下可能会打开不同的输入法,所以要逐个关闭。 10、问:IMETool 的修复功能有哪些,为何在界面中找不到? 答:IMETool 可以修复一些常见的输入法混乱情况:如: ⑴某输入法已经卸载,但仍在输入法列表中残留了条目。 ⑵某输入法已经卸载,但其先前设置的热键并没有取消。 ⑶高级文字服务模式下,将输入法列表条最小化后,任务栏上不出现语言栏。 ⑷2000/XP 提示“检测到不兼容的键盘驱动程序。该对话框已被停用。”,并且无法通过控制面板添加删除输入法。 以上修复过程完全是自动进行的,不需要人工干预,故没有在界面中设计。 11、问:软件包里附带的 internat.exe 和 indicdll.dll 文件有何作用? 答:这两个文件是从Windows 2000 简体中文专业版中提取的,并做过一些修改。Windows XP/2003 若想使用“输入法指示器”风格工作时需要将这两个文件复制到系统文件夹下使用。建议将 imetool.exe 文件也复制到系统文件夹下,这样就可以从输入法指示器右键属性中直接调用 IMETool 了。 12、问:如何卸载 IMETool? 答:IMETool 只有一个主文件,无须安装,自然也无须卸载,直接删除即可。 13、问:一些杀毒软件报 imetool.exe 为“病毒”。 答:IMETool 使用 upx 压缩过,一些比较敏感的杀毒软件会报其为加壳程序(注意不是报病毒!),从 2.8.1 版开始,不再使用 upx 压缩主程序。 Silence 2009.8.14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值