1

我有以下TForm1带有两个按钮(BitBtn)的示例表单:

基本形式

此外,我还有第二种形式TForm2,它是从第一种形式派生的。第二个按钮向左移动并添加了另一个按钮:

派生形式

在运行时(Windows 7),第二种形式如下所示:

标准字体大小

如果我将字体缩放比例更改为 125%,我的表单如下所示:

增加字体大小

不知何故,新按钮的位置和大小都错误。 我能做些什么呢?

我使用了以下.dfm文件(缩短):

object Form1: TForm1
  Left = 0
  Top = 0
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object BitBtn1: TBitBtn
    Left = 8
    Top = 8
    Width = 105
    Height = 105
    Caption = 'BitBtn1'
  end
  object BitBtn2: TBitBtn
    Left = 359
    Top = 8
    Width = 105
    Height = 105
    Caption = 'BitBtn2'
  end
end

inherited Form2: TForm2
  Caption = 'Form2'
  PixelsPerInch = 96
  TextHeight = 13
  inherited BitBtn2: TBitBtn
    Left = 191
    Top = 7
    ExplicitLeft = 191
    ExplicitTop = 7
  end
  object BitBtn3: TBitBtn
    Left = 359
    Top = 8
    Width = 105
    Height = 104
    Caption = 'BitBtn3'
  end
end

类文件在设计器生成时保持不变。它们不包含相关代码。

4

1 回答 1

2

我自己找到了一个可能的解决方案:必须ReadState用以下代码覆盖:

procedure TForm2.ReadState(Reader: TReader);
begin
  IntPtr(FReserved) := 0;
  inherited;
end;    

这看起来很奇怪。它是如何工作的?

我查看了VCL源代码,发现表单加载后的缩放是在TForm.ReadState(...). 显然,一个受保护的字段FReserved用于TControl存储当前应用的DPI值:

  • 首先,我的基类的所有组件dfm都被读取
  • 然后它们被正确缩放和定位
  • 当前应用的DPI值存储在FReserved
  • 之后ReadState再次调用,用于dfm派生类的文件
  • 但由于 中的值FReserved,缩放不适用于派生形式的组件

因此,一种想法是DPI在读取组件之前重置缓存值。它将组件缩放Form1两次,但这并没有什么坏处,因为原始大小和位置被记住为缩放的基础值,结果完全相同。

于 2017-06-28T19:38:27.183 回答