PocketPC中汉字输入法分析与实现(…

来源:互联网 发布:C语言编程输出声音 编辑:程序博客网 时间:2024/06/05 12:07
作者:朱晓旭,刁红军(苏州大学,江苏苏州 215006)

摘要
   嵌入式操作系统在PDA与智能电话等手持设备领域的应用日益广泛,如何在这些设备中方便、快速输入汉字需要解决,所以将目前PC平台上的优秀输入法移植到PDA与智能电话中是一个具有实际意义的问题。本文以在PocketPC平台上设计一个Unicode内码输入法为例,介绍PocketPC的输入法接口与编程实现一个PocketPC输入法的过程。
关键词:WindowsCE;IM(输入法);PDA;PocketPC
中图分类号:TP311.5     文献标识码:A

引言
   随着嵌入式应用需求的不断增加,Microsoft公司专门发布了嵌入式操作系统———WindowsCE操作系统,Win2dowsCE是一个模块化的操作系统,用户可以根据自己的需求选择WindowsCE中的模块架构自己的平台(例如有些移动电话不需要触摸屏的模块),换句话讲用WindowsCE架构的平台其实是WindowsCE操作系统的一个子集,这些平台通常与为配套硬件结合构成一个系统,其中最著名的平台是PocketPC和SmartPhone。Microsoft希望通过PocketPC在PDA市场与Palm一争高下,期待SmartPhone在移动电话领域对Symbian操作系统发起挑战。汉字的输入方法是中文信息处理的一个重要课题,Microsoft公司在Window9x/Me/2000/XP中都提供了基于IMM-IME的输入法接口,通过该接口可以编写出与Windows中文版无缝连接的汉字输入法。目前,在桌面Windows中有许多优秀的汉字输入法,它们能够很好地满足用户快速输入或学习简单等使用需求,但是Microsoft在PocketPC简体中文版中只提供了拼音和手写输入法,难以满足所有用户需要,所以如何将PC中优秀的汉字输入法移植到PocketPC中来,是一个很具有实用意义的问题,下面通过在PocketPC中用MicrosoftEmbeddedVisualC++3.0(下文简称EVC3)实现一个Unicode内码输入法的例子来讲解在PocketPC中设计汉字输入法的技术与注意要点。

PocketPC输入法简介与接口概述
   PocketPC没有提供物理键盘,用户主要是通过触控笔和触摸屏进行操作与输入,PocketPC用户可以通过SIP(SupplementaryInputPanel,辅助输入面板)完成用户汉字输入过程,SIP是屏幕上的一块区域,它可以根据用户的需要显示或隐藏,用户可以通过选择SIP中的IM(InputMethod,输入法)进行输入,SIP中可以有多个IM,例如PocketPC预先提供的“拼音输入法”和“手写输入法”就是两个IM。IM可以在不影响系统其它功能的前提下安装或删除,而且我们可以编写自己的IM安装到系统中。PocketPC中的输入法IM作为COM进程服务器来实现的,所以在编写IM的时候需要遵循COM进程服务器规范。在PocketPC中编写汉字输入法,主要要通过IInput2Method和IIMCallback两个接口与系统交互。其中IInput2Method接口是IM的核心部分,在编写IM的时候,我们需要实现一个继承了IInputMethod接口的类,并在该类中具体实现IInputMethod接口提供的方法,IInputMethod接口主要提供的方法与说明参见表1。

表1 IInputMethod接口简介方法名称方法说明

Select当用户选择IM时,IM所在DLL被加载,然后系统调用此方法,IM应该在此方法中创建自己的窗口与初始化相关数据。
Deselect当用户撤消使用该IM时(例如选择其它IM),IM应该在此方法中销毁自己创建的窗口,并做善后工作。
Showing当IM将被显示时,系统调用此方法。
Hiding当IM将被隐藏时,系统调用此方法。
GetInfo系统可以通过该方法获取IM的信息。
ReceiveSipInfo当系统显示SIP的时候将调用该方法。
RegisterCallback当选择IM后,系统将调用该函数以传递I2IMCallback接口的指针。
GetImData获取IM的专用数据,大多数IM在该方法中不做操作直接返回。
SetImData设置IM的专用数据,大多数IM在该方法中不做操作直接返回。
UserOptionDlg当系统需要显示IM的配置对话框时自动调用此方法。IM需要在方法中创建并显示配置对话框

   IInputMethod接口简介方法名称方法说明Select当用户选择IM时,IM所在DLL被加载,然后系统调用此方法,IM应该在此方法中创建自己的窗口与初始化相关数据。Deselect当用户撤消使用该IM时(例如选择其它IM),IM应该在此方法中销毁自己创建的窗口,并做善后工作。Showing当IM将被显示时,系统调用此方法。Hiding当IM将被隐藏时,系统调用此方法。GetInfo系统可以通过该方法获取IM的信息。ReceiveSipInfo当系统显示SIP的时候将调用该方法。RegisterCallback当选择IM后,系统将调用该函数以传递I2IMCallback接口的指针。GetImData获取IM的专用数据,大多数IM在该方法中不做操作直接返回。SetImData设置IM的专用数据,大多数IM在该方法中不做操作直接返回。UserOptionDlg当系统需要显示IM的配置对话框时自动调用此方法。IM需要在方法中创建并显示配置对话框。IIMCallback接口是IM回掉系统的途径,例如当IM根据用户的输入码检索到对应的字或词的时候就可以通过该接口将字或词回发给系统,该接口对于编写IM而言主要是调用该接口提供的方法,IIMCallback接口主要提供的方法与说明参见表2。

表2 IIMCallback接口简介方法名称方法说明

SetImInfoIM可以调用该方法控制自己在屏幕上的大小和位置。
SendVirtualKeyIM可以通过该方法向系统发送一个虚拟键。
SendCharEventsIM可以通过该方法向具有焦点的应用程序发送一个字符。
SendStringIM可以通过该方法向具有焦点的应用程序发送字符串。

在PocketPC中注册输入法
   PocketPC是通过检索[HKEYCLASSESROOT]\CLSID中符合条件的键来枚举系统的输入法的,所以在PocketPC中注册输入法的任务就是在[HKEYCLASSESROOT]\CLSID中建一个唯一的CLSID键,在该键中设置输入法的名称和输入法文件的dll文件路径,另外必须在该键中建立一个名为“IsSIPInputMethod”的子键,并且将它的值设为1。通常我们编写一个程序进行上述工作,该程序在进行输入法安装的时候自动运行,这样自己编写的输入法就可以被PocketPC枚举并使用。

UnicodeIM的实现步骤
   在实现PocketPC上IM的时候主要设计四个步骤,首先建立IM的工程,然后必须实现继承IInputMethod接口的类,接着编写窗口的消息循环处理代码,最后实现从输入码到对应字\词的转换检索模块。下面就Unicode汉字输入法的实现来具体加以描述。

    建立IM工程
   首先在EVC中新建一个名为CUnicodeInput的COM工程,在工程中添加一个类CUnicodeIM,该类继承IInput2Method接口,然后添加一个继承IclassFactory接口的Uni2codeClassFactory类,在UnicodeClassFactory的CreateIn2stance成员函数中添加新建CunicodeIM类对象的代码,接着在COM的DllGetClassObject函数中添加代码创建Uni2codeClassFactory类的对象,这样就完成了一个输入法COM的基本的结构。以上工作都可以通过EVC的AppWizard辅助快速完成。
    实现CUnicodeIM类
   这里我们主要实现CUnicodeIM类的Select、Deselect、RegisterCallback、Showing和Hiding成员函数,因为当用户选择IM的时候系统立刻就会调用Select方法,所以Select中的代码完成加载需要的图片、注册窗口类和用注册的窗口类创建窗口的工作,Deselect函数中添加销毁窗口和撤消窗口类,RegisterCallback函数中将系统传过来的参数保存在指针变量中,这样就可以在后面通过该指针调用IIM2Callback接口的方法,在Showing和Hiding函数中添加控制IM窗口显示与隐藏的代码。
    消息循环处理代码的实现
   本步骤主要实现IM与用户交互的功能,需要编写软键盘和用户输入码显示窗口的消息循环处理函数以及用户输入的捕获与处理,UnicodeIM中是利用了软键盘窗口的一块区域显示用户输入码,所以只编写了一个消息循环处理函数,UnicodeIM主要需要处理WMCREATE、WMPAINT、WMLBUTTONUP和WMDESTROY消息。WMCREATE和WMDESTROY的消息处理代码主要完成软键盘和用户输入码显示窗口初试化和销毁工作。在WMPAINT消息处理代码中我们是通过绘制矩形和输出文本实现了软键盘窗口中按键和用户输入码显示的功能,当然设计人员也可以在图形、图象处理软件中绘制精美的软键盘图片,然后加载以显示实现美观的效果。在WMLBUTTONUP消息的处理代码中根据LPARAM参数计算出触控笔点击处的按键,接着判断按键如果是回车、空格等键则通过IIMCallback接口的SendCharEvents方法直接传给应用程序,如果是有效的输入法的码元(如‘0’—‘9’或‘A’—‘F’),就保存在存储用户输入码的数组中,当用户已经输入四位输入码时就调用输入码到对应汉字的检索模块。
    汉字检索模块
   因为我们实现的是Unicode输入法,所以从输入码到汉字的检索模块比较简单,实际是通过计算而不是检索,只要将用户的4位输入码变成BCD码,然后通过移位拼装,就可以得到对应的汉字的Unicode内码。
    具体实现参见如下代码:
//====================
//本函数将用户输入的0-9和A-F变成BCD码
//====================
WORD Unicode2BCD(TCHARinput)
{
   if(input>=0x0030&&input<=0x0039)
     return(WORD)(input-0x30);
   elseif(input>=TEXT(’A’)&&input<=TEXT(’F’))
     return(WORD)(input-55);
    else
      return0xFF;
}
//下面的代码片段将用户的输入码变成BCD码后移位保存。
BYTEout[4]={0};
out[1]=(BYTE)(Unicode2BCD(srm[0])<<4);
out[1]|=(BYTE)(Unicode2BCD(srm[1]));
out[0]=(BYTE)(Unicode2BCD(srm[2])<<4);
out[0]|=(BYTE)(Unicode2BCD(srm[3]));//通过IIMCallback接口的SendString将汉字发给应用程序。appIMCallback->SendString((TCHAR3)out,1);

   通过以上的步骤就可以建立一个PocketPC中的Uni2code输入法,完成最基本的根据用户输入的Unicode输入码输入对应汉字的功能。
原创粉丝点击