Еще один способ загрузки битмапа на поверхность
Anti:>Тут возник такой вопрос, что функция LoadImage, которую я приводил
в Основах по DirectDraw имеет проблемы с загрузкой файлов под WinNT. В документации
Microsoft сказано, что эта API-функция требует WinNT 4.0 или больше, но как
бы то ни было, я получил письмо от Файзуллина
Рустама, где было указано на эту проблему. В результате, Рустам прислал
свой вариант загрузки битмапа. Вот он:
Сначала две вспомагательные функции, для создания поверхностей:
LPDIRECTDRAWSURFACE7 CreateVideoSurface(int width, int height)
{
if(!Ddraw) return NULL;
LPDIRECTDRAWSURFACE7 s;
DDSURFACEDESC2 tmp;
ZeroMemory(&tmp,sizeof(tmp));
tmp.dwSize=sizeof(tmp);
tmp.dwFlags=DDSD_HEIGHT |DDSD_WIDTH |DDSD_CAPS;
tmp.dwWidth=width;
tmp.dwHeight=height;
tmp.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
HRESULT r=Ddraw->CreateSurface(&tmp,&s,0);
if(r!=DD_OK) return NULL;
return s;
};
LPDIRECTDRAWSURFACE7 CreateMemSurface(int width, int height)
{
if(!Ddraw) return NULL;
LPDIRECTDRAWSURFACE7 s;
DDSURFACEDESC2 tmp;
ZeroMemory(&tmp,sizeof(tmp));
tmp.dwSize=sizeof(tmp);
tmp.dwFlags=DDSD_HEIGHT |DDSD_WIDTH |DDSD_CAPS;
tmp.dwWidth=width;
tmp.dwHeight=height;
tmp.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
HRESULT r=Ddraw->CreateSurface(&tmp,&s,0);
if(r!=DD_OK) return NULL;
return s;
};
Основная функция:
1) проецирует файл на адресное пространство
2) проверяет это bmp файл, если нет выход.
3) из загаловка bmp файла считывается его ширина высота
и указатель на DIB данные(void *bits)
4) создаётся поверхность, сначала пробуем в видео памяти,
если не получается то в системной, если нет то выход.
5) рисуем картинку функцией StretchDIBits
LPDIRECTDRAWSURFACE7 CreateSurBmp(char *Name)
{
HANDLE hF=CreateFile(Name, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hF==INVALID_HANDLE_VALUE) return NULL;
HANDLE hM=CreateFileMapping(hF, NULL, PAGE_READONLY, 0, 0, NULL);
CloseHandle(hF);
if(!hM) return NULL;
void *ptr=MapViewOfFile(hM, FILE_MAP_READ, 0, 0, 0);
CloseHandle(hM);
if(!ptr) return NULL;
LPBITMAPFILEHEADER FileHeader=(LPBITMAPFILEHEADER)ptr;
if(FileHeader->bfType!='BM')
{
UnmapViewOfFile(ptr);
return NULL;
}
void *bits=(void *)((BYTE *)FileHeader + FileHeader->bfOffBits);
LPBITMAPINFO Info=(LPBITMAPINFO)((BYTE *)ptr+sizeof(BITMAPFILEHEADER));
int w=Info->bmiHeader.biWidth;
int h=Info->bmiHeader.biHeight;
LPDIRECTDRAWSURFACE7 sur=CreateVideoSurface(w, h);
if(!sur) sur=CreateMemSurface(w, h);
if(!sur)
{
UnmapViewOfFile(ptr);
return NULL;
}
HDC dc=NULL; sur->GetDC(&dc);
SetStretchBltMode(dc, COLORONCOLOR);
StretchDIBits(dc, 0, 0, w, h, 0, 0, w, h, bits, Info, DIB_RGB_COLORS, SRCCOPY);
sur->ReleaseDC(dc);
UnmapViewOfFile(ptr);
return sur;
}
всё.
С уважением, Файзуллин Рустам <fr@alawar.com>
Posted: 23.01.2k1
Autor: Файзуллин Рустам
<fr@alawar.com>
|
 |
 |
|