XNA中的中文输入(二)
仅供个人学习使用,请勿转载,勿用于任何商业用途。
全屏模式下,由于GDI和DirectX会发生冲突,我们需要自己渲染IME窗口。很多人都觉得渲染IME窗口是件很复杂的事情,但仔细观察一下CustomUI或者WOW中的IME窗口,其实就是一个简单的text或者label控件而已!
只要得到IME中的字符信息,接下来就很简单了.为此,我们需要处理以下4个消息:
第一个是WM_IME_STARTCOMPOSITION,这个消息在按下第一个字符,开始一次新的字符组合时触发,可以把类似清除字符串buffer的工作放在这里。
接下来,WM_IME_COMPOSITION是一个很重要的消息。SDK文档里说“The IMM sends a WM_IME_COMPOSITION message to the application when the user enters a keystroke to change the composition string.”lParam参数说明IME发生了什么样的变化,这里我们只需关心GCS_COMPSTR或者GCS_COMPREADSTR,对于中文来说,这两个标志所表示的内容都是一致的,表示输入字符发生了变化。可以用ImmGetCompositionString获得此时的IME输入字符。
当IME窗口发生变化时,向程序发送WM_IME_NOTIFY消息,wParam参数说明发生了什么变化。一般来说只需要关心IMN_CHANGECANDIDATE,它表示IME窗口中的候选字符发生了变化。此时需要用ImmGetCandidateList获得候选字符。
最后,当完成输入时,处理WM_IME_ENDCOMPOSITION消息,同样使用ImmGetCompositionString获得最终生成的中文字符。
基本的步骤就那么简单,下面是一些实现细节,主要是P/Invoke时可能遇到的问题。首先是两个函数的声明。
public static extern int ImmGetCompositionString(IntPtr hIMC, int CompositionStringFlag, StringBuilder buffer, int bufferLength);
[DllImport("imm32.dll", CharSet = CharSet.Unicode, EntryPoint = "ImmGetCandidateList")]
public static extern uint ImmGetCandidateList(IntPtr hIMC, uint deIndex, IntPtr candidateList, uint dwBufLen);