您认为哪些是使 Windows 对话框与标准字体 (96 dpi) 和“大字体”设置 (120 dpi) 兼容的最佳做法,这样对象就不会重叠或被切断?
顺便说一句:以防万一,我有兴趣为 Delphi 对话框执行此操作。
提前致谢!
您认为哪些是使 Windows 对话框与标准字体 (96 dpi) 和“大字体”设置 (120 dpi) 兼容的最佳做法,这样对象就不会重叠或被切断?
顺便说一句:以防万一,我有兴趣为 Delphi 对话框执行此操作。
提前致谢!
通常,为此目的应该使用布局管理器。这就是他们的设计目的。
Delphi(很长时间没有使用它)没有这样的管理器,但从那时起就能够处理不同的 dpi。您必须使用组件的 autosize 属性来确保它们具有适合所显示文本的大小。为了防止组件重叠,使用对齐和锚属性将它们排列在表单上。最终,您必须将容器中的组件分组以实现正确的布局。
D2007 帮助文件中有一篇很好的文章,在“动态调整窗体和控件大小时的注意事项”下(请注意,该 URL 指向帮助文件本身,而不是网页本身)。
可以在D2010 帮助文件(与上述 URL 相同的警告)或docwiki中找到相同名称的相同主题。
检查 TForm.Scaled 和 TForm.ScaleBy 也是值得的(至少一点点)。
这就是我尝试处理 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。
但除此之外呢?也许:
我从未尝试过在那种情况下使用 TLabeledEdit,也许他们会自动这样做?
据称有商业解决方案(Developer Express VCL Layout Manager)。但我不相信他们中的任何一个。我怀疑 Embarcadero 应该将此作为当前 UI 组件集 (VCL) 中的一个关键弱点来解决。
我认为第三方组件集可能是您目前最快的解决方案。它是商业的,但不是非常昂贵。