输入法开发
  Windows 95输入法编辑器(IME)  原著:Microsoft
  翻译:TBsoft Software Studio
  一、关于Windows 95混合语言IME
  在Windows 95中,IME是一个动态链接库(DLL),与Windows 3.1远东版本IME不同的是,每一个运行的IME相当于混合语言键盘布局中的一种。与Windows 3.1 IME相比较,Windows 95混合语言IME提供下列增强功能:
  ●运行时相当于混合语言环境的一个部件
  ●为每一个应用程序任务提供多重输入上下文
  ●为每一个应用程序线程提供一个活动的IME
  ●通过应用程序消息循环给应用程序提供信息(消息顺序不能改变)
  ●为无IME支持应用程序和部分IME支持应用程序提供有力的支持
  要得到全部的增强功能,应用程序需要支持Windows 95 IME应用程序I/F。
  本文档描述了Windows 95 IME体系结构的应用程序I/F。
  1、IME的结构
  Windows 95 IME必须提供两个部件:IME转换接口和IME用户接口。IME转换接口由一组IME模块引出函数提供,这些函数被IMM(输入法管理器——译者注)调用。
  IME用户接口由一组窗口提供,这些窗口接收消息并提供IME的用户界面。
  2、IME支持应用程序(IME感知应用程序——译者注)
  应用程序有下列类型:
  ●无IME支持应用程序:这种应用程序不控制IME,然而,如果应用程序接受DBCS字符,用户可以通过IME在应用程序中输入DBCS字符。
  ●部分IME支持应用程序:这种应用程序只控制不同的IME上下文,例如打开和关闭IME、写作窗口等等,但是不重新显示任何IME用户界面。
  ●完全IME支持应用程序:这种应用程序负责管理通过IME显示给应用程序的任何信息。
  在Windows 95中,一个无IME支持应用程序有一个缺省的IME窗口和一个缺省的输入上下文。
  部分IME支持应用程序使用预定义的“IME”类创建自己的IME窗口,可以管理或者不管理自己的输入上下文。
  完全IME支持应用程序自己管理输入上下文,显示输入上下文给出的任何需要的信息,不使用IME窗口。
  二、IME用户界面
  IME用户界面包括IME窗口、用户界面(UI)窗口以及UI窗口的部件。
  1、特征
  IME类是实现IME用户界面部分的预定义全局窗口类。“IME”类与预定义的公共控制窗口类 有许多相同的特点,IME窗口实例与静态控制一样通过CreateWindowEx函数创建,IME类窗口自己不响应用户输入,取而代之的是接收不同类型 的控制消息实现全部IME用户接口。应用程序可以使用IME类创建自己的IME窗口,还可以使用ImmGetDefaultIMEWnd函数获取缺省 IME窗口。创建自己的IME窗口或者使用缺省IME窗口的应用程序被称为IME支持应用程序,具有以下优点(与对应的Windows3.1应用程序比 较):
  ●包括候选字列表窗口(候选窗口),每一个应用程序可以有自己的用户界面窗口实例,使得用户可以在任何输入过程的中途停止并切换到另一个应用程序。在Windows 3.1日文版本中,用户切换到另一个应用程序是必须放弃当前输入过程。
  ●因为IME用户界面窗口包括应用程序窗口句柄,IME用户界面窗口可以为应用程序提供缺省行为。例如当应用程序移动时IME用户界面窗口自动移动,自动跟随窗口中的插入符号位置,为每一个应用程序标示模式等等。
  即使系统仅仅只提供一个IME类,IME窗口仍然有两种类型。一种类型是系统为无IME支持应 用程序创建的IME窗口,DefWindowProc函数为该窗口处理消息,DefWindowProc函数的
IME用户接口被线程的所有无IME支持窗 口共享,在文档中,这种窗口称为缺省IME窗口。另一种类型是IME支持应用程序创建的IME窗口,在文档中,IME支持应用程序创建的IME窗口称作应 用程序IME窗口。
  2、缺省和应用程序IME窗口
  当线程初始化时系统创建缺省IME窗口,这就是说,线程自动获取缺省IME窗口。缺省IME窗 口为无IME支持应用程序提供IME用户界面,当IME或者IMM生成一个IME消息(WM_IME_*)时,无IME支持应用程序传递该消息到 DefWindowProc函数,DefWindowProc函数发送需要的消息到为应用程序提供缺省IME用户界面的缺省IME窗口。IME支持应用程 序当不从IME获取消息时也可以使用缺省IME窗口,需要时可以使用自身的IME窗口。
  3、IME类
  IME类是Windows95远东版本预定义的窗口类,就像Edit是预定义的窗口类一样。预 定义的IME类实现全部的IME用户接口,处理所有来自IME和包含IMM函数的应用程序的消息,应用程序使用IME类创建自己的IME窗口。系统IME 类不能被被任何IME替换。
  窗口过程与IME类通过WM_IME_SELECT消息交互,该消息包括新选中的IME的键盘布局,IME类使用键盘布局查到每一个IME定义的类名。使用类名,IME类为当前活动的IME创建IME用户界面窗口。
  4、IME UI类
  每一个IME必须向系统注册自己的用户界面(UI)类,UI类提供IME相关功能。当IME附 加在进程上时IME注册自己的UI类,这就是说,当DLLEntry函数被调用DLL_PROCESS_ATTACH功能时,IME必须在对 ImeInquire函数的调用过程中指定UI类名。UI类应该使用CS_IME窗口风格注册以使得每一个应用程序都可以使用UI类。
  UI类名(包括空终结符)可以使用16位的TCHAR字符,这个限制可能延续到Windows的未来版本。
  当注册一个UI类时,应该指定8个字节的窗口附加数据(这就是说,设置WNDCLASSEX类的cbWndExtra成员的值为2*sizeof(LONG)),系统使用该窗口附加数据。
  IME可以在为应用程序执行任务时注册任何类和创建任何窗口。
  下面的实例显示了怎样注册IME窗口类:
  BOOL WINAPI DLLEntry ( HINSTANCE hInstDLL, DWORD dwFunction, LPVOID lpNot){switch (dwFunction){case DLL_PROCESS_ATTACH:hInst= hInstDLL;wc.style = CS_MYCLASSFLAG | CS_IME;wc.lpfnWndProc = MyUIServerWndProc;wc.cbClsExtra = 0;wc.cbWndExtra = 2 * sizeof(LONG);wc.hInstance = hInst;wc.hCursor = LoadCursor( NULL, IDC_ARROW);wc.hIcon = NULL;wc.lpszMenuName = (LPSTR) NULL;wc.lpszClassName = (LPSTR) szUIClassName;wc.hbrBackground = NULL;if(!RegisterClass((LPWNDCLASS)&wc))return FALSE;wc.style = CS_MYCLASSFLAG | CS_IME;wc.lpfnWndProc = MyCompStringWndProc;wc.cbClsExtra = 0;wc.cbWndExtra = cbMyWndExtra;wc.hInstance = hInst;wc.hCursor = LoadCursor(NULL, IDC_ARROW);wc.hIcon = NULL;wc.lpszMenuName = (LPSTR) NULL;wc.lpszClassName = (LPSTR) szUICompStringClassName;wc.hbrBackground = NULL;if(!RegisterClass((LPWNDCLASS)&wc))return FALSE;break;case DLL_PROCESS_DETACH:UnregisterClass(szUIClassName,hInst);UnregisterClass(szUICompStringClassName,hInst);break;}return TRUE;}
  5、UI窗口
  IME类对应的IME窗口被应用程序或者系统创建,当IME窗口被创建时,IME自身提供的 UI窗口被创建并被IME窗口所拥有。每一个UI窗口有一个当前的输入上下文,当UI窗口接收到IME消息(WM_IME_*)时,可以通过调用 GetWindowLong函数和指定IMMGWL_IMC索引值查到输入上下文,UI窗口可以根据输入上下文处理消息,UI窗口可以在除响应 WM_CREATE消息以外的任何时间查到输入上下文。
  IME不允许改变UI窗口的窗口附加数据,如果UI窗口的某个实例需要窗口附加数据,可以使用 IMMGWL_PRIVATE参数值调用SetWindowLong和GetWindowLong函数,IMMGWL_PRIVATE参数值提供为UI窗 口的某个实例存取附加数据中LONG类型值的能力,如果需要大于LONG类型值的附加数据,可以保存一个内存块的句柄到IMMGWL_PRIVATE域。
  UI窗口过程可以使用DefWindowProc函数,但是UI窗口不允许传递IME消息给DefWindowProc函数,即使某个IME消息没有被处理,UI窗口也不允许传递该消息给DefWindowProc函数。
  LRESULT UIWndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){HIMC hIMC;HGLOBAL hMyExtra;switch(msg){case WM_CREATE:// Allocate the memory bloack for the window instance.hMyExtra = GlobalAlloc(GHND,size_of_MyExtra);if (!hMyExtra)MyError();// Set the memory handle into IMMGWL_PRIVATESetWindowLong(hWnd, IMMGWL_PRIVATE, (LONG)hMyExtra);...break;case WM_IME_xxxx:// Get IMC;hIMC = GetWindowLong(hWnd,IMMGWL_IMC);// Get the memory handle for the window instance.hMyExtra = GetWindowLong(hWnd, IMMGWL_PRIVATE);lpMyExtra = GlobalLock(hMyExtra);...GlobalUnlock(hMyExtra);break;...case WM_DESTROY:// Get the memory handle for the window instance.hMyExtra = GetWindowLong(hWnd, IMMGWL_PRIVATE);// Free the memory block for the window instance.GlobalFree(hMyExtra);break;default:return DefWindowProc(hWnd, msg, wParam, lParam);}}
server error翻译

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。