4

这听起来不符合 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

4 回答 4

5

对于您的第一个问题:添加另一个构造函数,例如 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,而是自己创建表单:

这里是 modal 和 MDI 的两个创作:

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

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

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

于 2009-09-22T09:53:40.647 回答
2

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

FormStyle = fsMDIChild

Form.Visible = False

在财产检查员。这是久经考验的!

于 2009-09-22T22:40:01.923 回答
1

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

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

这将禁用 MDI 子项的自动显示。完成其他初始化后,您可以简单地Show将其设置VisibleTrue.

我不会尝试回答您关于模态 MDI 子窗体的问题,因为这违反了 Windows 平台的约定。

于 2009-09-22T10:06:11.027 回答
1

上面没有答案实际上可以完成所需的工作。最佳答案也是错误的,原因如下:

  • 打开第一个表格;
  • 最大化它;
  • 现在说这个表格调用了另一个表格(mdi);
  • 当它以相同的方式构建时,您将获得错误的布局......(它将 mdi 子级,但不会最大化,但第一个仍将最大化)。所以一个错误的状态。

如果您确实需要在运行时决定它是 fsMDIChild 还是 fsNormal,您需要应用以下方法。

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

...

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;
于 2015-04-17T13:54:51.363 回答