Delphi: настройка предпочтений пользователя

Я придумал вызов, который получает предпочтение пользовательского интерфейса пользователя (как против Borland жестко кодированного выбора "MS Sans Serif" ).

Предположим, что предпочтительнее пользовательский шрифт:

Segoe Print, 15pt

Я устанавливаю шрифт всех элементов во всех формах во всех приложениях:

Segoe Print, 15pt

Проблема в том, что вещи теперь отрезаны. Кнопки слишком маленькие - слишком узкие, слишком короткий. Текст в ярлыках отключен и т.д.

Форма имеет свойство Scaled, но это не изменяется в зависимости от шрифта размеры. Масштабированное свойство масштабировало форму, когда она сериализована в соответствии с высота цифры "0".

Я не могу найти что-либо в помощи для того, как Borland намеревался меня поддерживать пользовательских настроек Windows.

Как мне обрабатывать предпочтения шрифтов пользователя?

Примечание.. Я перекрестился с сервером новостей группы Embargadero, поскольку сервер новостей Embargadero, кажется, умирает, подвергается цензуре или сломается или требует входа в систему.


Обновление 1

Я говорю о предпочтении шрифта пользователя, а не о настройках 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;

Связанные вопросы

Ответ 1

Во-первых, просто так ясно, что Borland больше не владеет Delphi. Теперь Embarcadero владеет Delphi, и теперь мы находимся в безопасных, надежных руках.

Хорошо, на ваш вопрос.

Трюк заключается в том, чтобы установить TForm.AutoScroll в значение False И убедитесь, что для вашей машины разработки заданы малые шрифты. Выход из TForm.Scaled в одиночку (значение по умолчанию - True).

То, как мы делаем это внутри здесь, и IDE обрабатывает все как можно лучше.

Ответ 2

Я чувствую себя с тобой. Но со всей справедливостью: Правильный графический интерфейс GUI просто не может быть создан с помощью механизма компоновки на основе пикселей, используемого VCL. Нужен динамический механизм компоновки, который выводит элементы управления только после

  • для каждого элемента управления был установлен правильный шрифт (это зависит от версии Windows, пользовательских настроек и, наконец, не в последнюю очередь от типа управления); и

  • текст в элементе управления был переведен в текущую локаль, поскольку это может уменьшить или увеличить пространство, необходимое для элемента управления.

Так как это все зависит от свойств времени выполнения, создание диалогов с помощью размещения элементов управления не может работать. Механизмы компоновки, такие как GTK и QT, или sizers в wxWidgets лучше подходят.

Я не знаю таких вещей для программ Delphi. То, что я делаю в некоторых программах, - это ручное измерение и позиционирование элементов управления после настройки шрифта и перевода текста. Много работы, но в зависимости от вашей аудитории это может стоить того.

Вы также можете посмотреть код, который Джордан Рассел написал для Inno Setup. Он не использует свойство Scaled форм, но написал код для пользовательского масштабирования элементов управления. Возможно, он также будет работать для очень больших шрифтов на высоких экранах DPI; Я замечаю, что по крайней мере на моих 124-дюймовых диалоговом окне настройки экрана ноутбука DPI выглядят неплохо.

Ответ 3

Мне нравится использовать эту функцию. Он основан на Graphics.GetFontData​​p >

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 файлы.

Ответ 4

Чтобы сделать это правильно, я думаю, вам придется:

1 - Загрузите предпочтение шрифта пользователя

2 - примените его так, как вы описали

3 - Определите ширину и высоту всех титров (в пикселях) и сравните их с шириной и высотой управления и соответствующим образом отрегулируйте.

К сожалению, часть "отрегулировать соответствующую" трудно. Вы можете расширить кнопку, но тогда вам нужно будет проверить, перекрывается ли это с другим элементом управления.

Лучше всего создать несколько негабаритных элементов управления и надеяться, что пользователь не выберет 32-точечный размер шрифта.

Ответ 5

У Kogus была правильная идея, но она оставила функцию, которую вам нужно использовать. Это будет Windows GetTextExtentPoint32. Вы передаете ему строку и вычисляет ширину и высоту строки, используя текущий выбранный шрифт. Вы найдете его в Windows.pas.

Возможно, вам захочется заранее рассчитать, какое максимальное пространство вам потребуется для шрифтов, которые вы разрешаете.

Или вы можете использовать эту функцию для динамической настройки размера области, отображающей текст, чтобы она соответствовала.

Это было бы хорошо для одного или двух элементов управления, но любой из этих методов был бы очень полезен, если вы пытаетесь сделать это на своем пользовательском интерфейсе.

Ответ 6

Я бы сказал, что это было похоже на перевод. В нашем приложении мы создали кнопки, метки, правки, все, что немного больше, чтобы можно было легко разместить более длинные слова, которые нужны на некоторых языках. Это немного мешает дизайну.