Solved

Using uninstalled fonts in Delphi programs

Posted on 1998-10-09
23
1,582 Views
Last Modified: 2013-12-02
 I want to use _uninstalled_ fonts in my program.
  Now, I am pretty happy using Screen.Fonts to use all the installed fonts, but my problem comes in using uninstalled fonts.
  I wrote a little loop to recursively traverse through a directory, and for each file I try AddFontResource () - this succeeds for each file that is a valid font file, and so I can identify the fonts.  However, I'm not sure what to do next.  AddFontResource () just takes a filename, but then to use the font I must presumably know the name of the font (i.e. the difference between, say, 'ozw88.ttf' and 'Ozzie Bold').
  How can I get the name of the font?  How can I use the font in my program?
0
Comment
Question by:davidmwilliams
  • 11
  • 7
  • 3
  • +2
23 Comments
 
LVL 5

Expert Comment

by:scrapdog
ID: 1342411
http://www.chami.com/tips/delphi/010297D.html

for directions on how to install the font.  You might have to copy the font files to the windows\system directory before you use AddFontResource.
0
 
LVL 4

Author Comment

by:davidmwilliams
ID: 1342412
 Interesting Web page, thanks ... however, I don't actually want to install the font under Windows or make it available to other applications, I just want to be able to print a sample of text using it.
  However, even if I did, the Web page says one must write a registry entry that has the name of the font, and the path to it - but this is my problem again; I know the path and filename of the font, but how do I actually work out its name?
  Will an EnumFontFamilies() before and after the AddFontResource do the trick, or will EnumFontFamilies only list the font after it's been installed using the procedure described on that Web page?
  What I really want to be able to do is temporarily make use of uninstalled fonts, and set some text messages to use them, by changing their (Component).font property.
0
 
LVL 4

Expert Comment

by:dwwang
ID: 1342413
I think it depends on your purpose of using the font.

If the you already now of the font file, just use the font name
that you see after adding it to windows. Since the font name
should be the same in any where, no matter when and where you
install the font resource file.

If you don't know the font, i.e. just want to let user to choose
a file and then show the font in it. I think there is no easy
way. But you can do like this, first enumerate all fonts before
install the new one, then install the font. Again enumerate all
fonts, compare the result of them, then you know the name of the
newly added font.


0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 8

Expert Comment

by:ZifNab
ID: 1342414
use this component, or look at the source of it...

http://www.bhnet.com.br/~simonet/archive/portfont.zip

Regards, Zif.
0
 
LVL 4

Author Comment

by:davidmwilliams
ID: 1342415
Hi Zifnab,
  Perhaps my original question was misleading.  I looked at
the component you directed me to, but it is sort of like a
persistent TFont ... a way of bundling a font in your
application (like bitmaps and cursors, etc.), so that you can
use it on a computer that may not necessarily have that font
installed.
  However, what I mean by wanting to use uninstalled fonts is
not so much that I want to use a specific font, but rather, I
want to be able to look at samples of arbitrary fonts on a
computer that are not installed, and not in the Screen.Fonts
list.  My program has no knowledge about what uninstalled fonts
a person may have on their system, or which directory the user
will direct the program to, etc.
  I thought maybe the component you listed may have a routine
to extract the name of a font out of the font ttf file, but
unfortunately one actually has to explicitly specify this
information in the constructor - that is, it does not do it
programatically.
  Hence, this answer does not help with what I wish to achieve,
but thanks.
0
 
LVL 4

Author Comment

by:davidmwilliams
ID: 1342416
 A comment to DWWang ... I don't think you can install a font
without knowing its name, because you need to write a key to
the registry.
  What I really need is a routine to extract the name of a font
out of the ttf file.
0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1342417
aha, I understand now, what you need.

maybe this can help you already a little bit further :

http://www.microsoft.com/truetype/tt/ttf_spec/ttspec.zip

regards, Zif.
0
 
LVL 4

Expert Comment

by:dwwang
ID: 1342418
Why? Can't you use AddFontResource to add a font while only know its file name?
0
 
LVL 4

Author Comment

by:davidmwilliams
ID: 1342419
Sure, but how do you then refer to that font?
You need to know its _name_ as well as its _file name_ to use it - in fact, if you want to install the font, you need to write a record to the registry straight after using AddFontResource - and this record includes the font name.
0
 
LVL 4

Expert Comment

by:dwwang
ID: 1342420
Well? I think AddfontResource and the sentence

SendMessage( HWND_BROADCAST, WM_FONTCHANGE, 0, 0 )

can help installing the font, maybe I was wrong, but have you tried that?
0
 
LVL 4

Author Comment

by:davidmwilliams
ID: 1342421
That message is used to let all other running programs know that a new font has been installed.  However, the key thing is that it has been _installed_.  And you can only install a font by using AddFontResource, and writing a key to the registry.  Once more, you need to know the name of the font in order to write the registry key.  The WM_FONTCHANGE message does not help at all.  Especially because I only want to work with the uninstalled fonts temporarily (i.e. for the lifetime of the program), and so I don't care to advise other programs a new font is available (because I will be using RemoveFontResource() afterwards anyway)
0
 
LVL 4

Expert Comment

by:dwwang
ID: 1342422
Well, I think there must be some misunderstanding in the function of these utilitie. Maybe you can look at this site, it just explained how to use a font in the programm's life time and remove it after using.

http://www.gnomehome.demon.nl/uddf/pages/fonts.htm#fonts0
0
 
LVL 4

Author Comment

by:davidmwilliams
ID: 1342423
Excellent, dwwang, what you described sounds like just what I want ... I'll check out
the URL straight away ...
0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1342424
Hi,

If I'm not wrong, I know of that function at undo and it is almost the same as the component link I refered to. It's only explained for Delphi 1. So usable.

here is what that component says : You can specify whether the font should be installed temporarily or permanently. Now the component is for 32 bit.

Zif.
0
 
LVL 4

Author Comment

by:davidmwilliams
ID: 1342425
 Sorry, all, for taking so long to get back to you.

  Zif - the ttf font info you referred me to sure looks like the sort of thing I need.  However, I'm having difficulty following it, and working out just how to programmatically extract the font name in Delphi, following those instructions -- but I can see it listed there as a field.
  DwWang - the code you supplied me to was interesting ... unfortunately it turns out, though, that although it loads an uninstalled font, the font is one you have supplied with your application (i.e. it resides in the .exe directory).  Hence, the name of the font is already known, and can be safely used in a, say, label Font.Name := ... assignment.
  This is really what I'm after ... I want to load uninstalled fonts ... but then get their name so I can use them in Font.Name type assignments, and actually display a sample of the font.  When the program ends it will unload the font.
  I hope I'm being clear.  It looks like this must not be a terribly straight-forward problem because all the examples above have not quite gone this far in their implementations.
0
 
LVL 4

Expert Comment

by:dwwang
ID: 1342426
So you mean you want to load a font that its name you don't know at the time yo load it?

That's what I suggested before, you can enumerate all font installed before you install the new one, then install the fonts, and enumerate again. By comparing two results, you can get the new font's name. This might not be a good method, but I think it's feasible.
0
 
LVL 4

Author Comment

by:davidmwilliams
ID: 1342427
Hi Dwwang,
  Sorry to have missed that nuance before - but yes, what you are suggesting is exactly what I'm after ... I want to load a font, whose name I don't know at the time I load it (just the filename).
  It does make sense I can enumerate the fonts before and after I load it, and compare the differences.
  Though, I'm only used to using the Delphi supplied Screen.Fonts ... I looked through the VCL .pas code, and I couldn't quite work out how to enumerate fonts using API calls.  I don't think Screen.Fonts updates automatically.
  Do you perhaps have some code to do this enumerating and comparison?
0
 
LVL 4

Accepted Solution

by:
dwwang earned 300 total points
ID: 1342428
Since you already browsed the source code of tscreen, you can copy some of the code fragments to implemnt this task.

I can e-mail you the example I've just written, or paste them here.
0
 
LVL 4

Author Comment

by:davidmwilliams
ID: 1342429
Please email me your code sample ... dave@qed.newcastle.edu.au
0
 
LVL 4

Expert Comment

by:dwwang
ID: 1342430
Hi, sorry that I can't send you the example right now -- I wrote it in my company, but now I'm at home, and tomorrow is weekend(here in China). I will try to send it to you at Sunday when I may goto company, OK?

Sorry for the delay.
0
 
LVL 4

Author Comment

by:davidmwilliams
ID: 1342431
Hi DWWang,
  No problem ... I've waited this long already :)
  Wow, China, eh?  I'm in Australia.

Regards,
 David Williams
0
 
LVL 4

Author Comment

by:davidmwilliams
ID: 1342432
 Thanks, DWWang, your code works well!  And you make it look so straightforward too ...
  I think I can get my program working in less than an hour, building on the code you emailed.

Regards,
 David Williams
0
 
LVL 40

Expert Comment

by:Richard Quadling
ID: 8750026
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
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…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

789 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