I've come up with the call that gets the user's UI font preference (as opposed to Borland's hard-coded choice of "MS Sans Serif").
Let's pretend the user's font preference is:
Segoe Print, 15pt
I set the font of all items, on all forms, in all applications to:
Segoe Print, 15pt
Problem is that things are now cut off. Buttons are too small - too narrow, too short. Text in labels is cut off, etc..
The form has it's Scaled property, but that doesn't change depending on font sizes. The scaled property scaled the form when it is serialized in based on the height of the numeral "0".
I can't find anything in the help for how Borland intended me to support the user's Windows application preferences.
How do I handle user font preferences?
Note: I cross posted this from Embargadero's news group server, since Embargadero's news server seems to be dying, or censoring, or broken, or requiring a login.
i'm talking about a user's font preference, not DPI settings. i.e.: imagine the following language neutral pseudo-code:
procedure TForm1.FormCreate(Sender: TObject);
var
FontFace: string;
FontHeight: Integer;
begin
GetUserFontPreference(out FontFace, out FontHeight);
Self.Font.Name := FontFace;
Self.Font.Height := FontHeight;
end;
Note: This isn't my actual code (it is language neutral pseudo-code after all). But additionally, you need to recursivly go through every control on the form, changing the font when it needs to be changed. When a font has a different style applied than its parent (e.g. bold), and no longer inherits from its parent, it needs to be manually set.
As per lkessler's request, here's the code to retrieve the user's UI font preference from Windows:
procedure GetUserFontPreference(out FaceName: string; out PixelHeight: Integer);
var
lf: LOGFONT;
begin
ZeroMemory(@lf, SizeOf(lf));
//Yes IconTitleFont (not SPI_GETNONCLIENTMETRICS MessageFont)
if SystemParametersInfo(SPI_GETICONTITLELOGFONT, SizeOf(lf), @lf, 0) then
begin
FaceName := PChar(Addr(lf.lfFaceName[0]));
PixelHeight := lf.lfHeight;
end
else
begin
{
If we can't get it, then assume the same non-user preferences that
everyone else does.
}
FaceName := 'MS Shell Dlg 2';
PixelHeight := 8;
end;
end;
First, just so we are clear, Borland doesn't own Delphi anymore. Embarcadero now owns Delphi, and we are in safe, secure hands now.
Okay, on to your question.
The trick is to set TForm.AutoScroll to False AND make sure that your development machine is set to Small fonts. Leaving TForm.Scaled alone (it's default value is True).
That's how we do it internally here, and the IDE handles everything just fine.
I'm feeling with you. But in all fairness: Proper GUI layout simply can not be created with a pixel-based layout mechanism as employed by the VCL. What is needed is a dynamic layout engine, which lays out controls only after
the proper font has been set for each control (this depends on Windows version, user preferences, and last but not least on the type of control); and
the text in the control has been translated to the current locale, because this may decrease or increase the space necessary for the control.
Since this is all depending on run-time properties creating dialogs by placing controls can not work. Layout mechanisms like those of GTK and QT or the sizers in wxWidgets are better suited.
I know of no such thing for Delphi programs. What I do in some programs is manual sizing and positioning of controls after font setting and translation of text. A lot of work, but depending on your audience it may be worth it.
You could also look into the code Jordan Russell has written for Inno Setup. He does not use the Scaled property of forms, but has written code for custom scaling of controls. Maybe it will also work for very large fonts on high DPI screens; I notice that at least on my 124 DPI laptop screen setup dialogs look quite good.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With