ImageList: Write implemented
Dimitrie O. Paun
dimi at cs.toronto.edu
Sat Jan 26 16:03:14 CST 2002
[extracted from office[12].diff]
ChangeLog:
Charles Loep for CodeWeavers
ImageList Control: implement ImageList_Write
--
Dimi.
-------------- next part --------------
Index: dlls/comctl32/imagelist.c
===================================================================
RCS file: /var/cvs/wine/dlls/comctl32/imagelist.c,v
retrieving revision 1.47
diff -u -r1.47 imagelist.c
--- dlls/comctl32/imagelist.c 15 Jan 2002 20:28:05 -0000 1.47
+++ dlls/comctl32/imagelist.c 26 Jan 2002 20:50:31 -0000
@@ -4,11 +4,11 @@
* Copyright 1998 Eric Kohl
* 2000 Jason Mawdsley.
* 2001 Michael Stefaniuc
+ * 2001 Charles Loep for CodeWeavers
*
* TODO:
* - Fix ImageList_DrawIndirect (xBitmap, yBitmap, rgbFg, rgbBk, dwRop).
* - Fix ImageList_GetIcon.
- * - Fix ImageList_Write.
* - Fix ImageList_SetFilter (undocumented).
* BTW does anybody know anything about this function???
* - It removes 12 Bytes from the stack (3 Parameters).
@@ -2853,6 +2853,105 @@
}
+
+/* helper for ImageList_Write - write bitmap to pstm
+ * currently everything is written as 24 bit RGB, except masks
+ */
+static BOOL
+_write_bitmap(HBITMAP hBitmap, LPSTREAM pstm, int cx, int cy)
+{
+ LPBITMAPFILEHEADER bmfh;
+ LPBITMAPINFOHEADER bmih;
+ LPBYTE data, lpBits, lpBitsOrg;
+ BITMAP bm;
+ INT bitCount, sizeImage, offBits, totalSize;
+ INT nwidth, nheight, nsizeImage, icount;
+ HDC xdc;
+ BOOL result = FALSE;
+
+
+ xdc = GetDC(0);
+ GetObjectA(hBitmap, sizeof(BITMAP), (LPVOID)&bm);
+
+ /* XXX is this always correct? */
+ icount = bm.bmWidth / cx;
+ nwidth = cx << 2;
+ nheight = cy * ((icount+3)>>2);
+
+ bitCount = bm.bmBitsPixel == 1 ? 1 : 24;
+ sizeImage = ((((bm.bmWidth * bitCount)+31) & ~31) >> 3) * bm.bmHeight;
+ nsizeImage = ((((nwidth * bitCount)+31) & ~31) >> 3) * nheight;
+
+ totalSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
+ if(bitCount != 24)
+ totalSize += (1 << bitCount) * sizeof(RGBQUAD);
+ offBits = totalSize;
+ totalSize += nsizeImage;
+
+ data = (LPBYTE)LocalAlloc(LMEM_ZEROINIT, totalSize);
+ bmfh = (LPBITMAPFILEHEADER)data;
+ bmih = (LPBITMAPINFOHEADER)(data + sizeof(BITMAPFILEHEADER));
+ lpBits = data + offBits;
+
+ /* setup BITMAPFILEHEADER */
+ bmfh->bfType = (('M' << 8) | 'B');
+ bmfh->bfSize = 0;
+ bmfh->bfReserved1 = 0;
+ bmfh->bfReserved2 = 0;
+ bmfh->bfOffBits = offBits;
+
+ /* setup BITMAPINFOHEADER */
+ bmih->biSize = sizeof(BITMAPINFOHEADER);
+ bmih->biWidth = bm.bmWidth;
+ bmih->biHeight = bm.bmHeight;
+ bmih->biPlanes = 1;
+ bmih->biBitCount = bitCount;
+ bmih->biCompression = BI_RGB;
+ bmih->biSizeImage = nsizeImage;
+ bmih->biXPelsPerMeter = 0;
+ bmih->biYPelsPerMeter = 0;
+ bmih->biClrUsed = 0;
+ bmih->biClrImportant = 0;
+
+ lpBitsOrg = (LPBYTE)LocalAlloc(LMEM_ZEROINIT, nsizeImage);
+ if(!GetDIBits(xdc, hBitmap, 0, bm.bmHeight, lpBitsOrg,
+ (BITMAPINFO *)bmih, DIB_RGB_COLORS))
+ goto failed;
+ else {
+ int i;
+ int obpl = (((bm.bmWidth*bitCount+31) & ~31)>>3);
+ int nbpl = (((nwidth*bitCount+31) & ~31)>>3);
+
+ for(i = 0; i < nheight; i++) {
+ int ooff = ((nheight-1-i)%cy) * obpl + ((i/cy) * nbpl);
+ int noff = (nbpl * (nheight-1-i));
+ memcpy(lpBits + noff, lpBitsOrg + ooff, nbpl);
+ }
+ }
+
+ bmih->biWidth = nwidth;
+ bmih->biHeight = nheight;
+
+ if(bitCount == 1) {
+ //Hack.
+ LPBITMAPINFO inf = (LPBITMAPINFO)bmih;
+ inf->bmiColors[0].rgbRed = inf->bmiColors[0].rgbGreen = inf->bmiColors[0].rgbBlue = 0;
+ inf->bmiColors[1].rgbRed = inf->bmiColors[1].rgbGreen = inf->bmiColors[1].rgbBlue = 0xff;
+ }
+
+ if(!SUCCEEDED(IStream_Write(pstm, data, totalSize, NULL)))
+ goto failed;
+
+ result = TRUE;
+
+ failed:
+ ReleaseDC(0, xdc);
+ LocalFree((HLOCAL)lpBitsOrg);
+
+ return result;
+}
+
+
/*************************************************************************
* ImageList_Write [COMCTL32.83]
*
@@ -2866,22 +2965,45 @@
* Success: TRUE
* Failure: FALSE
*
- * NOTES
- * This function can not be implemented yet, because
- * IStream32::Write is not implemented.
- *
* BUGS
- * empty stub.
+ * probably.
*/
BOOL WINAPI
ImageList_Write (HIMAGELIST himl, LPSTREAM pstm)
{
+ ILHEAD ilHead;
+ int i;
+
if (!himl)
return FALSE;
- FIXME("empty stub!\n");
+ ilHead.usMagic = (('L' << 8) | 'I');
+ ilHead.usVersion = 0x101;
+ ilHead.cCurImage = himl->cCurImage;
+ ilHead.cMaxImage = himl->cMaxImage;
+ ilHead.cGrow = himl->cGrow;
+ ilHead.cx = himl->cx;
+ ilHead.cy = himl->cy;
+ ilHead.bkcolor = himl->clrBk;
+ ilHead.flags = himl->flags;
+ for(i = 0; i < 4; i++) {
+ ilHead.ovls[i] = himl->nOvlIdx[i];
+ }
+
+ if(!SUCCEEDED(IStream_Write(pstm, &ilHead, sizeof(ILHEAD), NULL)))
+ return FALSE;
+
+ /* write the bitmap */
+ if(!_write_bitmap(himl->hbmImage, pstm, himl->cx, himl->cy))
+ return FALSE;
+
+ /* write the mask if we have one */
+ if(himl->flags & ILC_MASK) {
+ if(!_write_bitmap(himl->hbmMask, pstm, himl->cx, himl->cy))
+ return FALSE;
+ }
- return FALSE;
+ return TRUE;
}
More information about the wine-patches
mailing list