Шаг 134 - Установка и удаление шрифта в системе

Предыдущий способ позволял устанавливать шрифт на время работы системы. То есть после перезагрузки Windows приходиться заново его устанавливать. Это способ хорош в том случае если Ваша программа регистрирует шрифт при запуске. А что делать если Вы хотите установить его при инсталляции. Надо сделать следующие шаги:

  1. Скопировать его в папочку Fonts.
  2. Зарегистрировать в реестре.
  3. Использовать функцию AddResourceFont для того, чтобы не перезагружать компьютер.

Давайте договоримся что будет использовать имя файла шрифта как имя шрифта. Вообще то это не одно и тоже. Имя файла шрифта например GeoMap.ttf, a имя шрифта у него вот такое:

134_1.gif (3338 b)

Именно это имя будет использоваться, если добавить шрифт стандартными средствами Windows. Мы с Вами пока будет оперировать именем файла. Это удобно в том плане, что не надо запоминать имя шрифта. Оно же не совпадает с именем файла. Для простоты будет регистрировать под именем файла. Создадим класс CFontInstall. Мы будет пользоваться классами MFC поэтому код будет работать только с поддержкой MFC.

#include "afx.h"
#include "atlbase.h"

#define PATH_FONT "Fonts\\"
#define REGKEY_FONT "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts"


class CFontInstall  
{
public:
	void RemoveFonts(CString csFile);			// удалить шрифт
	void InstallFonts(CString csFile, CString csPath);	// добавить шрифт
	CFontInstall();
	virtual ~CFontInstall();

private:
	CString GetName(CString csFile);		// отрезать расширение
	CString GetWinDir();				// папка Windows
	void RegisterFont(CString csFile);		// регистрировать в реестре
};

Пишем код. Первое это отрезание расширения, чтобы получить имя:

CString CFontInstall::GetName(CString csFile)
{
	CString csTemp=csFile;
	csTemp=csTemp.Left(csTemp.Find('.',0));	// найти точку взять все что с лева
	return csTemp;
}

Получение системной папки Windows. Кто сказал, что она должны быть только на диске С.

CString CFontInstall::GetWinDir()
{
	char buffer[MAX_PATH];
	if (GetWindowsDirectory(buffer,MAX_PATH)==0) 
		throw CString("Error GetSystemDirectory");
	CString temp(buffer);
	temp+="\\";
	temp+=PATH_FONT;
	return temp;
}

Регистрация в реестре:

void CFontInstall::RegisterFont(CString csFile)
{
	CRegKey cKey;
	if (cKey.Open(HKEY_LOCAL_MACHINE,REGKEY_FONT)!=ERROR_SUCCESS)
		throw CString("Error Open Registry");
	if (cKey.SetValue(csFile,GetName(csFile))!=ERROR_SUCCESS)
		throw CString("Error Add Key");  
	AddFontResource(csFile);
	SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);  
}

Непосредственная установка:

void CFontInstall::InstallFonts(CString csFile,CString csPath)
{
	CString in=csPath+csFile;
	CString out=GetWinDir()+csFile;
	if (CopyFile(in,out,FALSE)==0)
		throw CString("Error Copy");
	RegisterFont(csFile);
}

Удаление:

void CFontInstall::RemoveFonts(CString csFile)
{
	if (DeleteFile(GetWinDir()+csFile)==0)
		throw CString("Error Delete ");
	CRegKey cKey;
	if (cKey.Open(HKEY_LOCAL_MACHINE,REGKEY_FONT)!=ERROR_SUCCESS)
		throw CString("Error Open Registry");
	if (cKey.DeleteValue(GetName(csFile))!=ERROR_SUCCESS)
		throw CString("Error Delete"); 
	RemoveFontResource(csFile);
	SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);  
}

Попробуем ?

#include "stdafx.h"
#include "iostream.h"
#include "FontInstall.h"
#include "conio.h"

void main()
{
	CFontInstall cf;
	try
	{
		cf.InstallFonts("geomap.ttf","D:\\VС\\InstallFont\\");
		cout << "install" << endl;
		getch();
		cf.RemoveFonts("geomap.ttf");
		cout <<  "remove" <<  endl; 
	}
	catch(CString s)
	{
		cout <<  s <<  endl;
	}
}

В проекте находится класс CFontInstall упaкованный для использования в Component Gallery, как ogx файл.


Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 12.08.2001