在同一应用程序上允许多个MDI父表单 [英] Allow multiple MDI Parent Forms on same Application

查看:115
本文介绍了在同一应用程序上允许多个MDI父表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试遵循答案,

I'm trying follow what was suggested in this answer, changing this part of Vcl.Forms.pas:

procedure TCustomForm.CreateWindowHandle(const Params: TCreateParams);
var
  CreateStruct: TMDICreateStruct;
  NewParams: TCreateParams;
begin
  if (FormStyle = fsMDIChild) and not (csDesigning in ComponentState) then
  begin
    {if (Application.MainForm = nil) or
      (Application.MainForm.ClientHandle = 0) then
      raise EInvalidOperation.Create(SNoMDIForm);}
    with CreateStruct do
    begin
      szClass := Params.WinClassName;
      szTitle := Params.Caption;
      hOwner := THandle(HInstance);
      X := Params.X;
      Y := Params.Y;
      cX := Params.Width;
      cY := Params.Height;
      style := Params.Style;
      lParam := THandle(Params.Param);
    end;
    WindowHandle := SendStructMessage(Application.MainForm.ClientHandle,
      WM_MDICREATE, 0, CreateStruct);
    Include(FFormState, fsCreatedMDIChild);
  end
  else

  //...

但仍然出现错误,指出没有MDI表单处于活动状态"

but still comes the error saying that "no MDI Form is active"

该建议工作还需要做些什么?预先感谢.

What more is need be made to this suggestion works? Thanks in advance.

带有表单的测试代码:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2 := TForm2.Create(Self); // MDIForm
  Form2.Show;
  Form3 := TForm3.Create(Form2); // MDIChild
  Form3.Show;
end;

推荐答案

在上面的注释(主要是@Remy Lebeau的注释)的帮助下,此代码正常工作.我希望可以帮助前面的人:-).

After the help of comments above (mainly of @Remy Lebeau) follows this code working. I hope that can help someone ahead :-).

// MainForm
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2 := TForm2.Create(Application);
  Form2.Show;
end;


// MDIForm
type
  TForm2 = class(TForm)
    MainMenu1: TMainMenu;
    O1: TMenuItem;
    procedure O1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

uses
  Unit3;

{$R *.dfm}

procedure TForm2.O1Click(Sender: TObject);
begin
  Form3 := TForm3.Create(Self);
  Form3.Show;
end;


// MDIChild
type
  TForm3 = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
    procedure CreateWindowHandle(const Params: TCreateParams); override;
    procedure DestroyWindowHandle; override;
  protected
    FMDIClientHandle: HWND;
  public
    { Public declarations }
  end;

var
  Form3: TForm3;

implementation

uses
  Unit1;

{$R *.dfm}

procedure TForm3.CreateWindowHandle(const Params: TCreateParams);
var
  CreateStruct: TMDICreateStruct;

  function GetMDIClientHandle: HWND;
  begin
    Result := 0;
    if (Owner is TForm) then
      Result := TForm(Owner).ClientHandle;
    if (Result = 0) and (Application.MainForm <> nil) then
      Result := Application.MainForm.ClientHandle;
    if Result = 0 then
      raise EInvalidOperation.Create('No Parent MDI Form');
  end;

begin
  if (FormStyle = fsMDIChild) and not (csDesigning in ComponentState) then
  begin
    FMDIClientHandle := GetMDIClientHandle;
    with CreateStruct do
    begin
      szClass := Params.WinClassName;
      szTitle := Params.Caption;
      hOwner := HInstance;
      X := Params.X;
      Y := Params.Y;
      cX := Params.Width;
      cY := Params.Height;
      style := Params.Style;
      lParam := Longint(Params.Param);
    end;
    WindowHandle := SendMessage(FMDIClientHandle, WM_MDICREATE, 0, LongInt(@CreateStruct));
    Include(FFormState, fsCreatedMDIChild);
  end
  else
  begin
    FMDIClientHandle := 0;
    inherited CreateWindowHandle(Params);
    Exclude(FFormState, fsCreatedMDIChild);
  end;
end;

procedure TForm3.DestroyWindowHandle;
begin
  if fsCreatedMDIChild in FFormState then
    SendMessage(FMDIClientHandle, WM_MDIDESTROY, Handle, 0)
  else
    inherited DestroyWindowHandle;
  FMDIClientHandle := 0;
end;

procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := CaFree;
end;

这篇关于在同一应用程序上允许多个MDI父表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆