此文僅記這個項目的坎坎坷坷.首次寫博客,排版措辭什么的多多包涵.
說到文本編輯框必然是一個可接受輸入的控件.那么我們先完成控件接受輸入的功能
先創建一個控件

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 }
好了,到此我們就完成文本的接收.下章我們完成文本保存