Allow multiple MDI Parent Forms on same Application

前端 未结 1 1214
长发绾君心
长发绾君心 2021-01-07 17:41

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

procedure TCustomForm.CreateWindowHandle(const Params         


        
相关标签:
1条回答
  • 2021-01-07 18:12

    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;
    

    0 讨论(0)
提交回复
热议问题