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
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
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
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
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...
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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)
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\Softwar e\Microsof t\Windows\ CurrentVer sion\Explo rer\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\Window s\CurrentV ersion\Fon ts", 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
1) Determine font directory (GetWindowsDirectory + '\Font' or GetSpecialFolderLocation or registry key (HKEY_CURRENT_USER\Softwar
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
4) Call AddFontResource to add the font to the internal table.
5) Register the font by:
if RegCreateKeyEx(HKEY_LOCAL_
@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
For Windows NT replace "Windows" by "Windows NT" in the registry keys.
Ciao, Mike
ASKER
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.Ha ndle;
gettextface(getdeviceconte xt(fonthan dle),100,t f);
label1.caption:=tf;
end;
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.Ha
gettextface(getdeviceconte
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 :-)
GetTextFace(Canvas.Handle,
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 :-)
ASKER
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 :-)
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 :-))
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 :-))
ASKER
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 :)
ASKER
Oh don't bother, I found out the info for myself.
Have 102, 6x the original 17. My, aren't I generous :)
Have 102, 6x the original 17. My, aren't I generous :)
ASKER
Oh, I'll actually accept the answer now. Oops.
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
begin
TFontDialog1.Options = TFontDialog1.Options + fdApplyButton;
TFontDialog1.Execute;
end;
procedure TForm1.FontDialog1Apply(Se
begin
if ActiveControl is TEdit then
with ActiveControl as TEdit do
Font.Assign(TFontDialog(Se
else if ActiveControl is TRichEdit then
with ActiveControl as TRichEdit do
SelAttributes.Assign(TFont
else
Beep;
end;
Cheers,
Epsylon.