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