Rearrange members of HIMAGELIST to match Windows.

Reuse image and mask DCs.
This commit is contained in:
Vitaliy Margolen 2003-05-13 03:36:27 +00:00 committed by Alexandre Julliard
parent ed3417e349
commit e43edbd557
2 changed files with 177 additions and 267 deletions

View File

@ -100,8 +100,8 @@ static inline BOOL is_valid(HIMAGELIST himl)
static void
IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl, INT nImageCount, INT cx, INT cy)
{
HDC hdcImageList, hdcBitmap;
HBITMAP hbmNewBitmap;
HDC hdcBitmap;
HBITMAP hbmNewBitmap, hbmNull;
INT nNewWidth, nNewCount;
if ((himl->cCurImage + nImageCount <= himl->cMaxImage)
@ -113,7 +113,6 @@ IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl, INT nImageCount, INT cx, INT c
nNewWidth = nNewCount * himl->cx;
TRACE("Create expanded bitmaps : himl=%p x=%d y=%d count=%d\n", himl, nNewWidth, cy, nNewCount);
hdcImageList = CreateCompatibleDC (0);
hdcBitmap = CreateCompatibleDC (0);
hbmNewBitmap =
@ -121,11 +120,12 @@ IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl, INT nImageCount, INT cx, INT c
if (hbmNewBitmap == 0)
ERR("creating new image bitmap (x=%d y=%d)!\n", nNewWidth, cy);
SelectObject (hdcImageList, himl->hbmImage);
SelectObject (hdcBitmap, hbmNewBitmap);
hbmNull = SelectObject (hdcBitmap, hbmNewBitmap);
BitBlt (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, cy,
hdcImageList, 0, 0, SRCCOPY);
himl->hdcImage, 0, 0, SRCCOPY);
SelectObject (hdcBitmap, hbmNull);
SelectObject (himl->hdcImage, hbmNewBitmap);
DeleteObject (himl->hbmImage);
himl->hbmImage = hbmNewBitmap;
@ -136,17 +136,17 @@ IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl, INT nImageCount, INT cx, INT c
if (hbmNewBitmap == 0)
ERR("creating new mask bitmap!\n");
SelectObject (hdcImageList, himl->hbmMask);
SelectObject (hdcBitmap, hbmNewBitmap);
BitBlt (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, cy,
hdcImageList, 0, 0, SRCCOPY);
himl->hdcMask, 0, 0, SRCCOPY);
SelectObject (hdcBitmap, hbmNull);
SelectObject (himl->hdcMask, hbmNewBitmap);
DeleteObject (himl->hbmMask);
himl->hbmMask = hbmNewBitmap;
}
himl->cMaxImage = nNewCount;
DeleteDC (hdcImageList);
DeleteDC (hdcBitmap);
}
@ -169,11 +169,11 @@ IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl, INT nImageCount, INT cx, INT c
INT WINAPI
ImageList_Add (HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask)
{
HDC hdcImage, hdcBitmap;
HDC hdcBitmap;
INT nFirstIndex, nImageCount;
INT nStartX;
BITMAP bmp;
HBITMAP hOldBitmapImage, hOldBitmap;
HBITMAP hOldBitmap;
TRACE("himl=%p hbmimage=%p hbmmask=%p\n", himl, hbmImage, hbmMask);
if (!is_valid(himl))
@ -186,28 +186,24 @@ ImageList_Add (HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask)
nStartX = himl->cCurImage * himl->cx;
hdcImage = CreateCompatibleDC(0);
hdcBitmap = CreateCompatibleDC(0);
hOldBitmapImage = SelectObject(hdcImage, himl->hbmImage);
hOldBitmap = SelectObject(hdcBitmap, hbmImage);
/* Copy result to the imagelist
*/
BitBlt (hdcImage, nStartX, 0, bmp.bmWidth, bmp.bmHeight,
BitBlt (himl->hdcImage, nStartX, 0, bmp.bmWidth, bmp.bmHeight,
hdcBitmap, 0, 0, SRCCOPY);
if(himl->hbmMask)
{
HDC hdcMask, hdcTemp;
HBITMAP hOldBitmapMask, hOldBitmapTemp;
HDC hdcTemp;
HBITMAP hOldBitmapTemp;
hdcMask = CreateCompatibleDC (0);
hdcTemp = CreateCompatibleDC(0);
hOldBitmapMask = SelectObject(hdcMask, himl->hbmMask);
hOldBitmapTemp = SelectObject(hdcTemp, hbmMask);
BitBlt (hdcMask,
BitBlt (himl->hdcMask,
nStartX, 0, bmp.bmWidth, bmp.bmHeight,
hdcTemp,
0, 0,
@ -218,19 +214,14 @@ ImageList_Add (HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask)
/* Remove the background from the image
*/
BitBlt (hdcImage,
BitBlt (himl->hdcImage,
nStartX, 0, bmp.bmWidth, bmp.bmHeight,
hdcMask,
himl->hdcMask,
nStartX, 0,
0x220326); /* NOTSRCAND */
SelectObject(hdcMask, hOldBitmapMask);
DeleteDC(hdcMask);
}
SelectObject(hdcImage, hOldBitmapImage);
SelectObject(hdcBitmap, hOldBitmap);
DeleteDC(hdcImage);
DeleteDC(hdcBitmap);
nFirstIndex = himl->cCurImage;
@ -279,10 +270,10 @@ INT WINAPI ImageList_AddIcon (HIMAGELIST himl, HICON hIcon)
INT WINAPI
ImageList_AddMasked (HIMAGELIST himl, HBITMAP hBitmap, COLORREF clrMask)
{
HDC hdcImage, hdcMask, hdcBitmap;
HDC hdcMask, hdcBitmap;
INT nIndex, nImageCount, nMaskXOffset=0;
BITMAP bmp;
HBITMAP hOldBitmap, hOldBitmapMask, hOldBitmapImage;
HBITMAP hOldBitmap;
HBITMAP hMaskBitmap=0;
COLORREF bkColor;
@ -300,16 +291,13 @@ ImageList_AddMasked (HIMAGELIST himl, HBITMAP hBitmap, COLORREF clrMask)
nIndex = himl->cCurImage;
himl->cCurImage += nImageCount;
hdcMask = CreateCompatibleDC (0);
hdcImage = CreateCompatibleDC(0);
hdcBitmap = CreateCompatibleDC(0);
hOldBitmapImage = SelectObject(hdcImage, himl->hbmImage);
hOldBitmap = SelectObject(hdcBitmap, hBitmap);
if(himl->hbmMask)
{
hOldBitmapMask = SelectObject(hdcMask, himl->hbmMask);
hdcMask = himl->hdcMask;
nMaskXOffset = nIndex * himl->cx;
}
else
@ -318,8 +306,9 @@ ImageList_AddMasked (HIMAGELIST himl, HBITMAP hBitmap, COLORREF clrMask)
Create a temp Mask so we can remove the background of
the Image (Windows does this even if there is no mask)
*/
hdcMask = CreateCompatibleDC(0);
hMaskBitmap = CreateBitmap(bmp.bmWidth, bmp.bmHeight, 1, 1, NULL);
hOldBitmapMask = SelectObject(hdcMask, hMaskBitmap);
SelectObject(hdcMask, hMaskBitmap);
nMaskXOffset = 0;
}
/* create monochrome image to the mask bitmap */
@ -350,22 +339,19 @@ ImageList_AddMasked (HIMAGELIST himl, HBITMAP hBitmap, COLORREF clrMask)
0x220326); /* NOTSRCAND */
/* Copy result to the imagelist
*/
BitBlt (hdcImage,
BitBlt (himl->hdcImage,
nIndex * himl->cx, 0, bmp.bmWidth, bmp.bmHeight,
hdcBitmap,
0, 0,
SRCCOPY);
/* Clean up
*/
SelectObject(hdcMask,hOldBitmapMask);
SelectObject(hdcImage, hOldBitmapImage);
SelectObject(hdcBitmap, hOldBitmap);
DeleteDC(hdcMask);
DeleteDC(hdcImage);
DeleteDC(hdcBitmap);
if(!himl->hbmMask)
{
DeleteObject(hMaskBitmap);
DeleteDC(hdcMask);
}
return nIndex;
@ -393,7 +379,6 @@ BOOL WINAPI
ImageList_BeginDrag (HIMAGELIST himlTrack, INT iTrack,
INT dxHotspot, INT dyHotspot)
{
HDC hdcSrc, hdcDst;
INT cx, cy;
TRACE("(himlTrack=%p iTrack=%d dx=%d dy=%d)\n", himlTrack, iTrack,
@ -417,21 +402,11 @@ ImageList_BeginDrag (HIMAGELIST himlTrack, INT iTrack,
InternalDrag.dxHotspot = dxHotspot;
InternalDrag.dyHotspot = dyHotspot;
hdcSrc = CreateCompatibleDC (0);
hdcDst = CreateCompatibleDC (0);
/* copy image */
SelectObject (hdcSrc, himlTrack->hbmImage);
SelectObject (hdcDst, InternalDrag.himl->hbmImage);
BitBlt (hdcDst, 0, 0, cx, cy, hdcSrc, iTrack * cx, 0, SRCCOPY);
BitBlt (InternalDrag.himl->hdcImage, 0, 0, cx, cy, himlTrack->hdcImage, iTrack * cx, 0, SRCCOPY);
/* copy mask */
SelectObject (hdcSrc, himlTrack->hbmMask);
SelectObject (hdcDst, InternalDrag.himl->hbmMask);
BitBlt (hdcDst, 0, 0, cx, cy, hdcSrc, iTrack * cx, 0, SRCCOPY);
DeleteDC (hdcSrc);
DeleteDC (hdcDst);
BitBlt (InternalDrag.himl->hdcMask, 0, 0, cx, cy, himlTrack->hdcMask, iTrack * cx, 0, SRCCOPY);
InternalDrag.himl->cCurImage = 1;
InternalDrag.bHSPending = TRUE;
@ -467,8 +442,6 @@ BOOL WINAPI
ImageList_Copy (HIMAGELIST himlDst, INT iDst, HIMAGELIST himlSrc,
INT iSrc, INT uFlags)
{
HDC hdcSrc, hdcDst;
TRACE("iDst=%d iSrc=%d\n", iDst, iSrc);
if (!is_valid(himlSrc) || !is_valid(himlDst))
@ -478,16 +451,13 @@ ImageList_Copy (HIMAGELIST himlDst, INT iDst, HIMAGELIST himlSrc,
if ((iSrc < 0) || (iSrc >= himlSrc->cCurImage))
return FALSE;
hdcSrc = CreateCompatibleDC (0);
if (himlDst == himlSrc)
hdcDst = hdcSrc;
else
hdcDst = CreateCompatibleDC (0);
if (uFlags & ILCF_SWAP) {
/* swap */
HDC hdcBmp;
HBITMAP hbmTempImage, hbmTempMask;
hdcBmp = CreateCompatibleDC (0);
/* create temporary bitmaps */
hbmTempImage = CreateBitmap (himlSrc->cx, himlSrc->cy, 1,
himlSrc->uBitsPixel, NULL);
@ -496,74 +466,51 @@ ImageList_Copy (HIMAGELIST himlDst, INT iDst, HIMAGELIST himlSrc,
/* copy (and stretch) destination to temporary bitmaps.(save) */
/* image */
SelectObject (hdcSrc, himlDst->hbmImage);
SelectObject (hdcDst, hbmTempImage);
StretchBlt (hdcDst, 0, 0, himlSrc->cx, himlSrc->cy,
hdcSrc, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
SelectObject (hdcBmp, hbmTempImage);
StretchBlt (hdcBmp, 0, 0, himlSrc->cx, himlSrc->cy,
himlDst->hdcImage, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
SRCCOPY);
/* mask */
SelectObject (hdcSrc, himlDst->hbmMask);
SelectObject (hdcDst, hbmTempMask);
StretchBlt (hdcDst, 0, 0, himlSrc->cx, himlSrc->cy,
hdcSrc, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
SelectObject (hdcBmp, hbmTempMask);
StretchBlt (hdcBmp, 0, 0, himlSrc->cx, himlSrc->cy,
himlDst->hdcMask, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
SRCCOPY);
/* copy (and stretch) source to destination */
/* image */
SelectObject (hdcSrc, himlSrc->hbmImage);
SelectObject (hdcDst, himlDst->hbmImage);
StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
StretchBlt (himlDst->hdcImage, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
himlSrc->hdcImage, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
SRCCOPY);
/* mask */
SelectObject (hdcSrc, himlSrc->hbmMask);
SelectObject (hdcDst, himlDst->hbmMask);
StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
StretchBlt (himlDst->hdcMask, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
himlSrc->hdcMask, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
SRCCOPY);
/* copy (without stretching) temporary bitmaps to source (restore) */
/* image */
SelectObject (hdcSrc, hbmTempImage);
SelectObject (hdcDst, himlSrc->hbmImage);
BitBlt (hdcDst, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
hdcSrc, 0, 0, SRCCOPY);
/* mask */
SelectObject (hdcSrc, hbmTempMask);
SelectObject (hdcDst, himlSrc->hbmMask);
BitBlt (hdcDst, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
hdcSrc, 0, 0, SRCCOPY);
BitBlt (himlSrc->hdcMask, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
hdcBmp, 0, 0, SRCCOPY);
/* image */
BitBlt (himlSrc->hdcImage, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
hdcBmp, 0, 0, SRCCOPY);
/* delete temporary bitmaps */
DeleteObject (hbmTempMask);
DeleteObject (hbmTempImage);
DeleteDC(hdcBmp);
}
else {
/* copy image */
SelectObject (hdcSrc, himlSrc->hbmImage);
if (himlSrc == himlDst)
hdcDst = hdcSrc;
else
SelectObject (hdcDst, himlDst->hbmImage);
StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
StretchBlt (himlDst->hdcImage, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
himlSrc->hdcImage, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
SRCCOPY);
/* copy mask */
SelectObject (hdcSrc, himlSrc->hbmMask);
if (himlSrc == himlDst)
hdcDst = hdcSrc;
else
SelectObject (hdcDst, himlDst->hbmMask);
StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
StretchBlt (himlDst->hdcMask, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
himlSrc->hdcMask, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
SRCCOPY);
}
DeleteDC (hdcSrc);
if (himlSrc != himlDst)
DeleteDC (hdcDst);
return TRUE;
}
@ -588,7 +535,6 @@ ImageList_Create (INT cx, INT cy, UINT flags,
INT cInitial, INT cGrow)
{
HIMAGELIST himl;
HDC hdc;
INT nCount;
HBITMAP hbmTemp;
static WORD aBitBlend25[] =
@ -603,6 +549,8 @@ ImageList_Create (INT cx, INT cy, UINT flags,
if (!himl)
return NULL;
cGrow = (cGrow < 4) ? 4 : (cGrow + 3) & ~3;
himl->magic = IMAGELIST_MAGIC;
himl->cx = cx;
himl->cy = cy;
@ -610,21 +558,24 @@ ImageList_Create (INT cx, INT cy, UINT flags,
himl->cMaxImage = cInitial + cGrow;
himl->cInitial = cInitial;
himl->cGrow = cGrow;
himl->cCurImage = 0;
himl->clrFg = CLR_DEFAULT;
himl->clrBk = CLR_NONE;
himl->hbmImage = 0;
himl->hbmMask = 0;
himl->hbrBlend25 = 0;
himl->hbrBlend50 = 0;
/* initialize overlay mask indices */
for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
himl->nOvlIdx[nCount] = -1;
hdc = CreateCompatibleDC (0);
himl->uBitsPixel = (UINT)GetDeviceCaps (hdc, BITSPIXEL);
DeleteDC (hdc);
/* Create Image & Mask DCs */
himl->hdcImage = CreateCompatibleDC (0);
if (!himl->hdcImage)
goto cleanup;
if (himl->flags & ILC_MASK){
himl->hdcMask = CreateCompatibleDC(0);
if (!himl->hdcMask)
goto cleanup;
}
himl->uBitsPixel = (UINT)GetDeviceCaps (himl->hdcImage, BITSPIXEL);
TRACE("Image: %d Bits per Pixel\n", himl->uBitsPixel);
@ -634,28 +585,21 @@ ImageList_Create (INT cx, INT cy, UINT flags,
1, himl->uBitsPixel, NULL);
if (himl->hbmImage == 0) {
ERR("Error creating image bitmap!\n");
ImageList_Destroy(himl);
return NULL;
goto cleanup;
}
SelectObject(himl->hdcImage, himl->hbmImage);
}
else
himl->hbmImage = 0;
if ( (himl->flags & ILC_MASK)) {
int images = himl->cMaxImage;
if (images <= 0)
images = 1;
himl->hbmMask = CreateBitmap (himl->cx * images, himl->cy,
1, 1, NULL);
if (himl->flags & ILC_MASK) {
himl->hbmMask =
CreateBitmap (himl->cx * himl->cMaxImage, himl->cy,
1, 1, NULL);
if (himl->hbmMask == 0) {
ERR("Error creating mask bitmap!\n");
ImageList_Destroy(himl);
return NULL;
goto cleanup;
}
SelectObject(himl->hdcMask, himl->hbmMask);
}
else
himl->hbmMask = 0;
/* create blending brushes */
hbmTemp = CreateBitmap (8, 8, 1, 1, &aBitBlend25);
@ -668,6 +612,10 @@ ImageList_Create (INT cx, INT cy, UINT flags,
TRACE("created imagelist %p\n", himl);
return himl;
cleanup:
if (himl) ImageList_Destroy(himl);
return NULL;
}
@ -696,6 +644,12 @@ ImageList_Destroy (HIMAGELIST himl)
if (himl->hbmMask)
DeleteObject (himl->hbmMask);
/* delete image & mask DCs */
if (himl->hdcImage)
DeleteDC(himl->hdcImage);
if (himl->hdcMask)
DeleteDC(himl->hdcMask);
/* delete blending brushes */
if (himl->hbrBlend25)
DeleteObject (himl->hbrBlend25);
@ -1090,7 +1044,7 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
UINT fStyle;
COLORREF clrBk, oldImageBk, oldImageFg;
HDC hImageDC, hImageListDC, hMaskListDC;
HBITMAP hImageBmp, hOldImageBmp, hOldImageListBmp, hOldMaskListBmp, hBlendMaskBmp;
HBITMAP hImageBmp, hOldImageBmp, hBlendMaskBmp;
BOOL bIsTransparent, bBlend, bResult = FALSE;
HIMAGELIST himl;
@ -1113,8 +1067,8 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
himl->hbmMask, pimldp->i, pimldp->x, pimldp->y, cx, cy);
/* we will use these DCs to access the images and masks in the ImageList */
hImageListDC = CreateCompatibleDC(0);
hMaskListDC = himl->hbmMask ? CreateCompatibleDC(0) : 0;
hImageListDC = himl->hdcImage;
hMaskListDC = himl->hdcMask;
/* these will accumulate the image and mask for the image we're drawing */
hImageDC = CreateCompatibleDC( pimldp->hdcDst );
@ -1126,9 +1080,7 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
(bBlend && !hBlendMaskBmp) || (himl->hbmMask && !hMaskListDC))
goto cleanup;
hOldImageListBmp = SelectObject(hImageListDC, himl->hbmImage);
hOldImageBmp = SelectObject(hImageDC, hImageBmp);
hOldMaskListBmp = hMaskListDC ? SelectObject(hMaskListDC, himl->hbmMask) : 0;
/*
* To obtain a transparent look, background color should be set
@ -1230,14 +1182,10 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
SetBkColor(hImageDC, oldImageBk);
SetTextColor(hImageDC, oldImageFg);
SelectObject(hImageDC, hOldImageBmp);
SelectObject(hImageListDC, hOldImageListBmp);
if (hMaskListDC) SelectObject(hMaskListDC, hOldMaskListBmp);
cleanup:
DeleteObject(hBlendMaskBmp);
DeleteObject(hImageBmp);
DeleteDC(hImageDC);
DeleteDC(hImageListDC);
DeleteDC(hMaskListDC);
return bResult;
}
@ -1258,7 +1206,6 @@ HIMAGELIST WINAPI
ImageList_Duplicate (HIMAGELIST himlSrc)
{
HIMAGELIST himlDst;
HDC hdcSrc, hdcDst;
if (!is_valid(himlSrc)) {
ERR("Invalid image list handle!\n");
@ -1270,23 +1217,12 @@ ImageList_Duplicate (HIMAGELIST himlSrc)
if (himlDst)
{
hdcSrc = CreateCompatibleDC (0);
hdcDst = CreateCompatibleDC (0);
SelectObject (hdcSrc, himlSrc->hbmImage);
SelectObject (hdcDst, himlDst->hbmImage);
BitBlt (hdcDst, 0, 0, himlSrc->cCurImage * himlSrc->cx, himlSrc->cy,
hdcSrc, 0, 0, SRCCOPY);
BitBlt (himlDst->hdcImage, 0, 0, himlSrc->cCurImage * himlSrc->cx, himlSrc->cy,
himlSrc->hdcImage, 0, 0, SRCCOPY);
if (himlDst->hbmMask)
{
SelectObject (hdcSrc, himlSrc->hbmMask);
SelectObject (hdcDst, himlDst->hbmMask);
BitBlt (hdcDst, 0, 0, himlSrc->cCurImage * himlSrc->cx,
himlSrc->cy, hdcSrc, 0, 0, SRCCOPY);
}
DeleteDC (hdcDst);
DeleteDC (hdcSrc);
BitBlt (himlDst->hdcMask, 0, 0, himlSrc->cCurImage * himlSrc->cx, himlSrc->cy,
himlSrc->hdcMask, 0, 0, SRCCOPY);
himlDst->cCurImage = himlSrc->cCurImage;
himlDst->cMaxImage = himlSrc->cMaxImage;
@ -1419,22 +1355,26 @@ ImageList_GetIcon (HIMAGELIST himl, INT i, UINT fStyle)
HBITMAP hOldDstBitmap;
HDC hdcDst;
TRACE("%p %d %d\n", himl, i, fStyle);
if (!is_valid(himl) || (i < 0) || (i >= himl->cCurImage)) return NULL;
hdcDst = CreateCompatibleDC(0);
ii.fIcon = TRUE;
ii.xHotspot = 0;
ii.yHotspot = 0;
/* draw mask*/
ii.hbmMask = CreateCompatibleBitmap (hdcDst, himl->cx, himl->cy);
hOldDstBitmap = (HBITMAP)SelectObject (hdcDst, ii.hbmMask);
ImageList_Draw(himl, i, hdcDst, 0, 0, ILD_MASK);
hOldDstBitmap = SelectObject (hdcDst, ii.hbmMask);
PatBlt (hdcDst, 0, 0, himl->cx, himl->cy, WHITENESS);
ImageList_Draw(himl, i, hdcDst, 0, 0, fStyle | ILD_MASK);
/* draw image*/
SelectObject (hdcDst, himl->hbmImage);
ii.hbmColor = CreateCompatibleBitmap (hdcDst, himl->cx, himl->cy);
ii.hbmColor = CreateCompatibleBitmap (himl->hdcImage, himl->cx, himl->cy);
SelectObject (hdcDst, ii.hbmColor);
ImageList_Draw(himl, i, hdcDst, 0, 0, fStyle);
PatBlt (hdcDst, 0, 0, himl->cx, himl->cy, BLACKNESS);
ImageList_Draw(himl, i, hdcDst, 0, 0, fStyle | ILD_TRANSPARENT);
/*
* CreateIconIndirect requires us to deselect the bitmaps from
@ -1779,7 +1719,6 @@ ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2,
INT dx, INT dy)
{
HIMAGELIST himlDst = NULL;
HDC hdcSrcImage, hdcDstImage;
INT cxDst, cyDst;
INT xOff1, yOff1, xOff2, yOff2;
INT nX1, nX2;
@ -1838,41 +1777,20 @@ ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2,
return NULL;
if (himlDst) {
hdcSrcImage = CreateCompatibleDC (0);
hdcDstImage = CreateCompatibleDC (0);
nX1 = i1 * himl1->cx;
nX2 = i2 * himl2->cx;
/* copy image */
SelectObject (hdcSrcImage, himl1->hbmImage);
SelectObject (hdcDstImage, himlDst->hbmImage);
BitBlt (hdcDstImage, 0, 0, cxDst, cyDst,
hdcSrcImage, 0, 0, BLACKNESS);
BitBlt (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy,
hdcSrcImage, nX1, 0, SRCCOPY);
SelectObject (hdcSrcImage, himl2->hbmMask);
BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
hdcSrcImage, nX2, 0, SRCAND);
SelectObject (hdcSrcImage, himl2->hbmImage);
BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
hdcSrcImage, nX2, 0, SRCPAINT);
BitBlt (himlDst->hdcImage, 0, 0, cxDst, cyDst, himl1->hdcImage, 0, 0, BLACKNESS);
BitBlt (himlDst->hdcImage, xOff1, yOff1, himl1->cx, himl1->cy, himl1->hdcImage, nX1, 0, SRCCOPY);
BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcMask , nX2, 0, SRCAND);
BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcImage, nX2, 0, SRCPAINT);
/* copy mask */
SelectObject (hdcSrcImage, himl1->hbmMask);
SelectObject (hdcDstImage, himlDst->hbmMask);
BitBlt (hdcDstImage, 0, 0, cxDst, cyDst,
hdcSrcImage, 0, 0, WHITENESS);
BitBlt (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy,
hdcSrcImage, nX1, 0, SRCCOPY);
BitBlt (himlDst->hdcMask, 0, 0, cxDst, cyDst, himl1->hdcMask, 0, 0, WHITENESS);
BitBlt (himlDst->hdcMask, xOff1, yOff1, himl1->cx, himl1->cy, himl1->hdcMask, nX1, 0, SRCCOPY);
BitBlt (himlDst->hdcMask, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcMask, nX2, 0, SRCAND);
SelectObject (hdcSrcImage, himl2->hbmMask);
BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
hdcSrcImage, nX2, 0, SRCAND);
DeleteDC (hdcSrcImage);
DeleteDC (hdcDstImage);
himlDst->cCurImage = 1;
}
@ -2069,8 +1987,14 @@ HIMAGELIST WINAPI ImageList_Read (LPSTREAM pstm)
DeleteObject(hbmMask);
return NULL;
}
SelectObject(himl->hdcImage, hbmColor);
DeleteObject(himl->hbmImage);
himl->hbmImage = hbmColor;
himl->hbmMask = hbmMask;
if (hbmMask){
SelectObject(himl->hdcMask, hbmMask);
DeleteObject(himl->hbmMask);
himl->hbmMask = hbmMask;
}
himl->cCurImage = ilHead.cCurImage;
himl->cMaxImage = ilHead.cMaxImage;
@ -2097,7 +2021,7 @@ BOOL WINAPI
ImageList_Remove (HIMAGELIST himl, INT i)
{
HBITMAP hbmNewImage, hbmNewMask;
HDC hdcSrc, hdcDst;
HDC hdcBmp;
INT cxNew, nCount;
TRACE("(himl=%p i=%d)\n", himl, i);
@ -2125,16 +2049,18 @@ ImageList_Remove (HIMAGELIST himl, INT i)
for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
himl->nOvlIdx[nCount] = -1;
DeleteObject (himl->hbmImage);
himl->hbmImage =
CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
hbmNewImage = CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
1, himl->uBitsPixel, NULL);
SelectObject (himl->hdcImage, hbmNewImage);
DeleteObject (himl->hbmImage);
himl->hbmImage = hbmNewImage;
if (himl->hbmMask) {
DeleteObject (himl->hbmMask);
himl->hbmMask =
CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
hbmNewMask = CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
1, 1, NULL);
SelectObject (himl->hdcMask, hbmNewMask);
DeleteObject (himl->hbmMask);
himl->hbmMask = hbmNewMask;
}
}
else {
@ -2157,50 +2083,46 @@ ImageList_Remove (HIMAGELIST himl, INT i)
else
hbmNewMask = 0; /* Just to keep compiler happy! */
hdcSrc = CreateCompatibleDC (0);
hdcDst = CreateCompatibleDC (0);
hdcBmp = CreateCompatibleDC (0);
/* copy all images and masks prior to the "removed" image */
if (i > 0) {
TRACE("Pre image copy: Copy %d images\n", i);
SelectObject (hdcSrc, himl->hbmImage);
SelectObject (hdcDst, hbmNewImage);
BitBlt (hdcDst, 0, 0, i * himl->cx, himl->cy,
hdcSrc, 0, 0, SRCCOPY);
SelectObject (hdcBmp, hbmNewImage);
BitBlt (hdcBmp, 0, 0, i * himl->cx, himl->cy,
himl->hdcImage, 0, 0, SRCCOPY);
if (himl->hbmMask) {
SelectObject (hdcSrc, himl->hbmMask);
SelectObject (hdcDst, hbmNewMask);
BitBlt (hdcDst, 0, 0, i * himl->cx, himl->cy,
hdcSrc, 0, 0, SRCCOPY);
SelectObject (hdcBmp, hbmNewMask);
BitBlt (hdcBmp, 0, 0, i * himl->cx, himl->cy,
himl->hdcMask, 0, 0, SRCCOPY);
}
}
/* copy all images and masks behind the removed image */
if (i < himl->cCurImage - 1) {
TRACE("Post image copy!\n");
SelectObject (hdcSrc, himl->hbmImage);
SelectObject (hdcDst, hbmNewImage);
BitBlt (hdcDst, i * himl->cx, 0, (himl->cCurImage - i - 1) * himl->cx,
himl->cy, hdcSrc, (i + 1) * himl->cx, 0, SRCCOPY);
SelectObject (hdcBmp, hbmNewImage);
BitBlt (hdcBmp, i * himl->cx, 0, (himl->cCurImage - i - 1) * himl->cx,
himl->cy, himl->hdcImage, (i + 1) * himl->cx, 0, SRCCOPY);
if (himl->hbmMask) {
SelectObject (hdcSrc, himl->hbmMask);
SelectObject (hdcDst, hbmNewMask);
BitBlt (hdcDst, i * himl->cx, 0,
SelectObject (hdcBmp, hbmNewMask);
BitBlt (hdcBmp, i * himl->cx, 0,
(himl->cCurImage - i - 1) * himl->cx,
himl->cy, hdcSrc, (i + 1) * himl->cx, 0, SRCCOPY);
himl->cy, himl->hdcMask, (i + 1) * himl->cx, 0, SRCCOPY);
}
}
DeleteDC (hdcSrc);
DeleteDC (hdcDst);
DeleteDC (hdcBmp);
/* delete old images and insert new ones */
SelectObject (himl->hdcImage, hbmNewImage);
DeleteObject (himl->hbmImage);
himl->hbmImage = hbmNewImage;
if (himl->hbmMask) {
SelectObject (himl->hdcMask, hbmNewMask);
DeleteObject (himl->hbmMask);
himl->hbmMask = hbmNewMask;
}
@ -2233,7 +2155,7 @@ BOOL WINAPI
ImageList_Replace (HIMAGELIST himl, INT i, HBITMAP hbmImage,
HBITMAP hbmMask)
{
HDC hdcImageList, hdcImage;
HDC hdcImage;
BITMAP bmp;
TRACE("%p %d %p %p\n", himl, i, hbmImage, hbmMask);
@ -2248,31 +2170,27 @@ ImageList_Replace (HIMAGELIST himl, INT i, HBITMAP hbmImage,
return FALSE;
}
hdcImageList = CreateCompatibleDC (0);
hdcImage = CreateCompatibleDC (0);
GetObjectA (hbmImage, sizeof(BITMAP), (LPVOID)&bmp);
/* Replace Image */
SelectObject (hdcImageList, himl->hbmImage);
SelectObject (hdcImage, hbmImage);
StretchBlt (hdcImageList, i * himl->cx, 0, himl->cx, himl->cy,
StretchBlt (himl->hdcImage, i * himl->cx, 0, himl->cx, himl->cy,
hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
if (himl->hbmMask)
{
/* Replace Mask */
SelectObject (hdcImageList, himl->hbmMask);
SelectObject (hdcImage, hbmMask);
StretchBlt (hdcImageList, i * himl->cx, 0, himl->cx, himl->cy,
StretchBlt (himl->hdcMask, i * himl->cx, 0, himl->cx, himl->cy,
hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
/* Remove the background from the image
*/
SelectObject (hdcImageList, himl->hbmImage);
StretchBlt (hdcImageList,
StretchBlt (himl->hdcImage,
i*himl->cx, 0, himl->cx, himl->cy,
hdcImage,
0, 0, bmp.bmWidth, bmp.bmHeight,
@ -2280,7 +2198,6 @@ ImageList_Replace (HIMAGELIST himl, INT i, HBITMAP hbmImage,
}
DeleteDC (hdcImage);
DeleteDC (hdcImageList);
return TRUE;
}
@ -2304,10 +2221,10 @@ ImageList_Replace (HIMAGELIST himl, INT i, HBITMAP hbmImage,
INT WINAPI
ImageList_ReplaceIcon (HIMAGELIST himl, INT i, HICON hIcon)
{
HDC hdcImageList, hdcImage;
HDC hdcImage;
INT nIndex;
HICON hBestFitIcon;
HBITMAP hbmOldSrc, hbmOldDst;
HBITMAP hbmOldSrc;
ICONINFO ii;
BITMAP bmp;
@ -2340,37 +2257,28 @@ ImageList_ReplaceIcon (HIMAGELIST himl, INT i, HICON hIcon)
else
nIndex = i;
hdcImageList = CreateCompatibleDC (0);
TRACE("hdcImageList=%p!\n", hdcImageList);
if (hdcImageList == 0)
ERR("invalid hdcImageList!\n");
hdcImage = CreateCompatibleDC (0);
TRACE("hdcImage=%p!\n", hdcImage);
TRACE("hdcImage=%p\n", hdcImage);
if (hdcImage == 0)
ERR("invalid hdcImage!\n");
hbmOldDst = SelectObject (hdcImageList, himl->hbmImage);
SetTextColor( hdcImageList, RGB(0,0,0));
SetBkColor( hdcImageList, RGB(255,255,255));
SetTextColor(himl->hdcImage, RGB(0,0,0));
SetBkColor (himl->hdcImage, RGB(255,255,255));
hbmOldSrc = SelectObject (hdcImage, ii.hbmColor);
StretchBlt (hdcImageList, nIndex * himl->cx, 0, himl->cx, himl->cy,
StretchBlt (himl->hdcImage, nIndex * himl->cx, 0, himl->cx, himl->cy,
hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
if (himl->hbmMask) {
SelectObject (hdcImageList, himl->hbmMask);
SelectObject (hdcImage, ii.hbmMask);
StretchBlt (hdcImageList, nIndex * himl->cx, 0, himl->cx, himl->cy,
StretchBlt (himl->hdcMask, nIndex * himl->cx, 0, himl->cx, himl->cy,
hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
}
SelectObject (hdcImage, hbmOldSrc);
SelectObject (hdcImageList, hbmOldDst);
if(hBestFitIcon)
DestroyIcon(hBestFitIcon);
if (hdcImageList)
DeleteDC (hdcImageList);
if (hdcImage)
DeleteDC (hdcImage);
if (ii.hbmColor)
@ -2555,6 +2463,7 @@ BOOL WINAPI
ImageList_SetIconSize (HIMAGELIST himl, INT cx, INT cy)
{
INT nCount;
HBITMAP hbmNew;
if (!is_valid(himl))
return FALSE;
@ -2569,16 +2478,18 @@ ImageList_SetIconSize (HIMAGELIST himl, INT cx, INT cy)
for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
himl->nOvlIdx[nCount] = -1;
DeleteObject (himl->hbmImage);
himl->hbmImage =
CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
hbmNew = CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
1, himl->uBitsPixel, NULL);
SelectObject (himl->hdcImage, hbmNew);
DeleteObject (himl->hbmImage);
himl->hbmImage = hbmNew;
if (himl->hbmMask) {
DeleteObject (himl->hbmMask);
himl->hbmMask =
CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
hbmNew = CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
1, 1, NULL);
SelectObject (himl->hdcMask, hbmNew);
DeleteObject (himl->hbmMask);
himl->hbmMask = hbmNew;
}
return TRUE;
@ -2602,7 +2513,7 @@ ImageList_SetIconSize (HIMAGELIST himl, INT cx, INT cy)
BOOL WINAPI
ImageList_SetImageCount (HIMAGELIST himl, INT iImageCount)
{
HDC hdcImageList, hdcBitmap;
HDC hdcBitmap;
HBITMAP hbmNewBitmap;
INT nNewCount, nCopyCount;
@ -2621,19 +2532,17 @@ ImageList_SetImageCount (HIMAGELIST himl, INT iImageCount)
nNewCount = iImageCount + himl->cGrow;
nCopyCount = min(himl->cCurImage, iImageCount);
hdcImageList = CreateCompatibleDC (0);
hdcBitmap = CreateCompatibleDC (0);
hbmNewBitmap = CreateBitmap (nNewCount * himl->cx, himl->cy,
1, himl->uBitsPixel, NULL);
if (hbmNewBitmap != 0)
{
SelectObject (hdcImageList, himl->hbmImage);
SelectObject (hdcBitmap, hbmNewBitmap);
/* copy images */
BitBlt (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
hdcImageList, 0, 0, SRCCOPY);
himl->hdcImage, 0, 0, SRCCOPY);
#if 0
/* delete 'empty' image space */
SetBkColor (hdcBitmap, RGB(255, 255, 255));
@ -2641,6 +2550,7 @@ ImageList_SetImageCount (HIMAGELIST himl, INT iImageCount)
PatBlt (hdcBitmap, nCopyCount * himl->cx, 0,
(nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS);
#endif
SelectObject (himl->hdcImage, hbmNewBitmap);
DeleteObject (himl->hbmImage);
himl->hbmImage = hbmNewBitmap;
}
@ -2653,12 +2563,11 @@ ImageList_SetImageCount (HIMAGELIST himl, INT iImageCount)
1, 1, NULL);
if (hbmNewBitmap != 0)
{
SelectObject (hdcImageList, himl->hbmMask);
SelectObject (hdcBitmap, hbmNewBitmap);
/* copy images */
BitBlt (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
hdcImageList, 0, 0, SRCCOPY);
himl->hdcMask, 0, 0, SRCCOPY);
#if 0
/* delete 'empty' image space */
SetBkColor (hdcBitmap, RGB(255, 255, 255));
@ -2666,6 +2575,7 @@ ImageList_SetImageCount (HIMAGELIST himl, INT iImageCount)
PatBlt (hdcBitmap, nCopyCount * himl->cx, 0,
(nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS);
#endif
SelectObject (himl->hdcMask, hbmNewBitmap);
DeleteObject (himl->hbmMask);
himl->hbmMask = hbmNewBitmap;
}
@ -2673,7 +2583,6 @@ ImageList_SetImageCount (HIMAGELIST himl, INT iImageCount)
ERR("Could not create new mask bitmap!\n");
}
DeleteDC (hdcImageList);
DeleteDC (hdcBitmap);
/* Update max image count and current image count */

View File

@ -29,28 +29,29 @@
/* the ones with offsets at the end are the same as in Windows */
struct _IMAGELIST
{
DWORD magic; /* 00: 'SAMX' */
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 */
DWORD magic; /* 00: 'SAMX' */
INT cCurImage; /* 04: ImageCount */
INT cMaxImage; /* 08: maximages */
INT cGrow; /* 0c: cGrow */
INT cx; /* 10: cx */
INT cy; /* 14: cy */
DWORD x4;
UINT flags; /* 1c: flags */
COLORREF clrFg; /* 20: foreground color */
COLORREF clrBk; /* 24: backgournd color */
HBITMAP hbmImage; /* 30: images Bitmap */
HBITMAP hbmMask; /* 34: masks Bitmap */
HDC hdcImage; /* 38: images MemDC */
HDC hdcMask; /* 3C: masks MemDC */
INT nOvlIdx[15]; /* 40: overlay images index */
/* not yet found out */
HBITMAP hbmImage;
HBITMAP hbmMask;
HBRUSH hbrBlend25;
HBRUSH hbrBlend50;
COLORREF clrFg;
INT cInitial;
INT cGrow;
UINT uBitsPixel;
INT nOvlIdx[15];
};
#define IMAGELIST_MAGIC 0x53414D58