【问题标题】:SDI application with multiple instances shown on taskbar任务栏上显示多个实例的 SDI 应用程序
【发布时间】:2016-06-17 17:31:35
【问题描述】:

我使用 Delphi Berlin VCL 模板创建了一个 SDI 应用程序。我可以通过编程 File|New 来创建额外的实例,如下所示:

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

只有所有者表单显示在任务栏上。此外,关闭所有者表单会关闭所有实例。如何取消链接其他实例,以便它们独立运行并单独显示在任务栏上?

【问题讨论】:

标签: delphi vcl delphi-10.1-berlin


【解决方案1】:

关闭分配为Application.MainFormTForm 会退出应用程序,这是设计使然。

如果您希望MainForm 像任何其他 SDI 窗口一样工作,并且在其他 SDI 窗口仍然打开的情况下独立关闭而不退出应用程序,则必须创建一个单独的 TForm 以充当真正的 @987654326 @ 然后对用户隐藏(在调用 Application.Run() 之前在启动时将 Application.ShowMainForm 设置为 false),然后您可以根据需要创建 TSDIAppForm 对象。当最后一个TSDIAppForm对象关闭后,您可以关闭MainForm,或者直接调用Application.Terminate()退出应用程序。

要为每个TSDIAppForm 赋予其自己的任务栏按钮,您需要重写虚拟CreateParams() 方法:

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

试试这个:

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;

【讨论】:

  • 进一步开发我的 SDI 程序,我从 TMS Software 添加了一个 TAdvStringGrid,并看到这导致创建了两个额外的表单。因此,当 Screen.FormCount 减少到 2 时终止应用程序不再起作用。因此,我将 FormDestroy 修改如下:procedure TSDIAppForm.FormDestroy(Sender: TObject); var I: Integer; NumAppSDIForms: Integer; begin NumAppSDIForms := 0; for I := 0 to Screen.FormCount - 1 do if Screen.Forms[I].UnitName = 'SDIMAIN' then Inc(NumAppSDIForms); if NumAppSDIForms = 1 then Application.Terminate; end;
  • @Duns 你有正确的 jist。不过,我会使用if Screen.Forms[i] is TSDIAppForm then
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-14
  • 1970-01-01
  • 2019-08-16
  • 2021-12-20
  • 2013-01-13
  • 1970-01-01
  • 2013-12-03
相关资源
最近更新 更多