If you have applied my techniques fixing Large Fonts and System Font to all forms in your Delphi application, most likely there will be two forms still untouched. These will be the forms hidden inside MessageDlg and InputQuery VCL functions.
Fortunately, MessageDlg supports Large Fonts and System Font ok, but InputQuery supports only Large Fonts. In this post I will show how to modify InputQuery to support System Font.
Screenshot: Original InputQuery when System Font is Tahoma, DPI=120

InputQuery implementation is hidden inside VCL, so a patch to VCL source code is needed.
The resulting InputQuery window will look like:

Most Delphi applications are using MS Sans Serif 8 as their default font, meanwhile Windows XP system font is Tahoma 8.25 and Windows Vista system font is Segoe UI.
Below code makes Delphi applications use Windows system font:
procedure TForm1.FormCreate(Sender: TObject);
var
NonClientMetrics: TNonClientMetrics;
begin
NonClientMetrics.cbSize := SizeOf(NonClientMetrics);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @NonClientMetrics, 0);
Font.Handle := CreateFontIndirect(NonClientMetrics.lfMessageFont);
if Scaled then
begin
Font.Height := NonClientMetrics.lfMessageFont.lfHeight;
end;
end;
99% of Delphi applications I have seen, do not support Large Fonts, or support it very badly. There is a Scaled property in TForm, people think it is about to scale the form in case of non-default DPI setting, but it is just not working properly.
Below code scales TForm the correct way:
procedure TForm1.FormCreate(Sender: TObject);
begin
Assert(not Scaled, 'TForm.Scaled property sucks, you should set it to False!');
if Screen.PixelsPerInch <> PixelsPerInch then
begin
ScaleBy(Screen.PixelsPerInch, PixelsPerInch);
end;
end;
Delphi stores design-time DPI of a form in PixelsPerInch property. This code handles scaling correctly even if some forms are designed in 96 DPI, and some forms in 120 DPI.
Windows API functions are declared in structured programming style.
For example consider classical example of using critical sections:
procedure Test;
var
CS: TCriticalSection;
begin
InitializeCriticalSection(CS);
try
EnterCriticalSection(CS);
try
//somecode
finally
LeaveCriticalSection(CS);
end;
finally
DeleteCriticalSection(CS);
end;
end;
Now consider the example rewritten in object-oriented Windows API:
procedure Test;
var
NewCS: TNewCriticalSection;
begin
NewCS.Initialize;
try
NewCS.Enter;
try
//somecode
finally
NewCS.Leave;
end;
finally
NewCS.Delete;
end;
end;
Bespoke the code is easier to read, the benefit is CodeInsight works nicely — type "NewCS." and press Control+Space…
Below unit implements new object-oriented Windows API:
unit NewWindows;
interface
uses Windows;
{$HINTS OFF}
type
TNewCriticalSection = object
private
FOldCriticalSection: TRTLCriticalSection;
public
procedure Initialize; stdcall;
procedure Delete; stdcall;
procedure Enter; stdcall;
procedure Leave; stdcall;
end;
{$HINTS ON}
implementation
procedure TNewCriticalSection.Initialize;
external kernel32 name 'InitializeCriticalSection';
procedure TNewCriticalSection.Delete;
external kernel32 name 'DeleteCriticalSection';
procedure TNewCriticalSection.Enter;
external kernel32 name 'EnterCriticalSection';
procedure TNewCriticalSection.Leave;
external kernel32 name 'LeaveCriticalSection';
end.
The trick is that Delphi object types are passed by value, hence when calling TNewCriticalSection.Initialize method, FOldCriticalSection field is occupying on the stack the same place argument of InitializeCriticalSection would do. Thus we can declare implementation of TNewCriticalSection.Initialize as external from kernel32.dll.
If you believe you've optimized your Delphi application to the max, and there is no room for performance improvement, then you should check out following site: http://sourceforge.net/projects/fastcode
Project Fastcode is competition of assembler developers on rewriting certain Delphi RTL functions to processor-specific code, utilizing extra instruction sets like SSE, SSE2, etc. This way Fastcode winners achieve 2x-4x performance boost compared to classic i386 implementations.
Each function in Fastcode project has 5 variants, each variant is optimized for certain processor architecture:
I have put together a package allowing you start on using Fastcode just in 5 mins. It contains units that auto-determine your CPU type and auto-patch VCL to use Fastcode. The following Fastcode functions are included:
I recommend using this package in non-GUI application servers, facilitating strong memory usage, etc.
Despite it will not make your application incredibly fast, overall speed up will be about 5%.