代码之家  ›  专栏  ›  技术社区  ›  LukLed

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

  •  21
  • LukLed  · 技术社区  · 15 年前

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

    编辑 :

    我使用Delphi7。

    6 回复  |  直到 15 年前
        1
  •  26
  •   LukLed    15 年前

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

    我认为这对属性是在Delphi 2006中添加的,但可能是在2005年。它们肯定在Delphi 2007及以后的版本中。

    类似的东西可能会起作用(未经测试,因为我不再使用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;
    

    如果Form2创建了一个模式窗口(正如您所提到的),只需重复这个过程-禁用Form2,创建Form3并以模式方式显示它,然后在它返回时重新启用Form2。请确保使用try..finally,如我所示,这样,如果模态表单中出现问题,则始终会重新启用创建表单。

        2
  •  8
  •   Jim Gilmartin    15 年前

    我找到了一个似乎合适的解决方案。我在Delphi2007中引用了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;
    

    class(TForm) class(TModalForm)

    它适合我,似乎接近CodeGear的解决方案。

        3
  •  2
  •   Jim Gilmartin    15 年前

    由此 link 问题似乎在于2000/XP中引入的“重影窗口”。您可以通过在启动时调用以下代码来禁用重影功能。

    procedure DisableProcessWindowsGhosting;
    var
      DisableProcessWindowsGhostingProc: procedure;
    begin
      DisableProcessWindowsGhostingProc := GetProcAddress(
        GetModuleHandle('user32.dll'),
        'DisableProcessWindowsGhosting');
      if Assigned(DisableProcessWindowsGhostingProc) then
        DisableProcessWindowsGhostingProc;
    end; 
    

    我能看到的唯一问题是,它将导致允许用户使用的功能出现问题 minimize, move, or close the main window of an application that is not responding Self.Enabled := False 代码。

        4
  •  1
  •   H. Gokhan Mamaci    14 年前

    只要设定 Visible False . 然后你就可以打开它了 .ShowModal();

        5
  •  0
  •   Scott W    15 年前

    我发现在多个表单上使用“始终在顶部”标志会导致Z顺序出现问题。你也可能会发现 BringWindowToTop 功能。

    使用内置WinAPI启动消息框时( MessageBox ),我发现传递调用窗口的句柄是必要的,以确保提示符始终显示在顶部。

        6
  •  0
  •   Mayank Jain Pushpendra Rathor    9 年前

    试试看 网上展示:

    PostMessage(Self.Handle, WM_USER_SET_FOCUS_AT_START, 0, 0);