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