显示MDI表单作为模态

时间:2009-09-22 09:32:43

标签: delphi mdi

这听起来违背了MDI的性质。我需要有时将MDI表单(FormStyle = fsMdiChild)显示为模态。我还需要访问另一个MDI表单的Application.CreateForm和OnShow事件之间的部分,即

Application.CreateForm(Form2,TForm2); // but don't set form2's visible property true.
Form2.caption:='not working example'; 
Form2.SomeMagicToSetVisibleTrue;

有什么想法吗?

4 个答案:

答案 0 :(得分:4)

第一个问题:添加另一个构造函数,例如CreateAsMDI,如下所示:

constructor TModalAndMDIForm.CreateAsMDI(AOwner: TComponent); 
begin 
  f_blChild := true; 
  GlobalNameSpace.BeginWrite; 
  try 
    inherited CreateNew(AOwner); 
    if(not(csDesigning in ComponentState)) then begin 
      Include(FFormState, fsCreating); 
      try 
        FormStyle := fsMDIChild; 
        if(not(InitInheritedComponent(self, TForm))) then 
          raise Exception.CreateFmt('Can't create %s as MDI child', [ClassName]); 
      finally 
        Exclude(FFormState, fsCreating); 
      end; 
    end; 
  finally 
    GlobalNameSpace.EndWrite; 
  end; 
end; 

在普通构造函数中,只需将变量f_blChild设置为false,然后调用继承的create。

你需要另外两件事,而不是自我解释:

procedure TModalAndMDIForm.Loaded; 
begin 
  inherited; 
  if(f_blChild) then 
    Position := poDefault 
  else begin 
    Position := poOwnerFormCenter; 
    BorderStyle := bsDialog; 
  end; 
end; 
//----------------------------------------------------------------------------- 
procedure TModalAndMDIForm.DoClose(var Action: TCloseAction); 
begin 
  if(f_blChild) then 
    Action := caFree; 
  inherited DoClose(Action); 
end; 

现在,如果使用标准构造函数创建,则可以调用表单模式,如果使用CreateAsMDI创建,则可以调用MDI子函数。

如果您在表单的声明中包含此内容

property IsChild: boolean read f_blChild; 

您甚至可以根据表单是否为MDI子进行操作,只需询问isChild属性。

至于你的第二个问题:不要使用Application.CreateForm,而是自己创建表单:

这里是模态和MDI的两个创作:

//Modal 
frmDialog := TMyForm.Create(self); 
// Your Code
frmDialog.ShowModal; 
frmDialog.Release; 

//MDI-Child 
frmDialog := TMyForm.CreateChild(self); 
// Your code
frmDialog.Show;

我已将此答案翻译成网站DelphiPraxis上的文章。

答案 1 :(得分:2)

最简单的方法是创建表单的普通子类,并设置

FormStyle = fsMDIChild

AND

Form.Visible = False

在物业检查员。经过试用和测试!

答案 2 :(得分:1)

至少对于Delphi 2007和2009来说,创建MDI子窗体是不可见的。对于早期的Delphi版本(在属性检查器中无法将Visible设置为False),您只需为OnCreate事件提供处理程序并访问受保护字段类:

procedure TMDIChild.FormCreate(Sender: TObject);
begin
  FFormState := FFormState - [fsVisible];
end;

这将禁用自动显示MDI子项。完成其他初始化后,您只需Show或将Visible设置为True

我不会尝试回答有关模态MDI子表单的问题,因为这违反了Windows平台的惯例。

答案 3 :(得分:1)

上面没有答案确实需要这份工作。最佳答案也是错误的,原因如下:

  • 打开第一张表格;
  • 最大化它;
  • 现在说这个表单调用另一个表单(mdi);
  • 当它以相同的方式构建时,你会得到错误的布局......(它将是mdi child,但没有最大化,但是第一个仍然会最大化)。所以一个越野车状态。

如果你真的需要在运行时决定它是fsMDIChild还是fsNormal,你需要应用以下方法。

  1. 您的表单在设计中存储为fsNormal(反之亦然);
  2. 覆盖InitializeNewForm方法;
  3. 将FFormStyle的值设置为fsMDIChild(如下所示)。
  4. ...

    TYourForm = class(TForm)
    ...
    protected
      procedure InitializeNewForm; override;
    ...
    
    procedure TYourForm.InitializeNewForm;
    var
      FS: ^TFormStyle;
    begin
      inherited;
      if DoYourCheckForMDI then
        begin
          FS := @FormStyle;
          FS^ := fsMDIChild;
        end;
    end;