1

TFrame在 C++Builder中缩放 a 的正确过程是什么?

我正在 PixelsPerInch=120(又名 Windows 字体大小 125%)中开发,但希望我的表单也可以在 PixelsPerInch=96 中工作(又名默认)。

我的主表单加载良好:创建 a 的 VCL 代码TForm包括检查设计 PPI 是否与运行时 PPI 不同,并在该点正确缩放所有内容。

但是,在加载 a 时TFrame,不会发生自动缩放。据我所知,我必须手动调用Frame1->ScaleBy(M, D);.

主要是可行的,但是它有一个错误(我将在下面描述),因此结果是一个未正确缩放的帧。

什么是创建 Frame 并让它在加载时缩放的正确方法,就像 Form 一样?

我目前正在使用以下内容:

// class member
TFrame *f;

// called just before Application->Run()
f = new TFrame(fMain);

int M = fMain->PixelsPerInch;
int D = 120;        // Matt's development

if ( M != D )
{    
    f->ScaleBy(M, D);
}

然后当我想激活框架时,`f->Parent = fMain->Panel1; (*f)->ScaleBy(M, D);

我也尝试f->Parent = fMain->Panel1;在调用之前编写ScaleBy,基于 Frame 具有控件使用等的理论ParentFont,因此如果在缩放期间可以使用此信息可能会更好;但是,这会引入其他错误。


错误是,当调用ScaleBy一个 Frame 或一个 Form 具有TLabelwhichAutoSize=true和includeParentFont=false时,Label 在窗口上显示的位置比它应该显示的要高得多(甚至可能在窗口顶部之外)。AnchorsakBottom

我已经找到了问题所在:该TControl.ChangeScale函数包括对 的调用ScaleMargins,并且 Margin 属性有一个设置触发器,该触发器最终调用AlignControls父窗体,它将移动任何带有AutoSize=true.

通过单步Vcl.Controls.pas执行,我看到我的 Label 一开始可以正确缩放,但是当处理下一个控件(恰好是一个单选组)时,会AlignControls触发 ,这会更改我的 Label 的Top.

当通过重新缩放操作中途调用时,该AlignControls函数显然无法处理我刚刚描述的参数。TLabel

我还没有确定原因,但我认为这是因为父窗体或框架尚未缩放(该ScaleControls函数在缩放自身之前缩放所有子对象),因此它使用表单的旧Height来计算实际Top结果从做对齐到底部。

第一次加载表单时不会触发此效果,因为缩放代码会检查csLoading组件状态并禁用很多反作用效果,包括对AlignControls.

我还没弄清楚为什么只有在ParentFont=false.


我目前的解决方法是在 FormResize 处理程序中包含一行,该处理程序手动将有问题的标签与另一个有问题的标签重新对齐ParentFont=true(因此不会受到错误的影响)。

4

0 回答 0