Загрузка изображения или курсора из 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.
|