当我的表单比我的屏幕大时,为什么我的Delphi表单控件会被裁剪?

当我的表单比我的屏幕大时,为什么我的Delphi表单控件会被裁剪?,第1张

概述场景是这样的: >我创建了一个Delphi(XE2)表单. >在它上面是一个拉伸的单个TGroupBox(或其他控件),因此它占据了顶部窗体的整个宽度. >设置TGroupBox上的右锚(除了左侧和顶部). >表格宽度设置为1200px(以说明要点). 如果我在Screen.Width属性大于1200px的监视器上运行此应用程序(我在没有任何DPI虚拟化AFAIK的情况下运行),则TGroupBo 场景是这样的: @H_403_2@>我创建了一个Delphi(XE2)表单.
>在它上面是一个拉伸的单个TGroupBox(或其他控件),因此它占据了顶部窗体的整个宽度.
>设置TGroupBox上的右锚(除了左侧和顶部).
>表格宽度设置为1200px(以说明要点).

@H_403_2@如果我在Screen.WIDth属性大于1200px的监视器上运行此应用程序(我在没有任何DPI虚拟化AFAIK的情况下运行),则TGroupBox会按照您的预期呈现.

@H_403_2@但是..如果显示器的宽度小于1200px,则无论您如何调整窗体大小,屏幕上都会丢失控件的右手部分.

@H_403_2@我用覆盖重写了我的表单的Create()方法;指令并验证我正确设置了wIDth属性,但仍然会裁剪控件.

@H_403_2@任何人都可以建议如何:

@H_403_2@a)设置表单的wIDth属性,使其影响子组件的定位或…

@H_403_2@b)建议在表单呈现后强制重新布局所有子组件的方法?

解决方法 跟踪代码看看会发生什么,我想出了以下调整.
procedure TForm1.WMWindowPosChanging(var Message: TWMWindowPosChanging);var  MessageWIDth: Integer;begin  MessageWIDth := Message.WindowPos.cx;  inherited;  if MessageWIDth > Message.WindowPos.cx then    GroupBox1.WIDth := GroupBox1.WIDth - MessageWIDth + Message.WindowPos.cx;end;
@H_403_2@这不是一个通用的解决方案,但它清楚地表明了问题所在. VCL要求其窗体大小不会被 *** 作系统授予,因为它比桌面大.从那时起,表单将恢复锚定子控件的设计时间指定宽度,该宽度大于表单的客户端宽度,因此子控件的右侧溢出.

@H_403_2@另一种解决方案是覆盖WM_GETMINMAXINFO消息的处理,让 *** 作系统授予所请求的宽度.

procedure TForm1.WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo);begin  inherited;  Message.MinMaxInfo.ptMaxTrackSize.X := 1200;end;
@H_403_2@这可能不是一个好的解决方案,因为那时表单将比桌面大.

@H_403_2@关于你的’a’和’b’项目,我不认为’b’是可能的 – 或者至少不可能自己进行VCL重新布局 – 因为VCL推迟应用锚定规则直到组件(表单)完成之后加载.到那时,表单的宽度与设计时间宽度不同,但子控件的放置不受影响.没有任何强制布局会使它们再次同步.

@H_403_2@但是,如果您自己的代码保留对设计时间宽度的引用,则应该可以从头开始重新计算所有内容.以下不是完整的代码.

type  TForm1 = class(TForm)    ..  private    FAdjustShrinkWIDth,FAdjustShrinkHeight: Integer;  protected    procedure Loaded; overrIDe;  public    procedure SetBounds(Aleft: Integer; Atop: Integer; AWIDth: Integer;      AHeight: Integer); overrIDe;  end;...procedure TForm1.SetBounds(Aleft,Atop,AWIDth,AHeight: Integer);var  TrackWIDth,TrackHeight: Boolean;begin  TrackWIDth := AWIDth = 1200;  TrackHeight := AHeight = ??;  inherited;  if TrackWIDth and (WIDth < AWIDth) then    FAdjustShrinkWIDth := AWIDth - WIDth;  if TrackHeight and (Height < AHeight) then    FAdjustShrinkHeight := AHeight - Height;end;procedure TForm1.Loaded;  procedure ReadjustControlAnchors(Control: TWinControl);  var    i: Integer;  begin    for i := 0 to Control.ControlCount - 1 do      if (akRight in Control.Controls[i].Anchors) or (akBottom in Control.Controls[i].Anchors) then begin        Control.Controls[i].left := // some complex calculation depending on the anchors set;        Control.Controls[i].top := // same as above;        Control.Controls[i].WIDth := // same as above;        Control.Controls[i].Height := // same as above;        if (Control.Controls[i] is TWinControl) and (TWinControl(Control.Controls[i]).ControlCount > 0) then          ReadjustControlAnchors(TWinControl(Control.Controls[i]));      end;  end;begin  inherited;  ReadjustControlAnchors(Self);end;
@H_403_2@我不知道如何填写上面代码中的空白.阅读和跟踪VCL代码可能是模仿VCL锚定的必要条件.

@H_403_2@我想不出’a’的任何东西.

@H_403_2@更新:

@H_403_2@VCL实际上已经为一个控制器留下了一个后门,让它的直接孩子们在他们的锚定时对他们父母的体型撒谎. Documentation解释它有点不同:

@H_403_2@UpdateControlOriginalParentSize is a protected method that updates the
original size of the parent control. It is used internally to update
the anchor rules of the control.

@H_403_2@我们可以用它来告诉groupBox预期的原始大小.

type  TForm1 = class(TForm)    ..  private    FWIDthChange,fheightChange: Integer;  protected    procedure UpdateControlOriginalParentSize(AControl: TControl;      var AOriginalParentSize: TPoint); overrIDe;  public    procedure SetBounds(Aleft: Integer; Atop: Integer; AWIDth: Integer;      AHeight: Integer); overrIDe;  end;...procedure TForm1.SetBounds(Aleft,AHeight: Integer);var  RequesteDWIDth,RequestedHeight: Integer;begin  RequesteDWIDth := AWIDth;  RequestedHeight := AHeight;  inherited;  if csloading in ComponentState then begin    if RequesteDWIDth <> WIDth then      FWIDthChange := WIDth - AWIDth;    if RequestedHeight <> Height then      fheightChange := Height - AHeight;  end;end;procedure TForm1.UpdateControlOriginalParentSize(AControl: TControl;  var AOriginalParentSize: TPoint);begin  inherited;  if akRight in AControl.Anchors then    AOriginalParentSize.X := AOriginalParentSize.X - FWIDthChange;  if akBottom in AControl.Anchors then    AOriginalParentSize.Y := AOriginalParentSize.Y - fheightChange;end;
@H_403_2@我再次注意到这只会影响表格的直接孩子.如果groupBox托管了右侧和底部锚定的控件,它还必须覆盖相同的方法.

@H_403_2@另请注意,这不会撤消表单宽度已更改的事实.那就是如果左侧锚定控件位于表单的最右侧,它将不会将其自身替换为客户端边界.它将表现为表格的宽度已经减小,即保持在视线之外.

总结

以上是内存溢出为你收集整理的当我的表单比我的屏幕大时,为什么我的Delphi表单控件会被裁剪?全部内容,希望文章能够帮你解决当我的表单比我的屏幕大时,为什么我的Delphi表单控件会被裁剪?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1128050.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-30
下一篇 2022-05-30

发表评论

登录后才能评论

评论列表(0条)

保存