前言
虽然C++Builder为一RAD式的程式发展工具,程式设计师在大多数情况下不需理会Windows讯息的细节,只要将心思放在软体元件的事件处理函式即可。然而由於Windows作业系统终究是一个以讯息驱动的系统,因此架构其上的的应用程式自然无法自外於系统之外,在遭遇到C++Builder没有定义的事件时,Windows讯息处理能力仍然是C++Builder程式人不可或缺的能力。
不可否认地,C++Builder所提供的事件处理能力已具备了某一程度的完备性,然而我们也必须承认,在C++Buider建构的VCL美丽新世界中,仍然不免有漏网之鱼。例如使用者自定讯息的处理,Winsock讯息的处理及一些Windows讯息如WM_NC**** 系列的讯息都是C++Builder的物件模型所未包含的。
在本文中我将告诉你如何以C++Builder来处理Windows讯息,并透过此一能力,来达成在一般VCL元件所无法做到的功能。
何谓Window讯息(Message)
大家都知道 Windows是一套以讯息驱动(Message Driven)的作业系统。然而对於讯息本身却讳莫如深,只知其然而不知其所以然,虽然C++Builder将某些Windows讯息封装於事件 (Event)系统中,但身为一个Windows程式设计师,实有必要了解Windows的讯息系统。
所谓讯息是由Windows作业系统送往程式的事件。它是系统中各个物件沟通的方式,举例来说,当移动滑鼠、按下滑鼠键、改变视窗大小时,Windows都会送出讯息以通知程式。当然,为了要辨别事件的内容,Windows系统中定义了许多的讯息,如WM_PAINT,WM_CHAR等等。
当事件发生时,Windows会判断该事件必须由那个程式接收,然後将事件以讯息的方式送往程式的视窗中。虽然在Windows系统中包含了数以百计的事件,但是作业系统并没有为各个事件设计不同的讯息结构,而是以一个一般性的结构来描述讯息,这个结构在C++Builder就称是TMessage.
当然,随着事件的不同,对於讯息的解释也有所不同,在C++Builder中也为各种常用的讯息定义了专属的结构,你可以直接使用它们来解释讯息。这些讯息定义在C++Builder目录下的Includevclmessages.hpp中,你可以决定要自行解释TMessage参数或是直接将其转换成专属的结构。很抽象吗? 我举个例子吧,以WM_NCHITTEST讯息来说,C++Builder为它定义了TWMNCHitTest的专属结构,所以你可以直接经由它来得到XPos、YPos等值。或者你也可以直接由TMessage的LParam取得其值,端看你使用的方便。仔细观察TMessage及TWMNCHitTest两个结构,你会发现它们是等价的,也就是说它们的大小是一致的,因此你可以直接用强制转型互相转换(这有点类似union的方法)。 struct TMessage
{ Cardinal Msg;
union
{ struct
{ Word WParamLo;
Word WParamHi;
Word LParamLo;
Word LParamHi;
Word ResultLo;
Word ResultHi;
};
struct
{ long WParam;
long LParam;
long Result;
};
};
};
struct TWMNCHitTest
{ Cardinal Msg;
long Unused;
union
{ struct
{ Windows::TSmallPoint Pos;
long Result;
};
struct
{ short XPos;
short YPos;
h };
};
} ;
在收到讯息後,程式必须处理该讯息,若是不处理,则可直接将它交给Windows的内定处理程序来处理之,若是程式需要传回值,也可以在此时传回,Windows会将该值传回给呼叫方。如此就完成了讯息传递的程序。
版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明!