调用ShowModal时,表单隐藏在其他表单后面

Luk*_*Led 25 delphi delphi-7

我的申请基于模态表格.主窗体用ShowModal打开一个窗体,这个窗体用ShowModal打开另一个窗体,所以我们有叠加的模态窗体.有时会出现一个问题,当我们以新的形式调用ShowModal时,它隐藏在以前的表单之后,而不是显示在顶部.按下alt + tab后,表单返回到顶部,但这不是一个好的解决方案.你遇到了这个问题,你是如何处理的?

编辑:

我使用的是Delphi 7.

Ken*_*ite 25

你没有提到哪个版本的Delphi ......

较新的Delphi版本为TCustomForm添加了两个新属性:PopupMode和PopupParent.将模式对话框的PopupParent设置为创建该对话框的表单,确保子表单保留在其父对象的顶部.它通常可以解决您所描述的问题.

我认为这对属性是在Delphi 2006中添加的,但它可能是2005年.它们肯定存在于Delphi 2007及更高版本中.

编辑:看到你使用Delphi 7后,我唯一的建议是,在显示模态表单的代码中,禁用创建它的表单,并在返回时重新启用.这应该会阻止创建窗口接收输入,这可能有助于保持Z顺序正确.

这样的东西可能会起作用(未经测试,因为我不再使用D7):

procedure TForm1.ShowForm2;
begin
  Self.Enabled := False;
  try
    with TForm2.Create(nil) do
    begin
      try
        if ShowModal = mrOk then
          // Returned OK. Do something;
      finally
        Free;
      end;
    end;
  finally
    Self.Enabled := True;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

如果Form2创建一个模态窗口(如您所述),只需重复该过程 - 禁用Form2,创建Form3并以模态方式显示它,并在返回时重新启用Form2.确保使用try..finally正如我所示,因此如果模态形式出现问题,则始终重新启用创建表单.


Jim*_*tin 6

很抱歉添加一个单独的答案,但我做了一些研究,其中一些表明我之前的答案(DisableProcessWindowsGhosting)没有帮助.由于我不能总是重现这个问题,我不能肯定地说.

我找到了一个合适的解决方案.我在Delphi 2007中为CreateParams方法引用了代码,它匹配非常接近(没有处理PopupMode的所有其他代码).

我在下面创建了子单元TForm.

unit uModalForms;

interface

uses Forms, Controls, Windows;
type
  TModalForm = class(TForm)
  protected
    procedure CreateParams(var params: TCreateParams); override;
  end;

implementation

procedure TModalForm.CreateParams(var params: TCreateParams);
begin
  inherited;

  params.WndParent := Screen.ActiveForm.Handle;

  if (params.WndParent <> 0) and (IsIconic(params.WndParent)
    or not IsWindowVisible(params.WndParent)
    or not IsWindowEnabled(params.WndParent)) then
    params.WndParent := 0;

  if params.WndParent = 0 then
    params.WndParent := Application.Handle;
end;
Run Code Online (Sandbox Code Playgroud)

我所做的是将此单元包含在表单单元中,然后将表单的类(在.pas代码文件中)class(TForm)更改为class(TModalForm)

它适用于我,似乎接近CodeGear的解决方案.