Delphi 和高 DPI:在运行时创建的控件获得了错误的位置

Delphi and High-DPI: Controls created on runtime obtain wrong position

我在高 DPI 应用程序中定位运行时创建的控件时遇到问题。例如,我创建了一个 Label 并想创建一个 Image 并将其直接放置在标签的右侧。

if USER_EMAIL <> '' then
begin
  lblSummary_Email := TcxLabel.Create(pnlSummary);
  with lblSummary_Email do
  begin
    Caption := 'E-Mail: ' + USER_EMAIL;
    Top := 125;
    Left := 278;
    AutoSize := true;
    Parent := pnlSummary;
  end;

  with TcxImage.Create(pnlSummary) do
  begin
    Width := 17;
    Height := 17;
    Top := lblSummary_Email .Top;
    Left := lblSummary_Email .Left + lblSummary_Email .Width + 10;
    Picture := imgConfirmed.Picture;
    Properties.ShowFocusRect := false;
    Style.BorderStyle := ebsNone;
    Enabled := false;
    Parent := pnlSummary;
  end;
end;

图片位置不正确。这表明我在运行时设置的位置将直接转换为 High-DPI。如何避免这种情况或如何在高 DPI 应用程序中为运行时创建的控件设置正确的位置?

当您在运行时创建组件时,它会以 96 DPI 创建。

将 Parent 分配给控件将缩放 position/size 以符合该父级的 DPI。

因此您将 Left/Top 设置为 96 DPI (100%) 像素坐标,并在 Parent 分配时将其转换为(比如说)150% 像素坐标。

因此,要解决您的问题,您应该在设置控件边界之前分配 Parent

if USER_EMAIL <> '' then
begin
  lblSummary_Email := TcxLabel.Create(pnlSummary);
  with lblSummary_Email do
  begin
    Parent := pnlSummary;
    Caption := 'E-Mail: ' + USER_EMAIL;
    Top := 125;
    Left := 278;
    AutoSize := true;
  end;

  with TcxImage.Create(pnlSummary) do
  begin
    Parent := pnlSummary;
    Width := 17;
    Height := 17;
    Top := lblSummary_Email .Top;
    Left := lblSummary_Email .Left + lblSummary_Email .Width + 10;
    Picture := imgConfirmed.Picture;
    Properties.ShowFocusRect := false;
    Style.BorderStyle := ebsNone;
    Enabled := false;
  end;
end;

标签的父分配在定位之前的移动取决于您分配的坐标是否应该缩放(如果是,请将其留在原来的位置),或者是绝对的(即始终在(278,175)像素坐标与缩放无关)。