【发布时间】:2018-03-11 13:56:52
【问题描述】:
我正在尝试将 Delphi 表单的宽度和高度像素计算为准确的对话框单元,以创建使用 DIALOGEX 语句的 .rc(资源脚本)文件。到目前为止,我还无法使用此处描述的 Microsoft 公式计算正确的对话单元:https://support.microsoft.com/en-us/help/145994/how-to-calculate-dialog-box-units-based-on-the-current-font-in-visual
以上链接使用GetDialogBaseUnits Win32 API 调用,但这不起作用,因为该API 函数使用系统字体。所以这是没用的。甚至微软也说我们应该改用MapDialogRect。因此,使用此处提供的公式来计算非系统字体的对话框基本单位https://support.microsoft.com/en-us/help/125681/how-to-calculate-dialog-base-units-with-non-system-based-font
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);
请注意,handle 来自创建的表单字体句柄。 avgSysWidth 和 avgSysHeight 我不确定如何获得这些值。
我已经看了两天了,似乎找不到最简单的进入对话单元的方法。我完全没有了?
更新 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;
给定一个 400z200 像素的形式,上述函数产生 269 x 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"
{
}
【问题讨论】:
-
图片看起来不错,如果您认为对话框资源指定了 client 维度,并且 Delphi 表单为您提供了 window 坐标。跨度>
-
啊,我完全错过了这个简单的事实。谢谢罗伯。我不敢相信我忽略了这个小细节。惊人的。我使用了表单的 ClientWidth 和 ClientHeight,现在它是一个完美的转换。你们摇滚!