利用IME完成接收输入法输入功能.

匿名 (未验证) 提交于 2019-12-02 22:06:11

调用windows的imm32.dll完成窗体接收输入法功能.

代码如下

   /// <summary>     /// 输入法组件     /// </summary>     class ImeComponent     {         #region Event         /// <summary>         /// 输入文本事件         /// </summary>         public delegate void InputTextEvent(string text);         /// <summary>         /// 输入文本事件         /// </summary>         public event InputTextEvent InputText;         #endregion          #region PrivateField         IntPtr hIMC;         IntPtr handle;         private const int WM_IME_SETCONTEXT = 0x0281;         private const int WM_IME_CHAR = 0x0286;         private const int WM_CHAR = 0x0102;         private const int WM_IME_COMPOSITION = 0x010F;         private const int GCS_RESULTSTR = 0x0800;         private const int GCS_COMPSTR = 0x0008;         #endregion          #region Construction         public ImeComponent(UserControl control)         {             var handle = control.Handle;             hIMC = ImmGetContext(handle);             this.handle = handle;         }         #endregion          #region Method         /// <summary>         /// 输入事件         /// </summary>         /// <param name="m"></param>         public void ImmOperation(Message m)         {             if (m.Msg == ImeComponent.WM_IME_SETCONTEXT && m.WParam.ToInt32() == 1)             {                 this.ImmAssociateContext(handle);             }             else if (m.Msg == WM_IME_COMPOSITION)             {                 var res = m.WParam.ToInt32();                 string text = CurrentCompStr(this.handle);                 if (!string.IsNullOrEmpty(text))                 {                     InputText(text);                 }             }             else if (m.Msg == WM_CHAR)             {                 char inputchar = (char)m.WParam;                 if (inputchar > 31 && inputchar < 127)                 {                     InputText(inputchar.ToString());                 }             }         }         /// <summary>         /// 当前输入的字符串流         /// </summary>         /// <param name="handle"></param>         /// <returns></returns>         public string CurrentCompStr(IntPtr handle)         {             try             {                 int strLen = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, null, 0);                 if (strLen > 0)                 {                     var buffer = new byte[strLen];                     ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, buffer, strLen);                     return Encoding.Unicode.GetString(buffer);                 }                 else                 {                     return string.Empty;                 }             }             finally             {                 ImmReleaseContext(handle, hIMC);             }         }         #endregion          #region Win Api         /// <summary>         /// 建立指定输入环境与窗口之间的关联         /// </summary>         /// <param name="hWnd"></param>         /// <returns></returns>         private IntPtr ImmAssociateContext(IntPtr hWnd)         {             return ImeComponent.ImmAssociateContext(hWnd, hIMC);         }          [DllImport("imm32.dll")]         public static extern IntPtr ImmGetContext(IntPtr hWnd);         [DllImport("Imm32.dll")]         public static extern bool ImmReleaseContext(IntPtr hWnd, IntPtr hIMC);         [DllImport("Imm32.dll")]         private static extern IntPtr ImmAssociateContext(IntPtr hWnd, IntPtr hIMC);         [DllImport("imm32.dll", CharSet = CharSet.Auto)]         private static extern int ImmCreateContext();         [DllImport("imm32.dll", CharSet = CharSet.Auto)]         private static extern bool ImmDestroyContext(int hImc);         [DllImport("imm32.dll", CharSet = CharSet.Auto)]         private static extern IntPtr SetFocus(IntPtr hWnd);         [DllImport("Imm32.dll", CharSet = CharSet.Unicode)]         private static extern int ImmGetCompositionStringW(IntPtr hIMC, int dwIndex, byte[] lpBuf, int dwBufLen);         [DllImport("imm32.dll")]         static extern int ImmGetCompositionString(IntPtr hIMC, int dwIndex, StringBuilder lPBuf, int dwBufLen);         #endregion     }

此外还需要重构一下窗体或控件的WndProc方法

代码如下:

     /// <summary>         /// win消息         /// </summary>         /// <param name="m"></param>         protected override void WndProc(ref Message m)         {             base.WndProc(ref m);             if (isInitialization)             {                 this.imeComponent.ImmOperation(m); //输入法             }         }

需要注意的是要保证输入法组件在实例化之后才会执行对象的ImmOperation方法.

这样修改之后绑定事件即可接收到键盘输入.

水平有限难免有所纰漏,如有错误请留言指出.=_=

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!