none
事件?我想知道我点击了按钮,它怎么就能触发Click事件呢? RRS feed

答案

  • 分两个方面。1、.NET 的 Click 响应;2、操作系统的 WM_LBUTTONDOWN 响应。

    具体说来:

    1、用户点击一个 Button,操作系统向该 Button 的父窗口 (注意,不是窗体) 发送 WM_LBUTTONDOWN 消息。
    2、.NET 根据其事件触发机制,找到 Click 事件的事件处理程序
    3、保存这个事件处理程序的句柄
    4、由于每个 Window 必须有一个 WndProc 方法,.NET 会在其默认的 WndProc 方法中响应操作系统级别的 WM_LBUTTONDOWN 消息。比如:

    void WndProc(IntPtr handle, nit msg, IntPtr wParam, IntPtr lParam)
    {
        if (msg == WM_LBUTTONDOWN)
        {
            if (handle == this.button.Handle)
            {
                if (this.button.Click != null)
                {
                    this.button.Click(this, EventArgs.Empty);
                }
            }
        }
    }

    上面的伪代码解释了操作系统如何处理来自子窗口的特定消息。

    所以可见,.NET 并不直接处理一些标准 Windows 控件的标准消息,它只是对标准的 Windows 控件包了一层,使用起来方便, 避免直接写 SendMessage 等 P/Invoke 而已。

    如果需要了解更多 Windows 怎么处理消息,如单击,关闭等。请参考 MSDN 的 Windows 消息、消息机制、消息泵、消息循环、SendMessage 等内容。


    Mark Zhou
    2011年9月12日 9:31

全部回复

  • 可能这个问题有些傻,虽然有了一年多的Click之类的控件事件,最近在想,我点击了按钮,怎么它就触发了Click事件呢?

    这个东西经常在用,但是要解释其原理很复杂。

    简单来说,Click事件可以理解成为被NET封装在底层的一个基本按钮方法。假设某个Button中存在这样一个方法:

    public class Button

    {

        public event EventHandler ClickHandler;

        public void Click()

        {

             …………

             ClickHandler(this,null);   //此处调用Click事件

        }

    }

    使用方法:

    当鼠标点击按钮时候,Windows内部自动调用传递消息,调用Click方法。执行完毕之后,自动调用Clickhandler事件。这个事件又是一个委托,在外部已经有对应的方法“定义”被挂钩了。因此触发了外部的ClickHandler事件。


    如果你有其它意见或私下交流,请直接发送maledong_work@foxmail.com;或者讨论(Talk)
    If you do not have QQ, please open the page and download it and click the image to talk or leave message for me.
    下载MSDN桌面工具(Vista,Win7)
    下载Technet桌面小工具(Vista,Win7)
    慈善点击,点击此处
    2011年9月11日 3:28
    版主
  • 分两个方面。1、.NET 的 Click 响应;2、操作系统的 WM_LBUTTONDOWN 响应。

    具体说来:

    1、用户点击一个 Button,操作系统向该 Button 的父窗口 (注意,不是窗体) 发送 WM_LBUTTONDOWN 消息。
    2、.NET 根据其事件触发机制,找到 Click 事件的事件处理程序
    3、保存这个事件处理程序的句柄
    4、由于每个 Window 必须有一个 WndProc 方法,.NET 会在其默认的 WndProc 方法中响应操作系统级别的 WM_LBUTTONDOWN 消息。比如:

    void WndProc(IntPtr handle, nit msg, IntPtr wParam, IntPtr lParam)
    {
        if (msg == WM_LBUTTONDOWN)
        {
            if (handle == this.button.Handle)
            {
                if (this.button.Click != null)
                {
                    this.button.Click(this, EventArgs.Empty);
                }
            }
        }
    }

    上面的伪代码解释了操作系统如何处理来自子窗口的特定消息。

    所以可见,.NET 并不直接处理一些标准 Windows 控件的标准消息,它只是对标准的 Windows 控件包了一层,使用起来方便, 避免直接写 SendMessage 等 P/Invoke 而已。

    如果需要了解更多 Windows 怎么处理消息,如单击,关闭等。请参考 MSDN 的 Windows 消息、消息机制、消息泵、消息循环、SendMessage 等内容。


    Mark Zhou
    2011年9月12日 9:31