Зарегистрировать шрифт:

AddFontResource('путь к фонту\\Algerian.ttf');

Объект.Font.Name:="Algerian";

 

Удалить -

RemoveFontResource('путь к фонту\\Algerian.ttf');

 

Автор Alex101

Как определить, какой шрифт установлен в системе, большой или маленький

 

Следующуя функция возвращает true, если маленькие шрифты установлены в системе. Так же можно заменить строку 'Result := (GetDeviceCaps(DC, logpixelsx) = 96);' на 'Result := (GetDeviceCaps(DC, logpixelsx) = 120);' чтобы определять - установлены ли в системе крупные шрифты.

 

Может ли кто-нибудь подсказать или решить такую проблему: мне нужно убедиться, что мое приложение использует доступные, а не ближайшие шрифты, установленные пользователем в системе? Я пробовал копировать файл #.ttf в директорию пользователя windows\system, но мое приложение так и не смогло их увидеть и выбрать для дальнейшего использования.

 

Ниже приведен код для Delphi, который динамически устанавливает шрифты, загружаемые только во время работы приложения. Вы можете расположить файл(ы) шрифтов в каталоге приложения. Они будут инсталлированы при загрузке формы и выгружены при ее разрушении. Вам возможно придется модифицировать код для работы с Delphi 2, поскольку он использует вызовы Windows API, которые могут как измениться, так и нет. Если в коде вы видите "...", то значит в этом месте может располагаться какой-либо код, не относящийся к существу вопроса.

 

Чтобы установить шрифт в систему, необходимо скопировать файл шрифта в 'Windows\Fonts' и добавить ключ в реестр:

 'Software\Microsoft\Windows\CurrentVersion\Fonts'

 Этот ключ указывает на файл шрифта. Далее запускаем API функцию 'AddFontRecource'. В заключении нужно уведомить систему широковещательным сообщением.

 

 

Code:

function SmallFonts: Boolean;

{Значение функции TRUE если мелкий шрифт}

var

DC: HDC;

begin

DC := GetDC(0);

Result := (GetDeviceCaps(DC, LOGPIXELSX) = 96);

{ В случае крупного шрифта будет 120}

ReleaseDC(0, DC);

end;

 

  

Code:

function IsTrueTypeInstalled: bool;

var

{$IFDEF WIN32}

rs : TRasterizerStatus;

{$ELSE}

rs : TRasterizer_Status;

{$ENDIF}

begin

result := false;

if not GetRasterizerCaps(rs, sizeof(rs)) then

   exit;

if rs.WFlags and TT_AVAILABLE <> TT_AVAILABLE then

   exit;

if rs.WFlags and TT_ENABLED <> TT_ENABLED then

   exit;

result := true;

end;

 

Когда мои программы работают на системах с установленными маленькими шрифтами, я получаю странный вид моей формы. К примеру, расположенные на форме компоненты Label становятся малы для размещения указанного теста, обрезая его в правой или нижней части. StringGrid не осуществляет положенного выравнивания и т.д.

 

Попробуй следующий код. Он масштабирует как размер формы, так и размер шрифтов. Вызывай его в Form.FormCreate. Надеюсь это поможет.

 

 

Code:

procedure TConsole.FontChanged(Sender: TObject);

var

DC: HDC;

Save: THandle;

Metrics: TTextMetric;

Temp: string;

begin

if Font.Handle <> FOldFont.Handle then

begin

   DC := GetDC(0);

   Save := SelectObject(DC, Font.Handle);

   GetTextMetrics(DC, Metrics);

   SelectObject(DC, Save);

   ReleaseDC(0, DC);

   if not (((Metrics.tmPitchAndFamily and ff_Modern) <> 0) and

     ((Metrics.tmPitchAndFamily and $01) = 0)) then

   begin

     Temp := 'TConsole: ' + Font.Name +

       ' не является шрифтом с фиксированной шириной';

     Font.Name := FOldFont.Name; { Возвращаем предыдущие атрибуты шрифта }

     raise EInvalidFont.Create(Temp);

   end;

   SetMetrics(Metrics);

end;

FOldFont.Assign(Font);

if csDesigning in ComponentState then

   InternalClrScr;

end;

 

 Я также долго мучился над проблемой решения этого вопроса, и ниже я излагаю свои выводы на основании моих многочисленных экспериментов.

 Свойство, отвечающее за размер шрифта важно, но не менее важны в этом вопросе и другие характеристики.

 

 

Code:

unit Fontlist;

 

interface

 

uses

Windows, Classes, Graphics, Forms, Controls, StdCtrls;

 

type

TForm1 = class(TForm)

   ListBox1: TListBox;

   Label1: TLabel;

   FontLabel: TLabel;

   procedure FormCreate(Sender: TObject);

   procedure ListBox1Click(Sender: TObject);

   procedure DrawItem(Control: TWinControl; index: Integer; Rect: TRect;

     State: TOwnerDrawState);

   procedure ListBox1MeasureItem(Control: TWinControl; index: Integer;

     var Height: Integer);

private

   { Private declarations }

public

   { Public declarations }

end;

 

var

Form1: TForm1;

 

implementation

 

{$R *.DFM}

 

procedure TForm1.FormCreate(Sender: TObject);

begin

Listbox1.Items := Screen.Fonts;

end;

 

procedure TForm1.ListBox1Click(Sender: TObject);

begin

FontLabel.Caption := ListBox1.Items[ListBox1.ItemIndex];

end;

 

procedure TForm1.DrawItem(Control: TWinControl; index: Integer;

Rect: TRect; State: TOwnerDrawState);

begin

with ListBox1.Canvas do

begin

   FillRect(Rect);

   Font.name := ListBox1.Items[index];

   Font.Size := 0; // use font's preferred size

   TextOut(Rect.Left+1, Rect.Top+1, ListBox1.Items[index]);

end;

end;

 

procedure TForm1.ListBox1MeasureItem(Control: TWinControl; index: Integer;

var Height: Integer);

begin

with ListBox1.Canvas do

begin

   Font.name := Listbox1.Items[index];

   Font.Size := 0; // use font's preferred size

   Height := TextHeight('Wg') + 2; // measure ascenders and descenders

end;

end;

 

end.

 

function GetFontResourceInfoW (FontPath : PWideChar; var BufSize : DWORD; FontName : PWideChar; dwFlags : DWORD) : DWORD; stdcall; external 'GDI32.DLL';

 

1-ый параметр - указатель на Wide-строку, содержащую путь к файлу шрифта;

2-ой параметр - указатель на DWORD-переменную, содержащую размер выходного буфера. После выполнения функции в этой переменной будет содержаться необходимая длина буфера;

3-ий параметр - указатель на буфер, в случае успешного выполнения будет содержать Wide-строку имени шрифта;

4-ый параметр - какие-то флаги, если рыться в функции GetFontResourceInfoW особым случаем является когда dwFlags=4, но зачем это, я так и не понял - в результате будет возвращен тот же путь к файлу; ну а для получения имени шрифта флаг должен быть равен 1.