为什么在firemonkey中的form.create之前调用form.show?

May*_*ani 5 delphi firemonkey delphi-10-seattle

每个人都知道为什么在Form.shate之前调用Form.show,如果属性Form.visible = true.

我在Delphi XE7和Delphi 10 Seattle(为Windows编译的Fmx表单)中测试过

例如:


    procedure TForm1.FormCreate(Sender: TObject);
    var
      i : integer;
    begin
      //break point here is called before if form.visible = false
      i := 0;
    end;

procedure TForm1.FormShow(Sender: TObject);
var
  i : integer;
begin
  //break point here is called before if form.visible = true
  i := 0;
end;
Run Code Online (Sandbox Code Playgroud)

J..*_*... 10

如果主窗体未设置为在设计器中可见,则调用CreateMainForm() 将强制窗体在构造完成后可见(因此在 OnCreate触发后).

procedure TApplication.CreateMainForm;
var
  I: Integer;
begin
  if FMainForm = nil then
  begin
     // here creating form...
  end;

  if FMainForm <> nil then
    FMainForm.Visible := True;  //** force visible here
end;
Run Code Online (Sandbox Code Playgroud)

否则,表单的Visible属性在调用期间设置TCommonCustomForm.Loaded(),在表单构造期间由DFM流系统调用,因此OnShow在表单变得可见时触发. OnCreate不叫,直到后建设完成,之后的DFM流式传输.

最重要的是,您不应该假设何时将执行这些事件.如果您需要控制事情发生的顺序,您需要明确地执行此操作.

  • 在展示之前必须存在(被创造)的东西并不是假设.这是一个简单的事实.VCL表单事件反映了这一点(并且有记录 - 无需假设).FMX表单的行为有所不同,因为......原因.文档声明OnCreate*首先*发生**并且**表示**表单创建时,而不是*表示*之后.记录的事件顺序忽略了甚至提到OnShow.几乎就好像他们对我认为的错误感到尴尬. (5认同)
  • @JasperSchellingerhout - 我强烈反对.当编码平台本地时,你必须考虑这些事情,但不是在使用像FireMonkey这样的东西时.作为一个跨平台*抽象**专门用于促进单源多平台开发*,您可以合理地期望FMX确保其跨平台的行为的一致性.这些是FMX事件,而不是浮出水面的平台事件.如果无法提供,则应精确记录差异,以避免有缺陷的假设.在这种情况下缺乏doc是非常难闻的味道imho. (4认同)