Solved

How to delete fonts in code

Posted on 1998-07-28
15
773 Views
Last Modified: 2013-12-02
I'm planning fontviewer for my gladness, with install/uninstall options, but when I have tried to delete some istalled fonts (no importants for the system) by deleting them from fonts-folder or from registry it will
caused errors such as 'acces denied' and 'file system error (1026)'. Sometimes fontfiles become so locked that I can delete them only in Dos. Next steps are prinsible of combinations how I have tried to delete them:

1. Removing current value from registry such as "myFont (TrueType)    myfont.ttf

2. Using Removefontresource - function
 
3. Deleting (if I can, mostly I cannot due to access denied and other errors)   myfont.ttf - file from fonts -folder.

4. Sendmessage(HWND_BROADCAST,WM_FONTCHANGE,0,0)

Can anybody say is there any special funtions in win95
for the purpose or how to solve the problem?
I have Delphi 2.00

Regards
Rauno


 

0
Comment
Question by:raunol
  • 6
  • 5
  • 3
  • +1
15 Comments
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
Tried it this way?


  if not(RemoveFontResource(PChar(Fname))) then
    FontError:= True
  else
    L:= SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);

have you sended the message ?
0
 

Author Comment

by:raunol
Comment Utility
I have tried to put to different places Sendmessage and
removeresource-functions but not succeed.

If I first try to delete file from Fonts folder I cannot do
it because "Acces denied" error occur. And if I first
delete the value the case in registry, I Cannot delete
the file after, due to errors like "file system error 1026".

Actually is my code to uninstall right way? Installing
plays well so that I first copy file to fonts folder,
then write value to Registry, and last AddFontResource+
Sendmessage+RemoveFontResource+SendMessage

My Uninstall code is in prinsiple like this: (some constants are defined by my self)


Function DelRegValue(FontName:String):Boolean
var
    Registry:TRegistry;
    Value:String;
Begin
     Result:=False;
     Registry:=Tregistry.Create;
     With Registry do
     Try
        LazyWrite:=False;
        RootKey:=HKEY_LOCAL_MACHINE;
        Value:=FontName+STR_TRUETYPE;
        Result:= OpenKey(FONTSFOLDER_KEY,false) and
            ValueExists(Value) And DeleteValue(Value);
     Finally
     Registry.Free;
     End;
End

Function UnInstallFont(FontName,FontFile):Boolean;
Var
    SHFileOPStruct:TSHFileOPStruct;
 
Begin

With SHFileOpStruct do
Begin
     
   
     DelRegValue(FontName);    
     

  // If I put Your code for example here, FontError occur
  //  and "access denied" error occur after trying delete the
  // file.  
  //   if not(RemoveFontResource(@FromFile[1])) then
  //   FontError=True
  //   Else
  //   L:= SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0)

     Wnd:=0;
     pFrom:=@FromFile[1];

     wFunc:=FO_DELETE;
     fFlags:=FOF_NOCONFIRMATION or FOF_ALLOWUNDO;

     Result:=SHFileOperation(SHFileOpStruct)=0;

End;
End;


0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
well, raunol, this is new for me (installing/unistalling fonts)... What if you use Fontname instead of fontfile?
0
 

Author Comment

by:raunol
Comment Utility
> this is new for me (installing/unistalling fonts)...

Bity. It might be poorly documented. In internet I have not found sources for it except installing fonts and it steps
like I wrote and really work very well, even updates Fonts
folder if its is opened. But why it  does not work in the opposite direction?

> What if you use Fontname instead of fontfile?

ööö..where?

There is a little mistake in my code "FromFile" should be "FontFile", but anyway, Add/removefontrecource functions
request filename of the font, also "pFrom" in SHFileOpStruct -structure.





It must use Fontname of  if You want to write or remove font-value in
registry. I don't know another way. Values are names in the registry ie. "Arial (TrueType)" and data of values are filenames
of the font. If the font installed is another place than
the Fonts folder, then the string data consist also path.
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
> fontname >>instead of fontfile >> if not(RemoveFontResource(@FromFile[1])) then ? Just trying, sorry.
Zif.
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
this might come in handy :





              Windows 95, Windows NT 3.x, Windows NT 4.x

                1.Copy your font files to the proper fonts directory.
                        If you're using Windows NT 3.x, your fonts directory would be
                        "windows\system"
                        If you're using Windows 95 or Windows NT 4.x, default fonts
                        directory would be "windows\fonts"
                2.Call AddFontResource() function and let all top level windows know about
                   the new font by sending the WM_FONTCHANGE message:

                   AddFontResource(
                     'c:\windows\system\myfont.ttf' );

                   { or }

                   AddFontResource(
                     'c:\windows\fonts\myfont.ttf' );

                   { and }

                   SendMessage(
                     HWND_BROADCAST,
                     WM_FONTCHANGE, 0, 0 );




                3.To make your fonts a permanent part of the system, list them in the
                   following registry section:
                        Windows 95:

                        HKEY_LOCAL_MACHINE\
                        SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts
                        Windows NT:

                        HKEY_LOCAL_MACHINE\
                        SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts

                   Each font listing should have the following format:

                   key name: <name of the font>
                   key data: <path to the font file>

                   for example:

                   "My Font (True Type)"
                   c:\windows\fonts\myfont.ttf

              Now, back to the tricky part -- verifying if the font you're about to install isn't
              already installed on the system. This is very important; if you install your new font
              over an existing font, you may experience random [fonts related] problems.

              If you're using win 3.1, you should get a list of installed fonts from the WIN.INI
              "[fonts]" section.

              If you're using Windows 95 or Windows NT, you should get a list of installed fonts
              using the EnumFontFamilies() function. The actual font names could be found by
              looking in the following registry key:

                   HKEY_LOCAL_MACHINE\
                   SOFTWARE\Microsoft\Windows[NT]\CurrentVersion\Fonts

              Once you have a list of installed fonts, compare them against the font you're
              about to install and make sure that...

                   It does not exist/not installed, or [if it's already installed,] the
                   currently installed version of the font is older than the version you're
                   about to install.
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
strange, everyware I look they always just talking about

RemoveFontResource();

Look :

Font loading and unloading function.}
function LoadFont(sFontFileName: string; bLoadIt: boolean): boolean;
var
sFont, sAppDir, sFontRes: string;
begin
result := TRUE;

if bLoadIt then
begin
{Load the font.}
if FileExists( sFontFileName ) then
begin
sFontRes := sFontFileName + #0;
if AddFontResource( @sFontRes[ 1 ] ) = 0 then
result := FALSE
else
SendMessage( HWND_BROADCAST, WM_FONTCHANGE, 0, 0 );
end;
end
else
begin
{Unload the font.}
sFontRes := sFontFileName + #0;
result := RemoveFontResource( @sFontRes[1] );
SendMessage( HWND_BROADCAST, WM_FONTCHANGE, 0, 0 );
end;
end; {LoadFont}

. strange... can you try this too? I'm interested in this stuff.
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

 

Author Comment

by:raunol
Comment Utility
The longer code above I have seen before somewhere in the Net,
but it tells only installing. I have used many search engine in the Net and found many code example for installing fonts, but no one uninstall examples.

What Your next code is conserned, it works only if You
take a font not installed in Your system. You get it with
addfontresource and then You can remove it from the space
just using Removefontresource (and for other applications sendmessage is needed) but it doesend remove installed fonts
away! (which names are found also in the registry) In fact RemoveFontResource returns false if You try to use it straight for installed fonts (for example for fonts in Fonts folder).








0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
Sometimes fonts are just "in use". You can't delete them right now, but only in DOS (like you said).
But there is a little trick:
In WinNT you can use "MoveFileEx('c:\windows\fonts\fontFile.tff',nil,MOVEFILE_REPLACE_EXISTING or MOVEFILE_DELAY_UNTIL_REBOOT)".
In Win95 you can create/edit "c:\windows\wininit.ini" and add to the "[rename]" key something like "NUL=c:\windows\fonts\fontFile.ttf'".
Both Win95 and WinNT will delete the file automatically after the next reboot.
0
 

Author Comment

by:raunol
Comment Utility
Madshi,

To delete font by Your way needs reebooting. ;-)

I should want to delete installed font by my program so that also win95 Fonts folder will be uptated immediately after deleting.

- Rauno -
 
0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
Yes, o.k.
Of course this should be the last way out, only. But what other possibility do you have, if the fonts just CAN'T (I think there are such situations) be deleted without a reboot?     :-(
All the installation/de-installation utilities reboot windows (if necessary), so why must your utility not reboot?
0
 
LVL 1

Accepted Solution

by:
duke_n earned 200 total points
Comment Utility
Try this:
Screen.fonts.delete
0
 

Author Comment

by:raunol
Comment Utility
Thank's duke_n

Hmm... I'm afraid to test. I think, Your proposal will
delete all fonts! So it gives me more problems than
benefit. Do You have an idea how to delete the one of the screenfonts?


0
 

Author Comment

by:raunol
Comment Utility
Madshi,

> why must your utility not reboot?

Because, If I delete or add (unlocked) fonts to/from
fonts-folder by Win95 the fonts folder updates
immidiately - without rebooting. I should want to do
same programmately by Delphi.

0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
raunol,

but often even windows has to reboot when you want to delete a font... I doubt that you can avoid rebooting if windows itself can't.
Of course in the cases where windows can delete a font without rebooting you should do, too.
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Suggested Solutions

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
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 video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

728 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

10 Experts available now in Live!

Get 1:1 Help Now