2010-03-31 3 views
35

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

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

Заранее благодарен!

+2

11 upvotes и ответов пока нет! Звучит неплохо. –

+0

Вопрос немного неспецифичен. Было бы легче ответить на конкретную проблему. Таким образом, ответы также широки в сфере охвата. – merula

+0

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

ответ

7

В файле справки D2007 имеется довольно хорошая статья в разделе «Considerations When Dynamically Resizing Forms and Controls» (обратите внимание, что URL-адрес относится к самому файлу справки, а не к веб-странице как таковой).

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

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

8

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

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

+4

Я думаю, что короткий ответ: «Это ОГРОМНОЕ слабое место дельфи». XAML делает это лучше. Java/Swing делает это лучше. Честно говоря, все остальное там делает это лучше, чем Delphi. Даже материал с открытым исходным кодом, такой как Glade, основанный на макете, делает это лучше. –

+0

Современные версии Delphi имеют компоненты управления компоновкой, по крайней мере в FireMonkey: [Стратегии макета FireMonkey] (http://docwiki.embarcadero.com/RADStudio/en/FireMonkey_Layouts_Strategies). Тем не менее, существуют сторонние компоненты компоновки, доступные для VCL. –

0
  • Никогда не ставьте контрольную и описывающую этикетку рядом друг с другом, всегда помещайте этикетку поверх нее.

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

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

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

0

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

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

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

+0

Есть ли поддержка по этой теме в современных версиях Delphi? (XE и выше) – EProgrammerNotFound

+0

Не для больших дисплеев DPI, что является основной проблемой, «Большие размеры шрифта» действительно означает дисплеи более высокого уровня, чем 96 DPI, а также «взломать DPI», используемый Microsoft (Fake DPI для увеличения шрифтов). –

2

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

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, включая VCL диалоги в Delphi.

+0

Почему вы используете «классный помощник» для собственного класса «TAppScreen»? Все члены класса должны быть в самом классе «TAppScreen». Нет необходимости использовать «класс-помощник» для «TAppScreen». Что касается получения доступа к члену 'TScreen.FPixelsPerInch', рассмотрите возможность использования Enhanced RTTI через модуль System.Rtti, который может получить доступ к закрытым и общедоступным полям, а не только к опубликованным свойствам, например, Legacy RTTI из модуля« TypInfo ». –

 Смежные вопросы

  • Нет связанных вопросов^_^