|
本帖最后由 faunus 于 2014-3-13 13:29 编辑
处理流程如下:- // MyButton.MyClick的真实处理情况是这样的:
- // 首先,向外公布一个MyClick方法变量,对这个变量的操作支持add和remove操作.
- // 当Add操作时(也就是从外边作+=操作时),将传入值写入一个列表,起个名字叫做事件列表.
- // 在MyButton内部的消息处理过程WndProc中,当截获到WM_LBUTTONUP消息时,调用WmMouseUp方法处理.
- // 在WmMouseUp实体中调用MyOnClick方法.
- // 在MyOnClick实体中,从事件列表中取到方法实例handler并调用方法.
- // MyButton.MyClick的工作原理与例4所描述的不同
- // 1.方法变量MyClick没有直接用来存放外部的方法实例,而是象属性那样,存放在一个字段_myEvents中.
- // 2.消息处理过程WndProc也没有MyClick的调用,而是在MyOnClick中调用方法字段.
- // 从本质上讲WndProc还是处理了MyClick的,但实现思路上区别很大.
- // 好像少了一个环节,MyClick在内部没实例化过.MyOnClick中进行了方法字段是否为空的判断.
- // 这说明方法变量在内部不一定需要传入实例,只要内部调用时进行非空判断就可以了.
- // 以上研究都是把方法变量当做一般变量来处理.
- // delegate与消息循环结合,这就是我们看到的事件.
- // 事件带来的效果,实现了一个对象将自己的方法公布给别人,并由别人进一步完善这个方法.
- // 这又绕回到最开始举的例子:领导委托下属做某件事!
- // 最初的例子委托用错了地方,把下属的方法定义了一个变量来调用.
- // 应该是把领导这个对象内定义一个方法变量,由下属具体实现.
- // 下一例重构最初的例子.
复制代码
消息处理过程如下:
【重载消息中心】
- protected override void WndProc(ref Message m)
- {
- base.WndProc(ref m);
- switch (m.Msg)
- {
- case WM_LBUTTONUP:
- this.WmMouseUp(ref m, System.Windows.Forms.MouseButtons.Left, 1);
- break;
- }
- }
复制代码 【加工消息参数】
- private void WmMouseUp(ref Message m, System.Windows.Forms.MouseButtons button, int clicks)
- {
- //验证状态、将传入的消息加工成事件参数
- // ...
- MouseEventArgs args = new MouseEventArgs(button, clicks, SignedLOWORD(m.LParam), SignedHIWORD(m.LParam), 0);
- this.MyOnClick(args);
- }
复制代码 【辅助函数】
- private int SignedLOWORD(IntPtr n)
- {
- return (short)((int)((long)n) & 0xffff);
- }
- private int SignedHIWORD(IntPtr n)
- {
- return (short)(((int)((long)n) >> 0x10) & 0xffff);
- }
复制代码
事件的定义部分:
【消息字段声明】
- const int WM_LBUTTONUP = 0x202;
- #region "字段声明"
- EventHandlerList _myEvents;
- object _eventClick = new object();
- #endregion
复制代码 【事件的定义】
- #region "属性定义"
- public EventHandlerList MyEvents
- {
- get
- {
- if (this._myEvents == null)
- {
- this._myEvents = new EventHandlerList();
- }
- return this._myEvents;
- }
- }
- #endregion
- #region "事件定义"
- public event EventHandler MyClick
- {
- add
- {
- Events.AddHandler(_eventClick, value);
- }
- remove
- {
- Events.RemoveHandler(_eventClick, value);
- }
- //AsyncCallback
- //Activator
- }
- #endregion
复制代码 【调用方法】
- private void MyOnClick(EventArgs e)
- {
- EventHandler handler = (EventHandler)base.Events[_eventClick];
- if (handler != null)
- {
- handler(this, e);
- }
- }
复制代码 注意:这里的handler是一个委托,将执行所有注册方法的列表。
附件(完整代码):
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|