FONTS
From: choate@cswnet.com (Brad Choate)
Can someone please tell me the neatest way to make sure my app uses fonts that I can provide, rather than the nearest font the user has installed on their system? I have tried copying a #.ttf file into the users windows\system directory but the app still can't pick it up.
The following is some Delphi 1 code that I have used for successfully installing dynamic fonts that are only loaded while the application is running. You can place the font file(s) within the application directory. It will be installed when the form loads and unloaded once the form is destroyed. You may need to modify the code to work with Delphi 2 since it calls various Windows API calls that may or may not have changed. Where you see "..." in the code, that is just to identify that other code can be placed there.
Of course, substitute "MYFONT" for the name of your font file.
type TForm1=class( TForm ) procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); ... private { Private declarations } bLoadedFont: boolean; public { Public declarations } end; procedure TForm1.FormCreate(Sender: TObject); var sAppDir: string; sFontRes: string; begin sAppDir := Application.ExeName; sAppDir := copy( sAppDir, 1, rpos( '\', sAppDir ) ); sFontRes := sAppDir + 'MYFONT.FOT'; if not FileExists( sFontRes ) then begin sFontRes := sFontRes + #0; sFont := sAppDir + 'MYFONT.TTF' + #0; CreateScalableFontResource( 0, @sFontRes[ 1 ], @sFont[ 1 ], nil ); end; sFontRes := sAppDir + 'MYFONT.FOT'; if FileExists( sFontRes ) then begin sFontRes := sFontRes + #0; if AddFontResource( @sFontRes[ 1 ] ) = 0 then bLoadedFont := false else begin bLoadedFont := true; SendMessage( HWND_BROADCAST, WM_FONTCHANGE, 0, 0 ); end; end; ... end; procedure TForm1.FormDestroy(Sender: TObject); var sFontRes: string; begin if bLoadedFont then begin sFontRes := sAppDir + 'MYFONT.FOT' + #0; RemoveFontResource( @sFontRes[ 1 ] ); SendMessage( HWND_BROADCAST, WM_FONTCHANGE, 0, 0 ); end; end;
I've worked with the fonts code and have some corrections for you to make it work with Delphi 2.0. I have not tried this on Delphi 3.0.
Information in an InstallShield article about installing fonts reveals that you do not need a FOT file in Win95 and WinNT environments. You only need the TTF file.
Resulting FormCreate code is as follows:
var sAppDir, sFontRes: string; begin {...other code...} sAppDir := extractfilepath(Application.ExeName); sFontRes := sAppDir + 'MYFONT.TTF'; if FileExists( sFontRes ) then begin sFontRes := sFontRes + #0; if AddFontResource( @sFontRes[ 1 ] ) = 0 then bLoadedFont := false else begin bLoadedFont := true; SendMessage( HWND_BROADCAST, WM_FONTCHANGE, 0, 0); end; end; {...} end; {FormCreate}
var sFontRes, sAppDir: string; begin {...other code...} if bLoadedFont then begin sAppDir := extractfilepath(Application.ExeName); sFontRes := sAppDir + 'MYFONT.TTF' + #0; RemoveFontResource( @sFontRes[ 1 ] ); SendMessage( HWND_BROADCAST, WM_FONTCHANGE, 0, 0 ); end; {...other code...} end; {FormDestroy}
{1998-01-16 Font loading and unloading function.} function LoadFont(sFontFileName: string; bLoadIt: boolean): boolean; var sFont, sAppDir, sFontRes: string; begin result := TRUE; if bLoadIt then begin {Load the font.} if FileExists( sFontFileName ) then begin sFontRes := sFontFileName + #0; if AddFontResource( @sFontRes[ 1 ] ) = 0 then result := FALSE else SendMessage( HWND_BROADCAST, WM_FONTCHANGE, 0, 0 ); end; end else begin {Unload the font.} sFontRes := sFontFileName + #0; result := RemoveFontResource( @sFontRes[1] ); SendMessage( HWND_BROADCAST, WM_FONTCHANGE, 0, 0 ); end; end; {LoadFont}
From: "Steve Harman" <harmdog@ne.uswest.net>
Include a font in your EXE:MY_FONT ANYOL1 "Bauhs93.ttf"
BRCC32 MyFont
{$R MyFont.res}
procedure TForm1.FormCreate(Sender: TObject); var Res : TResourceStream; begin Res := TResourceStream.Create(hInstance, 'MY_FONT', Pchar('ANYOL1')); Res.SavetoFile('Bauhs93.ttf'); Res.Free; AddFontResource(PChar('Bauhs93.ttf')); SendMessage(HWND_BROADCAST,WM_FONTCHANGE,0,0); end;
procedure TForm1.Button1Click(Sender: TObject); begin Button1.Font.Name := 'Bauhaus 93'; end;
Caveats:
The above example provides for no error checking whatsoever. :-)
Notice that the File name is NOT the same as the Font name. It's assumed that you know the font name associated with the file name. You can determine this by double clicking on the file name in the explorer window.
I would recommend placing your font file in the C:\WINDOWS\FONTS folder. It's easier to find them later.
Your newly installed font can be removed programatically, assuming the font is not in use anywhere:
procedure TForm1.FormDestroy(Sender: TObject); begin RemoveFontResource(PChar("Bauhs93.ttf")) SendMessage(HWND_BROADCAST,WM_FONTCHANGE,0,0); end;
Check the Win32 help for further details on the AddFontResource and RemoveFontResource.
I'm still building this part, so the Free buttons are not all included yet.