无法完全看到主窗体中的MDI子窗体

时间:2018-12-02 00:55:23

标签: delphi

有一个MDI应用程序,其中包含主要形式fMain和子形式fChartAcc和fReal。 主窗体已最大化,并且主窗体的客户区域受到屏幕尺寸的限制。 当打开子窗体时,在主窗体的客户区域中,我看不到子窗体的底部,并在子窗体上显示水平滚动条。我希望将子窗体完全粘贴到主窗体的客户区域中,按屏幕大小,并相应地粘贴至主窗体大小,而无需在水平滚动栏中。

child form at design time

child form when app is run

Main form

主要形式:Formstyle:MDIForm 子形式:
样式:MDIChild AlignalClient或alCustom 位置尝试的poDefaultPosOnly,poDefault,poDesigned
autoSize:假 已尝试在程序OnCreate,OnShow,OnResize中设置冰冻表单的大小,但没有成功。

Main form: Formstyle:MDIForm 
Childred forms:  
  Formstyle:MDIChild 
  Align- alClient or alCustom 
  Position-tried poDefaultPosOnly, poDefault, poDesigned  
  autoSize:false
  tried settings of size of chilled forms place in procedures OnCreate, 
    OnShow, OnResize but no success.

单位Umain;

    procedure TFmain.MDIChildCreated(const childHandle : THandle);
    begin
      mdiChildrenTabs.Tabs.AddObject(TForm(FindControl(childHandle)).Caption, TObject(childHandle));
      mdiChildrenTabs.TabIndex := -1 + mdiChildrenTabs.Tabs.Count;
    end;

    procedure TFmain.MDIChildDestroyed(const childHandle : THandle);
    var
      idx: Integer;
    begin
      idx := mdiChildrenTabs.Tabs.IndexOfObject(TObject(childHandle));
      mdiChildrenTabs.Tabs.Delete(idx);
    end;



    procedure TFmain.NChartAccClick(Sender: TObject);
    begin
      application.CreateForm(TfChartAcc, fChartAcc);
     fChartAcc.Show;
    end;

    procedure TFmain.realisatia1Click(Sender: TObject);
    begin
      application.CreateForm(TFgas, Fgas);
      Fgas.Show;
    end;

    end.

单位UChartAcc;

    procedure TfChartAcc.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
     action:=caFree;
    end;


    procedure TfChartAcc.FormCreate(Sender: TObject);
    begin
     Left:=0;
     Top:=Fmain.Toolbar.Height+Fmain.MDIChildrentabs.height;
     Height:=Fmain.ClientHeight-Fmain.Toolbar.Height-Fmain.MDIChildrentabs.height-Fmain.StatusBar.Height-2*GetSystemMetrics(SM_CXEDGE);
     Width:=Fmain.ClientWidth- 2*GetSystemMetrics(SM_CXEDGE);

      FMain.MDIChildCreated(self.Handle);
    end;


    procedure TfChartAcc.FormDestroy(Sender: TObject);
    begin
     FMain.MDIChildDestroyed(self.Handle);
    end;

    procedure TfChartAcc.FormResize(Sender: TObject);
    begin
     {
     Left:=0;
     Top:=Fmain.Toolbar.Height+Fmain.MDIChildrentabs.height;
     Height:=Fmain.ClientHeight-Fmain.Toolbar.Height-Fmain.MDIChildrentabs.height-Fmain.StatusBar.Height-2*GetSystemMetrics(SM_CXEDGE);
     Width:=Fmain.ClientWidth- 2*GetSystemMetrics(SM_CXEDGE);
     }
    end;





    procedure TfChartAcc.FormShow(Sender: TObject);
    begin
     Left:=0;
     Top:=Fmain.Toolbar.Height+Fmain.MDIChildrentabs.height;
     Height:=Fmain.ClientHeight-Fmain.Toolbar.Height-Fmain.MDIChildrentabs.height-Fmain.StatusBar.Height-2*GetSystemMetrics(SM_CXEDGE);
     Width:=Fmain.ClientWidth- 2*GetSystemMetrics(SM_CXEDGE);
    end;

    end.

Project 1

1 个答案:

答案 0 :(得分:0)

要获取ClientRect主表单的最新MDI,可以使用以下WinApi.Windows.GetClientRect()函数(适用于uChartAcc单位):

FChartAcc表单中添加一个新过程,例如MyAdjustSize。 我更改了名称,因为AdjustSize()TWinControl的虚拟方法

procedure TFChartAcc.MyAdjustSize;
var
  r: TRect;
begin
  if not WinApi.Windows.GetClientRect(FMain.ClientHandle, r) then
    RaiseLastOSError;
  BoundsRect := r;
end;

ClientHandle所引用的窗口已经排除了与窗体的两边对齐的菜单栏,工具栏等,因此不需要进一步的计算。

通过调用TFChartAcc.FormCreate来替换MyAdjustSize中先前建议的代码:

procedure TFChartAcc.FormCreate(Sender: TObject);
begin
  MyAdjustSize;

  FMain.MDIChildCreated(self.Handle);
end;

然后在主窗体中为OnResize事件添加一个事件处理程序,如下所示。目的是为所有当前存在的子表单调用MyAdjustSize过程:

procedure TFMain.FormResize(Sender: TObject);
var
  ix: integer;
  ob: TWinControl;
begin
  for ix := 0 to MDIChildrenTabs.Tabs.Count-1 do
  begin
      ob := FindControl(THandle(MDIChildrenTabs.Tabs.Objects[ix]));
      if ob is TFChartAcc then
        TFChartAcc(ob).MyAdjustSize;
  end;
end;

由于所有子窗口的大小均已正确设置,因此在选择其他子窗体时我们不需要调用MyAdjust

procedure TFMain.mdiChildrenTabsClick(Sender: TObject);
var
  ix: integer;
  ob: TWinControl;
begin
  ix := MDIChildrenTabs.TabIndex;
  if ix > -1 then
  begin
    ob := FindControl(THandle(MDIChildrenTabs.Tabs.Objects[ix]));
    ob.BringToFront;
  end;
end;