2 * ImageList implementation
4 * Copyright 1998 Eric Kohl
7 * - Fix ImageList_DrawIndirect (xBitmap, yBitmap, rgbFg, rgbBk, dwRop).
8 * - Fix ImageList_GetIcon.
9 * - Fix drag functions.
10 * - Fix ImageList_Read and ImageList_Write.
11 * - Fix ImageList_SetFilter (undocumented).
12 * BTW does anybody know anything about this function???
13 * - It removes 12 Bytes from the stack (3 Parameters).
14 * - First parameter SHOULD be a HIMAGELIST.
15 * - Second parameter COULD be an index?????
16 * - Third parameter.... ?????????????????????
19 * - ImageList_Draw, ImageList_DrawEx and ImageList_GetIcon use
20 * ImageList_DrawIndirect. Since ImageList_DrawIndirect is still
21 * partially imlemented, the functions mentioned above will be
22 * limited in functionality too.
25 /* This must be defined because the HIMAGELIST type is just a pointer
26 * to the _IMAGELIST data structure. But M$ does not want us to know
27 * anything about its contents. Applications just see a pointer to
28 * an empty structure. It's just to keep compatibility.
30 #define __WINE_IMAGELIST_C
36 #include "imagelist.h"
41 #define _MAX(a,b) (((a)>(b))?(a):(b))
42 #define _MIN(a,b) (((a)>(b))?(b):(a))
44 #define MAX_OVERLAYIMAGE 15
47 /* internal image list data used for Drag & Drop operations */
49 static HIMAGELIST himlInternalDrag = NULL;
50 static INT32 nInternalDragHotspotX = 0;
51 static INT32 nInternalDragHotspotY = 0;
53 static HWND32 hwndInternalDrag = 0;
54 static INT32 xInternalPos = 0;
55 static INT32 yInternalPos = 0;
57 static HDC32 hdcBackBuffer = 0;
58 static HBITMAP32 hbmBackBuffer = 0;
61 /*************************************************************************
62 * IMAGELIST_InternalExpandBitmaps [Internal]
64 * Expands the bitmaps of an image list by the given number of images.
67 * himl [I] image list handle
68 * nImageCount [I] Number of images to add.
74 * This function can NOT be used to reduce the number of images.
78 IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl, INT32 nImageCount)
80 HDC32 hdcImageList, hdcBitmap;
81 HBITMAP32 hbmNewBitmap;
82 INT32 nNewWidth, nNewCount;
84 TRACE(imagelist, "Create expanded bitmaps!\n");
86 nNewCount = himl->cCurImage + nImageCount + himl->cGrow;
87 nNewWidth = nNewCount * himl->cx;
89 hdcImageList = CreateCompatibleDC32 (0);
90 hdcBitmap = CreateCompatibleDC32 (0);
93 CreateBitmap32 (nNewWidth, himl->cy, 1, himl->uBitsPixel, NULL);
94 if (hbmNewBitmap == 0)
95 ERR (imagelist, "creating new image bitmap!\n");
97 SelectObject32 (hdcImageList, himl->hbmImage);
98 SelectObject32 (hdcBitmap, hbmNewBitmap);
99 BitBlt32 (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, himl->cy,
100 hdcImageList, 0, 0, SRCCOPY);
102 DeleteObject32 (himl->hbmImage);
103 himl->hbmImage = hbmNewBitmap;
107 CreateBitmap32 (nNewWidth, himl->cy, 1, 1, NULL);
109 if (hbmNewBitmap == 0)
110 ERR (imagelist, "creating new mask bitmap!");
112 SelectObject32 (hdcImageList, himl->hbmMask);
113 SelectObject32 (hdcBitmap, hbmNewBitmap);
114 BitBlt32 (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, himl->cy,
115 hdcImageList, 0, 0, SRCCOPY);
116 DeleteObject32 (himl->hbmMask);
117 himl->hbmMask = hbmNewBitmap;
120 himl->cMaxImage = nNewCount;
122 DeleteDC32 (hdcImageList);
123 DeleteDC32 (hdcBitmap);
127 /*************************************************************************
128 * ImageList_Add [COMCTL32.39]
130 * Add an image or images to an image list.
133 * himl [I] image list handle
134 * hbmImage [I] image bitmap handle
135 * hbmMask [I] mask bitmap handle
138 * Success: Index of the first new image.
143 ImageList_Add (HIMAGELIST himl, HBITMAP32 hbmImage, HBITMAP32 hbmMask)
145 HDC32 hdcSrc, hdcDst;
146 INT32 nFirstIndex, nImageCount;
150 if (!himl || !hbmImage)
153 GetObject32A (hbmImage, sizeof(BITMAP32), (LPVOID)&bmp);
154 nImageCount = bmp.bmWidth / himl->cx;
156 if (himl->cCurImage + nImageCount >= himl->cMaxImage)
157 IMAGELIST_InternalExpandBitmaps (himl, nImageCount);
159 nStartX = himl->cCurImage * himl->cx;
161 hdcSrc = CreateCompatibleDC32 (0);
162 hdcDst = CreateCompatibleDC32 (0);
164 /* copy image bitmap */
165 SelectObject32 (hdcDst, himl->hbmImage);
166 SelectObject32 (hdcSrc, hbmImage);
167 BitBlt32 (hdcDst, himl->cCurImage * himl->cx, 0,
168 bmp.bmWidth, himl->cy, hdcSrc, 0, 0, SRCCOPY);
172 /* copy mask bitmap */
173 SelectObject32 (hdcDst, himl->hbmMask);
174 SelectObject32 (hdcSrc, hbmMask);
175 BitBlt32 (hdcDst, nStartX, 0, bmp.bmWidth, himl->cy,
176 hdcSrc, 0, 0, SRCCOPY);
179 /* copy monochrome image to the mask bitmap */
180 SelectObject32 (hdcDst, himl->hbmMask);
181 SelectObject32 (hdcSrc, hbmImage);
182 SetBkColor32 (hdcSrc, GetNearestColor32 (hdcSrc,
183 GetPixel32 (hdcSrc, 0, 0)));
184 BitBlt32 (hdcDst, nStartX, 0, bmp.bmWidth, himl->cy,
185 hdcSrc, nStartX, 0, SRCCOPY);
192 nFirstIndex = himl->cCurImage;
193 himl->cCurImage += nImageCount;
199 /*************************************************************************
200 * ImageList_AddIcon [COMCTL32.40]
202 * Adds an icon to an image list.
205 * himl [I] image list handle
206 * hIcon [I] icon handle
209 * Success: index of the new image
214 ImageList_AddIcon (HIMAGELIST himl, HICON32 hIcon)
216 return (ImageList_ReplaceIcon (himl, -1, hIcon));
220 /*************************************************************************
221 * ImageList_AddMasked [COMCTL32.41]
223 * Adds an image or images to an image list and creates a mask from the
224 * specified bitmap using the mask color.
227 * himl [I] handle to image list.
228 * hBitmap [I] handle to bitmap
229 * clrMask [I] mask color.
232 * Success: Index of the first new image.
237 ImageList_AddMasked (HIMAGELIST himl, HBITMAP32 hBitmap, COLORREF clrMask)
239 HDC32 hdcImage, hdcMask, hdcBitmap;
240 INT32 nIndex, nImageCount;
246 if (!GetObject32A (hBitmap, sizeof(BITMAP32), &bmp))
249 nImageCount = bmp.bmWidth / himl->cx;
251 if (himl->cCurImage + nImageCount >= himl->cMaxImage)
252 IMAGELIST_InternalExpandBitmaps (himl, nImageCount);
254 nIndex = himl->cCurImage;
255 himl->cCurImage += nImageCount;
257 hdcImage = CreateCompatibleDC32 (0);
258 hdcBitmap = CreateCompatibleDC32 (0);
260 SelectObject32 (hdcBitmap, hBitmap);
261 SelectObject32 (hdcImage, himl->hbmImage);
262 BitBlt32 (hdcImage, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy,
263 hdcBitmap, 0, 0, SRCCOPY);
266 COLORREF bkColor = (clrMask != CLR_DEFAULT) ? clrMask :
267 GetNearestColor32 (hdcBitmap, GetPixel32 (hdcBitmap, 0, 0));
269 /* create mask from image */
270 hdcMask = CreateCompatibleDC32 (0);
271 SelectObject32 (hdcMask, himl->hbmMask);
273 /* create monochrome image to the mask bitmap */
274 SetBkColor32 (hdcBitmap, bkColor);
275 BitBlt32 (hdcMask, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy,
276 hdcBitmap, 0, 0, SRCCOPY);
278 DeleteDC32 (hdcMask);
281 DeleteDC32 (hdcImage);
282 DeleteDC32 (hdcBitmap);
288 /*************************************************************************
289 * ImageList_BeginDrag [COMCTL32.42]
291 * Creates a temporary image list that contains one image. It will be used
295 * himlTrack [I] Handle of the source image list
296 * iTrack [I] Index of the drag image in the source image list
297 * dxHotspot [I] X position of the hot spot of the drag image
298 * dyHotspot [I] Y position of the hot spot of the drag image
306 ImageList_BeginDrag (HIMAGELIST himlTrack, INT32 iTrack,
307 INT32 dxHotspot, INT32 dyHotspot)
309 HDC32 hdcSrc, hdcDst;
311 FIXME(imagelist, "partially implemented!\n");
313 if (himlTrack == NULL)
316 if (himlInternalDrag)
317 ImageList_EndDrag ();
320 ImageList_Create (himlTrack->cx, himlTrack->cy,
321 himlTrack->flags, 1, 1);
322 if (himlInternalDrag == NULL) {
323 ERR(imagelist, "Error creating drag image list!\n");
327 nInternalDragHotspotX = dxHotspot;
328 nInternalDragHotspotY = dyHotspot;
330 hdcSrc = CreateCompatibleDC32 (0);
331 hdcDst = CreateCompatibleDC32 (0);
334 SelectObject32 (hdcSrc, himlTrack->hbmImage);
335 SelectObject32 (hdcDst, himlInternalDrag->hbmImage);
336 StretchBlt32 (hdcDst, 0, 0, himlInternalDrag->cx, himlInternalDrag->cy, hdcSrc,
337 iTrack * himlTrack->cx, 0, himlTrack->cx, himlTrack->cy, SRCCOPY);
340 SelectObject32 (hdcSrc, himlTrack->hbmMask);
341 SelectObject32 (hdcDst, himlInternalDrag->hbmMask);
342 StretchBlt32 (hdcDst, 0, 0, himlInternalDrag->cx, himlInternalDrag->cy, hdcSrc,
343 iTrack * himlTrack->cx, 0, himlTrack->cx, himlTrack->cy, SRCCOPY);
348 himlInternalDrag->cCurImage = 1;
354 /*************************************************************************
355 * ImageList_Copy [COMCTL32.43]
357 * Copies an image of the source image list to an image of the
358 * destination image list. Images can be copied or swapped.
361 * himlDst [I] destination image list handle.
362 * iDst [I] destination image index.
363 * himlSrc [I] source image list handle
364 * iSrc [I] source image index
365 * uFlags [I] flags for the copy operation
372 * Copying from one image list to another is possible. The original
373 * implementation just copies or swapps within one image list.
374 * Could this feature become a bug??? ;-)
378 ImageList_Copy (HIMAGELIST himlDst, INT32 iDst, HIMAGELIST himlSrc,
379 INT32 iSrc, INT32 uFlags)
381 HDC32 hdcSrc, hdcDst;
383 TRACE(imagelist, "iDst=%d iSrc=%d\n", iDst, iSrc);
385 if ((himlSrc == NULL) || (himlDst == NULL))
387 if ((iDst < 0) || (iDst >= himlDst->cCurImage))
389 if ((iSrc < 0) || (iSrc >= himlSrc->cCurImage))
392 hdcSrc = CreateCompatibleDC32 (0);
393 if (himlDst == himlSrc)
396 hdcDst = CreateCompatibleDC32 (0);
398 if (uFlags & ILCF_SWAP) {
400 HBITMAP32 hbmTempImage, hbmTempMask;
402 /* create temporary bitmaps */
403 hbmTempImage = CreateBitmap32 (himlSrc->cx, himlSrc->cy, 1,
404 himlSrc->uBitsPixel, NULL);
405 hbmTempMask = CreateBitmap32 (himlSrc->cx, himlSrc->cy, 1,
408 /* copy (and stretch) destination to temporary bitmaps.(save) */
410 SelectObject32 (hdcSrc, himlDst->hbmImage);
411 SelectObject32 (hdcDst, hbmTempImage);
412 StretchBlt32 (hdcDst, 0, 0, himlSrc->cx, himlSrc->cy,
413 hdcSrc, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
416 SelectObject32 (hdcSrc, himlDst->hbmMask);
417 SelectObject32 (hdcDst, hbmTempMask);
418 StretchBlt32 (hdcDst, 0, 0, himlSrc->cx, himlSrc->cy,
419 hdcSrc, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
422 /* copy (and stretch) source to destination */
424 SelectObject32 (hdcSrc, himlSrc->hbmImage);
425 SelectObject32 (hdcDst, himlDst->hbmImage);
426 StretchBlt32 (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
427 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
430 SelectObject32 (hdcSrc, himlSrc->hbmMask);
431 SelectObject32 (hdcDst, himlDst->hbmMask);
432 StretchBlt32 (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
433 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
436 /* copy (without stretching) temporary bitmaps to source (restore) */
438 SelectObject32 (hdcSrc, hbmTempImage);
439 SelectObject32 (hdcDst, himlSrc->hbmImage);
440 BitBlt32 (hdcDst, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
441 hdcSrc, 0, 0, SRCCOPY);
443 SelectObject32 (hdcSrc, hbmTempMask);
444 SelectObject32 (hdcDst, himlSrc->hbmMask);
445 BitBlt32 (hdcDst, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
446 hdcSrc, 0, 0, SRCCOPY);
448 /* delete temporary bitmaps */
449 DeleteObject32 (hbmTempMask);
450 DeleteObject32 (hbmTempImage);
454 SelectObject32 (hdcSrc, himlSrc->hbmImage);
455 if (himlSrc == himlDst)
458 SelectObject32 (hdcDst, himlDst->hbmImage);
459 StretchBlt32 (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
460 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
464 SelectObject32 (hdcSrc, himlSrc->hbmMask);
465 if (himlSrc == himlDst)
468 SelectObject32 (hdcDst, himlDst->hbmMask);
469 StretchBlt32 (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
470 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
475 if (himlSrc != himlDst)
482 /*************************************************************************
483 * ImageList_Create [COMCTL32.44] Creates a new image list.
486 * cx [I] image height
488 * flags [I] creation flags
489 * cInitial [I] initial number of images in the image list
490 * cGrow [I] number of images by which image list grows
493 * Success: Handle to the created image list
498 ImageList_Create (INT32 cx, INT32 cy, UINT32 flags,
499 INT32 cInitial, INT32 cGrow)
505 static WORD aBitBlend25[] =
506 {0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00};
508 static WORD aBitBlend50[] =
509 {0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA};
511 TRACE (imagelist, "(%d %d 0x%x %d %d)\n", cx, cy, flags, cInitial, cGrow);
513 himl = (HIMAGELIST)COMCTL32_Alloc (sizeof(struct _IMAGELIST));
520 himl->cMaxImage = cInitial + cGrow;
521 himl->cInitial = cInitial;
524 himl->clrFg = CLR_DEFAULT;
525 himl->clrBk = CLR_NONE;
527 /* initialize overlay mask indices */
528 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
529 himl->nOvlIdx[nCount] = -1;
531 hdc = CreateCompatibleDC32 (0);
532 himl->uBitsPixel = (UINT32)GetDeviceCaps32 (hdc, BITSPIXEL);
535 TRACE(imagelist, "Image: %d Bits per Pixel\n", himl->uBitsPixel);
538 CreateBitmap32 (himl->cx * himl->cMaxImage, himl->cy,
539 1, himl->uBitsPixel, NULL);
540 if (himl->hbmImage == 0) {
541 ERR(imagelist, "Error creating image bitmap!\n");
545 if (himl->flags & ILC_MASK) {
546 himl->hbmMask = CreateBitmap32 (himl->cx * himl->cMaxImage, himl->cy,
548 if (himl->hbmMask == 0) {
549 ERR(imagelist, "Error creating mask bitmap!\n");
551 DeleteObject32 (himl->hbmImage);
558 /* create blending brushes */
559 hbmTemp = CreateBitmap32 (8, 8, 1, 1, &aBitBlend25);
560 himl->hbrBlend25 = CreatePatternBrush32 (hbmTemp);
561 DeleteObject32 (hbmTemp);
563 hbmTemp = CreateBitmap32 (8, 8, 1, 1, &aBitBlend50);
564 himl->hbrBlend50 = CreatePatternBrush32 (hbmTemp);
565 DeleteObject32 (hbmTemp);
571 /*************************************************************************
572 * ImageList_Destroy [COMCTL32.45]
574 * Destroys an image list.
577 * himl [I] image list handle
585 ImageList_Destroy (HIMAGELIST himl)
590 /* delete image bitmaps */
592 DeleteObject32 (himl->hbmImage);
594 DeleteObject32 (himl->hbmMask);
596 /* delete blending brushes */
597 if (himl->hbrBlend25)
598 DeleteObject32 (himl->hbrBlend25);
599 if (himl->hbrBlend50)
600 DeleteObject32 (himl->hbrBlend50);
602 COMCTL32_Free (himl);
608 /*************************************************************************
609 * ImageList_DragEnter [COMCTL32.46]
611 * Locks window update and displays the drag image at the given position.
614 * hwndLock [I] handle of the window that owns the drag image.
615 * x [I] X position of the drag image.
616 * y [I] Y position of the drag image.
623 * The position of the drag image is relative to the window, not
628 ImageList_DragEnter (HWND32 hwndLock, INT32 x, INT32 y)
630 if (himlInternalDrag == NULL) return (FALSE);
633 hwndInternalDrag = hwndLock;
635 hwndInternalDrag = GetDesktopWindow32 ();
640 hdcBackBuffer = CreateCompatibleDC32 (0);
641 hbmBackBuffer = CreateCompatibleBitmap32 (hdcBackBuffer,
642 himlInternalDrag->cx, himlInternalDrag->cy);
644 ImageList_DragShowNolock (TRUE);
650 /*************************************************************************
651 * ImageList_DragLeave [COMCTL32.47]
653 * Unlocks window update and hides the drag image.
656 * hwndLock [I] handle of the window that owns the drag image.
664 ImageList_DragLeave (HWND32 hwndLock)
667 hwndInternalDrag = hwndLock;
669 hwndInternalDrag = GetDesktopWindow32 ();
671 ImageList_DragShowNolock (FALSE);
673 DeleteDC32 (hdcBackBuffer);
674 DeleteObject32 (hbmBackBuffer);
680 /*************************************************************************
681 * ImageList_DragMove [COMCTL32.48]
683 * Moves the drag image.
686 * x [I] X position of the drag image.
687 * y [I] Y position of the drag image.
694 * The position of the drag image is relative to the window, not
699 ImageList_DragMove (INT32 x, INT32 y)
701 ImageList_DragShowNolock (FALSE);
706 ImageList_DragShowNolock (TRUE);
712 /*************************************************************************
713 * ImageList_DragShowNolock [COMCTL32.49]
715 * Shows or hides the drag image.
718 * bShow [I] TRUE shows the drag image, FALSE hides it.
729 ImageList_DragShowNolock (BOOL32 bShow)
733 FIXME (imagelist, "semi-stub!\n");
734 TRACE (imagelist, "bShow=0x%X!\n", bShow);
736 hdcDrag = GetDCEx32 (hwndInternalDrag, 0,
737 DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
740 /* show drag image */
742 /* save background */
744 /* draw drag image */
748 /* hide drag image */
750 /* restore background */
754 ReleaseDC32 (hwndInternalDrag, hdcDrag);
760 /*************************************************************************
761 * ImageList_Draw [COMCTL32.50] Draws an image.
764 * himl [I] image list handle
766 * hdc [I] display context handle
769 * fStyle [I] drawing flags
776 * Calls ImageList_DrawIndirect.
779 * ImageList_DrawIndirect.
783 ImageList_Draw (HIMAGELIST himl, INT32 i, HDC32 hdc,
784 INT32 x, INT32 y, UINT32 fStyle)
786 IMAGELISTDRAWPARAMS imldp;
788 imldp.cbSize = sizeof(IMAGELISTDRAWPARAMS);
798 imldp.rgbBk = CLR_DEFAULT;
799 imldp.rgbFg = CLR_DEFAULT;
800 imldp.fStyle = fStyle;
803 return (ImageList_DrawIndirect (&imldp));
807 /*************************************************************************
808 * ImageList_DrawEx [COMCTL32.51]
810 * Draws an image and allows to use extended drawing features.
813 * himl [I] image list handle
815 * hdc [I] device context handle
820 * rgbBk [I] background color
821 * rgbFg [I] foreground color
822 * fStyle [I] drawing flags
829 * Calls ImageList_DrawIndirect.
832 * ImageList_DrawIndirect.
836 ImageList_DrawEx (HIMAGELIST himl, INT32 i, HDC32 hdc, INT32 x, INT32 y,
837 INT32 dx, INT32 dy, COLORREF rgbBk, COLORREF rgbFg,
840 IMAGELISTDRAWPARAMS imldp;
842 imldp.cbSize = sizeof(IMAGELISTDRAWPARAMS);
854 imldp.fStyle = fStyle;
857 return (ImageList_DrawIndirect (&imldp));
861 /*************************************************************************
862 * ImageList_DrawIndirect [COMCTL32.52]
864 * Draws an image using ...
867 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
875 ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
877 HIMAGELIST himlLocal;
878 HDC32 hdcImageList, hdcTempImage;
879 HBITMAP32 hbmTempImage;
880 HBRUSH32 hBrush, hOldBrush;
884 BOOL32 bImage; /* draw image ? */
885 BOOL32 bImageTrans; /* draw image transparent ? */
886 BOOL32 bMask; /* draw mask ? */
887 BOOL32 bMaskTrans; /* draw mask transparent ? */
893 if (pimldp->cbSize < sizeof(IMAGELISTDRAWPARAMS))
895 if (pimldp->himl == NULL)
897 if ((pimldp->i < 0) || (pimldp->i >= pimldp->himl->cCurImage))
900 himlLocal = pimldp->himl;
902 cx = (pimldp->cx == 0) ? himlLocal->cx : pimldp->cx;
903 cy = (pimldp->cy == 0) ? himlLocal->cy : pimldp->cy;
905 /* ILD_NORMAL state */
912 if ((himlLocal->clrBk == CLR_NONE) && (himlLocal->hbmMask))
919 /* ILD_IMAGE state (changes) */
920 if (pimldp->fStyle & ILD_IMAGE)
927 /* ILD_MASK state (changes) */
928 if ((pimldp->fStyle & ILD_MASK) && (himlLocal->hbmMask))
934 if ((pimldp->fStyle & ILD_TRANSPARENT) && (himlLocal->hbmMask))
939 if ((himlLocal->clrBk == CLR_NONE) && (himlLocal->hbmMask))
942 if (pimldp->fStyle & ILD_BLEND50)
944 else if (pimldp->fStyle & ILD_BLEND25)
947 hdcImageList = CreateCompatibleDC32 (0);
952 SelectObject32 (hdcImageList, himlLocal->hbmMask);
953 SetBkColor32 (hdcImageList, RGB(255, 255, 255));
954 SetTextColor32 (hdcImageList, RGB(0, 0, 0));
955 BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
956 hdcImageList, himlLocal->cx * pimldp->i, 0,
957 bMaskTrans ? SRCAND : SRCCOPY);
963 SelectObject32 (hdcImageList, himlLocal->hbmImage);
967 hBrush = CreateSolidBrush32 (himlLocal->clrBk);
968 hOldBrush = SelectObject32 (pimldp->hdcDst, hBrush);
969 PatBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y,
971 DeleteObject32 (SelectObject32 (pimldp->hdcDst, hOldBrush));
974 BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
975 hdcImageList, himlLocal->cx * pimldp->i, 0, SRCPAINT);
977 if (bBlend25 || bBlend50)
979 if (pimldp->rgbFg == CLR_DEFAULT)
980 clrBlend = GetSysColor32 (COLOR_HIGHLIGHT);
982 clrBlend = pimldp->rgbFg;
984 hdcTempImage = CreateCompatibleDC32 (0);
985 hbmTempImage = CreateBitmap32 (himlLocal->cx, himlLocal->cy,
986 1, himlLocal->uBitsPixel, NULL);
987 SelectObject32 (hdcTempImage, hbmTempImage);
991 SelectObject32 (hdcTempImage,
992 bBlend50 ? himlLocal->hbrBlend50 : himlLocal->hbrBlend25);
993 PatBlt32 (hdcTempImage, 0, 0, himlLocal->cx, himlLocal->cy, PATCOPY);
995 SelectObject32 (hdcImageList, himlLocal->hbmMask);
996 BitBlt32 (hdcTempImage, 0, 0, himlLocal->cx,
997 himlLocal->cy, hdcImageList,
998 pimldp->i * himlLocal->cx, 0, SRCPAINT);
1000 BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
1001 hdcTempImage, 0, 0, SRCAND);
1004 hBrush = CreateSolidBrush32 (clrBlend);
1005 SelectObject32 (hdcTempImage, hBrush);
1006 PatBlt32 (hdcTempImage, 0, 0, himlLocal->cx, himlLocal->cy, PATCOPY);
1007 DeleteObject32 (hBrush);
1009 SelectObject32 (hdcTempImage,
1010 bBlend50 ? himlLocal->hbrBlend50 : himlLocal->hbrBlend25);
1011 PatBlt32 (hdcTempImage, 0, 0, himlLocal->cx, himlLocal->cy, 0x0A0329);
1013 SelectObject32 (hdcImageList, himlLocal->hbmMask);
1014 BitBlt32 (hdcTempImage, 0, 0, himlLocal->cx,
1015 himlLocal->cy, hdcImageList,
1016 pimldp->i * himlLocal->cx, 0, SRCPAINT);
1018 BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
1019 hdcTempImage, 0, 0, SRCPAINT);
1021 DeleteObject32 (hbmTempImage);
1022 DeleteDC32 (hdcTempImage);
1026 /* Draw overlay image */
1027 if (pimldp->fStyle & 0x0700) {
1028 nOvlIdx = (pimldp->fStyle & 0x0700) >> 8;
1029 if ((nOvlIdx >= 1) && (nOvlIdx <= MAX_OVERLAYIMAGE)) {
1030 nOvlIdx = pimldp->himl->nOvlIdx[nOvlIdx - 1];
1031 if ((nOvlIdx >= 0) && (nOvlIdx <= pimldp->himl->cCurImage)) {
1032 if (pimldp->himl->hbmMask) {
1033 SelectObject32 (hdcImageList, pimldp->himl->hbmMask);
1034 BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
1035 hdcImageList, pimldp->himl->cx * nOvlIdx, 0,
1038 SelectObject32 (hdcImageList, pimldp->himl->hbmImage);
1039 BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y,
1040 cx, cy, hdcImageList,
1041 pimldp->himl->cx * nOvlIdx, 0, SRCPAINT);
1046 DeleteDC32 (hdcImageList);
1052 /*************************************************************************
1053 * ImageList_Duplicate [COMCTL32.53] Duplicates an image list.
1056 * himlSrc [I] source image list handle
1059 * Success: Handle of duplicated image list.
1064 ImageList_Duplicate (HIMAGELIST himlSrc)
1067 HDC32 hdcSrc, hdcDst;
1069 if (himlSrc == NULL) {
1070 ERR (imagelist, "Invalid image list handle!\n");
1074 himlDst = ImageList_Create (himlSrc->cx, himlSrc->cy, himlSrc->flags,
1075 himlSrc->cInitial, himlSrc->cGrow);
1079 hdcSrc = CreateCompatibleDC32 (0);
1080 hdcDst = CreateCompatibleDC32 (0);
1081 SelectObject32 (hdcSrc, himlSrc->hbmImage);
1082 SelectObject32 (hdcDst, himlDst->hbmImage);
1083 BitBlt32 (hdcDst, 0, 0, himlSrc->cCurImage * himlSrc->cx, himlSrc->cy,
1084 hdcSrc, 0, 0, SRCCOPY);
1086 if (himlDst->hbmMask)
1088 SelectObject32 (hdcSrc, himlSrc->hbmMask);
1089 SelectObject32 (hdcDst, himlDst->hbmMask);
1090 BitBlt32 (hdcDst, 0, 0, himlSrc->cCurImage * himlSrc->cx,
1091 himlSrc->cy, hdcSrc, 0, 0, SRCCOPY);
1094 DeleteDC32 (hdcDst);
1095 DeleteDC32 (hdcSrc);
1102 /*************************************************************************
1103 * ImageList_EndDrag [COMCTL32.54] Finishes a drag operation.
1105 * Finishes a drag operation.
1119 ImageList_EndDrag (VOID)
1121 FIXME (imagelist, "semi-stub!\n");
1123 if (himlInternalDrag)
1126 ImageList_Destroy (himlInternalDrag);
1127 himlInternalDrag = NULL;
1129 nInternalDragHotspotX = 0;
1130 nInternalDragHotspotY = 0;
1138 /*************************************************************************
1139 * ImageList_GetBkColor [COMCTL32.55]
1141 * Returns the background color of an image list.
1144 * himl [I] Image list handle.
1147 * Success: background color
1152 ImageList_GetBkColor (HIMAGELIST himl)
1157 return (himl->clrBk);
1161 /*************************************************************************
1162 * ImageList_GetDragImage [COMCTL32.56]
1164 * Returns the handle to the internal drag image list.
1167 * ppt [O] Pointer to the drag position. Can be NULL.
1168 * pptHotspot [O] Pointer to the position of the hot spot. Can be NULL.
1171 * Success: Handle of the drag image list.
1179 ImageList_GetDragImage (POINT32 *ppt, POINT32 *pptHotspot)
1181 FIXME (imagelist, "semi-stub!\n");
1183 if (himlInternalDrag)
1184 return (himlInternalDrag);
1190 /*************************************************************************
1191 * ImageList_GetIcon [COMCTL32.57]
1193 * Creates an icon from a masked image of an image list.
1196 * himl [I] image list handle
1198 * flags [I] drawing style flags
1201 * Success: icon handle
1206 ImageList_GetIcon (HIMAGELIST himl, INT32 i, UINT32 fStyle)
1210 HDC32 hdcSrc, hdcDst;
1211 INT32 nWidth, nHeight;
1213 if ((himl == NULL) ||(i < 0) || (i >= himl->cCurImage))
1216 nWidth = GetSystemMetrics32 (SM_CXICON);
1217 nHeight = GetSystemMetrics32 (SM_CYICON);
1219 hdcSrc = CreateCompatibleDC32(0);
1220 hdcDst = CreateCompatibleDC32(0);
1223 ii.xHotspot = nWidth / 2;
1224 ii.yHotspot = nHeight / 2;
1225 ii.hbmMask = CreateCompatibleBitmap32 (hdcDst, nWidth, nHeight);
1226 ii.hbmColor = CreateCompatibleBitmap32 (hdcDst, nWidth, nHeight);
1230 SelectObject32 (hdcDst, ii.hbmMask);
1231 if (himl->hbmMask) {
1232 SelectObject32 (hdcSrc, himl->hbmMask);
1233 BitBlt32 (hdcDst, 0, 0, nWidth, nHeight,
1234 hdcSrc, i * himl->cx, 0, SRCCOPY);
1237 PatBlt32 (hdcDst, 0, 0, nWidth, nHeight, BLACKNESS);
1240 SelectObject32 (hdcDst, ii.hbmColor);
1241 SelectObject32 (hdcSrc, himl->hbmImage);
1242 BitBlt32 (hdcDst, 0, 0, nWidth, nHeight,
1243 hdcSrc, i * himl->cx, 0, SRCCOPY);
1245 hIcon = CreateIconIndirect (&ii);
1247 DeleteDC32 (hdcSrc);
1248 DeleteDC32 (hdcDst);
1249 DeleteObject32 (ii.hbmMask);
1250 DeleteObject32 (ii.hbmColor);
1256 /*************************************************************************
1257 * ImageList_GetIconSize [COMCTL32.58]
1259 * Retrieves the size of an image in an image list.
1262 * himl [I] image list handle
1263 * cx [O] pointer to the image width.
1264 * cy [O] pointer to the image height.
1271 * All images in an image list have the same size.
1275 ImageList_GetIconSize (HIMAGELIST himl, INT32 *cx, INT32 *cy)
1279 if ((himl->cx <= 0) || (himl->cy <= 0))
1291 /*************************************************************************
1292 * ImageList_GetImageCount [COMCTL32.59]
1294 * Returns the number of images in an image list.
1297 * himl [I] image list handle.
1300 * Success: Number of images.
1305 ImageList_GetImageCount (HIMAGELIST himl)
1310 return himl->cCurImage;
1314 /*************************************************************************
1315 * ImageList_GetImageInfo [COMCTL32.60]
1317 * Returns information about an image in an image list.
1320 * himl [I] image list handle.
1322 * pImageInfo [O] pointer to the image information.
1330 ImageList_GetImageInfo (HIMAGELIST himl, INT32 i, IMAGEINFO *pImageInfo)
1332 if ((himl == NULL) || (pImageInfo == NULL))
1334 if ((i < 0) || (i >= himl->cCurImage))
1337 pImageInfo->hbmImage = himl->hbmImage;
1338 pImageInfo->hbmMask = himl->hbmMask;
1340 pImageInfo->rcImage.top = 0;
1341 pImageInfo->rcImage.bottom = himl->cy;
1342 pImageInfo->rcImage.left = i * himl->cx;
1343 pImageInfo->rcImage.right = (i+1) * himl->cx;
1349 /*************************************************************************
1350 * ImageList_GetImageRect [COMCTL32.61]
1352 * Retrieves the rectangle of the specified image in an image list.
1355 * himl [I] handle to the image list
1357 * lpRect [O] pointer to the image rectangle
1364 * This is an UNDOCUMENTED function!!!
1368 ImageList_GetImageRect (HIMAGELIST himl, INT32 i, LPRECT32 lpRect)
1370 if ((himl == NULL) || (lpRect == NULL))
1372 if ((i < 0) || (i >= himl->cCurImage))
1375 lpRect->left = i * himl->cx;
1377 lpRect->right = lpRect->left + himl->cx;
1378 lpRect->bottom = himl->cy;
1384 /*************************************************************************
1385 * ImageList_LoadImage32A [COMCTL32.62][COMCTL32.63]
1387 * Creates an image list from a bitmap, icon or cursor.
1390 * hi [I] instance handle
1391 * lpbmp [I] name or id of the image
1392 * cx [I] width of each image
1393 * cGrow [I] number of images to expand
1394 * clrMask [I] mask color
1395 * uType [I] type of image to load
1396 * uFlags [I] loading flags
1399 * Success: handle of the loaded image
1407 ImageList_LoadImage32A (HINSTANCE32 hi, LPCSTR lpbmp, INT32 cx, INT32 cGrow,
1408 COLORREF clrMask, UINT32 uType, UINT32 uFlags)
1410 HIMAGELIST himl = NULL;
1414 handle = LoadImage32A (hi, lpbmp, uType, 0, 0, uFlags);
1415 if (!handle) return (NULL);
1417 if (uType == IMAGE_BITMAP) {
1419 GetObject32A (handle, sizeof(BITMAP32), &bmp);
1420 nImageCount = bmp.bmWidth / cx;
1422 himl = ImageList_Create (cx, bmp.bmHeight, ILC_MASK | ILC_COLOR,
1423 nImageCount, cGrow);
1424 ImageList_AddMasked (himl, (HBITMAP32)handle, clrMask);
1426 else if ((uType == IMAGE_ICON) || (uType == IMAGE_CURSOR)) {
1430 GetIconInfo (handle, &ii);
1431 GetObject32A (ii.hbmColor, sizeof(BITMAP32), (LPVOID)&bmp);
1432 himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight,
1433 ILC_MASK | ILC_COLOR, 1, cGrow);
1434 ImageList_Add (himl, ii.hbmColor, ii.hbmMask);
1435 DeleteObject32 (ii.hbmColor);
1436 DeleteObject32 (ii.hbmMask);
1439 DeleteObject32 (handle);
1445 /*************************************************************************
1446 * ImageList_LoadImage32W [COMCTL32.64]
1448 * Creates an image list from a bitmap, icon or cursor.
1451 * hi [I] instance handle
1452 * lpbmp [I] name or id of the image
1453 * cx [I] width of each image
1454 * cGrow [I] number of images to expand
1455 * clrMask [I] mask color
1456 * uType [I] type of image to load
1457 * uFlags [I] loading flags
1460 * Success: handle of the loaded image
1468 ImageList_LoadImage32W (HINSTANCE32 hi, LPCWSTR lpbmp, INT32 cx, INT32 cGrow,
1469 COLORREF clrMask, UINT32 uType, UINT32 uFlags)
1471 HIMAGELIST himl = NULL;
1475 handle = LoadImage32W (hi, lpbmp, uType, 0, 0, uFlags);
1477 ERR (imagelist, "Error loading image!\n");
1481 if (uType == IMAGE_BITMAP) {
1483 GetObject32A (handle, sizeof(BITMAP32), &bmp);
1484 nImageCount = bmp.bmWidth / cx;
1486 himl = ImageList_Create (cx, bmp.bmHeight, ILC_MASK | ILC_COLOR,
1487 nImageCount, cGrow);
1488 ImageList_AddMasked (himl, (HBITMAP32)handle, clrMask);
1490 else if ((uType == IMAGE_ICON) || (uType == IMAGE_CURSOR)) {
1494 GetIconInfo (handle, &ii);
1495 GetObject32A (ii.hbmMask, sizeof(BITMAP32), (LPVOID)&bmp);
1496 himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight,
1497 ILC_MASK | ILC_COLOR, 1, cGrow);
1498 ImageList_Add (himl, ii.hbmColor, ii.hbmMask);
1499 DeleteObject32 (ii.hbmColor);
1500 DeleteObject32 (ii.hbmMask);
1503 DeleteObject32 (handle);
1509 /*************************************************************************
1510 * ImageList_Merge [COMCTL32.65]
1512 * Creates a new image list that contains a merged image from the specified
1513 * images of both source image lists.
1516 * himl1 [I] first image list handle
1517 * i1 [I] first image index
1518 * himl2 [I] second image list handle
1519 * i2 [I] second image index
1520 * dx [I] X offset of the second image relative to the first.
1521 * dy [I] Y offset of the second image relative to the first.
1524 * Success: handle of the merged image list.
1529 ImageList_Merge (HIMAGELIST himl1, INT32 i1, HIMAGELIST himl2, INT32 i2,
1532 HIMAGELIST himlDst = NULL;
1533 HDC32 hdcSrcImage, hdcDstImage;
1535 INT32 xOff1, yOff1, xOff2, yOff2;
1538 if ((himl1 == NULL) || (himl2 == NULL))
1542 if ((i1 < 0) || (i1 >= himl1->cCurImage)) {
1543 ERR (imagelist, "Index 1 out of range! %d\n", i1);
1547 if ((i2 < 0) || (i2 >= himl2->cCurImage)) {
1548 ERR (imagelist, "Index 2 out of range! %d\n", i2);
1553 cxDst = _MAX (himl1->cx, dx + himl2->cx);
1558 cxDst = _MAX (himl2->cx, himl1->cx - dx);
1563 cxDst = _MAX (himl1->cx, himl2->cx);
1569 cyDst = _MAX (himl1->cy, dy + himl2->cy);
1574 cyDst = _MAX (himl2->cy, himl1->cy - dy);
1579 cyDst = _MAX (himl1->cy, himl2->cy);
1584 himlDst = ImageList_Create (cxDst, cyDst, ILC_MASK | ILC_COLOR, 1, 1);
1587 hdcSrcImage = CreateCompatibleDC32 (0);
1588 hdcDstImage = CreateCompatibleDC32 (0);
1589 nX1 = i1 * himl1->cx;
1590 nX2 = i2 * himl2->cx;
1593 SelectObject32 (hdcSrcImage, himl1->hbmImage);
1594 SelectObject32 (hdcDstImage, himlDst->hbmImage);
1595 BitBlt32 (hdcDstImage, 0, 0, cxDst, cyDst,
1596 hdcSrcImage, 0, 0, BLACKNESS);
1597 BitBlt32 (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy,
1598 hdcSrcImage, nX1, 0, SRCCOPY);
1600 SelectObject32 (hdcSrcImage, himl2->hbmMask);
1601 BitBlt32 (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
1602 hdcSrcImage, nX2, 0, SRCAND);
1604 SelectObject32 (hdcSrcImage, himl2->hbmImage);
1605 BitBlt32 (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
1606 hdcSrcImage, nX2, 0, SRCPAINT);
1609 SelectObject32 (hdcSrcImage, himl1->hbmMask);
1610 SelectObject32 (hdcDstImage, himlDst->hbmMask);
1611 BitBlt32 (hdcDstImage, 0, 0, cxDst, cyDst,
1612 hdcSrcImage, 0, 0, WHITENESS);
1613 BitBlt32 (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy,
1614 hdcSrcImage, nX1, 0, SRCCOPY);
1616 SelectObject32 (hdcSrcImage, himl2->hbmMask);
1617 BitBlt32 (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
1618 hdcSrcImage, nX2, 0, SRCAND);
1620 DeleteDC32 (hdcSrcImage);
1621 DeleteDC32 (hdcDstImage);
1628 /*************************************************************************
1629 * ImageList_Read [COMCTL32.66]
1631 * Reads an image list from a stream.
1634 * pstm [I] pointer to a stream
1637 * Success: image list handle
1641 * This function can not be implemented yet, because
1642 * IStream32::Read is not implemented yet.
1648 HIMAGELIST WINAPI ImageList_Read (LPSTREAM32 pstm)
1650 FIXME (imagelist, "empty stub!\n");
1657 /*************************************************************************
1658 * ImageList_Remove [COMCTL32.67] Removes an image from an image list
1661 * himl [I] image list handle
1670 ImageList_Remove (HIMAGELIST himl, INT32 i)
1672 HBITMAP32 hbmNewImage, hbmNewMask;
1673 HDC32 hdcSrc, hdcDst;
1674 INT32 cxNew, nCount;
1676 if ((i < -1) || (i >= himl->cCurImage)) {
1677 ERR (imagelist, "index out of range! %d\n", i);
1681 if (himl->cCurImage == 0) {
1682 ERR (imagelist, "image list is already empty!\n");
1688 TRACE (imagelist, "remove all!\n");
1690 himl->cMaxImage = himl->cInitial + himl->cGrow;
1691 himl->cCurImage = 0;
1692 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
1693 himl->nOvlIdx[nCount] = -1;
1695 DeleteObject32 (himl->hbmImage);
1697 CreateBitmap32 (himl->cMaxImage * himl->cx, himl->cy,
1698 1, himl->uBitsPixel, NULL);
1700 if (himl->hbmMask) {
1701 DeleteObject32 (himl->hbmMask);
1703 CreateBitmap32 (himl->cMaxImage * himl->cx, himl->cy,
1708 /* delete one image */
1709 TRACE (imagelist, "Remove single image! %d\n", i);
1711 /* create new bitmap(s) */
1712 cxNew = (himl->cCurImage + himl->cGrow - 1) * himl->cx;
1714 TRACE(imagelist, " - Number of images: %d / %d (Old/New)\n",
1715 himl->cCurImage, himl->cCurImage - 1);
1716 TRACE(imagelist, " - Max. number of images: %d / %d (Old/New)\n",
1717 himl->cMaxImage, himl->cCurImage + himl->cGrow - 1);
1720 CreateBitmap32 (cxNew, himl->cy, 1, himl->uBitsPixel, NULL);
1723 hbmNewMask = CreateBitmap32 (cxNew, himl->cy, 1, 1, NULL);
1725 hbmNewMask = 0; /* Just to keep compiler happy! */
1727 hdcSrc = CreateCompatibleDC32 (0);
1728 hdcDst = CreateCompatibleDC32 (0);
1730 /* copy all images and masks prior to the "removed" image */
1732 TRACE (imagelist, "Pre image copy: Copy %d images\n", i);
1734 SelectObject32 (hdcSrc, himl->hbmImage);
1735 SelectObject32 (hdcDst, hbmNewImage);
1736 BitBlt32 (hdcDst, 0, 0, i * himl->cx, himl->cy,
1737 hdcSrc, 0, 0, SRCCOPY);
1739 if (himl->hbmMask) {
1740 SelectObject32 (hdcSrc, himl->hbmMask);
1741 SelectObject32 (hdcDst, hbmNewMask);
1742 BitBlt32 (hdcDst, 0, 0, i * himl->cx, himl->cy,
1743 hdcSrc, 0, 0, SRCCOPY);
1747 /* copy all images and masks behind the removed image */
1748 if (i < himl->cCurImage - 1) {
1749 TRACE (imagelist, "Post image copy!\n");
1750 SelectObject32 (hdcSrc, himl->hbmImage);
1751 SelectObject32 (hdcDst, hbmNewImage);
1752 BitBlt32 (hdcDst, i * himl->cx, 0, (himl->cCurImage - i - 1) * himl->cx,
1753 himl->cy, hdcSrc, (i + 1) * himl->cx, 0, SRCCOPY);
1755 if (himl->hbmMask) {
1756 SelectObject32 (hdcSrc, himl->hbmMask);
1757 SelectObject32 (hdcDst, hbmNewMask);
1758 BitBlt32 (hdcDst, i * himl->cx, 0,
1759 (himl->cCurImage - i - 1) * himl->cx,
1760 himl->cy, hdcSrc, (i + 1) * himl->cx, 0, SRCCOPY);
1764 DeleteDC32 (hdcSrc);
1765 DeleteDC32 (hdcDst);
1767 /* delete old images and insert new ones */
1768 DeleteObject32 (himl->hbmImage);
1769 himl->hbmImage = hbmNewImage;
1770 if (himl->hbmMask) {
1771 DeleteObject32 (himl->hbmMask);
1772 himl->hbmMask = hbmNewMask;
1776 himl->cMaxImage = himl->cCurImage + himl->cGrow;
1783 /*************************************************************************
1784 * ImageList_Replace [COMCTL32.68]
1786 * Replaces an image in an image list with a new image.
1789 * himl [I] image list handle
1791 * hbmImage [I] image bitmap handle
1792 * hbmMask [I] mask bitmap handle. Can be NULL.
1800 ImageList_Replace (HIMAGELIST himl, INT32 i, HBITMAP32 hbmImage,
1803 HDC32 hdcImageList, hdcImage;
1807 ERR (imagelist, "Invalid image list handle!\n");
1811 if ((i >= himl->cCurImage) || (i < 0)) {
1812 ERR (imagelist, "Invalid image index!\n");
1816 hdcImageList = CreateCompatibleDC32 (0);
1817 hdcImage = CreateCompatibleDC32 (0);
1818 GetObject32A (hbmImage, sizeof(BITMAP32), (LPVOID)&bmp);
1821 SelectObject32 (hdcImageList, himl->hbmImage);
1822 SelectObject32 (hdcImage, hbmImage);
1824 StretchBlt32 (hdcImageList, i * himl->cx, 0, himl->cx, himl->cy,
1825 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1830 SelectObject32 (hdcImageList, himl->hbmMask);
1831 SelectObject32 (hdcImage, hbmMask);
1833 StretchBlt32 (hdcImageList, i * himl->cx, 0, himl->cx, himl->cy,
1834 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1837 DeleteDC32 (hdcImage);
1838 DeleteDC32 (hdcImageList);
1844 /*************************************************************************
1845 * ImageList_ReplaceIcon [COMCTL32.69]
1847 * Replaces an image in an image list using an icon.
1850 * himl [I] image list handle
1852 * hIcon [I] icon handle
1855 * Success: index of the replaced image
1860 ImageList_ReplaceIcon (HIMAGELIST himl, INT32 i, HICON32 hIcon)
1862 HDC32 hdcImageList, hdcImage;
1864 HBITMAP32 hbmOldSrc, hbmOldDst;
1868 TRACE (imagelist, "(0x%lx 0x%x 0x%x)\n", (DWORD)himl, i, hIcon);
1872 if ((i >= himl->cCurImage) || (i < -1))
1875 GetIconInfo (hIcon, &ii);
1876 if (ii.hbmMask == 0)
1877 ERR (imagelist, "no mask!\n");
1878 if (ii.hbmColor == 0)
1879 ERR (imagelist, "no color!\n");
1880 GetObject32A (ii.hbmMask, sizeof(BITMAP32), (LPVOID)&bmp);
1883 if (himl->cCurImage + 1 >= himl->cMaxImage)
1884 IMAGELIST_InternalExpandBitmaps (himl, 1);
1886 nIndex = himl->cCurImage;
1892 hdcImageList = CreateCompatibleDC32 (0);
1893 TRACE (imagelist, "hdcImageList=0x%x!\n", hdcImageList);
1894 if (hdcImageList == 0)
1895 ERR (imagelist, "invalid hdcImageList!\n");
1897 hdcImage = CreateCompatibleDC32 (0);
1898 TRACE (imagelist, "hdcImage=0x%x!\n", hdcImage);
1900 ERR (imagelist, "invalid hdcImage!\n");
1902 hbmOldDst = SelectObject32 (hdcImageList, himl->hbmImage);
1903 SetTextColor32( hdcImageList, RGB(0,0,0));
1904 SetBkColor32( hdcImageList, RGB(255,255,255));
1905 hbmOldSrc = SelectObject32 (hdcImage, ii.hbmColor);
1906 StretchBlt32 (hdcImageList, nIndex * himl->cx, 0, himl->cx, himl->cy,
1907 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1909 if (himl->hbmMask) {
1910 SelectObject32 (hdcImageList, himl->hbmMask);
1911 SelectObject32 (hdcImage, ii.hbmMask);
1912 StretchBlt32 (hdcImageList, nIndex * himl->cx, 0, himl->cx, himl->cy,
1913 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1916 SelectObject32 (hdcImage, hbmOldSrc);
1917 SelectObject32 (hdcImageList, hbmOldDst);
1920 DeleteDC32 (hdcImageList);
1922 DeleteDC32 (hdcImage);
1924 DeleteObject32 (ii.hbmColor);
1926 DeleteObject32 (ii.hbmMask);
1932 /*************************************************************************
1933 * ImageList_SetBkColor [COMCTL32.70]
1935 * Sets the background color of an image list.
1938 * himl [I] image list handle
1939 * clrBk [I] background color
1942 * Success: previous background color
1947 ImageList_SetBkColor (HIMAGELIST himl, COLORREF clrBk)
1954 clrOldBk = himl->clrBk;
1955 himl->clrBk = clrBk;
1960 /*************************************************************************
1961 * ImageList_SetDragCursorImage [COMCTL32.75]
1963 * Combines the specified image with the current drag image
1966 * himlDrag [I] drag image list handle
1967 * iDrag [I] drag image index
1968 * dxHotspot [I] X position of the hot spot
1969 * dyHotspot [I] Y position of the hot spot
1980 ImageList_SetDragCursorImage (HIMAGELIST himlDrag, INT32 iDrag,
1981 INT32 dxHotspot, INT32 dyHotspot)
1983 HIMAGELIST himlTemp;
1985 FIXME (imagelist, "semi-stub!\n");
1987 if (himlInternalDrag == NULL)
1990 TRACE (imagelist, " dxH=%d dyH=%d nX=%d nY=%d\n",
1991 dxHotspot, dyHotspot, nInternalDragHotspotX, nInternalDragHotspotY);
1993 himlTemp = ImageList_Merge (himlInternalDrag, 0, himlDrag, iDrag,
1994 dxHotspot, dyHotspot);
1996 ImageList_Destroy (himlInternalDrag);
1997 himlInternalDrag = himlTemp;
1999 nInternalDragHotspotX = dxHotspot;
2000 nInternalDragHotspotY = dyHotspot;
2006 /*************************************************************************
2007 * ImageList_SetFilter [COMCTL32.76]
2009 * Sets a filter (or does something completely different)!!???
2018 * Failure: FALSE ???
2021 * This is an UNDOCUMENTED function!!!!
2026 ImageList_SetFilter (HIMAGELIST himl, INT32 i, DWORD dwFilter)
2028 FIXME (imagelist, "(%p 0x%x 0x%lx):empty stub!\n",
2035 /*************************************************************************
2036 * ImageList_SetIconSize [COMCTL32.77]
2038 * Sets the image size of the bitmap and deletes all images.
2041 * himl [I] handle to image list
2042 * cx [I] image width
2043 * cy [I] image height
2051 ImageList_SetIconSize (HIMAGELIST himl, INT32 cx, INT32 cy)
2058 /* remove all images*/
2059 himl->cMaxImage = himl->cInitial + himl->cGrow;
2060 himl->cCurImage = 0;
2064 /* initialize overlay mask indices */
2065 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
2066 himl->nOvlIdx[nCount] = -1;
2068 DeleteObject32 (himl->hbmImage);
2070 CreateBitmap32 (himl->cMaxImage * himl->cx, himl->cy,
2071 1, himl->uBitsPixel, NULL);
2073 if (himl->hbmMask) {
2074 DeleteObject32 (himl->hbmMask);
2076 CreateBitmap32 (himl->cMaxImage * himl->cx, himl->cy,
2084 /*************************************************************************
2085 * ImageList_SetImageCount [COMCTL32.78]
2087 * Resizes an image list to the specified number of images.
2090 * himl [I] handle to image list
2091 * iImageCount [I] number of images in the image list
2099 ImageList_SetImageCount (HIMAGELIST himl, INT32 iImageCount)
2101 HDC32 hdcImageList, hdcBitmap;
2102 HBITMAP32 hbmNewBitmap;
2103 INT32 nNewCount, nCopyCount;
2107 if (himl->cCurImage <= iImageCount)
2109 if (himl->cMaxImage > iImageCount)
2112 nNewCount = iImageCount + himl->cGrow;
2113 nCopyCount = _MIN(himl->cCurImage, iImageCount);
2115 hdcImageList = CreateCompatibleDC32 (0);
2116 hdcBitmap = CreateCompatibleDC32 (0);
2118 hbmNewBitmap = CreateBitmap32 (nNewCount * himl->cx, himl->cy,
2119 1, himl->uBitsPixel, NULL);
2120 if (hbmNewBitmap == 0)
2122 SelectObject32 (hdcImageList, himl->hbmImage);
2123 SelectObject32 (hdcBitmap, hbmNewBitmap);
2126 BitBlt32 (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
2127 hdcImageList, 0, 0, SRCCOPY);
2129 /* delete 'empty' image space */
2130 SetBkColor32 (hdcBitmap, RGB(255, 255, 255));
2131 SetTextColor32 (hdcBitmap, RGB(0, 0, 0));
2132 PatBlt32 (hdcBitmap, nCopyCount * himl->cx, 0,
2133 (nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS);
2135 DeleteObject32 (himl->hbmImage);
2136 himl->hbmImage = hbmNewBitmap;
2139 ERR (imagelist, "Could not create new image bitmap !\n");
2143 hbmNewBitmap = CreateBitmap32 (nNewCount * himl->cx, himl->cy,
2145 if (hbmNewBitmap != 0)
2147 SelectObject32 (hdcImageList, himl->hbmMask);
2148 SelectObject32 (hdcBitmap, hbmNewBitmap);
2151 BitBlt32 (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
2152 hdcImageList, 0, 0, SRCCOPY);
2154 /* delete 'empty' image space */
2155 SetBkColor32 (hdcBitmap, RGB(255, 255, 255));
2156 SetTextColor32 (hdcBitmap, RGB(0, 0, 0));
2157 PatBlt32 (hdcBitmap, nCopyCount * himl->cx, 0,
2158 (nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS);
2160 DeleteObject32 (himl->hbmMask);
2161 himl->hbmMask = hbmNewBitmap;
2164 ERR (imagelist, "Could not create new mask bitmap!\n");
2167 DeleteDC32 (hdcImageList);
2168 DeleteDC32 (hdcBitmap);
2170 /* Update max image count and current image count */
2171 himl->cMaxImage = nNewCount;
2172 if (himl->cCurImage > nCopyCount)
2173 himl->cCurImage = nCopyCount;
2179 /*************************************************************************
2180 * ImageList_SetOverlayImage [COMCTL32.79]
2182 * Assigns an overlay mask index to an existing image in an image list.
2185 * himl [I] image list handle
2186 * iImage [I] image index
2187 * iOverlay [I] overlay mask index
2195 ImageList_SetOverlayImage (HIMAGELIST himl, INT32 iImage, INT32 iOverlay)
2199 if ((iOverlay < 1) || (iOverlay > MAX_OVERLAYIMAGE))
2201 if ((iImage < 0) || (iImage > himl->cCurImage))
2204 himl->nOvlIdx[iOverlay - 1] = iImage;
2209 /*************************************************************************
2210 * ImageList_Write [COMCTL32.80]
2212 * Writes an image list to a stream.
2215 * himl [I] Image list handle.
2216 * pstm [O] Pointer to a stream.
2223 * This function can not be implemented yet, because
2224 * IStream32::Write is not implemented.
2231 ImageList_Write (HIMAGELIST himl, LPSTREAM32 pstm)
2236 FIXME (imagelist, "empty stub!\n");