List of activated fonts does not include shortcut activations

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Our font management tool, Suitcase, activates fonts dynamically by creating shortcuts in the Windows font folder. Using System.Drawing.Text.InstalledFontCollection to get the list of font families from the system yields only the fonts whose files are physically in the system font folder- not the shortcuts. None of our applications have any problems using the fonts activated by shortcuts. Can anyone recommend another way to retrieve the complete list of fonts? Thanks for any suggestions

Josh Usovsk
Code
System.Drawing.Text.InstalledFontCollection installedFonts = new System.Drawing.Text.InstalledFontCollection()
System.Drawing.FontFamily[] fams = installedFonts .Families;
 
Hi Josh,

I'm not sure what do you mean activates fonts by creating shortcuts in font
folder.
Do you mean create a lnk file in the \windows\fonts ?
I'm not sure if windows supports this usage, because the lnk file can't be
shown in the explorer when browsing the font folder. could you give me a
detail steps to Create a Font object by the link file, so I can confirm if
it is a supported featue and then ask for why it is not included in the
InstalledFontCollection.

Another thought is, since you mean you need activates fonts dynamically by
creating a link in the font folder, I guess you only want to use this font
in your application and it should not be installed into the system font
folder. Then have you considered using the PrivateFontCollection class
under the same namespace? The PrivateFontCollection class allows
applications to install a private version of an existing font without the
need to replace the system version of the font.

For more information on the PrivatFontCollection you may refer to
<PrivateFontCollection Class>
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/
frlrfsystemdrawingtextprivatefontcollectionclasstopic.asp

Thanks!


Best regards,

Ying-Shen Yu [MSFT]
Microsoft community Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, please remove the word "online"
before sending mail.
 
Ying-Shen
If you create a link file in the system fonts folder to a .pfm or an OpenType .otf in a different folder, the font is installed and it is available in applications. Fonts installed in this manner are not part of the InstalledFontCollection. I don't need a private font collection since I am not using the fonts in my app, rather I am controlling the Adobe InDesign application via COM. I just need a list of all installed fonts on the system, and I need to be able to update it very quickly when the application receives focus. I haven't found another way to do this efficiently with the framework yet

Josh Usovsky
 
Hi Josh,

I'm contacting the GDI support team for this issue, they suggest using API
AddFontResource /RemoveFontResource to add/remove a font resource to the
system font table, it will not copy the file to the system folder, these
two APIs are not available in .NET so you need do P/invoke to call them:
[DllImport("gdi32.dll")]
private static extern int AddFontResource(string lpszFilename // font
file name);
[DllImport("gdi32.dll")]
private static extern int RemoveFontResource(string lpFileName // name of
font file);
Note, you need create the InstalledFontCollection after adding the font
resource, since InstalledFontCollection object can find only those fonts
that were installed in Windows before the object was created.

If you still have problem on this issue,
could you send me a simple sample to reproduce this issue?
Then, I can let the GDI team take a look at it.
Thanks!

Best regards,

Ying-Shen Yu [MSFT]
Microsoft community Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, please remove the word "online"
before sending mail.
 
Thanks, Ying-Shen. The list of fonts I am trying to gather is all fonts already installed and accessible by applications. I do not need to install the fonts myself. I would like to be able to update this list very frequently and quickly, say every time my application gets focus. To get this list using the method you have outlined, it looks like I would need to do the following

Create a new InstalledFontCollection objec
#Start Loop: For each .lnk file in the system fonts folde
Create a Font object to access the corresponding metadata for the .lnk's font fil
Compare the Font to the fonts in the InstalledFontCollection object to see if it is already presen
If it's not present, AddFontResource( the font pathname
#End Loo
Destroy the InstalledFontCollection object since it is now outdate
Create a new InstalledFontCollectio
And this doesn't account for removing fonts whose .lnk files have been removed from the system font folde
That sounds like a lot of overhead, since each font's program has to generate its characters whenever a new font object is created. Adobe InDesign, Photoshop, Microsoft Word, and other applications are able to rapidly update their available font lists transparently to the user even after thousands of fonts have been installed with Extensis Suitcase via the .lnk file method. I think I will have to search the WinAPI and leave managed code for this part, but I hope in future versions of the framework, the InstalledFontCollection will not ignore fonts installed using link files

Thanks
Josh Usovsk
 
Hi,

Unfortunately, GDI+ will not recognize the shortcuts and AddFontResource
only adds a font for the current session. It is not a permanently
installed font. To permanently install the font, try the code below (I
have not tested it). The font needs to be permanently installed on the
system for InstalledFontCollection to recognize it. The
InstalledFontCollection is instantiated when the GDI+ application starts.
Any fonts added after the GDI+ application starts will not be detected.
After you have added the font (permantently as described above), you must
restart the application.


// The following code is for demonstration purposes only and will not work
on Win9x. It was written before XP, so you may need to modify it.
//#define _WIN32_WINNT 0x0500
#include <Windows.H>
#include <StdIO.H>


void PrintError( DWORD dwError, LPCSTR lpString )
{
#define MAX_MSG_BUF_SIZE 512
char *msgBuf;
DWORD cMsgLen;

cMsgLen = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ALLOCATE_BUFFER | 40, NULL, dwError,
MAKELANGID(0, SUBLANG_ENGLISH_US), (LPTSTR) &msgBuf, MAX_MSG_BUF_SIZE,
NULL);

printf( "%s Error [%d]:: %s\n", lpString, dwError, msgBuf );

LocalFree( msgBuf );
#undef MAX_MSG_BUF_SIZE
}


int main( int argc, char *argv[] )
{
OSVERSIONINFO osv;
int iRet;
LONG lRet;
int iDisposition;
HKEY hKey = NULL;
TCHAR buffer[200];
GLYPHSET gs;
LOCALESIGNATURE ls;


// What version of Windows are we running?
osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osv);

// Abort if NT4 or Win2k not being used...
if (!((osv.dwPlatformId == VER_PLATFORM_WIN32_NT) && // NT
(((osv.dwMajorVersion == 4) && (osv.dwMinorVersion == 0)) || // 4.0
((osv.dwMajorVersion == 5) && (osv.dwMinorVersion == 0))))) // 5.0
(Win2k)
{
printf("Requires NT 4.0 or Windows 2000\n");
goto ABORT;
}

// Must specify printer name, font name, font file name...
if (argc != 3)
{
printf("Syntax: %s <font name> <.TTF file name>\n", argv[0]);
goto ABORT;
}

// Add the font to the local session...
SetLastError(0);
iRet = AddFontResource(argv[2]);
if (iRet == 0)
{
wsprintf(buffer, "AddFontResource(%s)", argv[2]);
PrintError(GetLastError(), buffer);
goto ABORT;
}

// Get a registry key for the Fonts information in the registry...
SetLastError(0);
lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows
NT\\CurrentVersion\\Fonts",
0, "REG_SZ", 0, KEY_WRITE, NULL, &hKey, &iDisposition);
if (lRet != ERROR_SUCCESS)
{
PrintError(GetLastError(), "RegCreateKeyEx");
goto ABORT;
}

// Add the font to the registry...
SetLastError(0);
lRet = RegSetValueEx(hKey, argv[1], 0, REG_SZ, argv[2], lstrlen(argv[2]) +
sizeof(TCHAR));
if (lRet != ERROR_SUCCESS)
{
PrintError(GetLastError(), "RegSetValueEx");
goto ABORT;
}

// Done with the registry...
SetLastError(0);
lRet = RegCloseKey(hKey);
if (lRet != ERROR_SUCCESS)
{
PrintError(GetLastError(), "RegCloseKey");
goto ABORT;
}
hKey = NULL;

// Notify other running applications that a font was added...
SendMessageTimeout(HWND_BROADCAST, WM_FONTCHANGE, 0L, 0L, SMTO_NORMAL,
1000,
NULL);

// Notify success...
printf("\n\"%s\" (file: %s) was successfully added to the system.\n",
argv[1],
argv[2]);


/* Cleanup and return... */
ABORT:
if (hKey)
RegCloseKey(hKey);

return 0;
}


Thanks,
-Greg
Microsoft Developer Support



This posting is provided "AS IS" with no warranties, and confers no rights.
Visit http://www.microsoft.com/security for current information on security.




--------------------
Thread-Topic: List of activated fonts does not include shortcut activations
thread-index: AcP9YqoSmJ+t7lfoRpem8QAnbtaVFA==
X-Tomcat-NG: microsoft.public.dotnet.framework.windowsforms,microsoft.public.dotnet.gener
al
From: "=?Utf-8?B?anVzb3Zza3lAYW5vdGhlcnJldGFyZGVkLmNvbQ==?="
Subject: List of activated fonts does not include shortcut activations
Date: Fri, 27 Feb 2004 10:51:09 -0800
Lines: 6
Message-ID: <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain;
charset="Utf-8"
Content-Transfer-Encoding: 7bit
X-Newsreader: Microsoft CDO for Windows 2000
Content-Class: urn:content-classes:message
Importance: normal
Priority: normal
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
Newsgroups: microsoft.public.dotnet.framework.windowsforms,microsoft.public.dotnet.gener
al
Path: cpmsftngxa06.phx.gbl
Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.general:126336 microsoft.public.dotnet.framework.windowsforms:62770
NNTP-Posting-Host: tk2msftcmty1.phx.gbl 10.40.1.180
X-Tomcat-NG: microsoft.public.dotnet.framework.windowsforms

Our font management tool, Suitcase, activates fonts dynamically by
creating shortcuts in the Windows font folder. Using
System.Drawing.Text.InstalledFontCollection to get the list of font
families from the system yields only the fonts whose files are physically
in the system font folder- not the shortcuts. None of our applications
have any problems using the fonts activated by shortcuts. Can anyone
recommend another way to retrieve the complete list of fonts? Thanks for
any suggestions.

Josh Usovsky
Code:
System.Drawing.Text.InstalledFontCollection installedFonts = new
System.Drawing.Text.InstalledFontCollection();
System.Drawing.FontFamily[] fams = installedFonts .Families;
 
Back
Top