• C#委托本质探索 五、点击事件的真实原理


    // 研究控件点击事件的真实原理
    // 这里定义了一个控件,编译后,将这个控件放到窗体上,找到MyClick事件,自己加点代码就可以测试
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.ComponentModel;
    using System.Windows.Forms;

    namespace ConsoleApplication1
    {
        class MyButton : Control
        {
            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

            #region " 私    有    方    法 "

            private void MyOnClick(EventArgs e)
            {
                EventHandler handler = (EventHandler)base.Events[_eventClick];
                if (handler != null)
                {
                    handler(this, e);
                }
            }

            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);
            }

            #endregion

            #region " 公    有    方    法 "

            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;
                }
            }

            #endregion

        }

        // 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与消息循环结合,这就是我们看到的事件.
        // 事件带来的效果,实现了一个对象将自己的方法公布给别人,并由别人进一步完善这个方法.
        // 这又绕回到最开始举的例子:领导委托下属做某件事!
        // 最初的例子委托用错了地方,把下属的方法定义了一个变量来调用.
        // 应该是把领导这个对象内定义一个方法变量,由下属具体实现.
        // 下一例重构最初的例子.
    }

  • 相关阅读:
    OpenSUSE下编译安装OpenFoam
    【一起学OpenFoam】01 OpenFoam的优势
    github+hexo搭建自己的博客网站(七)注意事项(避免read.me,CNAME文件的覆盖,手动改github page的域名)
    github+hexo搭建自己的博客网站(六)进阶配置(搜索引擎收录,优化你的url,添加RSS)
    github+hexo搭建自己的博客网站(五)进阶配置(畅言实现博客的评论)
    github+hexo搭建自己的博客网站(三)主题之外的一些基本配置(图片位置,文章目录功能)
    github+hexo搭建自己的博客网站(二)更换主题yilia
    github+hexo搭建自己的博客网站(一)基础入门
    git入门(4)团队中git保管代码常用操作
    node的包管理工具:yarn和npm
  • 原文地址:https://www.cnblogs.com/ww960122/p/1903956.html
Copyright © 2020-2023  润新知