Ресурсы приложения 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);
Комментариев нет:
Отправить комментарий