delphi组件VCL运行机制|TApplication 对象使用实例
2.TApplication 对象
如果用户曾经应用API 编写过Windows 程序,一定知道Windows 应用程序的每一个窗口都有一个大的消息循环以及一个窗口函数(WndProc),此函数用来分发和处理消息。VCL 将这些东西隐藏起来,而重新提供了一种易用的、易理解的虚拟机制给程序员。只要代码单元中包含了Form.pas,就会得到一个对象—TApplication。TApplication 对象是VCL 提供的,在Form.pas 中可以看到如下这个定义:
var
Application:Tapplication
从表面上看,TApplication 类定义了一个应用程序的特性及行为,可以从Application 对象得到应用程序的可执行文件名称(ExeName),设置应用程序的标题(Title)等属性,也可以执行最小化(Minimize)、打开帮助文件(HelpCommand)等操作。
当创建一个默认的应用程序时,会自动得到以下几行代码:
begin
Application.Initialize;
Application.CreateForm(TForm1,Form1)
Application.Run;
End.
这几行代码很简单地展示了TApplication 的功能、初始化、创建必要的窗体及运行。
TApplication 的构造函数主要完成了两项功能,注册窗口类及窗口函数,创建Application 窗口实例。TApplication 类的Run 方法中有这样一段代码:
repeat
try
HandleMessage;
except
HandleException(Self);
end;
until Terminated;
这是主消息循环。看上去似乎没有取消息、分发消息的过程,其实它们都包含在HandleMessage()方法中了。HandleMessage()方法是对ProcessMessage()方法的调用,而在ProcessMessage()中就可以看到取消息、分发消息的动作了,以下是TApplication 中的ProcessMessage()方法的源代码,请注意其中的注释:
function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
var
Handled: Boolean;
begin
Result := False;
// 取消息
if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
begin
Result := True;
if Msg.Message <> WM_QUIT then
begin
Handled := False;
if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) and
not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
begin
// 熟悉的分发消息过程
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end
else
/ 如果取到的消息为WM_QUIT,则将Fterminate 设为真
//通知主消息循环退出
//这和WindowDemo 程序中判断GetMessage()函数返回值是否为0 等效
//如果GetMessage()函数取出的消息是WM_QUIT,它的返回值为0
FTerminate := True;
end;
end;
窗口函数是一个回调函数,它被Windows 系统所调用,其参数会给出消息编号、消息参数等信息,以便进行处理。TApplication 的Createhandle 函数将Application 窗口的窗口函数设置为WndProc()。整个WndProc()方法基本只包含了一个庞大的Case 分支,其中给出了每个消息的处理代码,“WM_”打头的为Windows 定义的窗口消息,“CM_?开头的为VCL 库自定义的消息。 需要注意的是,这里给出的WndProc 是属于TApplication 的,而每个Form 另外有自己的窗口函数。