1

我正在学习 C#。我正在浏览语言的事件和代表部分。我正在开发一个用于自学的 WinForms 应用程序。我尝试深入了解按钮及其工作原理。我发现了以下内容:

1) 我的默认 Form1.cs 文件中有一行public partial class Form1 : Form。这是一个部分类。

2) 我还有一个 Form1.Designer.cs 类文件,它有一行partial class Form1。现在 1) 和 2) 中提到的文件组合成一个完整的类。

3)From1.Designer.cs文件有很多最终创建按钮对象的语句。它还有一个我特别感兴趣的声明:

this.btn_BaseBuildLocation.Click += new System.EventHandler(this.btn_BaseBuildLocation_Click);

此语句将自定义函数添加到委托 Click。此委托在 Control 类 (System.Windows.Forms.dll) 中声明如下:

public event EventHandler Click;

4) EventHandler 是在 System.EventHandler.cs (mscorlib.dll) 中定义的委托。

5) Button 类继承了 Control 类,因此可以访问 Click EventHandler。

6) Button 类一旦知道有人点击了它,就拥有处理流程的所有逻辑。我查看了 Mono 中使用的 Button 类以了解内部细节。我对几乎所有我想学习的课程都这样做。

7) 这一切都非常美丽。但困扰我的是,我不知道 Button 对象是如何知道它被点击的。

8) 我浏览了 VC++ 以及它如何处理事件。我发现了很多关于消息循环、事件队列等的信息......

问题:

1) VC++ 处理事件的方式是否与.NET 相同?

2)如果是这样,有没有办法调查这些细节?

任何帮助,将不胜感激。谢谢。

4

4 回答 4

2

从技术上讲,按钮是一个窗口。它有一个窗口句柄。

这意味着 Dispatcher 将在适当的时候将键盘和鼠标事件路由到 Button。Button 具有内部逻辑来确定 MouseDown 和 MouseUp 事件何时构成有效单击,然后引发 Click 事件。

于 2013-07-15T07:56:57.083 回答
2
  1. 1) Is the VC++ way of handling events the same as .NET's?

    是的,显然,处理是相同的,它是通过捕获窗口消息并相应地响应来完成的。.Net 提供了一个围绕窗口句柄“NativeWindow 类”的包装器,它是一个的低级封装Window Handle,System.Windows.Forms.Control 是所有控件的基类,它在内部使用NativeWindow命名的后代,ControlNativeWindow它将所有消息传递给控件。

  2. 如果是这样,有没有办法查看这些细节?

    是的,通过反射器深入控制类

希望这可以帮助

于 2013-07-15T08:21:35.327 回答
1

在 WinForm 应用程序中,您有带有 Main 方法的 Program 类。那里总是有一行:

Application.Run(new YourMainForm());

它开始在当前线程上运行标准应用程序消息循环。这是事件的“起点”。

这个问题的回答很好地解释了它,并且还链接到了一些来源

于 2013-07-15T08:03:43.893 回答
1

WinFormsButton是围绕非托管 Windows 类型的托管包装器,它通过一组 Win32 API 调用创建和管理,.NET 在这些 API 调用上执行 P/Invoke。

在深处,该按钮订阅了相同的窗口事件循环(或消息泵,如果您愿意),它驱动您可能在 VC++ 示例中看到的 Win32 API 调用。非托管 Windows 运行时将事件(如“已单击此按钮”)放入事件队列。当循环执行时,排队的事件被相关控件拾取并传播到“托管”事件中,此时您可以观察它。

从本质上讲,Windows 运行时提供了大部分基础设施,而 .NET 只提供了一组方便的包装器,这使得使用笨重的旧 Win32 库变得容易。

如果您使用Reflector并深入研究ButtonControl查看 .NET 代码的结束位置和非托管 Win32 调用的开始位置,您可以自己发现很多。

于 2013-07-15T09:21:29.863 回答