如何将DLU转换为像素?

And*_*rew 9 delphi pixels units-of-measurement

Microsoft在其UI准则中使用对话框长度单位(DLU).如何将它们转换为像素?

据我所知,DLU取决于系统字体大小.你能在Delphi for Win32中建议一些简单的转换方法吗?

Ian*_*oyd 16

首先我们先从什么一个对话框单位.

为此,我将引用一个我自己未回答的问题:

什么是对话单元?

对话框是基于用户首选字体大小的度量单位.定义一个对话框单元,使得平均字符宽4个对话框单位,高8个对话框单位:

在此输入图像描述

这意味着对话单元:

  • 用所选字体更改
  • 已选择DPI设置更改
  • 不正方形

我还会引用另一个我未回答的问题:

您可以查看Windows UX准则以查看这些测量的来源.简短版本是:

  • dlu = 对话框
  • dlu基于字体大小(项目随用户的字体大小而变化)
  • 一个水平 DLU是从不同的垂直 DLU(DLU的不是正方形)

这来自对话单元的定义:平均字符是8dlus高4dlus宽.

格鲁吉亚14pt:

在此输入图像描述

如果你使用较小的字体(即8pt Tahoma对14pt格鲁吉亚),dlus会变小:

Segoe UI 9pt:

在此输入图像描述

注意:您会注意到解决方案(即dpi)对讨论没有影响.

所以你需要的是一个角色的平均大小.Microsoft有一种计算平均字符大小的官方技术.

所以现在你需要水平和垂直对话单元的大小.请记住,水平对话框单位是平均字符宽度的1/4,垂直dlu是平均字符高度的1/8:

procedure GetDlus(dc: HDC; out HorizontalDluSize, VerticalDluSize: Real);
var
   tm: TTextMetric; 
   size: TSize;
begin
   GetTextMetric(dc, tm);
   VerticalDluSize := tm.tmHeight / 8.0;

   GetTextExtentPoint32(dc,
         PChar('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'), 52,
         size);
   HorizontalDluSize := size.cx / 52.0;
end;
Run Code Online (Sandbox Code Playgroud)

注意:任何代码都将发布到公共域中.无需归属.


Dav*_*nan 11

你应该使用这个MapDialogRect()功能.

传入一个RECT对话框单元,RECT返回以像素为单位的等效项.请注意,您需要一个对话框句柄才能提供MapDialogRect()足够的上下文.该函数需要知道字体才能执行转换.


如果您想要使用GetDialogBaseUnits(),请记住Raymond Chen所说的,GetDialogBaseUnits是一个缸.

正如你可以从这个条目的标题猜测,GetDialogBaseUnits是一个缸.由于GetDialogBaseUnits没有HWND参数,因此它不知道您要检索哪个对话框的DLU.所以它猜测.

它总是猜错了.

GetDialogBaseUnits返回使用默认系统字体的对话框的对话框基本单位.但是没有人再使用默认的系统字体了.它尖叫着"古老而愚蠢".但出于兼容性原因,它仍然是默认值.(因此GetDialogBaseUnits也是如此.)

如果必须从DLU计算像素尺寸,并且没有对话框的句柄,则必须使用此处概述的方法:如何使用非基于系统的字体计算对话框基本单位


但是,您在评论中明确指出,对于您的问题,您实际上不需要从DLU转换为像素.您可以使用Delphi的内置表单缩放来确保您的表单的大小适合于流行的字体缩放.