
Вывод изображения на Ассемблере с помощью OLE
Ранее я уже разбирал загрузку и вывод изображения с помощью GDI+, но это далеко не единственный способ загрузки изображения из файла. В дополнение к этой теме предлагаю рассмотреть еще один способ, как можно загрузить изображение из файла средствами OLE. Сперва пропишем GUID объекта IID_IPicture и создадим структуру для методов интерфейса IPicture. В MSDN методы перечислены в алфавитном порядке, а не так, как они фактически идут в интерфейсе, имейте это в виду.Code (Assembler) : Убрать нумерацию
- ; GUID {7BF80980-BF32-101A-8BBB-00AA00300CAB}
- IID_IPicture dd 7BF80980h
- dw 0BF32h
- dw 0101Ah
- db 08Bh, 0BBh, 0h, 0AAh, 0h, 030h, 00Ch, 0ABh
- ; IPicture Interface
- struct IPicture
- ; IUnknown
- QueryInterface dd ?
- AddRef dd ?
- Release dd ?
- ; IPicture
- get_Handle dd ?
- get_hPal dd ?
- get_Type dd ?
- get_Width dd ?
- get_Height dd ?
- Render dd ?
- set_hPal dd ?
- get_CurDC dd ?
- SelectPicture dd ?
- get_KeepOriginalFormat dd ?
- set_KeepOriginalFormat dd ?
- PictureChanged dd ?
- SaveAsFile dd ?
- get_Attributes dd ?
- SetHdc dd ?
- ends
Code (Assembler) : Убрать нумерацию
- ; Прочитать файл в память
- invoke _lopen,fname,OF_READ
- cmp eax,-1
- je loc_free_1
- mov ebx,eax
- ; Получить размер файла
- invoke GetFileSize,ebx,NULL
- mov [file_size],eax
- ; Выделить память под файл
- invoke GetProcessHeap
- mov [hProcHeap],eax
- invoke HeapAlloc,[hProcHeap],0,[file_size]
- mov [hLock],eax
- ; Загрузить картинку в память
- invoke _lread,ebx,[hLock],[file_size]
- invoke _lclose,ebx
Теперь вступают в дело функции OLE. При помощи функции CreateStreamOnHGlobal из блока памяти по его хэндлу формируется поток, а из этого потока функцией OleLoadPicture создается объект картинки, с которым мы дальше будем работать. Важное замечание: функция OleLoadPicture работает только с изображениями в формате JPEG, GIF, BMP, ICO, WMF и EMF. Формат PNG не поддерживается.
Code (Assembler) : Убрать нумерацию
- ; Создать поток из данных
- invoke CreateStreamOnHGlobal,[hLock],TRUE,iStream
- ; Загрузить картинку из памяти
- invoke OleLoadPicture,[iStream],0,TRUE,IID_IPicture,iPicture
Code (Assembler) : Убрать нумерацию
- ; Вызвать метод интерфейса IPicture->get_Handle()
- mov eax, [iPicture]
- mov eax, [eax]
- stdcall dword [eax+IPicture.get_Handle],[iPicture],hBitmap
- ; Хэндл изображения
- mov eax,[hBitmap]
- ; Вызвать метод интерфейса IPicture->get_Width()
- mov eax, [iPicture]
- mov eax,[eax]
- stdcall dword [eax+IPicture.get_Width],[iPicture],bm.bmWidth
- ; Количество пикселей на логический дюйм по горизонтали
- invoke GetDC,NULL
- invoke GetDeviceCaps,eax,LOGPIXELSX
- ; Пересчитать HIMETRIC в обычные пикселы
- mov ecx,[bm.bmWidth]
- xor edx,edx
- imul ecx
- mov ecx,HIMETRIC_PER_INCH
- idiv ecx
- ; Ширина изображения
- mov [bm.bmWidth],eax
- ; Вызвать метод интерфейса IPicture->get_Height()
- mov eax, [iPicture]
- mov eax, [eax]
- stdcall dword [eax+IPicture.get_Height],[iPicture],bm.bmHeight
- ; Количество пикселей на логический дюйм по вертикали
- invoke GetDC,NULL
- invoke GetDeviceCaps,eax,LOGPIXELSY
- ; Пересчитать HIMETRIC в обычные пикселы
- mov ecx,[bm.bmHeight]
- xor edx,edx
- imul ecx
- mov ecx,HIMETRIC_PER_INCH
- idiv ecx
- ; Высота изображения
- mov [bm.bmHeight],eax
Поскольку функция CreateStreamOnHGlobal работает с блоками памяти, это дает нам возможность загружать картинки не только из файла на диске, но и напрямую из памяти. Допустим, что файл с картинкой хранится где-то в сегменте данных.
Code (Assembler) : Убрать нумерацию
- ; Данные картинки для вывода на форму
- image_data:
- file 'image.jpg'
- data_size=$-image_data
Code (Assembler) : Убрать нумерацию
- ; Выделить память под картинку
- invoke GetProcessHeap
- mov [hProcHeap],eax
- invoke HeapAlloc,[hProcHeap],0,data_size
- mov [hLock],eax
- ; Скопировать картинку в выделенную память
- mov esi,image_data
- mov edi,[hLock]
- mov ecx,data_size
- rep movsb
- ; Создать поток из данных
- invoke CreateStreamOnHGlobal,[hLock],TRUE,iStream
Code (Assembler) : Убрать нумерацию
- ; Загрузить картинку из ресурсов
- invoke FindResource,NULL,1,RT_RCDATA
- mov ebx,eax
- invoke SizeofResource,NULL,eax
- mov [file_size],eax
- invoke LoadResource,NULL,ebx
- mov ebx,eax
- ; Выделить память под картинку
- invoke GetProcessHeap
- mov [hProcHeap],eax
- invoke HeapAlloc,[hProcHeap],0,[file_size]
- mov [hLock],eax
- ; Скопировать картинку в выделенную память
- invoke LockResource,ebx
- mov esi,eax
- mov edi,[hLock]
- mov ecx,[file_size]
- rep movsb
- ; Создать поток из данных
- invoke CreateStreamOnHGlobal,[hLock],TRUE,iStream
В приложении примеры программ с исходными текстами, загружающие картинку на форму из файла, из памяти и из ресурсов с помощью OLE.
Просмотров: 3130 | Комментариев: 0

Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет

Добавить комментарий
Заполните форму для добавления комментария
