我认为这必须是常见问题解答,但谷歌搜索并没有真正帮助。
我可以做什么 - 可能不会 - 在FormCreate()
?
我想知道所有表单的子控件是否已完全创建并可供访问等。
我问的原因是我偶然发现了一个旧项目,FormCreate()
只包含
Sleep(1000);
PostMessage(Handle, UM_PROGRAM_START, 0, 0);
似乎我想“稍微等一下”然后做一些初始化“当事情已经稳定下来”......
当然我当时有理由(?),但是,在没有启发性评论的情况下,我无法回想起为什么我认为这是必要的。
任何人都可以陈述或引用一条链接,说明对FormCreate()
中可能做的事情的任何限制吗?
[更新]我认为DavidHefferman在撰写“应用程序开始传送消息时找到了解决方案。当您在.dpr文件中调用Application.Run时会发生这种情况。”
我想我并不关心单一表格。例如,我的主要表单想要在启动时使用我的配置/选项表单做一些事情,所以显然必须等到它被创建。
这是我的一个项目的典型.DPR ......
Application.Initialize;
Application.CreateForm(TGlobal, Global);
Application.MainFormOnTaskbar := True;
Application.CreateForm(TMainForm, MainForm);
Application.CreateForm(TLoginForm, LoginForm);
Application.CreateForm(TConfigurationForm, ConfigurationForm);
//[snip] a bunch of other forms ...
Application.Run();
因此,我的应用mainForm.CreateForm()
向自己发送UM_APPLICATION_START
是有意义的,在创建所有表单之前,它不会处理。初始化(或者,我可以在调用Application.Run()
之后调用消息从我的.DPR触发的fn();但我更喜欢消息,因为它更明显 - 我很少查看我的.DPR文件)。
答案 0 :(得分:7)
没有明确的文档列出了您可以在表单的OnCreate中执行和完成的所有操作的列表。
至于是否已经处理了.dfm文件并创建了所有表单所拥有的组件,是的,他们有。
我不会在你找到的代码中放置太多商店。在启动期间调用Sleep,使主线程等待,绝对不是好习惯。如果代码想要等待另一个线程,它可以阻塞该线程,或者等待从该线程获取消息。这看起来就像一个不明白他/她正在做什么的人投入的代码。代码永远不会被删除。
另一行代码是合理的:
PostMessage(Handle, UM_PROGRAM_START, 0, 0);
由于此消息已发布,因此在应用程序开始传送消息之前不会对其进行处理。当您在.dpr文件中调用Application.Run时会发生这种情况。这意味着与主要表单创建相关的所有内容都会在该消息从队列中删除之前发生。
答案 1 :(得分:4)
我不会在FormCreate中添加太多初始化代码,而是将其放入单独的函数中,例如
fm := TForm.Create;
fm.Init;
问题是,不会重新抛出FormCreate()过程中抛出的异常(只有MessageBox)。这意味着,虽然表单未正确初始化,但您的代码仍在运行。
答案 2 :(得分:1)
您可以在FormCreate中执行任何操作。但是没有消息处理程序可以使用,就是这样。通常,我会在FormCreate中创建依赖对象,并在FormDestroy中释放它们。我也会尽量避免耗费时间的初始化程序。