【问题标题】:Working with 2 active modalforms in Delphi在 Delphi 中使用 2 个活动模态形式
【发布时间】:2021-06-25 18:41:20
【问题描述】:

我需要帮助...

我在 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;

【问题讨论】:

  • 重新考虑你的方法。如果您不希望表单是模态的,请不要以模态形式显示它。
  • 事情已经走得太远了。我正在寻找的解决方案将解决问题,如果它不存在,那么它可能必须完成。
  • 但这一开始是没有意义的:只要做到MDI 明智,不要禁用/模态任何窗口只是为了在之后摆弄它。只显示窗户。完成。
  • @Piotr 根据定义,模态表单会阻止现有 UI,直到表单关闭。因此,如果您显示 1 个模态表单,然后显示第 2 个模态表单,则第 1 个表单将被阻止,直到第 2 个表单关闭。 这是设计使然。如果您需要两个表单都具有交互性,包括能够独立关闭它们,那么模态就是错误的解决方案。
  • 该解决方法是错误的。模态窗口的设计正如@Remy 已经描述的那样。如果您不想要标准的模态行为,那么首先将您的代码修复为不使用模态窗口。试图将不适当的行为强加到您的应用程序中只会让您在未来失败。如果您一次需要多个活动窗口,则根本不应该使用模态窗口。期间。

标签: forms delphi modal-dialog


【解决方案1】:

您可以在每个窗口中工作,无论它是父窗口还是子窗口。

DFM-达泰:

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.

【讨论】:

  • 一些关于你在做什么以及为什么会很棒的解释......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-20
  • 1970-01-01
相关资源
最近更新 更多