Сделайте диалоги совместимыми с «большими шрифтами». [Дубликат]

36

Каковы, по вашему мнению, лучшие методы для создания диалогового окна Windows, совместимого со стандартными шрифтами (96 dpi) и "большими шрифтами" (120 dpi), чтобы объекты не перекрывались или не обрезались?

BTW: На всякий случай это актуально, я заинтересован в том, чтобы делать это для диалогов Delphi.

Спасибо заранее!

  • 2
    11 голосов и пока нет ответов! Звучит как довольно хороший вопрос.
  • 0
    Вопрос немного не конкретен. Было бы проще ответить на конкретную проблему. Так что ответы тоже широки.
Показать ещё 2 комментария
Теги:
dialog
font-size

5 ответов

7
Лучший ответ

В файле справки D2007 есть довольно хорошая статья: Соображения при динамическом изменении форм и элементов управления" (обратите внимание, что URL-адрес сам файл справки, а не веб-страницу как таковой).

Те же темы под тем же именем можно найти в файле справки D2010 (о том же предостережении о URL-адресе, как указано выше), или на docwiki.

Также полезно (по крайней мере немного) изучить TForm.Scaled и TForm.ScaleBy.

8

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

Delphi (не работал с ним в течение длительного времени) не имеет таких менеджеров, но с тех пор способен обрабатывать разные dpi. Вы должны использовать свойство autosize компонентов, чтобы убедиться, что они имеют нужный размер для текста, который они отображают. Чтобы предотвратить перекрытие компонентов, расположите их в форме с использованием свойств выравнивания и привязки. В конце концов вам нужно сгруппировать компоненты в контейнерах для достижения правильной компоновки.

  • 4
    Я думаю, что короткий ответ «это ОГРОМНОЕ слабое место delphi». XAML делает это лучше. Java / Swing делает это лучше. Честно говоря, все остальное делает это лучше, чем Delphi. Даже такие вещи с открытым исходным кодом, как Glade, основанный на менеджере компоновки, делают это лучше.
  • 0
    Современные версии Delphi имеют компоненты управления макетом, по крайней мере, в FireMonkey: FireMonkey Layouts Strategies . Однако для VCL доступны сторонние компоненты макета.
2

Вот как я пытаюсь работать с пикселями Delphi VCL независимо от настроек размера шрифта Window.

unit App.Screen;

interface

uses Controls;

type
  TAppScreen = class(TObject)
  private
    FDefaultPixelsPerInch: integer;
    FPixelsPerInch: integer;
    function GetPixelsPerInch: integer;
    procedure SetPixelsPerInch(const Value: integer);
  public
    procedure AfterConstruction; override;
    function DefaultPixelsPerInch: integer;
    function InAcceptableRange(const aPPI: integer): boolean;
    procedure ScaleControl(const aControl: TWinControl);
    property PixelsPerInch: integer read GetPixelsPerInch write SetPixelsPerInch;
  end;

  TAppScreenHelper = class helper for TAppScreen
  private
    class var FInstance: TAppScreen;
    class function GetInstance: TAppScreen; static;
  public
    class procedure Setup;
    class procedure TearDown;
    class property Instance: TAppScreen read GetInstance;
  end;

implementation

uses
  TypInfo, Windows, SysUtils, Forms, Graphics;

type
  TScreenEx = class(TScreen)
  published
    property PixelsPerInch;
  end;

  TScreenHelper = class helper for TScreen
  public
    procedure SetPixelsPerInch(Value: integer);
  end;

procedure TScreenHelper.SetPixelsPerInch(Value: integer);
begin
  PInteger(Integer(Self) + (Integer(GetPropInfo(TScreenEx, 'PixelsPerInch').GetProc) and $00FFFFFF))^ := Value;
end;

procedure TAppScreen.AfterConstruction;
begin
  inherited;
  FDefaultPixelsPerInch := Screen.PixelsPerInch;
  FPixelsPerInch := FDefaultPixelsPerInch;
end;

function TAppScreen.DefaultPixelsPerInch: integer;
begin
  Result := FDefaultPixelsPerInch;
end;

function TAppScreen.GetPixelsPerInch: integer;
begin
  Result := FPixelsPerInch;
end;

function TAppScreen.InAcceptableRange(const aPPI: integer): boolean;
begin
  if DefaultPixelsPerInch > aPPI then
    Result := DefaultPixelsPerInch * 0.55 < aPPI
  else if DefaultPixelsPerInch < aPPI then
    Result := DefaultPixelsPerInch * 1.55 > aPPI
  else
    Result := True;
end;

procedure TAppScreen.ScaleControl(const aControl: TWinControl);
begin
  aControl.ScaleBy(PixelsPerInch, DefaultPixelsPerInch);
end;

procedure TAppScreen.SetPixelsPerInch(const Value: integer);
begin
  FPixelsPerInch := Value;
  Screen.SetPixelsPerInch(FPixelsPerInch);
end;

class function TAppScreenHelper.GetInstance: TAppScreen;
begin
  if FInstance = nil then
    FInstance := TAppScreen.Create;
  Result := FInstance;
end;

class procedure TAppScreenHelper.Setup;
begin
  TAppScreen.Instance;
end;

class procedure TAppScreenHelper.TearDown;
begin
  FInstance.Free;
  FInstance := nil;
end;

initialization
  TAppScreen.Setup;
finalization
  TAppScreen.TearDown;
end.

Попробуйте выполнить следующие действия для проверки эффектов разных значений пикселей:

TAppScreen.Instance.PixelsPerInch := 120;
TAppScreen.Instance.PixelsPerInch := 96;
TAppScreen.Instance.PixelsPerInch := 150;

Вы должны изменить PixelsPerInch перед тем, как создать экземпляр TForm, включая диалоги Delphi VCL.

  • 0
    Почему вы используете class helper для своего собственного класса TAppScreen ? Все члены class должны быть в TAppScreen классе TAppScreen . Нет необходимости использовать class helper для TAppScreen вообще. Что касается получения доступа к TScreen.FPixelsPerInch , рассмотрите возможность использования расширенного RTTI через модуль System.Rtti , который может получать доступ к закрытым и общедоступным полям, а не только к опубликованным свойствам, таким как Legacy RTTI из TypInfo .
0

Существуют коммерческие решения (Developer Express VCL Layout Manager). Но я не доверяю никому из них. Я подозреваю, что Embarcadero должен рассматривать это как критическую слабость в текущем наборе компонентов пользовательского интерфейса (VCL).

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

http://www.devexpress.com/products/VCL/ExLayoutControl/

  • 0
    Есть ли поддержка этой темы в современных версиях Delphi? (XE и выше)
  • 0
    Не для дисплеев с высоким DPI, что является основной проблемой, «Большие размеры шрифтов» на самом деле означают дисплеи с разрешением выше 96 DPI, а также «взлом DPI», используемый Microsoft (Fake DPI для увеличения шрифтов).
0
  • Никогда не помещайте элемент управления и его описание рядом друг с другом, всегда помещайте этикетку поверх нее.

Но кроме этого? Может быть:

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

Я никогда не пробовал использовать TLabeledEdit в этом сценарии, возможно, они это делают автоматически?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню