如何将delphi表单的宽度和高度像素转换为对话框单元?

Tho*_*ger 6 delphi winapi

我正在尝试将Delphi表单的宽度和高度像素计算为精确的对话框单元,以创建使用DIALOGEX语句的.rc(资源脚本)文件.到目前为止,我还无法使用此处描述的Microsoft公式计算正确的对话框单元:https://support.microsoft.com/en-us/help/145994/how-to-calculate-dialog-box-units-基于-上的电流的字体功能于视觉

上面的链接使用GetDialogBaseUnitsWin32 API调用但这不起作用,因为该API函数使用系统字体.所以这没用.甚至微软也说我们应该使用MapDialogRect.因此,使用此处提供的关于如何使用非基于系统的字体计算对话框基本单位的公式https://support.microsoft.com/en-us/help/125681/how-to-calculate-dialog-base-units -with-非系统为基础的字体

1个horz对话框基本单位==(2*平均字符宽度对话框字体/平均字符宽度系统字体)像素

1个vert对话框基本单位==(2*平均字符高度对话框字体/平均字符高度系统字体)像素

我尝试过这样的事情:

  xPixels := 200
  yPixels := 50;

  dc := GetDC(0);

  SelectObject(dc,handle);  // handle := f.Font.Handle  (f := TForm created)
  if not GetTextMetrics(dc, tm) then
    ShowMessage('Error');
  avgHeight := tm.tmHeight / 8.0;

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

  avgSysWidth := 5;   // Made up value, how to calculate?
  avgSysHeight := 1;  // Made up value, how to calculate?

  horzPixels := Round(2 * 1 * (avgWidth / avgSysWidth));
  vertPixels := Round(2 * 1 * (avgHeight / avgSysHeight));

  HorizontalDialogBaseUnit := Round(xPixels / horzPixels);
  VerticalDialogBaseUnit := Round(yPixels / vertPixels);
Run Code Online (Sandbox Code Playgroud)

请注意,这handle是从创建的表单字体句柄.在avgSysWidthavgSysHeight我不知道怎么去这些值.

我已经看了两天了,似乎看不到最简单的方法来到对话单元.我完全不在了吗?

更新2: 我的更新功能:

// xPixesl := 400
// yPixels := 200
procedure Tdm.GetDlgBaseUnits(handle: HWND; xPixels, yPixels: integer; out HorizontalDLUs, VerticalDLUs: integer);
var
  dc: HDC;
  tm: TTextMetric;
  size: TSize;
  avgWidth, avgHeight: real;
  VerticalDlu, HorizontalDlu: real;
//  DialogUnits: Cardinal;
begin
//  DialogUnits := GetDialogBaseUnits;
  dc := GetDC(0);

  SelectObject(dc,handle);
  GetTextMetrics(dc, tm);
  avgHeight := tm.tmHeight;

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

  HorizontalDLUs := Round( (4 * xPixels) / avgWidth );
  VerticalDLUs := Round( (8 * yPixels) / avgHeight );

//  HorizontalDLUs := Round( (xPixels / (avgWidth * LOWORD(DialogUnits))));
//  VerticalDLUs := Round( (yPixels / (avgHeight * HIWORD(DialogUnits))));
end;
Run Code Online (Sandbox Code Playgroud)

给定400z200像素形式,上述功能产生269乘123 DLU.这是表格的图片.左边是400x200像素的设计形式,右边的是基于以下形式生成和创建的形式:

DesignForm DIALOGEX 0, 0, 269, 123
STYLE  WS_CAPTION | WS_SIZEBOX | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP
CAPTION "DesignForm"
CLASS "DLGCLASS"
FONT 8, "Tahoma"
{
} 
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

Dan*_*Sęk 3

GetTextMetrics(dc, tm);
avgHeight := tm.tmHeight;

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

HorizontalDLUs := Round( (4 * xPixels) / avgWidth );
VerticalDLUs := Round( (8 * yPixels) / avgHeight );
Run Code Online (Sandbox Code Playgroud)

DLU 基于对话框字体的大小。水平 DLU 是对话框字体的平均宽度除以四。垂直 DLU 是字体高度除以八。

另请参阅GetDialogBaseUnits 函数中的备注部分,建议使用 MulDiv 函数。