阅后即焚

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

此文仅记这个项目的坎坎坷坷.首次写博客,排版措辞什么的多多包涵.

说到文本编辑框必然是一个可接受输入的控件.那么我们先完成控件接受输入的功能

先创建一个控件

1 public class CodeEdit : UserControl  
2 {  
3 } 
View Code

我们的控件不应只能接受英文输入,还应该接受中文输入.所以我们使用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     }
View Code

在这里我们只要调用构造方法传入控件句柄,然后处理WndProc消息即可.

先处理控件构造方法.

1 public CodeEdit()  
2 {  
3     ImmManage = new ImmManage(this.Handle);  
4     ImmManage.InputText += Input;  
5     isInitialization = true;  
6 }  
View Code

在这里我加入了一个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 }
View Code

这时候只需要完成事件回调方法,即可获取到输入的文本了.

1 /// <summary>  
2 /// 输入事件  
3 /// </summary>  
4 /// <param name="ch"></param>  
5 private void InPut(char ch)  
6 {  
7    Console.WriteLine(ch.ToString());  
8 } 
View Code

好了,到此我们就完成文本的接收.下章我们完成文本保存

posted on 2018-01-18 21:15  阅后即焚  阅读(3058)  评论(1编辑  收藏  举报