Ресурсы приложения Windows – это данные, которые встроены внутрь EXE, DLL, CPL и MUI файлов. Общеизвестным примером такого ресурса является иконка приложения. Windows API предопределяет большое количество типов ресурсов приложений. Кроме них приложения могут определять свои собственные типы ресурсов. Хотя, как я понимаю, они все будут равнозначны RCDATA. Давайте добавим приложению как ресурсы логотип и пользовательское соглашение, а при его старте загрузим их на форму.
Добавление ресурсов в приложение начинается с создания текстового файла, который их описывает:
Теперь нам нужно скомпилировать наш RC-файл. Для этого у RAD Studio есть три компилятора командной строки:
License TEXT "license.txt"Назовем его "AddRes.rc". "RC" – это стандартное расширение для таких файлов. В файле описаны два ресурса. Первый называется "License", имеет нестандартный тип "TEXT" и ссылается на текстовый файл "license.txt". Второй имеет целочисленный идентификатор "123", предопределенный тип "RCDATA" и ссылается на файл JPEG-формата "BlackCat.jpg".
123 RCDATA "BlackCat.jpg"
Теперь нам нужно скомпилировать наш RC-файл. Для этого у RAD Studio есть три компилятора командной строки:
- Borland Resource Compiler (BRCC32.EXE):
- Microsoft SDK Resource Compiler (RC.EXE).
- CodeGear Resource Compiler/Binder (CGRC.EXE). В реальности CGRC.EXE – это не компилятор. Это программа, которая переводит параметры BRCC32.EXE в параметры RC.EXE и запускает с ними RC.EXE.
program GetResource;
uses
Vcl.Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
{$R AddRes.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Но есть более простой и надежный способ – это добавить RC-файл в проект:
program GetResource;
uses
Vcl.Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
{$R 'AddRes.res' 'AddRes.rc'}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
В этом случае нам не нужно вызывать компилятор ресурсов каждый раз при их изменении, а достаточно просто перекомпилировать проект. В параметрах проекта можно выбрать, какой из компиляторов RAD Studio будет использовать для этого (BRCC32.EXE или CGRC.EXE/RC.EXE):
Доступ к ресурсам приложения можно получить через функции Windows API. Мы же воспользуемся реализованным в Delphi специальным потоком для чтения ресурсов приложения – TResourceStream. Он позволяет получить доступ к ресурсам по имени (ResName):
constructor TResourceStream.Create(Instance: THandle; const ResName: string; ResType: PChar);или по целочисленному идентификатору (ResID):
constructor TResourceStream.CreateFromID(Instance: THandle; ResID: Integer; ResType: PChar);Параметры:
- Instance – это дескриптор приложения или DLL содержащие ресурс.
- ResType – это строка, определяющая тип ресурса. Предопределенные типы в Delphi описаны в модуле WinApi.Windows.
unit Unit1;
interface
uses
System.Classes, System.SysUtils, System.Types, Winapi.Windows, Vcl.Forms,
Vcl.Graphics, Vcl.Controls, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Imaging.jpeg;
type
TForm1 = class(TForm)
imgLogo: TImage;
mLicense: TMemo;
procedure FormCreate(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
rs: TResourceStream;
begin
// загрузка по целочисленному идентификатору
rs := TResourceStream.CreateFromID(HInstance, 123, RT_RCDATA);
try
var jpg: TJPEGImage := TJPEGImage.Create;
try
jpg.LoadFromStream(rs);
imgLogo.Picture.Assign(jpg);
finally
jpg.Free
end;
finally
rs.Free
end;
// загрузка по имени
rs := TResourceStream.Create(HInstance, 'License', 'TEXT');
try
var ss: TStringStream := TStringStream.Create;
try
ss.LoadFromStream(rs);
mLicense.Text := ss.DataString;
finally
ss.Free;
end;
finally
rs.Free
end;
// загрузка не существующего ресурса
rs := TResourceStream.Create(HInstance, 'freedom', RT_ICON);
try
finally
rs.Free
end;
end.
При запуске приложения мы получим сообщение об ошибке:
Оно информирует, нас о том, что ресурс "freedom" не найден. С этим легко можно столкнуться, если загружать ресурсы из другого модуля неправильной версии. Что бы избежать подобной досадной неожиданности можно проверить наличие ресурса с помощью функции FindResource:
if FindResource(hInstance, 'freedom', RT_ICON) <> 0 then
begin
rs := TResourceStream.Create(HInstance, 'freedom', RT_ICON);
try
finally
rs.Free
end;
end;
или заключить загрузку ресурса в try-except (это дополнительно поможет избежать ошибки при не правильном формате ресурса):
try
rs := TResourceStream.Create(HInstance, 'freedom', RT_ICON);
try
finally
rs.Free
end;
except
end;
Примечание. К ресурсу с целочисленным идентификатором тоже можно обратиться по имени. Для этого перед его идентификатором нужно поставить символ "#":
if FindResource(hInstance, '#123', RT_RCDATA) <> 0 then
begin
rs := TResourceStream.Create(HInstance, '#123', RT_RCDATA);





Комментариев нет:
Отправить комментарий