設為首頁收藏本站Access中國

Office中國論壇/Access中國論壇

 找回密碼
 注冊

QQ登錄

只需一步,快速開始

返回列表 發(fā)新帖
查看: 10113|回復: 8
打印 上一主題 下一主題

【原創(chuàng)】RibbonButton點擊事件的真實原理

[復制鏈接]
跳轉到指定樓層
1#
發(fā)表于 2014-3-9 16:01:50 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 faunus 于 2014-3-13 13:29 編輯

處理流程如下:
  1.     // MyButton.MyClick的真實處理情況是這樣的:
  2.     // 首先,向外公布一個MyClick方法變量,對這個變量的操作支持add和remove操作.
  3.     // 當Add操作時(也就是從外邊作+=操作時),將傳入值寫入一個列表,起個名字叫做事件列表.
  4.     // 在MyButton內(nèi)部的消息處理過程WndProc中,當截獲到WM_LBUTTONUP消息時,調(diào)用WmMouseUp方法處理.
  5.     // 在WmMouseUp實體中調(diào)用MyOnClick方法.
  6.     // 在MyOnClick實體中,從事件列表中取到方法實例handler并調(diào)用方法.
  7.     // MyButton.MyClick的工作原理與例4所描述的不同
  8.     // 1.方法變量MyClick沒有直接用來存放外部的方法實例,而是象屬性那樣,存放在一個字段_myEvents中.
  9.     // 2.消息處理過程WndProc也沒有MyClick的調(diào)用,而是在MyOnClick中調(diào)用方法字段.
  10.     // 從本質(zhì)上講WndProc還是處理了MyClick的,但實現(xiàn)思路上區(qū)別很大.
  11.     // 好像少了一個環(huán)節(jié),MyClick在內(nèi)部沒實例化過.MyOnClick中進行了方法字段是否為空的判斷.
  12.     // 這說明方法變量在內(nèi)部不一定需要傳入實例,只要內(nèi)部調(diào)用時進行非空判斷就可以了.
  13.     // 以上研究都是把方法變量當做一般變量來處理.
  14.     // delegate與消息循環(huán)結合,這就是我們看到的事件.
  15.     // 事件帶來的效果,實現(xiàn)了一個對象將自己的方法公布給別人,并由別人進一步完善這個方法.
  16.     // 這又繞回到最開始舉的例子:領導委托下屬做某件事!
  17.     // 最初的例子委托用錯了地方,把下屬的方法定義了一個變量來調(diào)用.
  18.     // 應該是把領導這個對象內(nèi)定義一個方法變量,由下屬具體實現(xiàn).
  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.         }
復制代碼
【加工消息參數(shù)】
  1.         private void WmMouseUp(ref Message m, System.Windows.Forms.MouseButtons button, int clicks)
  2.         {
  3.             //驗證狀態(tài)、將傳入的消息加工成事件參數(shù)
  4.             // ...
  5.             MouseEventArgs args = new MouseEventArgs(button, clicks, SignedLOWORD(m.LParam), SignedHIWORD(m.LParam), 0);
  6.             this.MyOnClick(args);
  7.         }
復制代碼
【輔助函數(shù)】
  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
復制代碼
【調(diào)用方法】
  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是一個委托,將執(zhí)行所有注冊方法的列表。

附件(完整代碼):



本帖子中包含更多資源

您需要 登錄 才可以下載或查看,沒有帳號?注冊

x
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享分享 分享淘帖 訂閱訂閱
2#
發(fā)表于 2014-3-10 11:52:05 | 只看該作者
沒有內(nèi)容,弄沒了吧

點擊這里給我發(fā)消息

3#
發(fā)表于 2014-3-10 21:15:14 | 只看該作者
是沒有看到內(nèi)容
4#
發(fā)表于 2014-3-11 17:00:31 | 只看該作者
???
回復

使用道具 舉報

點擊這里給我發(fā)消息

5#
發(fā)表于 2014-3-11 17:07:20 | 只看該作者
老大是在逗我們玩?
6#
發(fā)表于 2014-3-13 12:34:55 | 只看該作者
隱身可見?
回復

使用道具 舉報

7#
發(fā)表于 2014-3-13 13:48:31 | 只看該作者
留個足跡,待日后學習.

點擊這里給我發(fā)消息

8#
發(fā)表于 2014-3-13 14:07:43 | 只看該作者
占個位,便于以后查詢
9#
發(fā)表于 2015-1-9 20:45:03 | 只看該作者
#在這里快速回復#沒有內(nèi)容,弄沒了吧
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則

QQ|站長郵箱|小黑屋|手機版|Office中國/Access中國 ( 粵ICP備10043721號-1 )  

GMT+8, 2025-7-17 05:59 , Processed in 0.104014 second(s), 33 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回復 返回頂部 返回列表