Solved

Using uninstalled fonts in Delphi programs

Posted on 1998-10-09
23
1,577 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
 
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
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:RQuadling
ID: 8750026
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
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…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

760 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

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now