C#中消息处理机制(事件与委托)

编写过Windows桌面应用程序的人都知道,微软的Windows操作系统与应用程序之间的通信绝大部分是基于消息循环机制的。在VC++中,程序使用GetMessage,TranslateMessage,DispatchMessage语句从消息队列中获取消息,转换消息并且将消息分发到目标窗口的过程函数,并由过程函数对不同的Windows消息进行分别处理。

当你将开发平台转向C#的时候,由于C#对消息进行了面向对象的封装,消息被封装成了事件,使我们对消息传送机制的理解蒙上了一层迷雾,下面我们就从实际的代码着手,抽丝剥茧,逐步了解C# WinForm中的消息处理机制.当我们新建一个WinForm程序后在Program.cs中我们看到Application.Run(new Form1());Application类具有用于启动和停止应用程序和线程以及处理Windows消息的方法。通过此语句,当前线程上开始运行标准应用程序消息循环,并使指定窗口可见,消息循环被封装进了Application类的Run()静态方法中。程序结束时调用Exit或者ExitThread来停止消息循环,程序也就随之终止。  

我们为Form1窗体中创建鼠标点击事件MyClick,程序自动为我们增加一些代码。this.MouseClick+=newSystem.Windows.Forms.MouseEventHandler(this.MyClick);上面this.MouseClick是C#中定义的鼠标单击事件。它被定义为: public event MouseEventHandler MouseClick;而MouseEventHandler的定义是publicdelegate void MouseEventHandler(object sender, MouseEventArgs e);该语句定义了一个名为MouseEventHandler的委托,那什么是委托呢?  委托类型可以理解成在C++中的函数指针,但不同的是,委托是完全面向对象的,同时封装了对象的实例和方法。本质上,委托把一个实例和该实例上的方法函数封装成一个可调用的实体,它是面向对象的、安全的.我们可以把第一句代码理解成为this.MouseClick事件添加了一个指向MyClick处理函数的函数指针。C#中事件的处理方法需要使用委托类型对事件进行注册.当然,你也可以再次调用这句语句对事件添加另一个处理函数如MyClick2,这些对该事件的处理会形成处理函数列表。则在程序运行过程中点击鼠标后在完成MyClick函数后会继续运行MyClick2函数。

由上我们可以大致猜测其封装过程: 

Application类将对象发送过来的消息从应用程序消息队列中提取出来后,分发到相应的窗体,并转换成事件。NET框架定义了一个特殊的类型(Delegate委托),该类型提供函数指针的功能。这样,委托就等效于一个类型安全的函数指针或一个回调函数。C#中通过Delegate委托机制将事件与响应函数的函数地址关联起来,并形成一种函数指针列表,当消息到来的时候,即可通过这些函数指针列表逐一调用这些响应函数。我们通过以下方法自定义一个事件触发,来验证我们以上的猜测。我们通过手动添加代码来实现自定义的代理事件(同VC++中的自定义消息) 

1、声明事件委托。此处int para仅是方便实验,代表所需要的参数列表,但要注意参数列表需要和第3步的参数列表相统一。 public delegate void MyEventHandler(int para);

 2、声明事件,event 关键字用于在发行者类中声明事件,委托MyEventHandler作为事件的类型。 public event MyEventHandler MyEvent;

3、添加事件的处理程序(响应事件的方法)。public void OnMyEvent(int para) { MessageBox.Show(""事件触发,参数为:""+para);}

 4、将指定的事件处理程序邦定到要处理的事件上(订阅事件),注意,此语句需要写在程序执行语句中,如Form_Lord函数内。 this.MyEvent += new MyEventHandler(OnMyEvent);

 5、触发事件(调用事件的触发方法)。MyEvent(3); 

 6、通过事件委托的回调,执行我们需要的事件处理程序。弹出消息框“事件触发,参数为:3”。

 以上实验可以得出结论,C#中的消息通过Application转换成事件以后,通过以上6个步骤完成了事件与处理程序之间的对应关系,在用户触发事件以后,相应的时间处理程序得到准确执行。也可通过以上方法,增加用户自定义事件。

 


你可能感兴趣的:(学习摘录)