При разработке прототипа приложения, достаточно удобно использовать уже имеющиеся в команде изображения пиктограмм. Обычно все используемые пиктограммы упакованы в шрифт. А если чего-то не хватает, то можно использовать сервисы генерации шрифта, например Fontello, и добавить новые пиктограммы.
В процессе разработки, шрифт можно установить в систему, и он будет доступен для выбора у всех элементов (компонентов) в дизайнере окон Lazarus IDE. И если задать в качестве текста элемента нужный символ, то он сразу отобразится на данном элементе в дизайнере форм. Таким образом, не собирая приложение, можно будет оценить визуальный стиль, например, оценить то как будут смотреться значки, какого они будут размера и так далее.
Когда приложение, будет запускаться у пользователя, то не обязательно устанавливать шрифт в систему, его можно сделать доступным только самому приложению, поместив шрифт рядом с приложением или в ресурсах и загрузив его при инициализации.
Загрузка шрифта из файла ttf
При таком варианте использования шрифт должен располагаться рядом с приложением. В обработчики событий необходимо добавить код, который загрузит шрифт при создании формы и выгрузит его при уничтожении формы. Кроме того, при создании формы, необходимо установить шрифт для всех элементов, которым это необходимо.
procedure TForm1.FormCreate(Sender: TObject);
begin
AddFontResource(PChar(GetCurrentDir+'\MyFont.ttf'));
ToolBar1.Font.Name:='MyFont';
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
RemoveFontResource(PChar(GetCurrentDir+'\MyFont.ttf'));
end;
Загрузка шрифта из ресурса приложения
В этом случае, в начале шрифт необходимо добавить в ресурсы проекта. Для чего в настройках проекта, в пункте Ресурсы, необходимо добавить файл шрифта, а в окне выбора файла ресурса указать что необходимо отображать все файлы (*.*). Добавленному ресурсу присвоить нужное название и проверить, что указан тип RCDATA.
Для загрузки шрифта, в код нужно будет добавить специальный тип и определить дополнительные процедуры:
const
MM_MAX_NUMAXES = 16;
type
PDesignVector = ^TDesignVector;
TDesignVector = packed record
dvReserved: DWORD;
dvNumAxes: DWORD;
dvValues: array [0..MM_MAX_NUMAXES-1] of Longint;
end;
добавить в конец раздела type, перед разделом var определение двух функций:
function AddFontMemResourceEx (p1: Pointer; p2: DWORD; p3: PDesignVector; p4: LPDWORD): THandle; stdcall; external 'gdi32.dll' name 'AddFontMemResourceEx';
function RemoveFontMemResourceEx (p1: THandle): BOOL; stdcall; external 'gdi32.dll' name 'RemoveFontMemResourceEx';
А в раздел имплементации добавить функцию загрузки шрифта по имени ресурса, которая возвращает дескриптор, с помощью которого можно идентифицировать ресурс, и далее освободить его.
function LoadFontFromRes (FontName: PChar): THandle;
var
ResHandle: HRSRC;
ResSize, NbFontAdded: Cardinal;
ResAddr: HGLOBAL;
begin
ResHandle := FindResource (system.HINSTANCE, FontName, Windows.RT_RCDATA);
if ResHandle = 0 then RaiseLastOSError;
ResAddr := LoadResource (system.HINSTANCE, ResHandle);
if ResAddr = 0 then RaiseLastOSError;
ResSize := SizeOfResource (system.HINSTANCE, ResHandle);
if ResSize = 0 then RaiseLastOSError;
result := AddFontMemResourceEx (Pointer (ResAddr), ResSize, nil, @NbFontAdded);
if result = 0 then RaiseLastOSError;
end;
По аналогии с предыдущим вариантом в обработчики событий добавляется код для загрузки шрифта в при создании формы и выгрузке его при уничтожении формы.
procedure TForm1.FormCreate(Sender: TObject);
begin
RecourceFontHandle:=LoadFontFromRes('MYFONT'); // здесь RecourceFontHandle:THandle; - глобальная переменная
ToolBar1.Font.Name:='MyFont';
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
RemoveFontMemResourceEx(RecourceFontHandle);
end;
Заключение
Надеюсь что формат небольшой статьи, с описанием решений по маленькой, но конкретной теме будет более интересным и полезным чем предыдущие публикации.
Комментарии (2)
Antohin
24.12.2024 09:58Просто без объяснения этого момента весь дальнейший код, использующий эту функцию, превращается в "черную магию"
И мы же потом жалуется на молодежь, которая бездумно копирует код из интернета не пытаясь в нем разобраться.
Да, имея опыт использования WinAPI, пример использования функции и зная правила трансляции типов C<->Delphi в этом несложно разобраться, но приходится прилагать определенные усилия
Antohin
Всё хорошо, но хотелось бы видеть сигнатуру функции
AddFontMemResourceEx
а то ее параметры приходится угадывать исходя из способа ее использования.Цитируя первую попавшуюся под руку доку (вроде сходится по сигнатуре и смыслу параметров с приведенной в статье):
[in] pFileView
Указатель на ресурс шрифта.[in] cjSize
Количество байтов в ресурсе шрифта, на который указывает pbFont.[in] pvResrved
Зарезервировано. Должно быть равно 0.[in] pNumFonts
Указатель на переменную, указывающую количество установленных шрифтов.Если функция выполнена успешно, возвращаемое значение указывает дескриптор добавленного шрифта. Этот дескриптор однозначно идентифицирует шрифты, установленные в системе. Если функция выполняется неудачно, возвращается нулевое значение. Дополнительные сведения об ошибке недоступны.