Jump to content
markus_ja

How to disable, that all forms are created at startup?

Recommended Posts

Hello,

 

I just recognized, that all forms are created at startup, although I disabled all "auto" options in Project Options > Forms.

 

If I delete the initialization code Forms.RegisterForm(), an error message pops up at startup: "ClassType is nil"

 

Is this as designed or a bug? How can I disable, that all my forms are created at startup?

I have a lot of forms and want to optimize the startup time.

 

IE11 has a very high CPU load at startup. You have to wait some seconds (>10 sec) in order it performs well. Not sure if it is related to that that issue.

Share this post


Link to post
Share on other sites

It seems the TApplicationFormsList.AutoCreateForm doesn't check the IsAutoCreated flag.

{ **************************************************************************** }
{ TApplicationFormsList                                                        }
{ **************************************************************************** }

procedure TApplicationFormsList.AutoCreateForm(aFormInfo: TApplicationFormInfo);
begin
  if not Assigned(aFormInfo.Instance) then
  begin
    aFormInfo.Instance := aFormInfo.FormClass.Create(FFormOwner);
    Application.RegisterFormInstance(aFormInfo.Instance, aFormInfo.IsMainForm);
  end;
  aFormInfo.InitialAutoCreateDone := true;
end;

procedure TApplicationFormsList.AutoCreateForms(owner: TW3Component);
begin
  FFormOwner := owner;

  FNextAutoCreate := 0;
  for var info in FList do begin
    //ERROR: It creates the form regardless the info.IsAutoCreated flag!!
    AutoCreateForm(info);
    Inc(FNextAutoCreate);
    if info.IsMainForm then //ERROR?: Why to exit the loop here?
      break;
  end;

  w3_SetTimeout(AutoCreateNextForm, 50);
end;

It also looks strange, that if it is the MainForm, the AutoCreateForm stops. That means, that not all forms are auto created and the Project Options > Forms settings are ignored!

Share this post


Link to post
Share on other sites

Did some more investigations:

procedure TApplicationFormsList.AutoCreateForms(owner: TW3Component);
begin
  FFormOwner := owner;

  FNextAutoCreate := 0;
  for var info in FList do begin
    AutoCreateForm(info);
    Inc(FNextAutoCreate);
    if info.IsMainForm then
      break;
  end;

  w3_SetTimeout(AutoCreateNextForm, 50);
end;

procedure TApplicationFormsList.AutoCreateNextForm;
begin
  for var iForm := FNextAutoCreate to FList.High do begin
    var info := FList[iForm];
    if info.IsAutoCreated and (not assigned(info.Instance)) and (not info.InitialAutoCreateDone) then
    begin
      AutoCreateForm(info);
      Inc(FNextAutoCreate);
      if FNextAutoCreate < FList.High then
        w3_SetTimeout(AutoCreateNextForm, 50);
      break; //for iForm
    end;
  end;
end;

This code doesn't make sense to me. I think there is something broken and some copy past smells.

 

All forms which are before the main form (in FList) are always created immediately. Afterwards, all other forms are checked if they are AutoCreated and created with a delay.

 

Why Inc(FNextAutoCreate) and not FNextAutoCreate := iForm?

 

Please review and refactor that code for the final build!

Share this post


Link to post
Share on other sites

Hi.

This bug will be fixed. I am not sure what went wrong there, but we are investigating it.

 

As for copy & paste, that is not the case here.

Javascript is async, nothing is ever created "at once".

No control or form is ever ready until after the constructor has finished, the prototype constructed and finally injected into the DOM.

 

This is why the callback and setTimeOut calls are there.

The second procedure checks if the form already exists or is being created to avoid possible duplication, just in case someone calls this method by mistake.

 

After changing project options, did you remember to save the project before compiling & running it again?

 

 

Share this post


Link to post
Share on other sites

Yes, I saved everything. In my current project I create all forms on demand, so I disabled all "auto" create options. But when the project is started all forms are created (all html elements are created). I can see it in the HTML inspector, when debugging the project.

Share this post


Link to post
Share on other sites

I added the following line, and now it works as expected:

procedure TApplicationFormsList.AutoCreateForm(aFormInfo: TApplicationFormInfo);
begin
  if not Assigned(aFormInfo.Instance)
    and aFormInfo.IsAutoCreated //markus_ja - Added
  then
  begin
    aFormInfo.Instance := aFormInfo.FormClass.Create(FFormOwner);
    Application.RegisterFormInstance(aFormInfo.Instance, aFormInfo.IsMainForm);
  end;
  aFormInfo.InitialAutoCreateDone := true;
end;

There was no IsAutoCreated check.

 

I hope this will be fixed in the next hotfix!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×