Implemented ImageList_Read (not 100% correct in regarding to setting

the bitmap).
Filled out unknown members of ILHEAD.
Started reordering IMAGELIST to make it Windows binary compatible.
This commit is contained in:
Marcus Meissner 2000-01-29 21:00:25 +00:00 committed by Alexandre Julliard
parent 8b466e0ce8
commit d40170d20c
2 changed files with 162 additions and 35 deletions

View File

@ -1883,6 +1883,86 @@ ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2,
}
static int may_use_dibsection(HDC hdc) {
int bitspixel = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES);
if (bitspixel>8)
return TRUE;
if (bitspixel<=4)
return FALSE;
return GetDeviceCaps(hdc,94) & 0x10;
}
static HBITMAP _read_bitmap(LPSTREAM pstm,int x) {
HDC xdc = 0;
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
int bitsperpixel,palspace,longsperline,width,height;
LPBITMAPINFOHEADER bmihc = NULL;
int result = 0;
HBITMAP hbitmap = 0;
LPBYTE bits = NULL;
if (!SUCCEEDED(IStream_Read ( pstm, &bmfh, sizeof(bmfh), NULL)) ||
(bmfh.bfType != (('M'<<8)|'B')) ||
!SUCCEEDED(IStream_Read ( pstm, &bmih, sizeof(bmih), NULL)) ||
(bmih.biSize != sizeof(bmih))
)
return 0;
bitsperpixel = bmih.biPlanes * bmih.biBitCount;
if (bitsperpixel<=8)
palspace = (1<<bitsperpixel)*sizeof(RGBQUAD);
else
palspace = 0;
width = bmih.biWidth;
height = bmih.biHeight;
bmihc = (LPBITMAPINFOHEADER)LocalAlloc(LMEM_ZEROINIT,sizeof(bmih)+palspace);
memcpy(bmihc,&bmih,sizeof(bmih));
longsperline = ((width*bitsperpixel+31)&~0x1f)>>5;
bmihc->biSizeImage = (longsperline*height)<<2;
/* read the palette right after the end of the bitmapinfoheader */
if (!SUCCEEDED(IStream_Read ( pstm, bmihc+1, palspace, NULL)))
goto ret1;
xdc = GetDC(0);
if ((bitsperpixel>1) &&
((x!=0xfe) && (!x || may_use_dibsection(xdc)))
) {
hbitmap = CreateDIBSection(xdc,(BITMAPINFO*)bmihc,0,(LPVOID*)&bits,0,0);
if (!hbitmap)
goto ret1;
if (!SUCCEEDED(IStream_Read( pstm, bits, bmihc->biSizeImage, NULL)))
goto ret1;
bits = NULL;
result = 1;
} else {
if (bitsperpixel==1)
hbitmap = CreateBitmap(width,height,1,1,NULL);
else
hbitmap = CreateCompatibleBitmap(xdc,width,height);
/* Might be a bit excessive memory use here */
bits = (LPBYTE)LocalAlloc(0,longsperline*4*height);
if (!SUCCEEDED(IStream_Read ( pstm, bits, longsperline*4*height, NULL)))
goto ret1;
if (!SetDIBits(xdc,hbitmap,0,height,bits,(BITMAPINFO*)bmihc,0))
goto ret1;
result = 1;
}
ret1:
if (xdc) ReleaseDC(0,xdc);
if (bmihc) LocalFree((HLOCAL)bmihc);
if (bits) LocalFree((HLOCAL)bits);
if (!result) {
if (hbitmap) {
DeleteObject(hbitmap);
hbitmap = 0;
}
}
return hbitmap;
}
/*************************************************************************
* ImageList_Read [COMCTL32.66]
*
@ -1895,31 +1975,67 @@ ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2,
* Success: handle to image list
* Failure: NULL
*
* NOTES
* This function can not be implemented yet, because
* IStream32::Read is not implemented yet.
*
* BUGS
* empty stub.
* still not complete functional
*/
HIMAGELIST WINAPI ImageList_Read (LPSTREAM pstm)
{
HRESULT errCode;
ULONG ulRead;
ILHEAD ilHead;
HIMAGELIST himl;
ILHEAD ilHead;
HIMAGELIST himl;
HBITMAP hbmColor=0,hbmMask=0;
int i;
if (!SUCCEEDED(IStream_Read (pstm, &ilHead, sizeof(ILHEAD), NULL)))
return NULL;
if (ilHead.usMagic != (('L' << 8) | 'I'))
return NULL;
if (ilHead.usVersion != 0x101) /* probably version? */
return NULL;
FIXME("empty stub!\n");
#if 0
FIXME(" ilHead.cCurImage = %d\n",ilHead.cCurImage);
FIXME(" ilHead.cMaxImage = %d\n",ilHead.cMaxImage);
FIXME(" ilHead.grow = %d\n",ilHead.grow);
FIXME(" ilHead.cx = %d\n",ilHead.cx);
FIXME(" ilHead.cy = %d\n",ilHead.cy);
FIXME(" ilHead.flags = %x\n",ilHead.flags);
FIXME(" ilHead.ovls[0] = %d\n",ilHead.ovls[0]);
FIXME(" ilHead.ovls[1] = %d\n",ilHead.ovls[1]);
FIXME(" ilHead.ovls[2] = %d\n",ilHead.ovls[2]);
FIXME(" ilHead.ovls[3] = %d\n",ilHead.ovls[3]);
#endif
errCode = IStream_Read (pstm, &ilHead, sizeof(ILHEAD), &ulRead);
if (errCode != S_OK)
return NULL;
hbmColor = _read_bitmap(pstm,ilHead.flags & 0xfe);
if (!hbmColor)
return NULL;
if (ilHead.flags & 1) {
hbmMask = _read_bitmap(pstm,0);
if (!hbmMask) {
DeleteObject(hbmColor);
return NULL;
}
}
FIXME("Magic: 0x%x\n", ilHead.usMagic);
himl = ImageList_Create (
ilHead.cx,
ilHead.cy,
ilHead.flags,
1, /* initial */
ilHead.grow
);
if (!himl) {
DeleteObject(hbmColor);
DeleteObject(hbmMask);
return NULL;
}
himl = ImageList_Create (32, 32, ILD_NORMAL, 2, 2);
himl->hbmImage = hbmColor;
himl->hbmMask = hbmMask;
ImageList_SetBkColor(himl,ilHead.bkcolor);
for (i=0;i<4;i++)
ImageList_SetOverlayImage(himl,ilHead.ovls[i],i+1);
return himl;
}

View File

@ -7,43 +7,54 @@
#ifndef __WINE_IMAGELIST_H
#define __WINE_IMAGELIST_H
#include "wingdi.h"
#include "pshpack1.h"
/* the ones with offsets at the end are the same as in Windows */
struct _IMAGELIST
{
DWORD magic; /* 00: 'LMIH' */
INT cCurImage; /* 04: ImageCount */
INT cMaxImage; /* 08: maximages */
DWORD x3;
INT cx; /* 10: cx */
INT cy; /* 14: cy */
DWORD x4;
UINT flags; /* 1c: flags */
DWORD x5;
COLORREF clrBk; /* 24: bkcolor */
/* not yet found out */
HBITMAP hbmImage;
HBITMAP hbmMask;
HBRUSH hbrBlend25;
HBRUSH hbrBlend50;
COLORREF clrBk;
COLORREF clrFg;
INT cInitial;
INT cGrow;
INT cMaxImage;
INT cCurImage;
INT cx;
INT cy;
UINT flags;
UINT uBitsPixel;
INT nOvlIdx[15];
};
typedef struct _IMAGELIST *HIMAGELIST;
/* header used by ImageList_Read() and ImageList_Write() */
/* Header used by ImageList_Read() and ImageList_Write() */
typedef struct _ILHEAD
{
USHORT usMagic;
USHORT usParam1;
INT Param2;
INT Param3;
INT Param4;
INT Param5;
INT Param6;
INT Param7;
USHORT usMagic;
USHORT usVersion;
WORD cCurImage;
WORD cMaxImage;
WORD grow; /* unclear */
WORD cx;
WORD cy;
COLORREF bkcolor;
WORD flags;
WORD ovls[4];
} ILHEAD;
#include "poppack.h"
#endif /* __WINE_IMAGELIST_H */