CSDN博客

img kathywp

输入法简介

发表于2002/11/4 13:03:00  2242人阅读

分类: 杂谈

这个又是很早的东西了,呵呵,也许有人会用的着吧!

输入法编辑器篇
输入法编辑器(IME)是允许用户使用标准键盘输入复杂字母与符号,如日文汉字的程式。本文描述创建及管理IME(input method editor)视窗的方法。
1、输入法编辑器简介
IME 不是检索用户可能用到的所字符值,而是监控用户的按键,来预料用户可能需要的字符,并提供一张备择字符列表以供用户从中选出所需字符。
  默认情况下,IME为用户提供一个可以键入并选择备择字符的IME视窗。通过使用IME变换功能提供的定制接口,Win32程式可以利用输入法管理器 (Input method manager),IMM,函式和消息创建自己的IME视窗。
IMM仅在远东地区的Windows95/98和WindowsNT4.0/3.5/平台上可被激活。在这些系统上用SM_DBCSENABLED调用GetSystemMetrics来判定IMM是否被激活。WINDOWS2000为所有地区的语言均提供全部特征的IME支持。然而须注意,仅当安装了亚洲语言包时,IMM方可被激活,一个可激活IMM的程序用SM_IMMENABLED调用GetSystemMetrics来决定当前IMM是否活动。
1.1 状态、录字和备择视窗
用户接口为IME提供状态、录字和备择视窗。状态视窗指示IME被打开,并向用户提供设置转换模式的方法;在用户输入文本时,录字视窗弹出来,依赖转换模式显示输入文本或转换后的文本。备择视窗同录字视窗也一同出现,包含待选的备择字符或录字视窗中的字符,用户可以滚动备择列表来选择所需的字符,然后返回至录字视窗。用户可用此方法录入所需文本,直至录入字符串结束且视窗关闭。以WM_IME_CHAR或WM_IME_COMPOSITION/GCS_RESULT消息的形式,IME向程式送入录入字符。若程序不处理这些消息,DefWindowProc函式将它们转译成一个或多个WM_CHAR消息。
默认时,系统自动地为所有需要文本输入的视窗创建和管理状态、录字及备择视窗。对许多程式而言,这一默认处理是高效的。这些程式完全依赖于系统对IME的支持并被称为“无觉察IME”( IME-unaware)。这是因为他们忽略许多系统管理IME视窗的任务。
相对应,一个“IME察觉”(IME-aware)程序,必参与IME视窗的创建与管理工作。此类程序通过传递、截取和处理送往默认视窗的消息,来控制视窗的操作、位置以及外观。在有些情况下,程序可以创建自己的IME视窗,并对自己定制的状态、录字和备择视窗提供完整处理方法。
1.2 IME视窗类
"IME" 视窗类是预定义的定义标准IME视窗行为和外观系统全局类。视窗类与通用控件类相似,在该类中,可以用CreateWindowEx函数创建该类的视窗,如同静态控件IME视窗不自身响应用户输入,相反,它通知用户输入行为IME和用IME或响应用户行为的程式给它传送进程控制消息。
IME-aware 程序有时用IME类创建自己的IME视窗。这就允许程序利用默认的IME视窗进程以及视窗位置控件。
1.3  IME消息
当某个事件发生时,系统送出IME视窗消息到程序视窗程序来影响IME视窗。例如,当激活一个视窗,系统给应用程序送出WM_IME_SETCONTEXT消息。IME-Unaware程序传送这些消息给DefWindowProc函数,后者再把消息送到相应默认的IME视窗。
可以使用WM_IME_CONTROL消息指导IME视窗执行命令,如改变录字视窗的位置;IME使用WM_IME_COMPOSITION消息通知程序录入字串的改变;送出WM_IME_NOTIFY消息通知程序IME视窗状态的通用变化。
1.4 输入上下文
输入上下文是IME支持的内部结构,包括IME状态及IME视窗使用的信息。默认情况下,系统为每个线程创建和指派一个输入上下文,在该线程内,此默认输入上下文是共享资源并被连接到每个新建视窗。
要在IME中检索或设置信息,应用程式须首先检索,连接到指定视窗输入上下文的句柄,可调用ImmGetContext函数来完成检索。随后,可用检索到的句柄调用输入法管理器函数检索和设置IME值,如录字视窗风格,录字的风格和状态视窗位置。一旦使用完上下文必须用ImmReleaseContext函数释放它。
由于默认的上下文是共享资源,故它的任何变化均会反应到线程的所有视窗中。然而可以由创建和关联自己的输入上下文到一个或多个线程的视窗,来越过此默认行为。此后只有与自己的输入上下文关联的视窗才会改变。
由使用ImmCreateContext函数,可以创建输入上下文。为给视窗指派上下文,可调用ImmAssociateContext函数来给先前的关联输入上下文返回一个句柄。若先前没有将输入上下文与视窗关联,则返回句柄是默认输入上下文的。典型情况下,可保存此句柄,并在后面不再使用自己的输入上下文时,将该句柄与视窗重新连接。
一旦输入上下文与视窗连接,系统自动选择何时视窗被激活和被输入焦点的上下文。输入上下文的风格和其它信息会影响该视窗后面的键盘输入,并决定如何和是否进行IME操作。
在结束应用程序前,必须消除任何用户自己创建的输入上下文。首先必须移除在线程中由使用ImmAssociateContext函数关联到视窗的任何输入上下文。随后,调用ImmDestroyContext函数。
1.5、 录入字符串
录入字符串是录入视窗的当前文本。即IME转换到最终字符的文本。每个录入字符串由一个或多个Clauses组成,这里Clauses是IME能转换到最终字符的字符最小组合。可以调用ImmSetCompositionString和ImmGetCompositionString函数来获取和设置录入字符串。
用户在录入视窗输入文本时,IME跟踪录入视窗的状态,包括属性信息,clause信息,键入信息和光标位置。可以用ImmGetCompositionString函数检索录入状态。
在属性信息数组中,一个Clause中的所有字符,必须有相同的属性。属性信息是一个8位值数组,用来指定字符在录入字符串中的状态。串中的每字节对应一个值,如串中的任何双字节字符分别用一个字节来表示前导字节和第二字节。对于数组中的每个值,可按下表来组合1位到3位值。
值 含     义
ATTR_INPUT 将由IME转换的用户输入字符。
ATTR_INPUT_ERROR 字符错误且不能由IME 转换。如, 一些不能放在一起的辅音。
ATTR_TARGET_CONVERTED 已被转换的字符, 用户已选择此字符且IME业已转换了它。
ATTR_CONVERTED 已被转换的字符。
ATTR_TARGET_NOTCONVERTED 正被转换的字符,用户已选择此字符但IME还未转换它。
ATTR_FIXEDCONVERTED 将不被转换的字符, IME 不会转换这些字符。
所有其它值被保留。日文中,任何有ATTR_INPUT属性的未转换字符是平假名、片假名或字母数字字符。韩文中,此字符为不被IME转换的Hangeul字符。在繁简中文中,每个IME在某个范围均有限制的字符。Clause信息是32位值数组,来指定录入视窗中Clause的位置。每个Clause有一个值,且最后一个值用来指定字符串的长度。数组的每个值指定从串开始到Clause的字节数偏移量。由于第一个Clause总从串头起始,故第一个值总为零。如:一个串有两个Clause,则Clause信息有3个值:第一个值为零,第二个值为第二个Clause的偏移量,第三个值为串的长度。对Unicode,Clause的长度是Unicode字符中的大小。
键入信息(typing information)是一个null结束的字符串,代表键盘的键入字符。
光标位置(cursor position)是指示与录入串中字符相关的光标位置的值。该值用字节表示从串头的偏移量。若此值为零,则光标在串中第一个字符的正前方。若值为串的长度,则光标紧挨在串中最后一个字符后边。若值为-1,则无光标。对Unicode位置和长度在Unicode字符中度量,可利用ImmSetCompositionString函数来设定录入串或录入状态元素。为确保录入视窗更新基于这些变化的外观,函数允许给视窗传送通知消息,设定录入状态元素组合的应用程序,可以为该函数的除了最后一次调用的所有调用设定Notify参数为FALSE,故对录入视窗仅产生一个通知消息。最后,编辑控件支持两个消息来改变IME的录入串句柄。
1.6 备择列表
备择列表是一个CANDIDATELIST结构。该结构由指定字符串的数组成或用户可以从中选择的字符串组成,可以用ImmGetCandidateListCount和ImmGetCandidateList函数来检索备择列素。
1.7 热键
热键使用户可以快迅地改变IME输入模式或切换到其它IME。尽管程序无法给系统增加热键,但使用ImmSimulateHotKey函数,可使启动同一行作为热键。Hex To Unicode IME 也允许十六进制字符和Unicode字符的互转。
1.8  Hex To Unicode IME
Rich Edit 3.0支持Hex To Unicode IME,允许用户采用一种或两种热键方式在十六进制字符和Unicode字符间互换。
在第一种方法中,用户键入十六进制字符码,而且按下Alt+x。则IME在插入点前用Unicode字符代替十六进制数字。若当前字体不支持字符码,则支持的适当字体被选择。由Unicode变到十六进制,则按下Shift+Alt+x。特殊地,允许确定由“丢失符号”指示器指示的字符。若十六进制字符码紧跟在合法(非字符)十六进制字符后,在按Alt+x前须选择想去变换的特定数字。此种方法的例题是,Alt+x有时被用作“退出”命令的组合键,如在微软的office中,作为“文件”菜单的选项而发生。
第二种方法涉及数字Pad。这里,用户输入Alt+Num Pad(大于255的值)数字来用十进制值输入Unicode字符。此法不如第一种方法有用,因为无法看到输入的十六进制数。同时除了重新输入一遍否则无法订正错误。


2、输入法编辑器应用
2.1 处理WM-IME-COMPOSITION消息
处理WM_IME_COMPOSITION消息的程序测试lParam参数的位数和调用ImmGetCompositionString函数检索指示串或数据。下例检查结果串,为串指派足够的内存,并从IME中检索结果串。
HIMC hIMC;
HWND hWnd;
DWORD dwSize;
HGLOBAL hstr;
LPSTR lpstr;

case WM_IME_COMPOSITION:
    if (lParam & GCS_RESULTSTR)
    {
        hIMC = ImmGetContext(hWnd);

        If (!hIMC)
            MyError(ERROR_NULLCONTEXT);

        // Get the size of the result string.
        dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);

        // increase buffer size for NULL terminator,
        //   maybe it is in UNICODE
        dwSize += sizeof(WCHAR);

        hstr = GlobalAlloc(GHND,dwSize);
        if (hstr == NULL)
             MyError(ERROR_GLOBALALLOC);

        lpstr = GlobalLock(hstr);
        if (lpstr == NULL)
             MyError(ERROR_GLOBALLOCK);

        // Get the result strings that is generated by IME into lpstr.
        ImmGetCompositionString(hIMC, GCS_RESULTSTR, lpstr, dwSize);
        ImmReleaseContext(hWnd, hIMC);

        // add this string into text buffer of application

        GlobalUnlock(hstr);
        GlobalFree(hstr);
    }
2.2 输入法编辑器和Unicode
微软® Windows NT ®/2000 和微软® Windows® 98两种平台均为IME支持Unicode接口,当然还有从Windows95起,就支持的ANSI接口。Windows98支持除ImmIsUIMessage以外的所有Unicode函数。此外Windows98中的所有消息均是基于ANSI的。既然Windows98不支持Unicode消息,程序可以利用ImmGetCompositionString从Win98中基于IME的Unicode中检索Unicode字符。
有两个问题涉及Unicode句柄和IME。一个是IME例行程序的Unicode版本返回缓存字节的大小,而不是16位Unicode字符;另一个是IME通常在WM_CHAR 和WM_IME_CHAR消息中返回Unicode字符(不是DBCS)。
用RegisterClassW使WM_CHAR和 WM_IME_CHAR消息在wParam参数中返回Unicode字符而不是DBCS字符。此法仅在Windows NT/2000中可用。在win95/98中不可用。
2.3  复原IME
在Windows 98/2000中,IME具有复原的新特征。通常情况下,IME仅限于由键入来决定备择列表。复原允许IME依照其所在的句子(上下文)来决定备择的字符(或仅一个备择字符)。复原有三种类型:简单,正常和高级。
当用户在文件中发现录入错误时,复原是很有用的。此时,用户选出错误,并在菜单中选择复原,则IME用上下文来确定最佳替代。ImmSetCompositionString可用来支持复原的使用。
2.4 开发IME-aware多线程应用程序。
当前的输入法管理器(IMM)结构不支持访问IMM句柄的异步工具。
Windows 2000的IMM包含线程确认检查,用来确认调用的线程是否是指定输入法上下文句柄(hIMc)或视窗句柄(hWnd)的创建者。若不是,则函数调用失败并从GetLastError函数中返回ERROR_INVALID_ACCESS
这一过程须要开发者遵循以下原则:
⑴一个线程不应该同由其它线程创建的输入上下文。
⑵一个线程不应连接输入上下文和其它线程创建的视窗,或反之。
2.5、Windows 2000中的IME
Windows 2000为任何地方的语言版本均提供IME的所有特性。因此,可以在Windows 2000的任何版本中安装和使用IME,而不仅是仅为亚洲语言设计的Windows 2000。
然而,仅当用户在Win 2000上安装了亚洲语言包,IMM方可被激活。基于IME的程序, 用SM_IMMENABLED调用GetSystemMetrics函数来判定IMM是否被激活。

0 0

我的热门文章

相关博文

img
取 消
img即使是一小步
也想与你分享
打开
img