Простой способ подключения ресурсов *.res в Delphi.

Здравствуйте уважаемые коллеги!

В сети присутствует большое количество информации о том, как подключить ресурсы к своему проекту в Delphi. И как правило это старый «дедовский» метод через создание *.rc файла с последующей компиляцией его через командную строку. Но начиная с версии 2009 (и далее) в Delphi появилась возможность делать это намного проще.

В среде Delphi заходим в меню «Project» пункт «Resources and Images»:
Откроется менеджер ресурсов, в котором мы можем добавлять картинки, иконки, звуки и прочие файлы:

res

При добавлении мы можем указать строку идентификатор ресурса и его тип.

resmgr

Теперь давайте рассмотрим, как можно использовать подключенные ресурсы в своей программе.

Для начала получим список ресурсов программы.

Нам понадобятся 2 API функции: EnumResourceTypes и EnumResourceNames.

EnumResourceTypes
Получает список типов ресурсов.

EnumResourceTypes(
	hModule: HMODULE; 
	lpEnumFunc: ENUMRESTYPEPROC;
	lParam: IntPtr
): BOOL;

hModule — Указатель на модуль.
lpEnumFunc — Указатель на функцию, которая будет вызвана для каждого из типов ресурсов.
lParam — Пользовательский параметр.

Функция которая должна быть передана в качестве параметра lpEnumFunc должна выглядеть следующим образом:

EnumResTypeProc(
	Module: HMODULE; 
	lpszType: PChar; 
	lParam: NativeInt
): BOOL;

Module — Указатель на модуль.
lpszType — Тип ресурса.
lParam — Пользовательский параметр.

Параметр lpszType может содержать как наименование типа, так и его ID. В зависимости от того какого типа наш lpszType мы должны обращаться к нему как к типу строка или целое. В противном случае можем получить ошибку «Неверная попытка доступа к адресу памяти». Для определения типа можно воспользоваться функцией IS_INTRESOURCE, которая вернет True в случае если это ID и False в случае наименования.
Список наименований и кодов можно посмотреть на этой странице

EnumResourceNames
Получает список наименований ресурсов.

EnumResourceNames(
	hModule: HMODULE; 
	lpType: LPCWSTR;
	lpEnumFunc: ENUMRESNAMEPROC; 
	lParam: IntPtr
): BOOL;

hModule — Указатель на модуль.
lpType — Тип ресурса.
lpEnumFunc — Указатель на функцию, которая будет вызвана для каждого наименования ресурса.
lParam — Пользовательский параметр.

Функция lpEnumFunc:

EnumResNameProc(
	Module: HMODULE; 
	lpszType: PChar; 
	lpszName: PChar; 
	lParam: NativeInt
): BOOL;

Module — Указатель на модуль.
lpszType — Тип ресурса.
lpszName — Имя ресурса.
lParam — Пользовательский параметр.

Код для формирования списка ресурсов:

function EnumResNameProc(Module: HMODULE; lpszType: PChar; lpszName: PChar; lParam: NativeInt): BOOL; stdcall;
var
  List: TStrings;
  s: string;
begin
  List := TStrings(lParam);
  s := '';
  if IS_INTRESOURCE(lpszType) then
    s := 'Тип ресурса ID: ' + IntToStr(NativeUInt(lpszType))
  else
    s := 'Тип ресурса : ' + lpszType;

  if IS_INTRESOURCE(lpszName) then
    s := s + ' Ресурс ID: ' + IntToStr(NativeUInt(lpszName))
  else
    s := s + ' Ресурс: ' + lpszName;
  List.Add(s);
  Result := True;
end;

function EnumResTypeProc(Module: HMODULE; lpszType: PChar; lParam: NativeInt): BOOL; stdcall;
begin
  EnumResourceNames(Module, lpszType, @EnumResNameProc, NativeInt(lParam));
  Result := True;
end;

procedure TfmMain.FormCreate(Sender: TObject);
begin
  if not EnumResourceTypes(HInstance, @EnumResTypeProc, NativeInt(Pointer(ListBox1.Items))) then
    raise Exception.Create('Ошибка получения списка ресурсов: '+ SysErrorMessage(GetLastError));
end;

GetLastErrorAPI функция, которая показывает код последней системной ошибки.
SysErrorMessage — Функция, которая по коду получает текст системной ошибки.
В качестве параметра lParam функции EnumResourceNames передаем указатель на элементы списка ListBox1.

После запуска программы у нас сформируется список ресурсов:

res_list

Теперь давайте вытащим картинки, которые мы поместили в ресурсы. Добавим кнопку и 4 компонента TImage.
На клик кнопки добавим код:

procedure TfmMain.Button1Click(Sender: TObject);
var
  p: TPNGImage;
begin
  p := TPngImage.Create;
  try
    p.LoadFromResourceName(HInstance, 'pict1');
    Image1.Picture.Assign(p);
    p.LoadFromResourceName(HInstance, 'pict2');
    Image2.Picture.Assign(p);
    p.LoadFromResourceName(HInstance, 'pict3');
    Image3.Picture.Assign(p);
    p.LoadFromResourceName(HInstance, 'pict4');
    Image4.Picture.Assign(p);
  finally
    p.Free;
  end
end;

При нажатии картинки появятся на форме:
res_picts

Надеюсь данная статья будет полезной для Вас.

Исходные коды примера можно скачать тут.

Статья добавлена в Delphi. Добавить ссылку в закладки.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *