35

您认为哪些是使 Windows 对话框与标准字体 (96 dpi) 和“大字体”设置 (120 dpi) 兼容的最佳做法,这样对象就不会重叠或被切断?

顺便说一句:以防万一,我有兴趣为 Delphi 对话框执行此操作。

提前致谢!

4

5 回答 5

8

通常,为此目的应该使用布局管理器。这就是他们的设计目的。

Delphi(很长时间没有使用它)没有这样的管理器,但从那时起就能够处理不同的 dpi。您必须使用组件的 autosize 属性来确保它们具有适合所显示文本的大小。为了防止组件重叠,使用对齐和锚属性将它们排列在表单上。最终,您必须将容器中的组件分组以实现正确的布局。

于 2010-03-31T12:33:01.627 回答
7

D2007 帮助文件中有一篇很好的文章,在“动态调整窗体和控件大小时的注意事项”下(请注意,该 URL 指向帮助文件本身,而不是网页本身)。

可以在D2010 帮助文件(与上述 URL 相同的警告)或docwiki中找到相同名称的相同主题。

检查 TForm.Scaled 和 TForm.ScaleBy 也是值得的(至少一点点)。

于 2010-03-31T12:49:44.807 回答
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;

您应该在实例化 TForm 的后代(包括 Delphi 的 VCL 对话框)之前更改 PixelsPerInch。

于 2010-04-01T03:29:41.517 回答
0
  • 切勿将控件及其描述标签并排放置,始终将标签放在其顶部。

但除此之外呢?也许:

  • 在标签的右侧和底部留出足够的空间,以便在使用大字体时它们不会与其他控件重叠。

我从未尝试过在那种情况下使用 TLabeledEdit,也许他们会自动这样做?

于 2010-03-31T13:18:10.457 回答
0

据称有商业解决方案(Developer Express VCL Layout Manager)。但我不相信他们中的任何一个。我怀疑 Embarcadero 应该将此作为当前 UI 组件集 (VCL) 中的一个关键弱点来解决。

我认为第三方组件集可能是您目前最快的解决方案。它是商业的,但不是非常昂贵。

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

于 2010-03-31T20:05:52.353 回答