logo资料库

IME输入法VC编程的详细解说.pdf

第1页 / 共51页
第2页 / 共51页
第3页 / 共51页
第4页 / 共51页
第5页 / 共51页
第6页 / 共51页
第7页 / 共51页
第8页 / 共51页
资料共51页,剩余部分请下载后查看
IME 输入法 VC 编程的详细解说 初探 WINDOWS 下 IME 编程 IME 编程心得 第一章 Windows9x 系统下汉字输入法的基本原理 第二章 Windows9x 系统提供的 ime 管理函数 第三章 ime 文件中必须使用的结构 自由拼音输入法的测试 输入法程序[ime]的调试方法 输入法(IME)实现原理
初探 WINDOWS 下 IME 编程 大家知道,DELPHI 许多控件有 IME 属性。这么好用的东西 VC 可没自带,怎么办呢?其 实,可通过注册表,用 API 实现。下面说一下本人对 IME 的研究结果,并提供示例工程供 大家参考: 1、将用到的 API Cpp 代码 1. RegOpenKey:打开注册表一键 2. RegQueryValue:查询一键值 3. RegQueryValueEx:同上 4. RegCloseKey:关闭打开的键 5. 6. LoadKeyboardLayout:装载输入法 7. ActivateKeyboardLayout:激活输入法 2、IME 信息在注册表中的位置 在 HKEY_USERS:".DEFAULT\keyboard layout\preload"放的是已安装的输入法,下有几 个以数字为名的子键,内容是输入法代号(keyboard layout),如"e0040804",其中左 4 位是 设备代码(device identifier),右 4 位是语言代码(language identifier)。例如上面:左 e004 指智能 ABC,右 0804 指大陆中文。(详见 MSDN) 在 HKEY_LOCAL_MACHINE:"System\CurrentControlSet\Control\Keyboard Layouts\"放 的是已注册的输入法。他的子键名为输入法代号(keyboard layout),内容为该输入法的 ime 文件,名称等信息。 3、主要思路 我们可先把已装的输入法枚举出来(从注册表),用户选择其一后,再激活该输入法。 两关键函数: HKL LoadKeyboardLayout(LPCTSTR pwszKLID,UINT Flags); 第一个参数是待打开的输入法代号,如"e0040804"(智能 ABC); 第二个参数是标志位,如 KLF_ACTIVATE(激活)。 HKL ActivateKeyboardLayout(HKL hkl,UINT Flags); 第一个参数是打开的输入法句柄(由 LoadKeyboardLayout 返回); 第二个参数是标志位,如 KLF_SETFORPROCESS。(详见 MSDN) 4、例子程序
新建一基于对话框的工程,加入一 combobox 控件,增加控制变量 m_cb1。加入一 edit 控 件,增加控制变量 m_edt1.对 combobox,增加对 CBN_SELCHANGE 的映射函数 OnSelchangeCombo1()。对 edit1,增加对 EN_SETFOCUOS 的 SetfocusEdit1().在对话 框类头文件的 public:下加入数组声明:CString lst[10]; 在 OnInitDialog()的 return 前加如下代码: Cpp 代码 1. HKEY hk,hk1; long cp=16; 2. 3. char lp[15]; 4. char a[2]; 5. a[0]='1'; 6. a[1]='\0'; 7. CString str,str1; 8. str=".DEFAULT\\keyboard layout\\preload\\";//已装的输入法。注:win2000 有所不 同 9. str+=a; 10. int i=0; 11. while(::RegOpenKey(HKEY_USERS,str,&hk)==ERROR_SUCCESS)//打开键 12. { 13. a[0]++;//下一子键 14. str=".DEFAULT\\keyboard layout\\preload\\"; 15. str+=a; 16. if(::RegQueryValue(hk,NULL,lp,&cp)!=ERROR_SUCCESS)//已装的输入法 17. MessageBox("Error"); 18. ::RegEnumKeyEx 19. str1="System\\CurrentControlSet\\Control\\Keyboard Layouts\\";//keyboardlay outLayout 20. str1+=lp; 21. lst[i++]=lp; 22. //打开对应的 keyboardlayoutLayout 23. if(RegOpenKey(HKEY_LOCAL_MACHINE,str1,&hk1)==ERROR_SUCCESS ) 24. { 25. LPBYTE lpD=new BYTE[80];//DataValue 26. DWORD lpT=REG_SZ;//DataType 27. DWORD lpS=80; //DataSize 28. if(RegQueryValueEx(hk1,"Layout text",NULL,&lpT,lpD,&lpS)!=ERROR_SUC CESS) 29. MessageBox("Query error",(LPCTSTR)lpD); 30. m_cb1.AddString((LPCTSTR)lpD); 31. delete lpD; 32. } 33. else MessageBox("open error");
34. RegCloseKey(hk1); 35. } 36. ::RegCloseKey(hk); 37. m_cb1.SetCurSel(0); 在 OnSetfocusEdit1()加入如下代码: Cpp 代码 temp=m_cb1.GetCurSel()!=CB_ERR?st[m_cb1.GetCurSel()]:"00000409"; 1. CString temp; 2. 3. 4. HKL hkl; 5. hkl=LoadKeyboardLayout(temp,KLF_ACTIVATE);//装载输入法 6. 7. ActivateKeyboardLayout(hkl,KLF_SETFORPROCESS);//激活输入法 if(hkl==NULL) OnOK(); 在 OnSelchangeCombo1()加入如下代码: Cpp 代码 1. m_edt1.SetFocus(); 即可编译运行。 5、注意:win2000 下有所不同。注册表 HKEY_USERS:".DEFAULT\keyboard layout\preload 没有子键只有以数字为名的项,值为输入法代号(keyboard layout)。在示例 代码中不仅提供了 WIN 9X 下的代码,也提供了 2000 下的相应代码段,具体请参考示例 工程。
IME 编程心得 一、基础知识:(不断补充) 1.输入法管理器(IMM) 2.输入法编程器(IME) 3.输入上下文(IC) 4.应用程序(App) 二、IMM-IME 结构的基本工作过程及特点 用户键盘消息->系统通过 IMM 传递给与当前线程对应的 IME->IME 根据输入的消息和输入 上下文中记录的数据,将用户的键盘动作转换成结果串->以字串消息的形式返回给 IMM-> 放到应用程序窗口的消息队列中。 三、IME 的构成 1.IME 转换接口(IME conversion interface) 2.IME 用户接口(IME user interface) 由用户实现的一组窗口,这些窗口用来接收和处理由 IMM 发来的输入消息,提供与用户交互 的界面.由下面的窗口组成: 1)缺省的 IME 窗口(Default IME window) 2)用户接口窗口(UI interface) 3)用户接口窗口的组件:状态窗口(status window);编码窗口(compsition window);候选窗口 (candidate window). 4)软键盘和系统菜单/图标等 四、IME 的实现 1.IME 转换接口的实现
这些接口函数在供管理器在适当的时候调用.这些函数并非每个都要进行自己的处理,大部 分保留一个空函数即可,但没有却不可.系统默认是要调用的,找不到就不行.有以下函数: 1)ImeInquire 2)ImeConfigure 3)ImeProcessKey 4)ImeToAsciiEx 5)ImeSelect 6)ImeSetActiveContext 7)NotifyIME 8)ImeDestroy 9)ImeConversionList 10)ImeEscape 11)ImeSetCompsitionString 12)ImeRegisterWord 13)ImeUnregisterWord 14)ImeGetRegisterWordStyle 15)ImeEnumRegisterWord 2.IME 用户接口的实现 主要包括用户接口窗口(窗口类和窗口过程),用户界面窗口的组件(状态窗口,编码窗口和候 选窗口的窗口类和窗口过程),输入法的配置窗口,软键盘,任务条上的指示器窗口(图标,菜单, 工具提示)和输入法热键等. 1)用户接口窗口:编程中主要是处理由缺省的 IME 窗口传入的 IME 消息,当然,并非所有的 IME 消息都需要给出具体处理(可以看出这是 IME 编程中的一个原则).如: WM_IME_COMPOSITION WM_IME_STARTCOMPSITION/WM_IME_ENDCOMPOSITION WM_IME_SELECT
WM_IME_NOTIFY WM_IME_CHAR 五、具体实现步骤: IME 实质上是一个 DLL 实现,由系统调用。而这个 DLL 则分别实现了系统要调用的功能 函数。所以有些函数虽然不做什么事情,但是必需挂上一个空壳。否则调用出错。 1.DLLMain()的架构 1)进入进程 DLL_PROCESS_ATTACH 事件中,注册用户接口窗口类及其组件的窗口类:使用 RegisterClassEx()完成此注册过程。设置类名字段(lpszClassName)为用户接口窗口类类 名(包括结束标志'\0'在内最长可达 16 字符),在类风格(style)字段中必须包括 CS_IME 风格。设置附加内存大小(cbWndExtra)。 2)退出进程 注销上述与输入法编辑器有关的窗口类,进行全局性的清理工作。 2.打开/关闭输入法编辑器时进行的初始化操作 1)用户接口窗口是由缺省的 IME 窗口在接到 WM_IME_SELECT 消息时创建的。输入法管 理器通过调用 ImeRequire 接口函数获取输入法编辑器的相关信息(属性、用户接口窗口 类,可选项),据此进行输入法编辑器的初始化工作,创建输入法编辑器的用户接口窗口。 所以 ImeRequire 是输入法转换接口必须实现的第一个函数。 2)在用户接口窗口被创建后,可以进行输入法编辑器全局性的一些初始化工作,比如申请 自己的私有内存,建立私有上下文等,这些工作一般在处理 WM_IME_SELECT 消息或在 接口函数 ImeSelect 中进行,也可以在窗口过程处理 WM_CREATE 消息时进行。 3.进入进程后: 1)初始化词库 2)创建字体 3)注册窗口类
4.在 UI 窗口建立后,建立写作窗口和候选窗口 各个窗口下进行各自的消息函数处理 在这里有疑问:UI 窗口是什么?UI 窗口处理了 IME 的好多消息.--解答参看<<基于 IMM-IME 输入法接口的实现方法>> 下一个任务:看这个论文 UI 窗口是对用户不可见的,但是它是所有用户界面窗口的组件窗口的父窗口,是全部组件窗 口的管理者. 5.构建框架的问题 在 projects-settings-c/c++-catagory:prepossessor:additional include directories:./ 避免添加系统默认的头文件 6.注意的细节问题: 1)global.c 中的#pragma data_seg(".zhenhuadic"),应详细了解其作用,其与 Czh.def 中的定 义有相关联的地方.(对我们的工程名 Czh 来说) 2)freepy.exp : warning LNK4070: /OUT:Czh.ime directive in .EXP differs from output filename;C:\WINDOWS\system32\freepy.ime; ignoring directive 对于这个 BUILD 中的错误,关联之处在于 Czh.def 中定义了 lib 的输出名为 Czh,要求这个 lib 的输出名与 Output file name freepy 相同. 3)如果.ime 名和上述 2)中说的问题没有的话,且 freepy.h(原工程)中的#define FREEPYFILENAME _T("freepy.ime")定义正确,则在 HZfreepy.h 中改变以下几个文件名 与 C:\windows\system32\(window xp 系统下)下的相关文件名相同则可: freepy.tab--字库 freepysys.dic--系统词库 freepyusr.dic--用户词库 4)在 ImeSelect 的函数中,有个注册表键值的处理与工程有关联 5)有四条消息的遗漏:
分享到:
收藏