如何将DLU转换为像素?

时间:2011-07-29 08:25:22

标签: delphi pixels units-of-measurement

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

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

3 个答案:

答案 0 :(得分:16)

首先我们从对话单元开始。

为此,我引用my own un-answered questions之一:

  

什么是对话单元?

     

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

     

enter image description here

     

这意味着对话框单元:

     
      
  • 使用所选字体进行更改
  •   
  • 使用所选的DPI设置进行了更改
  •   
  • 不是正方形
  •   

我还会引用另一个my own un-answered questions

  

您可以查看Windows UX Guidelines以查看这些内容   测量来自。简短版本是:

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

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

     

格鲁吉亚14pt:

     

enter image description here

     

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

     

Segoe UI 9pt:

     

enter image description here

     

注意:您会注意到分辨率(即dpi)对讨论没有影响。

所以你需要的是一个角色的平均大小。 Microsoft有official technique来计算平均字符大小。

  • 平均身高:

    GetTextMetrics(dc, {var}textMetrics);
    averageHeight := textMetrics.tmHeight;
    
  • 平均宽度:

    使用GetTextExtentPoint32测量字符串 ABCDEFGHIJLKMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ,并除以52:

    GetTextExtentPoint32(dc,
          PChar('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'), 52, Size));
    averageWidth := size.cx / 52.0;
    

所以现在你需要水平和垂直对话单元的大小。请记住,水平对话单位是平均字符宽度的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;
  

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

答案 1 :(得分:10)

您应该使用MapDialogRect()功能。

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


如果您想要使用GetDialogBaseUnits(),请记住Raymond Chen所说的GetDialogBaseUnits is a crock

  

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

     

它总是猜错了。

     

GetDialogBaseUnits返回对话框的对话框基本单位   使用默认的系统字体。但是没有人使用默认的系统字体   更多。它尖叫着“古老而愚蠢”。但它仍然是默认值   兼容性原因。 (因此GetDialogBaseUnits也是如此。)

如果必须从DLU计算像素尺寸,并且没有对话框的句柄,则必须使用此处概述的方法:How To Calculate Dialog Base Units with Non-System-Based Font


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

答案 2 :(得分:-4)

对于基值(当然,系统字体),请调用GetDialogBaseUnits。另请参见remarks段,了解翻译对话框单元的替代方法< - > GetTextMetrics和/或GetTextExtentPoint32没有对话框HWND的像素。