Я придумал вызов, который получает предпочтение шрифта пользовательского интерфейса (как в отличие от жестко запрограммированного выбора Borland "MS Sans Serif").
Представим, что предпочтение шрифта пользователя составляет:
Segoe Print, 15pt
Я установил шрифт всех элементов во всех формах во всех приложениях следующим образом:
Segoe Print, 15pt
Проблема в том, что сейчас все отрезано. Кнопки слишком маленькие - слишком узкие, слишком короткий. Текст в этикетках обрезан и т. д.
У формы есть свойство Scaled, но оно не меняется в зависимости от шрифта. размеры. Свойство scaled масштабировало форму при ее сериализации на основе высота цифры «0».
Я не могу найти в справке ничего о том, как Borland намеревался поддерживать пользовательские настройки приложения Windows.
Как мне управлять пользовательскими настройками шрифтов?
Примечание: Я отправил это перекрестно с сервера группы новостей Embargadero, так как сервер новостей Embargadero, кажется, умирает, или подвергается цензуре, или сломан, или требует входа в систему.
Я говорю о предпочтениях шрифта пользователя, а не о настройках DPI. то есть: представьте себе следующий псевдокод языковой нейтральный:
procedure TForm1.FormCreate(Sender: TObject);
var
FontFace: string;
FontHeight: Integer;
begin
GetUserFontPreference(out FontFace, out FontHeight);
Self.Font.Name := FontFace;
Self.Font.Height := FontHeight;
end;
Примечание: Это не мой настоящий код (в конце концов, это псевдокод, не зависящий от языка). Но, кроме того, вам нужно рекурсивно пройти через все элементы управления в форме, изменяя шрифт, когда его нужно изменить. Если к шрифту применен стиль, отличный от его родительского (например, полужирный), и он больше не наследуется от своего родителя, его необходимо установить вручную.
В соответствии с запросом Lkessler, вот код для получения предпочтения шрифта пользовательского интерфейса из Windows:
procedure GetUserFontPreference(out FaceName: string; out PixelHeight: Integer);
var
lf: LOGFONT;
begin
ZeroMemory(@lf, SizeOf(lf));
//Yes IconTitleFont (not SPI_GETNONCLIENTMETRICS MessageFont)
if SystemParametersInfo(SPI_GETICONTITLELOGFONT, SizeOf(lf), @lf, 0) then
begin
FaceName := PChar(Addr(lf.lfFaceName[0]));
PixelHeight := lf.lfHeight;
end
else
begin
{
If we can't get it, then assume the same non-user preferences that
everyone else does.
}
FaceName := 'MS Shell Dlg 2';
PixelHeight := 8;
end;
end;
Я обновлю исходный вопрос кодом
Разные шрифты или разные настройки DPI - какая разница, зачем нужно настраивать размеры и положение элементов управления? Адаптация к предпочтениям шрифта пользователя потребует, чтобы размеры и положение элементов управления вычислялись во время выполнения, как и при других настройках DPI.
Но, как я сказал в своем ответе, возможно, код Джордана Рассела может вам помочь. Просто масштабируйте все формы пропорционально соотношению средней ширины и высоты шрифта пользовательского шрифта и шрифта MS Sans Serif 8 (или любого другого шрифта, с которым были разработаны формы).
Почему: если вы измените настройку «Шрифт сообщения», вы заметите, что Windows не реагирует на это - она использует настройку «Заголовок значка». Итак, если вы хотите соответствовать шрифту пользовательского интерфейса, который использует Windows, вы хотите использовать IconTitleFont. В противном случае вы будете выглядеть иначе, чем все остальное, а это не то, что вам нужно.
@anonymousstackoverflowuser: Спасибо. Это могло произойти со мной без «внешней» помощи. :-) Я в настоящее время (неправильно) использую MessageFont, попробую IconTitleFont.





Во-первых, чтобы нам было ясно, Borland больше не владеет Delphi. Embarcadero теперь владеет Delphi, и теперь мы в надежных и надежных руках.
Хорошо, к твоему вопросу.
Хитрость заключается в том, чтобы установить для TForm.AutoScroll значение False И убедиться, что на вашей машине разработки установлены мелкие шрифты. Оставив TForm.Scaled в покое (значение по умолчанию - True).
Вот как мы делаем это внутри, и IDE справляется со всем отлично.
AFAICS, IDE не справляется со всем просто отлично. На экране моего ноутбука (установленном на 124 DPI) все строки в инспекторе объектов Delphi 2007 обрезаются ...
Сказать разработчикам «убедиться, что на вашей машине разработки установлены мелкие шрифты» не является уловкой в моей книге. Это либо невежество, либо садизм. Просто попробуйте мелкие шрифты на дисплее с разрешением 145 точек на дюйм ...
Вы не читаете вопрос; предполагая разные настройки DPI. я говорю о разных шрифтах. Предположим, для целей этого вопроса, что каждая машина в мире настроена на 96 точек на дюйм.
«Embarcadero теперь владеет Delphi, и теперь мы в надежных руках». я подожду 10 лет, прежде чем согласиться.
Я чувствую себя с тобой. Но честно говоря: правильный макет GUI просто не может быть создан с помощью механизма макета на основе пикселей, который используется VCL. Что необходимо, так это механизм динамической компоновки, который размещает элементы управления только после того, как
для каждого элемента управления установлен правильный шрифт (это зависит от версии Windows, пользовательских настроек и, наконец, что не менее важно, от типа элемента управления); а также
текст в элементе управления был переведен в текущую локаль, так как это может уменьшить или увеличить пространство, необходимое для элемента управления.
Поскольку все это зависит от свойств времени выполнения, создание диалоговых окон путем размещения элементов управления не может работать. Механизмы компоновки, такие как GTK и QT или сайзеры в wxWidgets, подходят лучше.
Я ничего не знаю о программах на Delphi. Что я делаю в некоторых программах, так это ручное изменение размера и положения элементов управления после установки шрифта и перевода текста. Много работы, но, в зависимости от вашей аудитории, она того стоит.
Вы также можете изучить код, написанный Джорданом Расселом для Inno Setup. Он не использует свойство Scaled форм, но написал код для настраиваемого масштабирования элементов управления. Возможно, это также будет работать для очень больших шрифтов на экранах с высоким разрешением; Я заметил, что, по крайней мере, на моем экране ноутбука с разрешением 124 точек на дюйм диалоговые окна настройки выглядят неплохо.
я не согласен. Концепция DLU работает очень хорошо. Microsoft почти исправила это в WinForms, но упустила важные моменты, так что это так же плохо, как и Borlands.
Использование DLU не поможет, если: а) разные элементы управления используют разные шрифты (как в Vista); б) длина текста будет меняться во время выполнения, в зависимости от перевода; и c) механизм компоновки также должен использоваться для изменения размеров диалогов во время выполнения. Существуют механизмы компоновки, поддерживающие все три. DLU не помогают.
а) DLU масштабируются шрифтами (как в Vista) б) я никогда ничего не писал, кроме английского в)
a) Vista использует разные шрифты для разных элементов управления (см. msdn.microsoft.com/en-us/library/aa511282.aspx), и их нужно соответственно масштабировать. Какой DLU это будет? Но давайте остановимся, это никуда не денется.
Чтобы сделать это правильно, я думаю, вам придется:
1 - Загрузить настройки шрифта пользователя
2 - Примените его, как вы описали
3 - Определите ширину и высоту всех заголовков (в пикселях) и сравните их с шириной и высотой элемента управления и отрегулируйте соответствующим образом.
К сожалению, «отрегулировать соответственно» сложно. Вы можете расширить кнопку, но тогда вам нужно будет проверить, не перекрывается ли она с другим элементом управления.
Лучше всего создать элементы управления немного завышенного размера и надеяться, что пользователь не выберет размер шрифта в 32 пункта.
:( <-sad face, и этот текст здесь только для того, чтобы сделать комментарий достаточно длинным, чтобы stackoverflow разрешил принять мой двухсимвольный комментарий как действительный.
У Когуса была правильная идея, но он не упомянул функцию, которую вам нужно использовать. Это будет процедура Windows GetTextExtentPoint32. Вы передаете ему строку, и он вычисляет ширину и высоту строки, используя текущий выбранный шрифт. Вы найдете его в Windows.pas.
Возможно, вы захотите заранее рассчитать, какое максимальное пространство вам понадобится для разрешенных шрифтов.
Или вы можете использовать эту функцию для динамической регулировки размера области, отображающей текст, по размеру.
Это было бы хорошо для одного или двух элементов управления, но любой метод потребует много работы, если вы попытаетесь сделать это для всего пользовательского интерфейса.
Я бы сказал, это было похоже на перевод. В нашем приложении мы сделали кнопки, метки, правки, все немного больше, чтобы можно было легко разместить более длинные слова, необходимые для некоторых языков. Это нисколько не повредит дизайну.
Мне нравится использовать эту функцию. Он основан на Graphics.GetFontData
procedure SystemFont(Font: TFont);
var
LogFont: TLogFont;
begin
if SystemParametersInfo(SPI_GETICONTITLELOGFONT, SizeOf(TLogFont), @LogFont, 0) then
begin
Font.Height := LogFont.lfHeight;
Font.Orientation := LogFont.lfOrientation;
Font.Charset := TFontCharset(LogFont.lfCharSet);
Font.Name := PChar(@LogFont.lfFaceName);
Font.Style := [];
if LogFont.lfWeight >= FW_BOLD then
Font.Style := Font.Style + [fsBold];
if LogFont.lfItalic = 1 then
Font.Style := Font.Style + [fsItalic];
if LogFont.lfUnderline = 1 then
Font.Style := Font.Style + [fsUnderline];
if LogFont.lfStrikeOut = 1 then
Font.Style := Font.Style + [fsStrikeOut];
case LogFont.lfPitchAndFamily and $F of
VARIABLE_PITCH: Font.Pitch := fpVariable;
FIXED_PITCH: Font.Pitch := fpFixed;
else Font.Pitch := fpDefault;
end;
end;
end;
Вы просто используете его для всех событий TForm.OnCreate. Альтернативой может быть создание нового класса, который будет делать это при создании или зацикливании Screen.Forms.
Если вы измените некоторые свойства шрифта по умолчанию для любого из элементов управления в форме, они все равно будут использовать старый шрифт. Если вам нужны настраиваемые свойства для некоторых элементов управления, вам придется настроить их после вызова SystemFont.
Изменение Graphics.DefFontData во время выполнения могло бы помочь, если бы разработчик форм только записывал измененные свойства в файлы .dfm.
Это не решает проблему, заключающуюся в том, что нестандартные шрифты могут сделать текст в элементах управления слишком большим, поэтому необходимо изменить размер и положение.
я собирался сказать то же самое. у меня нет проблем получающий шрифт по умолчанию, вопрос: "Обработка предпочтений шрифта пользователя"
Мне любопытно. Какой вызов вы используете, чтобы получить предпочтение шрифта пользовательского интерфейса?