3

我认为这一定是一个常见问题解答,但谷歌搜索并没有真正帮助。

我可以做什么,不可以做什么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()因此,我的应用程序向其自身发送 a是有意义的,UM_APPLICATION_START在创建和初始化所有表单之前它不会处理(或者,我可以只调用 fn() ,在调用之后从我的 .DPR 触发消息Application.Run();但是我更喜欢这条信息,因为它更明显——我很少查看我的 .DPR 文件)。

4

3 回答 3

7

没有明确的文档列出您在表单的 OnCreate 中可以做和不能做的所有事情。

至于 .dfm 文件是否已处理并创建了所有表单拥有的组件,是的。

我不会在您找到的代码中放置太多存储。在启动期间调用 Sleep 以使主线程等待,这绝对不是一个好习惯。如果代码想要等待另一个线程,它可以阻塞该线程,或者等待从该线程获取消息。这看起来就像是由不了解他/她在做什么的人输入的代码。并且代码从未被删除。

另一行代码是合理的:

PostMessage(Handle, UM_PROGRAM_START, 0, 0);

由于此消息已发布,因此在应用程序开始发送消息之前不会对其进行处理。当您在 .dpr 文件中调用 Application.Run 时,就会发生这种情况。这意味着与创建主表单相关的所有事情都发生在该消息被拉出队列之前。

于 2012-11-16T06:56:15.750 回答
4

我不会在 FormCreate 中添加太多初始化代码,而是将其放入单独的函数中,例如

fm := TForm.Create;
fm.Init;

问题是,FormCreate() 过程中抛出的异常不会重新抛出(只有一个 MessageBox)。这意味着,您的代码会继续运行,尽管表单未正确初始化。

于 2012-11-16T07:57:25.267 回答
2

您可以在 FormCreate 中做任何您想做的事情。但是没有消息处理程序可以使用,仅此而已。一般来说,我会在 FormCreate 中创建依赖对象并在 FormDestroy 中释放它们。我也会尽量避免耗时的初始化程序。

于 2012-11-16T06:56:44.487 回答