Link to home
Start Free TrialLog in
Avatar of delphiexpert
delphiexpert

asked on

Fonts

2 Font questions, probably both silly but I thought I'd ask:

a) how do you register fonts (ie so that they'll come up when a program gets the listing of fonts installed)
b) how do you use a font if it isn't registered as above?
That'll do for now :)  cheers

Avatar of Epsylon
Epsylon

Use TFontDialog

Drop the component in the Dialogs palette on your form.

Example from Delphi help:

This example takes an edit control, a button, and a rich edit control on a form.  When the user presses the button, a Font dialog appears.  When the user clicks the Apply button in the Font dialog, the currently selected font is applied to the active control.

procedure TForm1.Button1Click(Sender: TObject);

begin
   TFontDialog1.Options = TFontDialog1.Options + fdApplyButton;
   TFontDialog1.Execute;

end;

procedure TForm1.FontDialog1Apply(Sender: TObject; Wnd: Integer);

begin
  if ActiveControl is TEdit then
    with ActiveControl as TEdit do
       Font.Assign(TFontDialog(Sender).Font)
  else if ActiveControl is TRichEdit then
    with ActiveControl as TRichEdit do
      SelAttributes.Assign(TFontDialog(Sender).Font)
  else
    Beep;
end;


Cheers,

Epsylon.
Eps, it seems you got the question wrong. If I'm not totally mistaken then delphiexpert :-)  wants to know how to install fonts to the system by a program to use it there.

To a) look at CreateFontRessource
To b) no way, a font must at least be temporarily (see a) installed to be used by the system.

Ciao, Mike
Avatar of delphiexpert

ASKER

Epsylon:
yeah you've got the wrong idea I'm afraid :)

Lischke:
I couldnt find any info about CreateFontResource, only CreateFont & CreateFontIndirect.. and I didn't see how either of thse could help me.

Thanks...

ASKER CERTIFIED SOLUTION
Avatar of Lischke
Lischke

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hmm to me what is said above (I know you didn't write it) is conflicting; why call RemoveFontResource if it's not going to be there on next reboot anyway?
How _do_ you install a font permanently then?  All it refers to is that is has to be listed in the registry.. is there an API call or is manual registry modification necessary?
Pardon my ignorance/stupidity.. I had a good read up on those functions and it wasnt clear (to me anyway)
Right, I understood your question also not fully :-) But the way I pointed you to is correct. Additionally, you need to set a registry key to make the font permanently available (I was assuming you want to install a font only temporarily). So the complete way is:

1) Determine font directory (GetWindowsDirectory + '\Font' or GetSpecialFolderLocation or registry key (HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders))
2) Copy the ttf into it (if you have the fot file then copy it too).
3) If you don't have the fot file then use CreateScalableFontResource to create one.
4) Call AddFontResource to add the font to the internal table.
5) Register the font by:

 if RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts", 0, "REG_SZ", 0, SECURITY_ACCESS_MASK, 0, @Key,
@iDisplay) = ERROR_SUCCESS then
  begin
    RegSetValueEx(Key, sFontName, 0, 1, sFontFileName, 13);
    RegCloseKey(Key);
  end;

6) To make the job really good notify all top level windows about the font change:

  SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);

For Windows NT replace "Windows" by "Windows NT" in the registry keys.

Ciao, Mike
Sorry, I see now that my question wasnt completely clear.  Anyway, I'm making real progress now, my only further question is: How do I tell what the name of the font is when I go to install it?

My attempt below always returns 'system'.. and its not the font I'm using.
var tf:array[0..100] of char;
    fonthandle:hwnd;
begin
     fonthandle:=label1.font.Handle;
     gettextface(getdevicecontext(fonthandle),100,tf);
     label1.caption:=tf;
end;
The code you have given above cannot work as you are trying to get a device context for a font handle. I assume this is part of your form's code, thus use

  GetTextFace(Canvas.Handle, 100, tf);

On the other hand, this will tell you the name of the font currently selected into this device context, which can change all the time while the form is painting different labels etc. One way to avoid confusions is to explicitely assign the label's font into the canvas by using

  Canvas.Font := Label1.Font;

just before you call GetTextFace. But is this really necessary? The font name can already be read by using Label1.Font.Name. And this is a font which is already installed, so it makes no sense to read it to get a name for font installation process.

I assume further you want to display a font name in a installation dialog to let the user know what he's going to install, right? I think you can only do this by temporarily installing the currently selected font and selecting it into a device context from where you can get its name.

Ciao, Mike

PS: Fine that you increased the points for this question. It has grown beyond the initial 25 points :-)
Yes, I would like to know the font's name
a) so the user can be informed what its called
b) so it can be called the correct name if I add it to the registry.  My thinking above is obviously flawed.
How do I select the font into a device context then?

Sorry for being stupid :)

BTW the points have increased with every comment I've made, I wondered if you'd notice or not :-)


This is harder than I thought initially. You are right, you can't select the font (even if it is installed temporary) into a device context as you don't get a valid font handle from AddFontResource. Even enumeration wouldn't work as you only have a file name.

I found out that many people where asking about this problem and found also a solution. Unfortunately, this is written in C++ and goes beyond the initial request of this question. Anyway, here's the link for you to follow:

http://www.users.cts.com/sd/m/menright/ttfname.html

Ciao, Mike

PS: No, I didn't realize that you increased the points with every comment. Nice way of motivating people :-))
OK well based on that source, and ttf documentation I managed to extract the info I wanted.  For bonus points: what are all the field names for font info? ie there's the copyright field, trademark, font name, etc etc (codes 0-8) but I have fonts with fields up to #14, and cant find any documentation on what the field names these are for.  I figure that seeing as the information is easily retrievable, I might as well use it :)

Oh don't bother, I found out the info for myself.
Have 102, 6x the original 17.  My, aren't I generous :)

Oh, I'll actually accept the answer now.  Oops.