在 Delphi 中使用 2 个活动模态形式

Working with 2 active modalforms in Delphi

我需要帮助...

我在 Delphi VCL Forms 应用程序中有两个单独的模态表单。 基于以下解决方案: How can I make a form that is not disabled when another form is shown modally?

我使用 EnableWindow(Self.Handle, True) 并且效果很好:我可以打开和编辑第一个表单,无需关闭它,打开第二个表单。两者都处于活动状态且可编辑。

当我尝试关闭第一个模态窗体而不关闭第二个时,问题就出现了。它等到第二个关闭。

是否存在强制关闭第一个模态窗体(Self.Free 除外,因为我需要父窗体中模型窗体的一些信息)而第二个模态窗体仍然打开的方法?

代码很简单:

主窗体(带有 Button1):

procedure TfrMainForm.WMEnable(var _Msg: TWMEnable);
begin
  inherited;
     if not _Msg.Enabled and (Application.ModalLevel > 0) then Begin
          EnableWindow(Self.Handle, True);
     End;
end;


procedure TfrMainForm.Button1Click(Sender: TObject);
Var
     tmpSubForm: TfrSubForm;
begin
     tmpSubForm := TfrSubForm.Create(Self);
     Try
          tmpSubForm.ShowModal;
          //get some information from tmpSubForm
     Finally
          tmpSubForm.Free;
     End;
end;

“子”表单(什么都不做 - 只打开):

procedure TfrSubForm.WMEnable(var _Msg: TWMEnable);
begin
  inherited;
     if not _Msg.Enabled and (Application.ModalLevel > 0) then Begin
          EnableWindow(Self.Handle, True);
     End;
end;

您可以在每个 window 工作,无论是 parent window 还是 child window.

DFM-Datei:

object frm: Tfrm
  Left = 0
  Top = 0
  Caption = 'frm'
  ClientHeight = 194
  ClientWidth = 283
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnClose = FormClose
  PixelsPerInch = 96
  TextHeight = 13
  object btnShow: TButton
    Left = 104
    Top = 132
    Width = 75
    Height = 25
    Caption = 'Show'
    TabOrder = 0
    OnClick = btnShowClick
  end
  object txt: TEdit
    Left = 8
    Top = 40
    Width = 121
    Height = 21
    TabOrder = 1
  end
end

单位:

unit Unit1;

interface

uses
  System.SysUtils, System.Variants, System.Classes,
  Vcl.Controls, Vcl.Forms, Vcl.StdCtrls;

type
  Tfrm = class(TForm)
    btnShow: TButton;
    txt: TEdit;
    procedure btnShowClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
  protected
     procedure CreateParams(var Params: TCreateParams); override;
  public
    { Public-Deklarationen }
  end;

var
  frm: Tfrm;

implementation

{$R *.dfm}

procedure Tfrm.CreateParams(var Params: TCreateParams);
var
  Lfrm: TForm;
begin
  inherited CreateParams(Params);

  Lfrm := nil;
  if Owner is TControl then
    Lfrm := (GetParentForm(Owner as TControl, false) as TForm);
  if not Assigned(Lfrm) then
    Lfrm := Application.MainForm;

  if Assigned(Lfrm) and (Lfrm <> Self) then
  //Bind the child window to its parent window.
      Params.WndParent := Lfrm.Handle;
end;


procedure Tfrm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if Self <> Application.MainForm then
  //Action caHide -> caFree
    Action := caFree;
end;

procedure Tfrm.btnShowClick(Sender: TObject);
var
  Lfrm: Tfrm;
begin
  Lfrm := Tfrm.Create(Self);
  Lfrm.Top  := Top  + 10;
  Lfrm.Left := Left + 10;
  //Since you want to work in the parent window, the child window must not 
  //   display this in a showmodal manner!
  Lfrm.Show;
end;

end.