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)像素坐标与缩放无关)。
我在高 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)像素坐标与缩放无关)。