Delphi,如何制作独立的窗口

Roy*_*ver 10 forms delphi user-interface tabs

我有一个使用Chrome浏览器等标签的应用程序.现在我希望能够打开更多表格而不仅限于一种表格.这些表格应该是相同的,但如果我关闭主表格,所有表格都将被关闭.如何使所有表格都相同,所以无论我关闭哪种表格,只关闭该表格而不是在所有表格关闭之前退出申请表?有任何想法吗?

我的探险家的形象

亲切的问候Roy M Klever

Zoë*_*son 16

这样做并不难,尽管它会根据你想要的完整程度而迅速变得复杂.让多个模态对话框独立工作是一项艰巨的任务.

首先,您需要完全避免Application.MainForm.总是用Form := TMyForm.Create(Application)而不是Application.CreateForm(TMyForm, Form).后者设置了MainForm,你永远不希望这种情况发生.

要使事情正常关闭,您需要在表单的OnClose事件处理程序中执行以下操作:

if Screen.FormCount = 1 then
  Application.Terminate;
CloseAction := caFree;
Run Code Online (Sandbox Code Playgroud)

Application.Run 依赖于MainForm的分配,所以在你的DPR中用这个循环替换该行:

repeat
  try
    Application.HandleMessage;
  except
    Application.HandleException(Application);
  end;
until Application.Terminated;
Run Code Online (Sandbox Code Playgroud)

有几种方法可以处理任务栏条目.

  1. 单个任务栏条目:将使用Set Application.MainFormOnTaskbar := False;和隐藏的TApplication句柄.单击任务栏条目将使所有窗口都显示在前面.您需要覆盖Application.OnMessage或添加TApplicationEvents组件,并WM_CLOSE使用Msg.Handle = Application.Handle`进行监视.在这种情况下,用户右键单击任务栏并选择关闭,因此您应该关闭所有窗口.

  2. 多个任务栏条目:设置Application.MainFormOntaskbar := True.覆盖表单的CreateParams方法并设置Params.WndParent := 0;.每个任务栏条目都将控制该表单.

可能还有其他一些问题,但这是基础知识.


正如我所说,制作ShowModalTOpenDialog/TSaveDialog独立工作,所以它只影响其父形式,因此可以同时打开多个对话框,是一大堆工作,我不能真正推荐它.如果你是一个受虐狂,这里是一般步骤:

  1. 替换TCustomForm.ShowModal为自定义版本.除此之外,该例程禁用了应用程序中的所有其他窗口,因此您需要替换DisableTaskWindows/EnableTaskWindows调用EnableWindow(Owner.Handle, False/True)以仅禁用父窗体.此时,您可以打开多个对话框,但它们只能以后进先出顺序关闭,因为调用最终是递归的.如果没关系,请停在这里.

    有两种方法可以解决这个问题:

    1. 而不是ShowModal阻塞,拥有StartModalEndModal具有ShowModal代码的第一位和最后一位的例程,并在OnShowModalDone关闭对话框时调用事件.这是一种使用起来很痛苦,但相对容易编码并且易于稳定.

    2. 使用Windows 光纤例程交换堆栈并启动新的消息循环.这种方法很容易使用,因为它ShowModal是阻塞的,所以你可以像平常一样调用它.这是我们在Beyond Compare中使用的方法. 不要这样做. 这是复杂的写,有是因为有第三方的代码不兼容的不平凡的应用程序(Windows全局消息钩子,TWebBrowser,.NET在通过浏览对话框加载的外壳扩展,等等)的稳定性的问题,如果它是一个跨平台项目,Unix ucontext函数也不安全.

  2. 常见对话框(TOpenDialog,TColorDialog等)具有类似的限制.要使它们只禁用父表单,您需要覆盖TCommonDialog.TaskModalDialog并替换DisableTaskWindows/EnableTaskWindows那里的调用.它们不能像上面的常规Delphi对话那样异步,因为它们阻止了Windows提供的功能(GetOpenFileName,ChooseColor等).允许那些以任何顺序关闭的唯一方法是让每个对话框在专用线程中运行.Windows可以处理大部分同步,只要你小心访问VCL对象,但它基本上涉及重写大部分Dialogs.pas.