Delphi: DLL библиотеки

КОМПЬЮТЕРНЫЕ КУРСЫ "ПОИСК"

[Главная страница] [Delphi] [DLL] [Контакты]

Изображения в DLL


Создаем библиотеку DLL.

В ресурсы DLL добавляем рисунки chemical.bmp и factory.bmp.

В проектную группу добавить новый проект VCL Forms. Project - Add New Project... .

На форме нового окна создать две кнопки и один Image.

Для кнопок создать событийные процедуры OnClick.

var
  Form1: TForm1;
  H: THandle;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  H := LoadLibrary('MyDLL.dll');
  if H <> 0 then
  begin
    Image1.Picture.Bitmap.Handle := LoadBitmap(H, 'BDelphi');
    FreeLibrary(H);
  end
  else
    ShowMessage('Не удалось загрузить изображение');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  H := LoadLibrary('MyDLL.dll');
  if H <> 0 then
  begin
    Image1.Picture.Bitmap.Handle := LoadBitmap(H, 'BEarth');
    FreeLibrary(H);
  end
  else
    ShowMessage('Не удалось загрузить изображение');
end;

Отметим, что аналогичным образом в файле ресурсов DLL можно создавать и набор пиктограмм. Использоваться они могут тоже аналогично, только вместо функции LoadBitmap надо использовать функцию Loadlcon.

Исходный код проекта (Delphi XE)


Поиск изображений и пиктограмм в ресурсах


В API Windows имеется функция EnumResourceNames, позволяющая полуполучить список имен ресурсов указанного типа, содержащихся в ресурсе любого вывыполняемого модуля, в частности, DLL. Рассмотрим ее применение в приложениях VCL Win32. В модуле Windows эта функция объявлена следующим образом:

function EnumResourceNames(
  hModule: HMODULE;
  lpType: PWideChar;
  lpEnumFunc: ENUMRESNAMEPROC;
  lParam: Longint
): BOOL; stdcall;

Параметр hModule является дескриптором модуля, ресурсы которого исследуисследуются. Параметр lpType является строкой, указывающей тип исследуемых ресурресурсов. В частности, этот параметр может принимать значения следующих констант:

RT_BITMAP ресурсы BMP
RT_GROUP_ICON ресурсы аппаратнонезависимых пикторамм
RT_ICON ресурсы аппаратнозависимых пикторамм

Остальные возможные значения посмотрите в справке API Windows.

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

Функция EnumResourceNames работает так. Если в файле ресурсов выполняемого модуля имеются ресурсы типа, указанного параметром lpType, то для каждого такого ресурса вызывается функция, адрес которой указан параметром lpEnumFunc. Эта функция должна иметь заголовок вида:

function MyEnumResNameProc(
  hModule: THandle;
  lpType, pszName:PChar;
  lParam: longint
): BOOL; stdcall;

В функцию автоматически передаются параметры hModule, lpType, lParam, указанные аргументами при вызове EnumResourceNames. Кроме того, передается параметр pszName — строка с именем ресурса. Функция MyEnumResNameProc может как-то обработать полученную информацию. Если требуется продолжать исследование ресурсов данного типа, то функция MyEnumResNameProc должна вернуть true. Если функция вернет false, цикл вызовов этой функции, инициированный функцией EnumResourceNames, прервется.

Рассмотрим пример, вид формы которого приведен на рисунке ниже. Приложение сосодержит одну кнопку, вызывающую стандартный диалог открытия файла. Если пользователь выбрал в диалоге выполняемый файл, то в выпадающие списки ComboBox1 и ComboBox2 загружаются соответственно имена ресурсов BMP и пиктограмм, содержащихся в файле. Если такие ресурсы нашлись, пользователь может посмотреть их, выбирая имя ресурса в выпадающем списке.

Ниже приведен код этого приложения:

var
  Form1: TForm1;
  H: THandle;

implementation

{$R *.dfm}

function MyEnumResnameProc(hModule: THandle; lpType, pszName: PChar;
                            lParam: Integer): Boolean; stdcall;
begin
  if lpType = RT_BITMAP then
    Form1.ComboBox1.Items.Append(pszName)
  else if (lpType = RT_GROUP_ICON) or (lpType = RT_ICON) then
    Form1.ComboBox2.Items.Append(pszName);
  Result := True;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
  begin
    H := LoadLibrary(PChar(OpenDialog1.FileName));
    if H <> 0 then
    begin
      Label1.Caption := 'Файл: ' + OpenDialog1.FileName;
      Image1.Picture.Bitmap.Handle := 0;
      Image1.Picture.Icon.Handle := 0;
      ComboBox1.Clear;
      EnumResourceNames(H, RT_BITMAP, @MyEnumResnameProc, 0);
      ComboBox1.ItemIndex := 0;
      ComboBox2.Clear;
      EnumResourceNames(H, RT_GROUP_ICON, @MyEnumResnameProc, 0);
      EnumResourceNames(H, RT_ICON, @MyEnumResnameProc, 0);
      ComboBox2.ItemIndex := 0;
      FreeLibrary(H);
    end;
  end;
end;


procedure TForm1.ComboBox1Click(Sender: TObject);
begin
  H := LoadLibrary(PChar(OpenDialog1.FileName));
  if H <> 0 then
  begin
    Image1.Picture.Bitmap.Handle := LoadBitmap(H, PChar(ComboBox1.Text));
    FreeLibrary(H);
  end
  else
    ShowMessage('Не удалось загрузить изображение');
end;


procedure TForm1.ComboBox2Click(Sender: TObject);
begin
  H := LoadLibrary(PChar(OpenDialog1.FileName));
  if H <> 0 then
  begin
    Image1.Picture.Icon.Handle := LoadIcon(H, PChar(ComboBox2.Text));
    FreeLibrary(H);
  end
  else
    ShowMessage('Не удалось загрузить изображение');
end;

Функция MyEnumResNameProc — это та самая функция, к которой в цикле следуют обращения для каждого элемента ресурсов. В этой функции анализируется тип ресурса lpType и имена ресурсов BMP заносятся в список ComboBox1, а имена пиктограмм — в список ComboBox2. Функция всегда возвращает true, так что происходит просмотр всех ресурсов.

Процедура Button1Click является обработчиком щелчка на кнопке. Процедура вызывает диалог открытия файла и загружает функцией LoadLibrary выбранный пользователем модуль. Далее удаляется изображение из Image1, очищаются выпадающие списки ComboBox и производится вызов EnumResourceNames для различных типов ресурсов. В заключение загруженный модуль выгружается из памяти функцией FreeLibrary.

Обработчики щелков на выпадающих списках ComboBox сводятся к тому, что функциями LoadBitmap или Loadlcon выбранный пользователем ресурс загружается в Image1.

Исходный код проекта (Delphi XE)

Используемая литература:
Иван Хладни. Внутренний мир Borland Delphi 2006.
А.Я. Архангельский. Приемы программирования Delphi на основе VCL. Версия Delphi 5 - Delphi 2006.