Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Fonts

Posted on 1999-07-26
13
Medium Priority
?
778 Views
Last Modified: 2013-12-02
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

0
Comment
Question by:delphiexpert
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 5
13 Comments
 
LVL 13

Expert Comment

by:Epsylon
ID: 1391203
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.
0
 
LVL 10

Expert Comment

by:Lischke
ID: 1391204
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
0
 
LVL 1

Author Comment

by:delphiexpert
ID: 1391205
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...

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 10

Accepted Solution

by:
Lischke earned 400 total points
ID: 1391206
Sorry, the function name was wrong. You must use CreateScalableFontResource and AddFontResource. Here the description from MSDN about it:

Font Installation and Deletion
A font must already be resident on a given device or installed in the system font table in order for an application to draw text using glyphs from that font. The font table is an internal array that identifies all nondevice fonts that are available to a Win32-based application. An application can retrieve the names of fonts currently installed on a device and stored in the internal font table by calling the EnumFontFamilies or ChooseFont function.

An application can loada font by calling AddFontResource or AddFontResourceEx. These functions load a font that is stored in a font-resource file. However, this is a temporary installation, because at the next reboot the font will not be present. To install a font that will remain after the system is rebooted, the font must be listed in the registry.

In the case of TrueType and OpenType fonts, an additional step is sometimes necessary before the font can be installed in the font table. Some font manufacturers ship only the TrueType or OpenType font-data files (identified by the .ttf extension). Before The system can load these fonts, it requires a corresponding header file (identified by the .fot extension). To create this header file, an application must call the CreateScalableFontResource function and pass the name of the font-data file as the third parameter. When this header file is created, an application can install the font by calling the AddFontResource or AddFontResourceEx function and passing the name of the new header file.

When an application finishes using an installed font, it must remove that font by calling the RemoveFontResource function.

Whenever an application calls the functions that add and delete font resources, it should also call the SendMessage function and send a WM_FONTCHANGE message to all top-level windows in the system. This message notifies other applications that the internal font table has been altered by an application that added or removed a font.

Ciao, Mike
0
 
LVL 1

Author Comment

by:delphiexpert
ID: 1391207
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)
0
 
LVL 10

Expert Comment

by:Lischke
ID: 1391208
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
0
 
LVL 1

Author Comment

by:delphiexpert
ID: 1391209
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;
0
 
LVL 10

Expert Comment

by:Lischke
ID: 1391210
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 :-)
0
 
LVL 1

Author Comment

by:delphiexpert
ID: 1391211
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 :-)


0
 
LVL 10

Expert Comment

by:Lischke
ID: 1391212
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 :-))
0
 
LVL 1

Author Comment

by:delphiexpert
ID: 1391213
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 :)

0
 
LVL 1

Author Comment

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

0
 
LVL 1

Author Comment

by:delphiexpert
ID: 1391215
Oh, I'll actually accept the answer now.  Oops.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
Suggested Courses

670 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question