Сначала мы начнем с что такое диалоговая единица.
Для этого я процитирую один из моих собственных неотвеченных вопросов :
Что такое диалоговая единица?
Диалог - это единица измерения, основанная на предпочитаемом пользователем размере шрифта.Диалоговая единица определяется так, что средний символ имеет ширину 4 диалоговых элемента и высоту 8 диалоговых блоков:
Это означает, что диалоговые единицы:
- изменить с выбранным шрифтом
- изменить с выбранной настройкой DPI
- не квадратные
я также процитирую другой мои собственные неотвеченные вопросы :
Вы можете проверить Руководство по Windows UX , чтобы увидеть, откуда приходят эти измерения.Краткая версия:
- dlu = диалоговое окно
- dlu основано на размере шрифта ( элементы изменяются с размером шрифта пользователя )
- a по горизонтали Длу отличается от по вертикали Длу ( Длу не квадратные )
Этопроисходит от определения диалоговой единицы: средний символ имеет высоту 8dlus и ширину 4dlus .
Georgia 14pt:
Если вы используете шрифт меньшего размера (т. Е. Стихи Тахомы 8pt, 14pt Georgia), dlus становится меньше:
Пользовательский интерфейс Segoe 9pt:
Примечание : Вы заметите, что разрешение (т.е. dpi) не влияет на обсуждение.
Так что вам нужно средний размер символа.У Microsoft есть официальный метод для расчета среднего размера символов.
средняя высота:
GetTextMetrics(dc, {var}textMetrics);
averageHeight := textMetrics.tmHeight;
средняя ширина:
Измерьте строку ABCDEFGHIJLKMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz , используя GetTextExtentPoint32
, и разделите на 52:
GetTextExtentPoint32(dc,
PChar('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'), 52, Size));
averageWidth := size.cx / 52.0;
ТеперьВам нужен размер горизонтального и вертикального диалоговых блоков.Помните, что горизонтальная единица диалога равна 1/4 средней ширины символа, а вертикальная длина равна 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;
Примечание : любой кодпубликуется в открытом доступе.Указание авторства не требуется.