程序启动后需要访问一些组件,但我发现从窗体的onCreate事件这样做是不好的,因为此时它们可能仍然不可用(发生访问冲突)。在任何组件中找不到onCreate事件。我错过了什么吗?
这是代码。ValueListEditor的空表单。
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.ValEdit;
type
TForm1 = class(TForm)
ValueListEditor1: TValueListEditor;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
procedure: Load;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Load;
end;
procedure Load;
begin
(Application.MainForm.FindComponent('ValueListEditor1') as TValueListEditor)
.Strings.LoadFromFile('c:\li');
end;
end.
3条答案
按热度按时间j8ag8udp1#
问题不在于你的组件还没有被创建,而在于它已经被创建了,真实的的问题在于当你的主窗体的
OnCreate
事件被触发时,Application.MainForm
属性还没有被赋值,所以你在nil
窗体指针上调用FindComponent()
。由于
Load()
仅访问TForm1
的成员,因此Load()
也应该是TForm1
的成员,然后您可以调用它,从而通过隐式Self
指针访问您的组件,该指针在窗体的OnCreate
事件期间有效,例如:无论出于何种原因,如果
Load()
必须是一个独立的过程,那么至少让它使用全局Form1
变量,在主窗体的OnCreate
事件触发之前,对Application.CreateForm()
的调用将分配该变量,例如:或者,您可以回退到在
Screen.Forms[]
数组中查找Form1
对象,例如:bz4sfanl2#
使用窗体的onShow()事件。
但是要注意,onShow()事件在每次显示表单时都会被调用,而不仅仅是第一次。
vohkndzv3#
在表单中,您应该覆盖
DoShow
方法并在那里插入代码。由于每次表单从不可见变为可见时都会调用DoShow
,因此您还应该在表单中添加布尔变量,并签入DoShow
覆盖(如果它是false
)。在这种情况下,这是第一次调用DoShow
,然后将变量设置为true
,并执行第一次需要执行的操作。请注意,在
DoShow
中表单是不可见的。如果您需要在表单可见后执行一些操作,您可以从DoShow
发布一条自定义消息,并将代码放入相应的消息处理程序中。在执行时,表单才变为可见。