此文仅记这个项目的坎坎坷坷.首次写博客,排版措辞什么的多多包涵.
说到文本编辑框必然是一个可接受输入的控件.那么我们先完成控件接受输入的功能
先创建一个控件
1 public class CodeEdit : UserControl 2 { 3 }
我们的控件不应只能接受英文输入,还应该接受中文输入.所以我们使用ImmAssociateContext来获取输入.
创建Imm类来完成接收输入.
1 class ImmManage 2 { 3 #region 事件 4 /// <summary> 5 /// 输入文本事件 6 /// </summary> 7 public delegate void EventInputText(char ch); 8 /// <summary> 9 /// 输入文本事件 10 /// </summary> 11 public event EventInputText InputText; 12 #endregion 13 14 #region 私有字段 15 IntPtr hIMC; 16 IntPtr handle; 17 private const int WM_IME_SETCONTEXT = 0x0281; 18 private const int WM_CHAR = 0x0102; 19 #endregion 20 21 #region 构造方法 22 public ImmManage(IntPtr handle) 23 { 24 hIMC = ImmGetContext(handle); 25 this.handle = handle; 26 } 27 #endregion 28 29 #region 方法 30 /// <summary> 31 /// 输入事件 32 /// </summary> 33 /// <param name="m"></param> 34 public void ImmOperation(Message m) 35 { 36 if (m.Msg == ImmManage.WM_IME_SETCONTEXT && m.WParam.ToInt32() == 1) 37 { 38 this.ImmAssociateContext(handle); 39 } 40 if (m.Msg == WM_CHAR) 41 { 42 KeyEventArgs e = new KeyEventArgs(((Keys)((int)((long)m.WParam))) | Control.ModifierKeys); 43 InputText((char)e.KeyData);//触发输入事件 44 } 45 } 46 #endregion 47 48 #region Win Api 49 /// <summary> 50 /// 建立指定输入环境与窗口之间的关联 51 /// </summary> 52 /// <param name="hWnd"></param> 53 /// <returns></returns> 54 private IntPtr ImmAssociateContext(IntPtr hWnd) 55 { 56 return ImmManage.ImmAssociateContext(hWnd, hIMC); 57 } 58 59 [DllImport("Imm32.dll")] 60 private static extern IntPtr ImmGetContext(IntPtr hWnd); 61 [DllImport("Imm32.dll")] 62 private static extern IntPtr ImmAssociateContext(IntPtr hWnd, IntPtr hIMC); 63 [DllImport("imm32.dll", CharSet = CharSet.Auto)] 64 private static extern int ImmCreateContext(); 65 [DllImport("imm32.dll", CharSet = CharSet.Auto)] 66 private static extern bool ImmDestroyContext(int hImc); 67 [DllImport("imm32.dll", CharSet = CharSet.Auto)] 68 private static extern IntPtr SetFocus(IntPtr hWnd); 69 [DllImport("Imm32.dll", CharSet = CharSet.Unicode)] 70 private static extern int ImmGetCompositionStringW(IntPtr hIMC, int dwIndex, byte[] lpBuf, int dwBufLen); 71 #endregion 72 }
在这里我们只要调用构造方法传入控件句柄,然后处理WndProc消息即可.
先处理控件构造方法.
1 public CodeEdit() 2 { 3 ImmManage = new ImmManage(this.Handle); 4 ImmManage.InputText += Input; 5 isInitialization = true; 6 }
在这里我加入了一个isInitialization变量,用来防止ImmManage类未创建时调用实体中的方法.同时注册输入事件.
处理Win消息
1 protected override void WndProc(ref Message m) 2 { 3 base.WndProc(ref m); 4 if (isInitialization) 5 { 6 this.ImmManage.ImmOperation(m); //输入法 7 } 8 }
这时候只需要完成事件回调方法,即可获取到输入的文本了.
1 /// <summary> 2 /// 输入事件 3 /// </summary> 4 /// <param name="ch"></param> 5 private void InPut(char ch) 6 { 7 Console.WriteLine(ch.ToString()); 8 }
好了,到此我们就完成文本的接收.下章我们完成文本保存