Windows消息

Windows消息

从大四开始学习Windows编程,至今已有三年时间,回顾起来,觉得这个学习过程其实就是对消息的理解过程。

最初消息给我的感觉就是一种事件通知,而窗口是通知的目的地。当键盘鼠标或者窗口的某些状态改变时,系统包装了一个消息结构,并“找到”处理消息的窗口“发送或投递”给它。有了这一层理解,就知道要在特定的时机做一些特定的事情:WM_CREATE创建所有子控件,WM_SIZE调整子控件的位置;WM_PAINT绘制客户区的内容。

后来,我沉迷于一些技巧,总喜欢作一些“特殊的效果”。有一次,我不满足只能通过标题栏拖动窗口,想在任何位置都可以拖动窗口,这个需求使我认识了WM_NCHITTEST,只要处理该消息后返回HTCAPTION,窗口就随鼠标移动了。而我也渐渐明白,消息不只作为单纯的事件通知,有时系统还会给程序机会,让它参与窗口状态的改变。最明显的例子是尺寸变化,处理WM_WINDOWPOSCHANGINGWM_GETMINMAXINFO,程序能控制尺寸变化的结果。

再后来,我经常使用标准控件开发程序,发现标准控件的操作竟然不是通过API,而是通过消息。我记不住这些消息,MSDN成了必不可少的工具,也曾抱怨MS,既然提供一批常用的标准控件,为何不将操作封成函数?很多初学Windows的程序员也有这种感觉吧,那MSG结构的成员就像汇编的EAXEDX一样没有明显的意义,全凭具体的消息赋予它们具体的含意,这让我们不得不整天寻求MSDN的帮助。但是当你站在操作系统层面去看待这个问题时,就觉得通过消息操作控件是很有必要的。操作系统的关键任务是保持兼容性和稳定性。假设我在WinXP下写了一个程序,XP的标准控件或许多了很多扩展,即使XP以下的操作系统没有这些扩展,但程序至少应该是可以跑起来的。如果控件操作是通过函数来完成的,那么会发生什么事情呢?比如我调用Edit控件的一个函数DoSomething,这个函数是XP下的EDIT控件的一个扩展,在Win2000以前是没有的,这个程序拿到Win2000下,一运行发现DLL没有这个导出函数,必定就跑不起来了。换成消息的方式就不会有这个问题,我发送一个WM_DOSOMETHING消息的EDIT控件,在XP下可以正确处理,在2000下没有这个消息不会得到处理,但是程序仍然能很好的运行。理解这个之后,反而觉得消息机制是一个伟大的发明,因为它不仅提供了很好的扩展性,还最大程度地保持系统的稳定性。当然这样做的代价是难于编程,这时界面库地出现就显得很重要了。

       我接触过的界面库主要是VCLMFCWTL。仅管具体的实现技巧各有不同,但封装的对象都是差不多的:

  1. 窗口句柄的封装。
  2. 消息的封装。
  3. 通用标准控件的封装。

简而言之,将窗口句柄封装成对象的形式,将窗口消息引入对象的成员函数,将标准控件的操作变成易懂的函数调用。

WTL是最能体现上面三点的库,也是封装得最简洁小巧的库,它没有改变Windows编程的东西,该学什么还是得学什么。第1点的结果就是一个CWindow,第3点的结果就是CEditCStatic类。第2点是CWindowImplCWindow, CEdit类似于接口,因为这是Windows已提供的东西。CWindowImpl类似于实现,因为消息可以让窗口子类化,超类化,这使得你可以实现自己的窗口或控件。

因此,所有封装的点中,我认为第2点是最重要的,对于消息的封装,将决定一个界面库的能力,这也是界面库封装的核心。

 

你可能感兴趣的:(编程,windows,汇编,XP,mfc,扩展)