【问题标题】:Application.CreateForm() forms visibility / stateApplication.CreateForm() 形成可见性/状态
【发布时间】:2015-04-22 02:38:37
【问题描述】:

在创建多表单 VCL 应用程序时,使用 TApplication.CreateForm() 创建的表单的状态是什么?是否有调用 WinAPI 将它们设置为不可见状态,还是由某些 VCL 内部工作机制处理?

  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm2, Form2); // Invisible
  Application.CreateForm(TForm3, Form3); // Invisible
  Application.Run;

【问题讨论】:

  • 它们是在没有 WS_VISIBLE 样式集的情况下创建的 (CreateWindowEx),如果在调用 ShowWindow 调用可能的 OnCreate 事件处理程序后它们是“可见的”,则显示辅助表单,有趣的是在主窗体显示之前,这发生在 Application.Run 中。
  • 在我看来,您应该只调用一次 CreateForm。它的唯一目的是创建主窗体。

标签: delphi


【解决方案1】:

使用Application.CreateForm() 创建的第一个表单将成为应用程序的MainForm,如果Application.ShowMainForm 为真,主窗体的WindowState 不是wsMinimized,则将由Application.Run() 自动显示,并且未使用指定的SW_SHOWMINNOACTIVE 标志创建进程。

Application.CreateForm() 创建的所有其他表单只有在其Visible 属性设置为True 时才会自动显示。默认情况下,IDE 将辅助表单的 Visible 属性设置为 False

请注意,在应用程序启动时自动创建所有表单通常不是一个好主意。您应该从项目选项中的自动创建列表中删除第二个和第三个表单,然后在实际需要时在代码中动态创建它们。您甚至可以将 IDE 设置为默认不自动创建辅助表单。

【讨论】:

  • 创建表单总是需要相同的时间。如果您自动创建所有表单,您将始终花费时间,无论是否需要表单。因此,该应用程序将启动较慢。这不是一个很好的权衡 IMO。
  • 我明白了。但话又说回来,如果您多次调用辅助表单,您将花费更多时间为每次调用创建和销毁表单。我想这两种方式都有权衡。
  • 如果你不销毁它们,它们就不必重新创建。如果这样做,则还必须重新创建自动创建的表单。您可以通过设置CloseAction 来控制关闭的表单是隐藏还是销毁。
  • 嗯,非常非常好。不知道那个。 TCloseAction 是要走的路。谢谢mghie。
  • 这篇文章更多地讨论了 CreateForm 但它已经很老了:pages.cs.wisc.edu/~rkennedy/createform
【解决方案2】:

This 文章谈到了在其自己的 OnCreate 事件处理程序中访问表单实例的危险。避免这种情况的一种方法是避免在主窗体的 OnCreate 处理程序中进行任何初始化。等到主窗体真正准备好。为此,请向您自己发送一条消息。像这样的:

const 
   MSG_LateInitialize= WM_APP + 4711;

TMainForm = class(TForm)
    ...
    procedure LateInitialize(var Message: TMessage); message MSG_LateInitialize;
 end;

procedure TMainForm.FormCreate (Sender: TObject);
begin
 { Send custom message to self }
 PostMessage(Self.Handle, MSG_LateInitialize, 0, 0);
end;

procedure TMainForm.LateInitialize; { This is called only after the main form was fully created }
begin
  init stuff here...
end;

只要您在应用初始化期间不使用 Application.ProcessMessage 的“魔法”,它就可以工作(嘿!停止使用它,不仅在您的应用初始化期间。完全不要使用它!)。


PS: 如果您看上面,有很多样板代码需要进行基本/正确的初始化。如果 Delphi 假装安全且易于使用(确实如此),它应该为初学者提供这种功能,(隐藏)在引擎盖下。类似于名为 AfterApplicationInitialized 或 AfterFormTrullyCreated 的函数 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-21
    • 1970-01-01
    • 2019-10-14
    相关资源
    最近更新 更多