首页 > 解决方案 > Delphi 和 High-DPI:在运行时创建的控件获得错误的位置

问题描述

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

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 应用程序中创建的控件设置正确的位置?

标签: delphihighdpi

解决方案


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

将父级分配给控件将缩放位置/大小以符合该父级的 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) 像素坐标处,而与缩放无关)。


推荐阅读