精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品开源心得,转载请注明:“锐英源www.wisestudy.cn,孙老师作品,电话13803810136。需要全文内容也请联系孙老师。
In the previous article, I discussed adding Click event on a TextBox which is applicable in Windows Forms. Unfortunately that same code will not work on smart device applications as .NET Compact Framework does not support that overridden onClick implementation of textbox. So we need to find a new workaround for it.
在前一篇文章中,我讨论了一个适用于Windows窗体的添加Click事件的文本框。不幸的是相同的代码无法在智能设备应用程序上工作,作为.NET Compact Framework不支持覆盖的onClick实现文本框。所以我们需要找到一个新的解决方案。
Compact Framework, as its name suggests, has given limited but necessary functionality and limited support of events in comparison to .NET Framework to decrease its size as it has to be available on devices which have limited resources. At the same time, they have provided few classes which you can use to implement events which you need; In our case, Click Event on TextBox. These classes capture mouse Click Messages which are handled by the machine itself. Processes of capturing an event is when the mouse button is clicked, a message is generated which is passed to the device and in return the OS returns a handle to the object which has raised an event with few other parameters. There are different structures and methods defined for the available list of window messages in the provided classes which, using a handle of object you can implement event on Control. This method of implementing events on controls is called “SubClassing a Control Using Native Callbacks”.
Compact Framework,顾名思义,和.NET框架相比,赋予有限但必要的功能和支持有限的事件来减少其尺寸。因为它在具有有限资源的设备必须是可用的。同时,他们提供了一些类,您可以使用它来实现需要的事件。在我们的示例中是文本框单击事件。这些类由机器本身捕获鼠标单击消息。捕获事件的过程是当鼠标按钮被单击时,生成一个消息传递到设备,作为结果操作系统返回一个对象句柄,这对象触发事件和其他一些参数。提供的类有不同的定义结构和方法,这服务于可用window消息列表,这些结构和方法可在有对外句柄基础上来实现事件的处理。这个在控件上实现事件的方法被称为“使用原生回调子类化一个控制”。
I have used the following classes to create a smart device control library project: 我已经使用了下列类来创建一个智能设备控件库项目:
WndProcHooker.cs
Win32.cs
You can find these classes here.
你可以在这里找到这些类。
The steps required to create the CF control library project are listed below:
创建CF控件库项目所需的步骤如下:
1.Open your Visual Studio 2005 IDE and Create New Project > In Visual C# > Smart device > Pocket PC 2003 > Select Control Library from available Templates. Name it as ClickableTextBox or whatever you like.
打开你的Visual Studio 2005 IDE然后创建新项目>在Visual c# >智能设备> Pocket PC 2003 > 从可用模板中选择控件库。将其命名为可点击文本框或任何你喜欢的。
2.Add a new *.cs class, name it as WndProcHooker and copy the contents of the downloaded WndProcHooker class into it. 添加一个新*.cs类,名字是WndProcHooker并且复制下载的WndProcHooker类的内容到*.cs中。
3.Add a new *.cs class, name it Win32 and copy the contents of the downloaded Win32 class into it. 添加一个新*.cs类,,命名为Win32并且复制下载的Win32类的内容到*.cs类。
4..Add a new Component Class and name it as ClickableTextBox. 添加一个新的组件类,命名为ClickableTextBox。
In its source code, change the base class to TextBox. Remember to change the base class to TextBox in the designer.cs class too. 在其源代码,改变文本框的基类。请记住,在designer.cs类中更改基类文本框。
5.Following is the code you need to write in the Component class:.
以下是您需要编写的组件类代码:。
public partial class ClickableTextBox : TextBox { public delegate void onClick(object sender, EventArgs e); public event onClick ClickableTextBox_Clicked; public ClickableTextBox() { InitializeComponent(); WndProcHooker.HookWndProc(this, new WndProcHooker.WndProcCallback(this.WM_LButtonDown_Handler), Win32.WM_LBUTTONDOWN); WndProcHooker.HookWndProc(this new WndProcHooker.WndProcCallback(this.WM_LButtonUp_Handler), Win32.WM_LBUTTONUP); } #region OnClick /// <span class="code-SummaryComment"><summary></span> /// The method that gets called when a WM_NOTIFY message is received by the /// TextBox's parent. /// <span class="code-SummaryComment"></summary></span> /// <span class="code-SummaryComment"><param name="hwnd">The handle of the window that received the message</span> /// <span class="code-SummaryComment"></param></span> /// <span class="code-SummaryComment"><param name="msg">The message received</param></span> /// <span class="code-SummaryComment"><param name="wParam">The wParam arguments for the message</param></span> /// <span class="code-SummaryComment"><param name="lParam">The lParam arguments for the message</param></span> /// <span class="code-SummaryComment"><param name="handled">Set to true to indicate that </span> /// this message was handled<span class="code-SummaryComment"></param></span> /// <span class="code-SummaryComment"><returns>An appropriate return code for the message handled (see MSDN)</span> /// <span class="code-SummaryComment"></returns></span> int WM_Notify_Handler( IntPtr hwnd, uint msg, uint wParam, int lParam, ref bool handled) { Win32.NMHDR nmHdr = new Win32.NMHDR(); System.Runtime.InteropServices.Marshal.PtrToStructure ((IntPtr)lParam, nmHdr); switch (nmHdr.code) { case Win32.WM_LBUTTONDOWN: case Win32.WM_LBUTTONUP: // get the cursor coordinates on the client Point msgPos = Win32.LParamToPoint((int)Win32.GetMessagePos()); msgPos = this.PointToClient(msgPos); RaiseMouseClickEvent(MouseButtons.Left, msgPos); break; default: break; } return 0; } public void OnMouseClick(MouseEventArgs e) { this.OnClick(new EventArgs()); } protected override void OnClick(EventArgs e) { base.OnClick(e); } /// <span class="code-SummaryComment"><summary></span> /// Raises the MouseClick event for the TextBox with the specified handle. /// <span class="code-SummaryComment"></summary></span> /// <span class="code-SummaryComment"><param name="hNode">The handle of the node for which the event is raised</span> /// <span class="code-SummaryComment"></param></span> /// <span class="code-SummaryComment"><param name="button">The [mouse] buttons that were pressed </span> /// to raise the event<span class="code-SummaryComment"></param></span> /// <span class="code-SummaryComment"><param name="coords">The [client] cursor coordinates </span> /// at the time of the event<span class="code-SummaryComment"></param></span> public void RaiseMouseClickEvent(MouseButtons button, Point coords) { MouseEventArgs e = new MouseEventArgs(button, 1, coords.X, coords.Y, 0); OnMouseClick(e); } // The callback called when the window receives a WM_LBUTTONDOWN // message. We capture the mouse and draw the button in the "pushed" // state. // hwnd - The handle to the window that received the // message. // wParam - Indicates whether various virtual keys are // down. // lParam - The coordinates of the cursor. // handled - Set to true if we don't want to pass this // message on to the original window procedure. // Returns zero if we process this message. int WM_LButtonDown_Handler( IntPtr hwnd, uint msg, uint wParam, int lParam, ref bool handled) { // Start capturing the mouse input. this.Capture = true; // someone clicked on us so grab the focus this.Focus(); // Fire the MouseDown event ClickableTextBox_Clicked(this, null); // We have handled this windows message and we don't want the // sub-classed window to do anything else. handled = true; return 0; } // The callback called when the window receives a WM_LBUTTONUP // message. We release capture on the mouse, draw the button in the // "un-pushed" state and fire the OnMouseUp event if the cursor was // let go of inside our client area. // hwnd - The handle to the window that received the // message // wParam - Indicates whether various virtual keys are // down. // lParam - The coordinates of the cursor // handled - Set to true if we don't want to pass this // message // on to the original window procedure // Returns zero if we process this message. int WM_LButtonUp_Handler( IntPtr hwnd, uint msg, uint wParam, int lParam, ref bool handled) { this.Capture = false; // TODO : implement your login on mouse key up event handled = true; return 0; } #endregion }Let’s examine the code in the ClickableTextBox class. 让我们来看看在可点击文本框类的代码。
In ClickableTextBox constructor, Mouse LEFT button up and Mouse LEFT Button Down events messages are hooked. 在构造函数ClickableTextBox,鼠标左按钮,鼠标左按钮事件消息被固定。
WM_Notify_Handler is the method which gets called to notify when some event is raised by mouse. This method checks for Left mouse up and down events and calls win32 function which gets the cursor position and converts them into respective client points and raises MouseClickEvent which raises OnMouseClick and finally onClick event is fired on TextBox.
WM_Notify_Handler是当某些鼠标事件触发时通知进而被调用的方法。该方法检查鼠标事件和调用win32函数,获取光标位置,将他们转换成各自的客户端,触发MouseClickEvent导致OnMouseClick最后在文本框onClick事件触发。
6.Add a delegate with public access modifier which is something like this with its handler: 添加一个委托的公共访问修饰符后,程序这样:
public delegate void onClick(object sender, EventArgs e); public event onClick Clicked;
7.WM_LButtonDown_Handler is the handler for Mouse Left button Down which I have left unimplemented. WM_LButtonDown_Handler是鼠标左键按下的处理程序,我还未实现。
8.The last function is WM_LButtonUp_Handler here. I have added handler ClickableTextBox_Clicked. That’s it. Compile the project. And you might get errors !
最后一个函数是WM_LButtonUp_Handler。我已经添加处理程序ClickableTextBox_Clicked。就是这样。编译该项目。你可能会得到错误!
If you have used MSDN downloaded WndProcHooker and Win32 classes, they don’t have the necessary libraries added at the top. Add them in the respective classes.
如果你有使用MSDN下载WndProcHooker和Win32类,他们没有必要在顶部添加库。将它们添加在各自的类。
9.Create a Test Pocket PC Application and add the ClickableTextBox.dll by right clicking on tools bar, choose Items and browse to the specified DLL. The control will be added as a drag and drop control.
创建一个测试Pocket PC应用程序并且通过工具栏上单击右键添加ClickableTextBox.dll,选择项目和浏览指定的dll。该控件将被添加为一个拖放控件。