设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

返回列表 发新帖
查看: 9582|回复: 8
打印 上一主题 下一主题

【原创】RibbonButton点击事件的真实原理

[复制链接]
跳转到指定楼层
1#
发表于 2014-3-9 16:01:50 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
本帖最后由 faunus 于 2014-3-13 13:29 编辑

处理流程如下:
  1.     // MyButton.MyClick的真实处理情况是这样的:
  2.     // 首先,向外公布一个MyClick方法变量,对这个变量的操作支持add和remove操作.
  3.     // 当Add操作时(也就是从外边作+=操作时),将传入值写入一个列表,起个名字叫做事件列表.
  4.     // 在MyButton内部的消息处理过程WndProc中,当截获到WM_LBUTTONUP消息时,调用WmMouseUp方法处理.
  5.     // 在WmMouseUp实体中调用MyOnClick方法.
  6.     // 在MyOnClick实体中,从事件列表中取到方法实例handler并调用方法.
  7.     // MyButton.MyClick的工作原理与例4所描述的不同
  8.     // 1.方法变量MyClick没有直接用来存放外部的方法实例,而是象属性那样,存放在一个字段_myEvents中.
  9.     // 2.消息处理过程WndProc也没有MyClick的调用,而是在MyOnClick中调用方法字段.
  10.     // 从本质上讲WndProc还是处理了MyClick的,但实现思路上区别很大.
  11.     // 好像少了一个环节,MyClick在内部没实例化过.MyOnClick中进行了方法字段是否为空的判断.
  12.     // 这说明方法变量在内部不一定需要传入实例,只要内部调用时进行非空判断就可以了.
  13.     // 以上研究都是把方法变量当做一般变量来处理.
  14.     // delegate与消息循环结合,这就是我们看到的事件.
  15.     // 事件带来的效果,实现了一个对象将自己的方法公布给别人,并由别人进一步完善这个方法.
  16.     // 这又绕回到最开始举的例子:领导委托下属做某件事!
  17.     // 最初的例子委托用错了地方,把下属的方法定义了一个变量来调用.
  18.     // 应该是把领导这个对象内定义一个方法变量,由下属具体实现.
  19.     // 下一例重构最初的例子.
复制代码

消息处理过程如下:
【重载消息中心】
  1.         protected override void WndProc(ref Message m)
  2.         {
  3.             base.WndProc(ref m);
  4.             switch (m.Msg)
  5.             {
  6.                 case WM_LBUTTONUP:
  7.                     this.WmMouseUp(ref m, System.Windows.Forms.MouseButtons.Left, 1);
  8.                     break;
  9.             }
  10.         }
复制代码
【加工消息参数】
  1.         private void WmMouseUp(ref Message m, System.Windows.Forms.MouseButtons button, int clicks)
  2.         {
  3.             //验证状态、将传入的消息加工成事件参数
  4.             // ...
  5.             MouseEventArgs args = new MouseEventArgs(button, clicks, SignedLOWORD(m.LParam), SignedHIWORD(m.LParam), 0);
  6.             this.MyOnClick(args);
  7.         }
复制代码
【辅助函数】
  1.         private int SignedLOWORD(IntPtr n)
  2.         {
  3.             return (short)((int)((long)n) & 0xffff);
  4.         }

  5.         private int SignedHIWORD(IntPtr n)
  6.         {
  7.             return (short)(((int)((long)n) >> 0x10) & 0xffff);
  8.         }
复制代码

事件的定义部分:
【消息字段声明】
  1.         const int WM_LBUTTONUP = 0x202;

  2.         #region "字段声明"
  3.         EventHandlerList _myEvents;
  4.         object _eventClick = new object();
  5.         #endregion
复制代码
【事件的定义】
  1.         #region "属性定义"
  2.         public EventHandlerList MyEvents
  3.         {
  4.             get
  5.             {
  6.                 if (this._myEvents == null)
  7.                 {
  8.                     this._myEvents = new EventHandlerList();
  9.                 }
  10.                 return this._myEvents;
  11.             }
  12.         }
  13.         #endregion

  14.         #region "事件定义"
  15.         public event EventHandler MyClick
  16.         {
  17.             add
  18.             {
  19.                 Events.AddHandler(_eventClick, value);
  20.             }

  21.             remove
  22.             {
  23.                 Events.RemoveHandler(_eventClick, value);
  24.             }
  25.             //AsyncCallback
  26.             //Activator
  27.         }

  28.         #endregion
复制代码
【调用方法】
  1.         private void MyOnClick(EventArgs e)
  2.         {
  3.             EventHandler handler = (EventHandler)base.Events[_eventClick];
  4.             if (handler != null)
  5.             {
  6.                 handler(this, e);
  7.             }
  8.         }
复制代码
注意:这里的handler是一个委托,将执行所有注册方法的列表。

附件(完整代码):



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享分享 分享淘帖 订阅订阅
9#
发表于 2015-1-9 20:45:03 | 只看该作者
#在这里快速回复#没有内容,弄没了吧

点击这里给我发消息

8#
发表于 2014-3-13 14:07:43 | 只看该作者
占个位,便于以后查询
7#
发表于 2014-3-13 13:48:31 | 只看该作者
留个足迹,待日后学习.
6#
发表于 2014-3-13 12:34:55 | 只看该作者
隐身可见?
回复

使用道具 举报

点击这里给我发消息

5#
发表于 2014-3-11 17:07:20 | 只看该作者
老大是在逗我们玩?
4#
发表于 2014-3-11 17:00:31 | 只看该作者
???
回复

使用道具 举报

点击这里给我发消息

3#
发表于 2014-3-10 21:15:14 | 只看该作者
是没有看到内容
2#
发表于 2014-3-10 11:52:05 | 只看该作者
没有内容,弄没了吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-12-1 20:32 , Processed in 0.092867 second(s), 34 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表