Этот вопрос уже имеет ответ здесь:
Которые делают Вы думаете, лучшие практики для того, чтобы сделать диалоговое окно окон совместимым и со стандартными шрифтами (96 точек на дюйм) и "большими шрифтами" установка (120 точек на дюйм) так, чтобы объекты не накладывались или были отключены?
BTW: На всякий случай это релевантно, я интересуюсь выполнением этого для диалоговых окон Delphi.
Заранее спасибо!
довольно хорошая статья в файле справки D2007 в разделе « Рекомендации при динамическом изменении размера форм и элементов управления » (обратите внимание, что URL-адрес указывает на сам файл справки, а не на веб-страницу как таковую).
Эту же тему под тем же названием можно найти в файле справки D2010 (такое же предостережение относительно URL-адреса, как указано выше) или в docwiki .
Также стоит (хотя бы немного) изучить TForm.Scaled и TForm.ScaleBy.
Вот как я пытаюсь работать с пикселями Delphi VCL независимо от настройки размера шрифта Windows.
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.
Обычно для этой цели следует использовать менеджеры по расположению. Вот для чего они предназначены.
В Delphi (давно с ним не работал) таких менеджеров нет, но с тех пор он может обрабатывать разные dpi. Вы должны использовать свойство автоматического изменения размера компонентов, чтобы гарантировать, что они имеют правильный размер для текста, который они отображают. Чтобы компоненты не перекрывались, расположите их на форме, используя свойства выравнивания и привязки. В конце концов вам придется сгруппировать компоненты в контейнеры, чтобы получить правильный макет.
Но кроме этого? Возможно:
Я никогда не пробовал использовать TLabeledEdit в этом сценарии, может быть, они делают это автоматически?
Существуют предполагаемые коммерческие решения (Developer Express VCL Layout Manager). Но я не доверяю никому из них. Я подозреваю, что Embarcadero должен решить эту проблему как критическую слабость в текущем наборе компонентов пользовательского интерфейса (VCL).
Я думаю, что набор сторонних компонентов может быть вашим самым быстрым решением прямо сейчас. Это коммерчески, но не очень дорого.