Duns
Duns

Reputation: 438

SDI application with multiple instances shown on taskbar

I've created an SDI application using the Delphi Berlin VCL template. I can create additional instances by programming File|New as follows:

procedure TSDIAppForm.FileNew1Execute(Sender: TObject);
var
   LNewDoc: TSDIAppForm;
begin
   LNewDoc := TSDIAppForm.Create(Application);
   LNewDoc.Show;
end;

Only the owner form shows on the taskbar. Also, closing the owner form closes all the instances. How do I unlink the additional instances so that they operate independently and show individually on the taskbar?

Upvotes: 2

Views: 421

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 597265

Closing the TForm that is assigned as the Application.MainForm exits the app, that is by design.

If you want the MainForm to act like any other SDI window and be closed independently without exiting the app if other SDI windows are still open, you will have to create a separate TForm to act as the real MainForm and then hide it from the user (set Application.ShowMainForm to false at startup before Application.Run() is called), and then you can create TSDIAppForm objects as needed. When the last TSDIAppForm object is closed, you can then close the MainForm, or call Application.Terminate() directly, to exit the app.

To give each TSDIAppForm its own Taskbar button, you need to override the virtual CreateParams() method:

How can I get taskbar buttons for forms that aren't the main form?

Try this:

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TMyRealMainForm, MyRealMainForm);
  Application.CreateForm(TSDIAppForm, SDIAppForm);
  SDIAppForm.Visible := True;
  Application.ShowMainForm := False;
  Application.Run;
end.

procedure TSDIAppForm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
  Params.WndParent := 0;
end;

procedure TSDIAppForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

procedure TSDIAppForm.FormDestroy(Sender: TObject);
begin
  if Screen.FormCount = 2 then // only this Form and the MainForm
    Application.Terminate;
end;

procedure TSDIAppForm.FileNew1Execute(Sender: TObject);
var
  LNewDoc: TSDIAppForm;
begin
  LNewDoc := TSDIAppForm.Create(Application);
  LNewDoc.Show;
end;

Upvotes: 5

Related Questions