[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 851
  • Last Modified:

How to delete fonts in code

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
raunol
Asked:
raunol
  • 6
  • 5
  • 3
  • +1
1 Solution
 
ZifNabCommented:
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
 
raunolAuthor Commented:
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
 
ZifNabCommented:
well, raunol, this is new for me (installing/unistalling fonts)... What if you use Fontname instead of fontfile?
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
raunolAuthor Commented:
> 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
 
ZifNabCommented:
> fontname >>instead of fontfile >> if not(RemoveFontResource(@FromFile[1])) then ? Just trying, sorry.
Zif.
0
 
ZifNabCommented:
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
 
ZifNabCommented:
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
 
raunolAuthor Commented:
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
 
MadshiCommented:
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
 
raunolAuthor Commented:
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
 
MadshiCommented:
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
 
duke_nCommented:
Try this:
Screen.fonts.delete
0
 
raunolAuthor Commented:
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
 
raunolAuthor Commented:
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
 
MadshiCommented:
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

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

  • 6
  • 5
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now