2019独角兽企业重金招聘Python工程师标准>>>
ImeConversionList:根据输入上下文的有关内容,将一个字符或者字符串转换成远东字符结果列表或者另一个字符串。
此函数的作用是在输入串和结果串之间进行变换以便于进行重新转换,所以在此函数中不应该产生任何相关的输入法编辑器消息;
BOOL WINAPI ImeConfigure(HKL hKL,HWND hWnd, DWORD dwMode, LPVOID lpData)
这是最后一个需要注意的接口,在显示输入法属性配置时会Windows会调用这个接口.
#ImeConfigure:此接口函数将在用户通过控制面板或系统图标设置输入法属性时被输入法管理器调用。在此函数中可以显示属性设置对话框,供用户配置输入法的可选项;
ImeDestroy:结束输入法编辑器的工作;
ImeEscape:应用程序通过调用这个函数可以直接访问某个输入法编辑器的特定功能,这些功能通常无法通过其他的IMM函数调用实现。这么做的目的主要是为了支持特定语种的函数或者IME的私有函数;
/**********************************************************************/
/* ImeInquire() */
/**********************************************************************/
BOOL WINAPI ImeInquire(LPIMEINFO lpImeInfo, LPTSTR lpszWndCls, DWORD dwSystemInfoFlags)
这个函数是除了DllMain后第一个会被win32 IMM调用的函数.
IMM通过调用这个函数知道你的输入法有什么特性. 比如,除了按键消息外,你是不是还想处理键放开的消息.
#ImeInquire:此接口函数在用户选择某个输入法时最先由输入法管理器调用,以获得该输入法的有关信息。函数应返回输入法编辑器的初始化信息,在IMEINFO结构中设置当前输入法的各项属性,以及当前输入法的用户界面窗口类名称;
/***********************************************************************/
/*系统调用这个接口来判断IME是否处理当前键盘输入 */
/*HIMC hIMC:输入上下文 */
/*UINT uKey:键值 */
/*LPARAM lKeyData: unknown */
/*CONST LPBYTE lpbKeyState:键盘状态,包含256键的状态 */
/*return : TRUE-IME处理,FALSE-系统处理 */
/*系统则调用ImeToAsciiEx,否则直接将键盘消息发到应用程序 */
/**********************************************************************/
BOOL WINAPI ImeProcessKey(HIMC hIMC,UINT uKey,LPARAM lKeyData,CONST LPBYTE lpbKeyState)
观察注释,您可以看到在个接口是用来判断用户敲击的哪个键需要处理,哪个键又应该交给系统自己处理.
如果输入法需要自己处理用户输入的键,则在这个接口中返回true,否则返回false.
#ImeProcessKey:此接口函数由输入法管理器在处理键盘事件时调用。在此函数中对键盘事件进行预处理,根据此函数的返回值,系统确定对于特定的输入上下文来说此键盘事件是否应送交输入法编辑器进行处理。如果返回TRUE,
则表示应该先把键盘消息传送到输入法编辑器进行处理,所以输入法管理器会紧接着继续调用ImeToAsciiEx函数;
如果返回FALSE,说明此消息不需要输入法编辑器进行处理,输入法管理器将其直接送到应用程序
/**********************************************************************/
/* ImeSelect() */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
BOOL WINAPI ImeSelect(HIMC hIMC,BOOL fSelect)
在这个接口中,系统通知输入法当前是否打开了输入法输入.
一般输入法启动时会调用一次,在一些软件(如EmEditor)中提供打开与关闭输入法的功能就是通过这个接口实现的.
如果打开输入法,一般会在这个接口中做一些数据的初始化工作.
#ImeSelect:此接口函数在用户打开或关闭输入法时被调用。在此函数中对输入法上下文内容进行初始化或恢复释放。在实现某个输入法编辑器的时候,可能需要对输入法上下文中包含的内容项进行扩充,扩充后的输入法上下文称为此输入法的私有上下文。在打开输入法时,函数的fSelect参数为TRUE,需要完成对标准的输入法上下文的扩充工作,申请追加内存,预设各个内容项的初值;在关闭输入法时,fSelect参数为FALSE,需要释放为私有上下文申请的附加资源;
ImeSetActiveContext:如果在某个窗口中打开了输入法编辑器,那么此接口函数会在应用程序窗口获得或失去输入焦点时被调用。在此函数中可以获取当前的输入法上下文并通知输入法编辑器用户界面窗口组件,令其刷新显示;
ImeSetCompositionString:根据参数中给出的数据,修改写作字符串。这个函数将向输入法编辑器发送一条WM_IME_COMPOSITION.
/****************************************************************************************************************/
/* function:应用程序调用这个接口来进行输入上下文的转换,输入法程序在这个接口中转换用户的输入 */
/* UINT uVKey:键值,如果在ImeInquire接口中为fdwProperty设置了属性IME_PROP_KBD_CHAR_FIRST,则高字节是输入键值*/
/* UINT uScanCode:按键的扫描码,有时两个键有同样的键值,这时需要使用uScanCode来区分 */
/* CONST LPBYTE lpbKeyState:键盘状态,包含256键的状态 */
/* LPDWORD lpdwTransKey:消息缓冲区,用来保存IME要发给应用程序的消息,第一个双字是缓冲区可以容纳的最大消息条数 */
/* UINT fuState:Active menu flag(come from msdn) */
/* HIMC hIMC:输入上下文 */
/* return : 返回保存在消息缓冲区lpdwTransKey中的消息个数 */
/****************************************************************************************************************/
UINT WINAPI ImeToAsciiEx (UINT uVKey,UINT uScanCode,CONST LPBYTE lpbKeyState,LPDWORD lpdwTransKey,UINT fuState,HIMC hIMC)
这个接口可以说是输入法最重要的部分,程序员需要在这个接口中实现编码与重码的转换,转换完成或者显示在编码窗口及重码窗口,或者发送到应用程序.
由于在这个接口中没有传入窗口句柄,如何通知输入法程序的窗口更新显示呢?当然我们可以使用全局变量,在此我个人推荐的方法是使用IME消息(没有什么道理),您将消息类型参数保存到lpdwTransKey指示的缓冲区中,User.exe会根据消息类型做相应的处理并传递到UIWnd这个窗口中.
那么如何输入文字呢?要输入文字需要3个消息配合使用,分别是WM_IME_STARTCOMPOSITIONWM_IME_COMPOSITION和WM_IME_ENDCOMPOSITION,它们分别指示开始输入编码,输入编码或者结果(视参数而异)及编码输入完成.
在开始编写输入法的时候,为了省事,我的输入法在用户确定要输入一个重码时才连续调用这3个消息以向编码器中输入文字.由于WM_IME_STARTCOMPOSITION和WM_IME_ENDCOMPOSITION需要成对使用,这种方法可以确保它们配对.
最初这种方式工作得很好,但是后来发现在一些软件中出现兼容性问题如智能五笔在遨游中就存在这个问题,在遨游中的地址栏中打开智能五笔,当需要使用回退键来删除错误输入的编码时,会发现删除的不是编码窗口中的编码而是编辑器中的文字这是因为类似遨游这类软件主动接管了按键输入如处理一些控制键,当它发现这些控制键不在WM_IME_STARTCOMPOSITION和WM_IME_ENDCOMPOSITION这两个消息之间时就自己处理控制键而不是先交给User.exe了.
因此正确的流程应该是在开始输入编码时发送WM_IME_STARTCOMPOSITION,输入结束后发送WM_IME_ENDCOMPOSITION消息.
#ImeToAsciiEx:根据输入法上下文的内容,使用输入法编辑器的转换引擎产生转换结果,将相应的字符消息放入指定缓冲区中。返回值是产生消息的条数,如果此数量大于消息缓冲区的长度,系统转而从输入法上下文的hMsgBuf项中读取消息的内容。该函数和ImeProcessKey函数一起构成了键盘输入方式下输入法编辑器转换引擎的主体;
NotifyIME:系统或(IME有意识)应用程序通知输入法编辑器根据参数修改输入法编辑器的当前状态。比如:显示/隐藏候选窗口,选定某个候选项,更新候选窗口页起始位置和页尺寸,更新输入上下文内容,修改写作串内容等等;
ImeRegisterWord:向输入法编辑器的词典里增加一个新词;
ImeUnregisterWord:把某个词从此输入法编辑器的词典里去掉;
ImeGetRegisterWordStyle:取得本输入法编辑器支持的词风格的列表;
ImeEnumRegisterWord:列出符合给定条件的所有字符串。
/**********************************************************************/
/* UIWndProc() */
/* IME UI window procedure */
/**********************************************************************/
LRESULT WINAPI UIWndProc(HWND hUIWnd, UINT message,WPARAM wParam, LPARAM lParam)
这是一个非常重要的接口,基本上一它负责各种消息的传递.一般您需要在这个接口中根据不同的消息类型,实现输入法窗口(如编码窗口,重码窗口,状态栏窗口)的显示隐藏及更新等操作.
这个接口实现的功能可能非常复杂,视情况而异,在此就不做更加深入的说明了.在使用时可以参见示例工程.
StatusWndProc:状态窗口的窗口函数.
CompWndProc:写作窗口的窗口函数.
CandWndProc:候选窗口的窗口函数.