Delphi 程序运行的构造、加载过程 ( 积分: 200 )

  • 主题发起人 主题发起人 mosane
  • 开始时间 开始时间
M

mosane

Unregistered / Unconfirmed
GUEST, unregistred user!
请指教 Delphi 工程编译运行的过程,
如各级组件如何逐层逐个构造的,他们构造顺序,
以及资源文件(包括res、dfm等)的加载在什么时候,创建窗体在什么时候,再什么时候才开始运行我们编写的代码。

现在有个实际的问题是:
工程里有个 ADOConnection1,设计时是打开的,
即 Connected = True,请不要叫我设成 False,我必须要这么做的,
这样运行后 ADOConnection1 会自动 Connect,
而我不希望这样,用
procedure TForm1.FormCreate(Sender: TObject);
begin
ADOConnection1.Connected := False
//慢了!
//ADOConnection1.ConnectionString := '...';
//ADOConnection1.Connected := True;
end;
不起效果,程序总是在运行到这段代码之前就已经尝试 Connect 了,
那有办法在程序装载完 dfm 中 ADOConnection1 的属性值时,马上改变 Connected = False,也就不让它自动 Connect 吗?总之让它不要自动连接就是了。

诸位请指教,不尽感激。分数自然不成问题。
 
请指教 Delphi 工程编译运行的过程,
如各级组件如何逐层逐个构造的,他们构造顺序,
以及资源文件(包括res、dfm等)的加载在什么时候,创建窗体在什么时候,再什么时候才开始运行我们编写的代码。

现在有个实际的问题是:
工程里有个 ADOConnection1,设计时是打开的,
即 Connected = True,请不要叫我设成 False,我必须要这么做的,
这样运行后 ADOConnection1 会自动 Connect,
而我不希望这样,用
procedure TForm1.FormCreate(Sender: TObject);
begin
ADOConnection1.Connected := False
//慢了!
//ADOConnection1.ConnectionString := '...';
//ADOConnection1.Connected := True;
end;
不起效果,程序总是在运行到这段代码之前就已经尝试 Connect 了,
那有办法在程序装载完 dfm 中 ADOConnection1 的属性值时,马上改变 Connected = False,也就不让它自动 Connect 吗?总之让它不要自动连接就是了。

诸位请指教,不尽感激。分数自然不成问题。
 
估计做不到
DFM载入时应该是在被构造之后
而装载完DFM之后ADOCONNECTION已经完成了尝试连接的过程了
这时即使你能插手立即更改它,按你的要求也没什么意义了
真搞不懂你要干什么?不得不设为TRUE又不得让它自动连接,自相矛盾吗?!
 
很简单,从这个组件继承一个组件,
判断,如果是正在Loading, 则不激活

或者,将这个属性标记为不保存

这些方法都很简单的,但必须要继承一个新组件
 
在单元的initialization中设置ADOConnection1.Connected := False;
 
建议楼主在程序头设断点,逐步跟踪,只是需要很好的耐心,呵呵
 
还真是佩服楼主,连这么高深的问题都能想得出来,看来非得请BORLAND公司DELPHI的设计专家来解决才行呀,你也能因此得个什么"BORLAND BUG发明奖"吧
 
问题的解决方法我已经说了,我以前写组件时就是这么做的

扯到更底层,更高深的问题上也没什么好处,
除非你想学习VCL源码
 
谢谢各位的帮助。

刚写了一长段我这么做的原因,提交后出错结果什么都没了。。[:(!][:(!][:(!]

lich,
如何将一个属性标记为不保存?我学编写组件的时候没学到这一招。。

delphi 的编译是一步步的加载过程,我想,应该可以在哪个环节进行控制的。
而且,我也想深入学习 VCL 源码。
 
很简单
property Name: TComponentName read FName write SetName stored False;
 
The stored directive must be followed by True, False, the name of a Boolean field, or the name of a parameterless method that returns a Boolean value. For example,

property Name: TComponentName read FName write SetName stored False;

If a property has no stored directive, it is treated as if stored True were specified.
The default directive must be followed by a constant of the same type as the property. For example,

property Tag: Longint read FTag write FTag default 0;

To override an inherited default value without specifying a new one, use the nodefault directive. The default and nodefault directives are supported only for ordinal types and for set types, provided the upper and lower bounds of the set抯 base type have ordinal values between 0 and 31
if such a property is declared without default or nodefault, it is treated as if nodefault were specified. For reals, pointers, and strings, there is an implicit default value of 0, nil, and '' (the empty string), respectively.

When saving a component抯 state, the storage specifiers of the component抯 published properties are checked. If a property抯 current value is different from its default value (or if there is no default value) and the stored specifier is True, then the property抯 value is saved. Otherwise, the property抯 value is not saved.
 
非常感谢,

lich, 100分属于你的了,
再问一下,“判断,如果是正在Loading, 则不激活”,具体些好吗?不知道哪里是 Loading 和激活。

哪位高手再跟我说说构造、加载的过程。谢。
 
哪位高手再跟我说说构造、加载的过程。
[red]三言两语难以所清楚, 建议你看看VCL 的源代码。[/red]

在你这个问题,需要 继承一个 TAdoConnection;
我给你写了个Demo, 测试通过!

//新控件 tadoconnection1;
unit adoconnection1;

interface

uses
Windows, Messages, SysUtils, Classes, DB, ADODB;

type
tadoconnection1 = class(tadoconnection)
private
{ Private declarations }
protected
{ Protected declarations }
procedure SetConnected(Value: Boolean)
override;
public
{ Public declarations }
published
{ Published declarations }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Rui', [tadoconnection1]);
end;

{ tadoconnection1 }

procedure tadoconnection1.SetConnected(Value: Boolean);
begin
[blue]if not (csLoading in ComponentState) [/blue]then inherited;
end;

end.


//测试单元;
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, adoconnection1;

type
TForm1 = class(TForm)
cn: tadoconnection1;
procedure FormCreate(Sender: TObject);
procedure cnAfterConnect(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}


procedure TForm1.FormCreate(Sender: TObject);
begin
cn.Connected:=false;
cn.ConnectionString:='aaa';
cn.Connected:=true;
end;

procedure TForm1.cnAfterConnect(Sender: TObject);
begin
beep;
end;

end.
 
多人接受答案了。
 
后退
顶部