delphi组件VCL运行机制|TObject对象使用实例技巧
组件运行机制
本节将通过分析VCL 组件中的两个典型对象:TObject 和TApplication,向读者介绍VCL 库的核心知识,剖析VCL 的代码的执行。本节内容有一定难度,需要读者仔细体会。
TObject对象
因为所有的VCL 子类,都抽象自TObject 类,所以首先向读者介绍一下TObject 类,TObject 的声明如下:
TObject = class
constructor Create;
procedure Free;
class function InitInstance(Instance: Pointer): TObject;
procedure CleanupInstance;
function ClassType: TClass;
class function ClassName: ShortString;
class function ClassNameIs(const Name: string): Boolean;
class function ClassParent: TClass;
class function ClassInfo: Pointer;
class function InstanceSize: Longint;
class function InheritsFrom(AClass: TClass): Boolean;
class function MethodAddress(const Name: ShortString): Pointer;
class function MethodName(Address: Pointer): ShortString;
function FieldAddress(const Name: ShortString): Pointer;
function GetInterface(const IID: TGUID; out Obj): Boolean;
class function GetInterfaceEntry(const IID: TGUID): PInterfaceEntry;
class function GetInterfaceTable: PInterfaceTable;
function SafeCallException(ExceptObject: TObject;
ExceptAddr: Pointer): HResult; virtual;
procedure AfterConstruction; virtual;
procedure BeforeDestruction; virtual;
procedure Dispatch(var Message); virtual;
procedure DefaultHandler(var Message); virtual;
class function NewInstance: TObject; virtual;
procedure FreeInstance; virtual;
destructor Destroy; virtual;
end;
从TObject 的声明中可以看出,TObject 包含了诸如实例初始化、实例析构、RTTI、消息分发等相关实现的方法。在TObject 类中,有一个Dispatch()方法和一个DefaultHandler()方法,它们都是与消息分发机制相关的。Dispatch()负责将特定的消息分发给合适的消息处理函数。首先它会在对象本身所属的类中寻找该消息的处理函数,如果找到,则调用它;如果没有找到而该类又覆盖了TObject 的DefaultHandler(),则调用该类的DefaultHandler();如果两者都不存在,则继续在其基类中寻找,直至寻找到TObject 这一层,而TObject 已经提供了默认的DefaultHandler()方法。下面将分几部分详细讲解TObject 封装组件的原理。
TObject 提供了最基本的消息分发和处理的机制,而VCL 是在TControl 中才开始对Windows 系统消息封装的,当Windows 向应用程序发送消息时,首先接收到消息的是Control 类,然后由Control类将消息转换成VCL 的事件,进行进一步的处理。下面以鼠标消息变鼠标事件的过程来解释系统消息是如何变成事件的。