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 具有TLabel
whichAutoSize=true
和includeParentFont=false
时,Label 在窗口上显示的位置比它应该显示的要高得多(甚至可能在窗口顶部之外)。Anchors
akBottom
我已经找到了问题所在:该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
(因此不会受到错误的影响)。