Solved

Installing fonts with application

Posted on 2001-06-25
5
228 Views
Last Modified: 2013-12-03
Does anyone know a good way to temporarily (or permanently) install fonts for use with my app. I am leaning toward temporary installation because i am worried about all the ways things can break if i try the permanent install approach (e.g. win95 has limits on number of fonts)?

I'll append my own approach as a comment, which doesn't seem to work yet, in case someone has specific comments on what i have come up with so far.

Cheers,
-d
0
Comment
Question by:djelescu
5 Comments
 
LVL 1

Author Comment

by:djelescu
ID: 6225058
Here is what I came up with so far...

Reading the microsoft white-paper 'PRB: Embedded Read-Only Fonts in Multiple...',
I thought I understood the process for doing this. And I made a little FontmanagerClass
to hand the work for me. The use of this class is simple...
1. Inside CMyApp:InitInstance() you must call...
      FontManager::OnInitInstanceLoadFonts(m_pszHelpFilePath);
   The help path is used as a tipoff for where ttf files may be found.
   Fontmanager looks throu that directory and copies ttf files into windows\system
   Then it folows the guidelines of the microsoft whitepaper to registre those fonts
2. Any rules for transforming the 'notmal' name of a font to the name that is really
   appropriate for filling in the FONT structure, are expected to happen inside ToInstanceName()
   Thus, one could  write...
   cMyFont.CreatePointFont(100, FontManager::ToInstanceName("Dungeon"));
   and let the FontManager transform the name (e.g. append '.ttf' or somethin) as appropriate.

I thought this class was a really cool idea.
But it just does not seem to work.
All the font registration call appear to be successful,
but in the end, I can not use any font
that has not already been registered on my system in the usual way.
How can my application use irregular fonts, if I can't get this to work?
Help!!!!!!!

Regards,
-d

p.s. Code below is my best effort to implement FontManager.
Try fontfreak.com to get a wacky/unregistered font to try on your system.

// FontManager.h

class FontManager  
{
protected:
      static CStringArray _deletables;
      static CString _tempTtfPrefix;
public:
      static void OnInitInstanceLoadFonts(CString helpFilePathForReference);
      static void OnExitInstanceUnloadFonts();
      static CString ToInstanceName(CString commonName);
};

// FontManager.cpp

CString FontManager::_tempTtfPrefix = "";
CStringArray FontManager::_deletables;

CString FontManager::ToInstanceName(CString commonName)
{
      // What to return here???
      // commonName  ???
      // commonName + ".ttf" ???
      // _tempTtfPrefix + commonName + ".ttf" ??
      // This is just a guess...
      return _tempTtfPrefix + commonName;
}

void FontManager::OnInitInstanceLoadFonts(CString helpFilePathForReference)
{
      // We use the help file to get a reference to the main application directory.
      // Probably there is a better way, but this seems to work.
      int iPos = helpFilePathForReference.ReverseFind('.');
      if(iPos != helpFilePathForReference.GetLength() - 4) {
            ASSERT(false);
      } else {
            ////////////////////////////////////////////////
            // Now we use the application name
            // and the time to generate a unique string
            // that we will prepend to each ttf file
            // as we copy it to the system folder.
            // This will help avoid conflicts with existing copies
            // if they exist.
            _tempTtfPrefix = helpFilePathForReference.Left(iPos);
            iPos = helpFilePathForReference.ReverseFind('\\');
            CString fontDirectory = helpFilePathForReference.Left(iPos);
            _tempTtfPrefix = _tempTtfPrefix.Right(_tempTtfPrefix.GetLength() - iPos - 1);
            ///////////////////////////
            char systemDir[MAX_PATH+1];
            GetSystemDirectory(systemDir, MAX_PATH);
            ///////////////////////////
            int timeAsInt = time(NULL);
            char buffer[20];
            _itoa(timeAsInt, buffer, 10);
            _tempTtfPrefix += buffer;
            ////////////////////
            // To do the copying, we iterate through the application folder and
            // find the ttf files and copy them to the system with prefix prepended...
            CFileFind ttfFinder;
            BOOL bWorking = ttfFinder.FindFile(fontDirectory + "\\*.ttf");
            while (bWorking)    {
                  bWorking = ttfFinder.FindNextFile();
                  CString source = ttfFinder.GetFilePath();
                  CString dest = systemDir + CString("\\") + _tempTtfPrefix + ttfFinder.GetFileName();
                  try{
                        if(CopyFile(source, dest, false)) {
                              //////////////////////////////////////////////////
                              // After each copy is made in system directory, we
                              // use CreateScalableFontResource to make a temporary resource
                              CString fotFile = systemDir + CString("\\") + _tempTtfPrefix + ttfFinder.GetFileTitle() + ".fot";
                              if(CreateScalableFontResource(1,
                                    fotFile.GetBuffer(MAX_PATH+1),
                                    dest.GetBuffer(MAX_PATH+1),
                                    NULL))
                              {
                                    ////////////////////////////////
                                    // And we add the font resource
                                    // so we can use it
                                    int numFontsAdded = AddFontResource(fotFile);
                                    if(numFontsAdded > 0)
                                          AfxMessageBox("Success!");
                                    else
                                          AfxMessageBox("Failure!");
                              } else {
                                    AfxMessageBox("Failure!");
                              }
                              fotFile.ReleaseBuffer();
                              dest.ReleaseBuffer();
                              _deletables.Add(fotFile);
                              _deletables.Add(dest);
                        }
                  } catch(...) {}
            }
      }
}

void FontManager::OnExitInstanceUnloadFonts()
{
      for(int i=0; i<_deletables.GetSize(); i++) {
            try{ DeleteFile(_deletables[i]); } catch(...) {}
      }
}
0
 
LVL 1

Author Comment

by:djelescu
ID: 6225255
Did I mention that the code above does not work.
What to do?
0
 
LVL 49

Accepted Solution

by:
DanRollins earned 300 total points
ID: 6225448
Remove the try... catch to see if an erro is occuring (or at least add AfxMessageBox("Catch caught")

How do you know that the font installation has failed? Does CreatePointFont return FALSE?  Show your test code.

Have you tried just hardcoding some font as a "proof-of-concept" test?  That is always a good idea before implementing a class:  Find out if the basic premise is viable, then build around that functionality.

Also, it looks like you may be confusing the font file name with the font face name.  They are distinct.  CreatePointFont needs to see the font face name, not a filename.

-- Dan
0
 

Expert Comment

by:cternoey
ID: 6225659
0
 
LVL 23

Expert Comment

by:Roshan Davis
ID: 9490126
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Answered by : DanRollins

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Roshan Davis
EE Cleanup Volunteer
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
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…

920 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

11 Experts available now in Live!

Get 1:1 Help Now