Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Загрузка изображения или курсора из RES-файла

Загрузка изображений и курсоров из RES-файлов

Изображения и курсоры могут храниться в файлах ресурсов (RES) и прилинковываться (связаваться) к EXE-файлу вашего приложения. RES-файлы могут создаваться с помощью Delphi утилит Image Editor и Borland Resource Workshop, входящие в поставку Delphi RAD Pack. Изображения и курсоры, хранимые в RES-файлах (после упаковки их в EXE или DLL) могут быть извлечены с помощью API функций LoadBitmap и LoadCursor соответственно.

Загрузка изображений

Функция API LoadBitmap определена следующим образом:


function LoadBitmap(Instance: THandle; BitmapName: PChar): HBitmap;  

Первый параметр должен содержать дескриптор модуля (EXE или DLL), содержащего файл RES, из которого вы хотите получить ресурс. Delphi хранит дескриптор запущенного EXE-файла в глобальной переменной с именем Hinstance. В приведенном ниже примере мы предполагаем, что модуль, из которого мы пытаемся загрузить изображение, - ваше приложение. Тем не менее, модуль мог бы быть другим EXE- или DLL-файлом. Следующий пример загружает изображение с именем BITMAP_1 из RES-файла, прилинкованного к EXE-файлу приложения:


procedure TForm1.Button1Click(Sender: TObject);
var
  Bmp: TBitmap;
begin
  Bmp := TBitmap.Create;
  Bmp.Handle := LoadBitmap(HInstance,'BITMAP_1');
  Canvas.Draw(0, 0, Bmp);
  Bmp.Free;
end;

Имеется один недостаток использования API вызова LoadBitmap: LoadBitmap все же является API вызовом Windows 3.0, и грузит изображение только как DDB (Device Dependent Bitmaps). Это может вызвать проблемы с цветовой палитрой при загрузке DIB (Device Independent Bitmaps) из RES-файла. Приведенный ниже код может использоваться для извлечения DIB-ов из RES-файлов. Данный код загружает изображение как общий ресурс, передает его в поток, после чего делает Delphi вызов LoadFromStream, реализующий палитру автоматически.


procedure TForm1.Button1Click(Sender: TObject);
const
  BM = $4D42; {Идентификатор типа изображения}
var
  Bmp: TBitmap;
  BMF: TBitmapFileHeader;
  HResInfo: THandle;
  MemHandle: THandle;
  Stream: TMemoryStream;
  ResPtr: PByte;
  ResSize: Longint;
begin
  BMF.bfType := BM;
  {Ищем, загружаем и блокируем ресурс, содержащий BITMAP_1}
  HResInfo := FindResource(HInstance, 'BITMAP_1', RT_Bitmap);
  MemHandle := LoadResource(HInstance, HResInfo);
  ResPtr := LockResource(MemHandle);

  {Создаем Memory-поток, устанавливаем его размер, записываем
  туда заголовок изображения и, наконец, само изображение }
  Stream := TMemoryStream.Create;
  ResSize := SizeofResource(HInstance, HResInfo);
  Stream.SetSize(ResSize + SizeOf(BMF));
  Stream.Write(BMF, SizeOf(BMF));
  Stream.Write(ResPtr^, ResSize);

  {Освобождаем поток и сбрасываем его позицию в 0}
  FreeResource(MemHandle);
  Stream.Seek(0, 0);

  {Создаем TBitmap и загружаем изображение из MemoryStream}
  Bmp := TBitmap.Create;
  Bmp.LoadFromStream(Stream);
  Canvas.Draw(0, 0, Bmp);
  Bmp.Free;
  Stream.Free;
end;

Загрузка курсоров

Функция API LoadCursor определена следующим образом:


function LoadCursor(Instance: THandle; CursorName: PChar): HCursor; 

Первый параметр Instance должен содержать дескриптор модуля, содержащего файл RES. Как и пример, приведенный выше, данный пример предполагает, что модуль, из которого мы пытаемся загрузить курсор, - ваше приложение. Второй параметр - имя курсора. В секции interface сделайте следующее объявление:


const
  crMyCursor = 5; {Другие модули могут также использовать эту константу}

Затем добавьте следующие две строчки к обработчику события формы OnCreate:


procedure TForm1.FormCreate(Sender: TObject);
begin
  Screen.Cursors[crMyCursor] := LoadCursor(HInstance, 'CURSOR_1');
  Cursor := crMyCursor;
end;

или же вы можете изменить один из стандартных курсоров Delphi как показано ниже (константы Cursor описаны в электронной справке в статье Cursors Property):


procedure TForm1.FormCreate(Sender: TObject);
begin
  {Данный пример изменяет курсор SQL Hourglass}
  Screen.Cursors[crSQLWait] := LoadCursor(HInstance, 'CURSOR_1');
end;

Примечание: в нормальной ситуации необходимо удалить любые ресурсы курсоров с помощью DeleteCursor, тем не менее, в Delphi в этом нет необходимости, поскольку Delphi сама удаляет все курсоры из массива Cursors.

Проект Delphi World © Выпуск 2002 - 2004
Автор проекта: ___Nikolay