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
33 #include "wine/obj_base.h"
34 #include "wine/obj_storage.h"
35 #include "imagelist.h"
40 #define _MAX(a,b) (((a)>(b))?(a):(b))
41 #define _MIN(a,b) (((a)>(b))?(b):(a))
43 #define MAX_OVERLAYIMAGE 15
46 /* internal image list data used for Drag & Drop operations */
48 static HIMAGELIST himlInternalDrag = NULL;
49 static INT32 nInternalDragHotspotX = 0;
50 static INT32 nInternalDragHotspotY = 0;
52 static HWND32 hwndInternalDrag = 0;
53 static INT32 xInternalPos = 0;
54 static INT32 yInternalPos = 0;
56 static HDC32 hdcBackBuffer = 0;
57 static HBITMAP32 hbmBackBuffer = 0;
60 /*************************************************************************
61 * IMAGELIST_InternalExpandBitmaps [Internal]
63 * Expands the bitmaps of an image list by the given number of images.
66 * himl [I] handle to image list
67 * nImageCount [I] number of images to add
73 * This function can NOT be used to reduce the number of images.
77 IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl, INT32 nImageCount)
79 HDC32 hdcImageList, hdcBitmap;
80 HBITMAP32 hbmNewBitmap;
81 INT32 nNewWidth, nNewCount;
83 TRACE(imagelist, "Create expanded bitmaps!\n");
85 nNewCount = himl->cCurImage + nImageCount + himl->cGrow;
86 nNewWidth = nNewCount * himl->cx;
88 hdcImageList = CreateCompatibleDC32 (0);
89 hdcBitmap = CreateCompatibleDC32 (0);
92 CreateBitmap32 (nNewWidth, himl->cy, 1, himl->uBitsPixel, NULL);
93 if (hbmNewBitmap == 0)
94 ERR (imagelist, "creating new image bitmap!\n");
96 SelectObject32 (hdcImageList, himl->hbmImage);
97 SelectObject32 (hdcBitmap, hbmNewBitmap);
98 BitBlt32 (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, himl->cy,
99 hdcImageList, 0, 0, SRCCOPY);
101 DeleteObject32 (himl->hbmImage);
102 himl->hbmImage = hbmNewBitmap;
106 CreateBitmap32 (nNewWidth, himl->cy, 1, 1, NULL);
108 if (hbmNewBitmap == 0)
109 ERR (imagelist, "creating new mask bitmap!");
111 SelectObject32 (hdcImageList, himl->hbmMask);
112 SelectObject32 (hdcBitmap, hbmNewBitmap);
113 BitBlt32 (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, himl->cy,
114 hdcImageList, 0, 0, SRCCOPY);
115 DeleteObject32 (himl->hbmMask);
116 himl->hbmMask = hbmNewBitmap;
119 himl->cMaxImage = nNewCount;
121 DeleteDC32 (hdcImageList);
122 DeleteDC32 (hdcBitmap);
126 /*************************************************************************
127 * ImageList_Add [COMCTL32.39]
129 * Add an image or images to an image list.
132 * himl [I] handle to image list
133 * hbmImage [I] handle to image bitmap
134 * hbmMask [I] handle to mask bitmap
137 * Success: Index of the first new image.
142 ImageList_Add (HIMAGELIST himl, HBITMAP32 hbmImage, HBITMAP32 hbmMask)
144 HDC32 hdcSrc, hdcDst;
145 INT32 nFirstIndex, nImageCount;
149 if (!himl || !hbmImage)
152 GetObject32A (hbmImage, sizeof(BITMAP32), (LPVOID)&bmp);
153 nImageCount = bmp.bmWidth / himl->cx;
155 if (himl->cCurImage + nImageCount >= himl->cMaxImage)
156 IMAGELIST_InternalExpandBitmaps (himl, nImageCount);
158 nStartX = himl->cCurImage * himl->cx;
160 hdcSrc = CreateCompatibleDC32 (0);
161 hdcDst = CreateCompatibleDC32 (0);
163 /* copy image bitmap */
164 SelectObject32 (hdcDst, himl->hbmImage);
165 SelectObject32 (hdcSrc, hbmImage);
166 BitBlt32 (hdcDst, himl->cCurImage * himl->cx, 0,
167 bmp.bmWidth, himl->cy, hdcSrc, 0, 0, SRCCOPY);
171 /* copy mask bitmap */
172 SelectObject32 (hdcDst, himl->hbmMask);
173 SelectObject32 (hdcSrc, hbmMask);
174 BitBlt32 (hdcDst, nStartX, 0, bmp.bmWidth, himl->cy,
175 hdcSrc, 0, 0, SRCCOPY);
178 /* copy monochrome image to the mask bitmap */
179 SelectObject32 (hdcDst, himl->hbmMask);
180 SelectObject32 (hdcSrc, hbmImage);
181 SetBkColor32 (hdcSrc, GetNearestColor32 (hdcSrc,
182 GetPixel32 (hdcSrc, 0, 0)));
183 BitBlt32 (hdcDst, nStartX, 0, bmp.bmWidth, himl->cy,
184 hdcSrc, nStartX, 0, SRCCOPY);
191 nFirstIndex = himl->cCurImage;
192 himl->cCurImage += nImageCount;
198 /*************************************************************************
199 * ImageList_AddIcon [COMCTL32.40]
201 * Adds an icon to an image list.
204 * himl [I] handle to image list
205 * hIcon [I] handle to icon
208 * Success: index of the new image
213 ImageList_AddIcon (HIMAGELIST himl, HICON32 hIcon)
215 return ImageList_ReplaceIcon (himl, -1, hIcon);
219 /*************************************************************************
220 * ImageList_AddMasked [COMCTL32.41]
222 * Adds an image or images to an image list and creates a mask from the
223 * specified bitmap using the mask color.
226 * himl [I] handle to image list.
227 * hBitmap [I] handle to bitmap
228 * clrMask [I] mask color.
231 * Success: Index of the first new image.
236 ImageList_AddMasked (HIMAGELIST himl, HBITMAP32 hBitmap, COLORREF clrMask)
238 HDC32 hdcImage, hdcMask, hdcBitmap;
239 INT32 nIndex, nImageCount;
245 if (!GetObject32A (hBitmap, sizeof(BITMAP32), &bmp))
248 nImageCount = bmp.bmWidth / himl->cx;
250 if (himl->cCurImage + nImageCount >= himl->cMaxImage)
251 IMAGELIST_InternalExpandBitmaps (himl, nImageCount);
253 nIndex = himl->cCurImage;
254 himl->cCurImage += nImageCount;
256 hdcImage = CreateCompatibleDC32 (0);
257 hdcBitmap = CreateCompatibleDC32 (0);
259 SelectObject32 (hdcBitmap, hBitmap);
260 SelectObject32 (hdcImage, himl->hbmImage);
261 BitBlt32 (hdcImage, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy,
262 hdcBitmap, 0, 0, SRCCOPY);
265 COLORREF bkColor = (clrMask != CLR_DEFAULT) ? clrMask :
266 GetNearestColor32 (hdcBitmap, GetPixel32 (hdcBitmap, 0, 0));
268 /* create mask from image */
269 hdcMask = CreateCompatibleDC32 (0);
270 SelectObject32 (hdcMask, himl->hbmMask);
272 /* create monochrome image to the mask bitmap */
273 SetBkColor32 (hdcBitmap, bkColor);
274 BitBlt32 (hdcMask, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy,
275 hdcBitmap, 0, 0, SRCCOPY);
277 DeleteDC32 (hdcMask);
280 DeleteDC32 (hdcImage);
281 DeleteDC32 (hdcBitmap);
287 /*************************************************************************
288 * ImageList_BeginDrag [COMCTL32.42]
290 * Creates a temporary image list that contains one image. It will be used
294 * himlTrack [I] handle to the source image list
295 * iTrack [I] index of the drag image in the source image list
296 * dxHotspot [I] X position of the hot spot of the drag image
297 * dyHotspot [I] Y position of the hot spot of the drag image
305 ImageList_BeginDrag (HIMAGELIST himlTrack, INT32 iTrack,
306 INT32 dxHotspot, INT32 dyHotspot)
308 HDC32 hdcSrc, hdcDst;
310 FIXME(imagelist, "partially implemented!\n");
312 if (himlTrack == NULL)
315 if (himlInternalDrag)
316 ImageList_EndDrag ();
319 ImageList_Create (himlTrack->cx, himlTrack->cy,
320 himlTrack->flags, 1, 1);
321 if (himlInternalDrag == NULL) {
322 ERR(imagelist, "Error creating drag image list!\n");
326 nInternalDragHotspotX = dxHotspot;
327 nInternalDragHotspotY = dyHotspot;
329 hdcSrc = CreateCompatibleDC32 (0);
330 hdcDst = CreateCompatibleDC32 (0);
333 SelectObject32 (hdcSrc, himlTrack->hbmImage);
334 SelectObject32 (hdcDst, himlInternalDrag->hbmImage);
335 StretchBlt32 (hdcDst, 0, 0, himlInternalDrag->cx, himlInternalDrag->cy, hdcSrc,
336 iTrack * himlTrack->cx, 0, himlTrack->cx, himlTrack->cy, SRCCOPY);
339 SelectObject32 (hdcSrc, himlTrack->hbmMask);
340 SelectObject32 (hdcDst, himlInternalDrag->hbmMask);
341 StretchBlt32 (hdcDst, 0, 0, himlInternalDrag->cx, himlInternalDrag->cy, hdcSrc,
342 iTrack * himlTrack->cx, 0, himlTrack->cx, himlTrack->cy, SRCCOPY);
347 himlInternalDrag->cCurImage = 1;
353 /*************************************************************************
354 * ImageList_Copy [COMCTL32.43]
356 * Copies an image of the source image list to an image of the
357 * destination image list. Images can be copied or swapped.
360 * himlDst [I] handle to the destination image list
361 * iDst [I] destination image index.
362 * himlSrc [I] handle to the source image list
363 * iSrc [I] source image index
364 * uFlags [I] flags for the copy operation
371 * Copying from one image list to another is possible. The original
372 * implementation just copies or swapps within one image list.
373 * Could this feature become a bug??? ;-)
377 ImageList_Copy (HIMAGELIST himlDst, INT32 iDst, HIMAGELIST himlSrc,
378 INT32 iSrc, INT32 uFlags)
380 HDC32 hdcSrc, hdcDst;
382 TRACE(imagelist, "iDst=%d iSrc=%d\n", iDst, iSrc);
384 if ((himlSrc == NULL) || (himlDst == NULL))
386 if ((iDst < 0) || (iDst >= himlDst->cCurImage))
388 if ((iSrc < 0) || (iSrc >= himlSrc->cCurImage))
391 hdcSrc = CreateCompatibleDC32 (0);
392 if (himlDst == himlSrc)
395 hdcDst = CreateCompatibleDC32 (0);
397 if (uFlags & ILCF_SWAP) {
399 HBITMAP32 hbmTempImage, hbmTempMask;
401 /* create temporary bitmaps */
402 hbmTempImage = CreateBitmap32 (himlSrc->cx, himlSrc->cy, 1,
403 himlSrc->uBitsPixel, NULL);
404 hbmTempMask = CreateBitmap32 (himlSrc->cx, himlSrc->cy, 1,
407 /* copy (and stretch) destination to temporary bitmaps.(save) */
409 SelectObject32 (hdcSrc, himlDst->hbmImage);
410 SelectObject32 (hdcDst, hbmTempImage);
411 StretchBlt32 (hdcDst, 0, 0, himlSrc->cx, himlSrc->cy,
412 hdcSrc, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
415 SelectObject32 (hdcSrc, himlDst->hbmMask);
416 SelectObject32 (hdcDst, hbmTempMask);
417 StretchBlt32 (hdcDst, 0, 0, himlSrc->cx, himlSrc->cy,
418 hdcSrc, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
421 /* copy (and stretch) source to destination */
423 SelectObject32 (hdcSrc, himlSrc->hbmImage);
424 SelectObject32 (hdcDst, himlDst->hbmImage);
425 StretchBlt32 (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
426 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
429 SelectObject32 (hdcSrc, himlSrc->hbmMask);
430 SelectObject32 (hdcDst, himlDst->hbmMask);
431 StretchBlt32 (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
432 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
435 /* copy (without stretching) temporary bitmaps to source (restore) */
437 SelectObject32 (hdcSrc, hbmTempImage);
438 SelectObject32 (hdcDst, himlSrc->hbmImage);
439 BitBlt32 (hdcDst, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
440 hdcSrc, 0, 0, SRCCOPY);
442 SelectObject32 (hdcSrc, hbmTempMask);
443 SelectObject32 (hdcDst, himlSrc->hbmMask);
444 BitBlt32 (hdcDst, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
445 hdcSrc, 0, 0, SRCCOPY);
447 /* delete temporary bitmaps */
448 DeleteObject32 (hbmTempMask);
449 DeleteObject32 (hbmTempImage);
453 SelectObject32 (hdcSrc, himlSrc->hbmImage);
454 if (himlSrc == himlDst)
457 SelectObject32 (hdcDst, himlDst->hbmImage);
458 StretchBlt32 (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
459 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
463 SelectObject32 (hdcSrc, himlSrc->hbmMask);
464 if (himlSrc == himlDst)
467 SelectObject32 (hdcDst, himlDst->hbmMask);
468 StretchBlt32 (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
469 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
474 if (himlSrc != himlDst)
481 /*************************************************************************
482 * ImageList_Create [COMCTL32.44] Creates a new image list.
485 * cx [I] image height
487 * flags [I] creation flags
488 * cInitial [I] initial number of images in the image list
489 * cGrow [I] number of images by which image list grows
492 * Success: Handle to the created image list
497 ImageList_Create (INT32 cx, INT32 cy, UINT32 flags,
498 INT32 cInitial, INT32 cGrow)
504 static WORD aBitBlend25[] =
505 {0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00};
507 static WORD aBitBlend50[] =
508 {0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA};
510 TRACE (imagelist, "(%d %d 0x%x %d %d)\n", cx, cy, flags, cInitial, cGrow);
512 himl = (HIMAGELIST)COMCTL32_Alloc (sizeof(struct _IMAGELIST));
519 himl->cMaxImage = cInitial + cGrow;
520 himl->cInitial = cInitial;
523 himl->clrFg = CLR_DEFAULT;
524 himl->clrBk = CLR_NONE;
526 /* initialize overlay mask indices */
527 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
528 himl->nOvlIdx[nCount] = -1;
530 hdc = CreateCompatibleDC32 (0);
531 himl->uBitsPixel = (UINT32)GetDeviceCaps32 (hdc, BITSPIXEL);
534 TRACE(imagelist, "Image: %d Bits per Pixel\n", himl->uBitsPixel);
537 CreateBitmap32 (himl->cx * himl->cMaxImage, himl->cy,
538 1, himl->uBitsPixel, NULL);
539 if (himl->hbmImage == 0) {
540 ERR(imagelist, "Error creating image bitmap!\n");
544 if (himl->flags & ILC_MASK) {
545 himl->hbmMask = CreateBitmap32 (himl->cx * himl->cMaxImage, himl->cy,
547 if (himl->hbmMask == 0) {
548 ERR(imagelist, "Error creating mask bitmap!\n");
550 DeleteObject32 (himl->hbmImage);
557 /* create blending brushes */
558 hbmTemp = CreateBitmap32 (8, 8, 1, 1, &aBitBlend25);
559 himl->hbrBlend25 = CreatePatternBrush32 (hbmTemp);
560 DeleteObject32 (hbmTemp);
562 hbmTemp = CreateBitmap32 (8, 8, 1, 1, &aBitBlend50);
563 himl->hbrBlend50 = CreatePatternBrush32 (hbmTemp);
564 DeleteObject32 (hbmTemp);
570 /*************************************************************************
571 * ImageList_Destroy [COMCTL32.45]
573 * Destroys an image list.
576 * himl [I] handle to image list
584 ImageList_Destroy (HIMAGELIST himl)
589 /* delete image bitmaps */
591 DeleteObject32 (himl->hbmImage);
593 DeleteObject32 (himl->hbmMask);
595 /* delete blending brushes */
596 if (himl->hbrBlend25)
597 DeleteObject32 (himl->hbrBlend25);
598 if (himl->hbrBlend50)
599 DeleteObject32 (himl->hbrBlend50);
601 COMCTL32_Free (himl);
607 /*************************************************************************
608 * ImageList_DragEnter [COMCTL32.46]
610 * Locks window update and displays the drag image at the given position.
613 * hwndLock [I] handle of the window that owns the drag image.
614 * x [I] X position of the drag image.
615 * y [I] Y position of the drag image.
622 * The position of the drag image is relative to the window, not
627 ImageList_DragEnter (HWND32 hwndLock, INT32 x, INT32 y)
629 if (himlInternalDrag == NULL)
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] handle to image list
766 * hdc [I] handle to device context
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] handle to image list
815 * hdc [I] handle to device context
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)
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] handle to image list
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] handle to image list
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] handle to image list
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] handle to image list
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 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.63][COMCTL32.62]
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 to the loaded image list
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);
1416 ERR (imagelist, "Error loading image!\n");
1420 if (uType == IMAGE_BITMAP) {
1422 GetObject32A (handle, sizeof(BITMAP32), &bmp);
1423 nImageCount = bmp.bmWidth / cx;
1425 himl = ImageList_Create (cx, bmp.bmHeight, ILC_MASK | ILC_COLOR,
1426 nImageCount, cGrow);
1427 ImageList_AddMasked (himl, (HBITMAP32)handle, clrMask);
1429 else if ((uType == IMAGE_ICON) || (uType == IMAGE_CURSOR)) {
1433 GetIconInfo32 (handle, &ii);
1434 GetObject32A (ii.hbmColor, sizeof(BITMAP32), (LPVOID)&bmp);
1435 himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight,
1436 ILC_MASK | ILC_COLOR, 1, cGrow);
1437 ImageList_Add (himl, ii.hbmColor, ii.hbmMask);
1438 DeleteObject32 (ii.hbmColor);
1439 DeleteObject32 (ii.hbmMask);
1442 DeleteObject32 (handle);
1448 /*************************************************************************
1449 * ImageList_LoadImage32W [COMCTL32.64]
1451 * Creates an image list from a bitmap, icon or cursor.
1454 * hi [I] instance handle
1455 * lpbmp [I] name or id of the image
1456 * cx [I] width of each image
1457 * cGrow [I] number of images to expand
1458 * clrMask [I] mask color
1459 * uType [I] type of image to load
1460 * uFlags [I] loading flags
1463 * Success: handle to the loaded image list
1471 ImageList_LoadImage32W (HINSTANCE32 hi, LPCWSTR lpbmp, INT32 cx, INT32 cGrow,
1472 COLORREF clrMask, UINT32 uType, UINT32 uFlags)
1474 HIMAGELIST himl = NULL;
1478 handle = LoadImage32W (hi, lpbmp, uType, 0, 0, uFlags);
1480 ERR (imagelist, "Error loading image!\n");
1484 if (uType == IMAGE_BITMAP) {
1486 GetObject32A (handle, sizeof(BITMAP32), &bmp);
1487 nImageCount = bmp.bmWidth / cx;
1489 himl = ImageList_Create (cx, bmp.bmHeight, ILC_MASK | ILC_COLOR,
1490 nImageCount, cGrow);
1491 ImageList_AddMasked (himl, (HBITMAP32)handle, clrMask);
1493 else if ((uType == IMAGE_ICON) || (uType == IMAGE_CURSOR)) {
1497 GetIconInfo32 (handle, &ii);
1498 GetObject32A (ii.hbmMask, sizeof(BITMAP32), (LPVOID)&bmp);
1499 himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight,
1500 ILC_MASK | ILC_COLOR, 1, cGrow);
1501 ImageList_Add (himl, ii.hbmColor, ii.hbmMask);
1502 DeleteObject32 (ii.hbmColor);
1503 DeleteObject32 (ii.hbmMask);
1506 DeleteObject32 (handle);
1512 /*************************************************************************
1513 * ImageList_Merge [COMCTL32.65]
1515 * Creates a new image list that contains a merged image from the specified
1516 * images of both source image lists.
1519 * himl1 [I] handle to first image list
1520 * i1 [I] first image index
1521 * himl2 [I] handle to second image list
1522 * i2 [I] second image index
1523 * dx [I] X offset of the second image relative to the first.
1524 * dy [I] Y offset of the second image relative to the first.
1527 * Success: handle of the merged image list.
1532 ImageList_Merge (HIMAGELIST himl1, INT32 i1, HIMAGELIST himl2, INT32 i2,
1535 HIMAGELIST himlDst = NULL;
1536 HDC32 hdcSrcImage, hdcDstImage;
1538 INT32 xOff1, yOff1, xOff2, yOff2;
1541 if ((himl1 == NULL) || (himl2 == NULL))
1545 if ((i1 < 0) || (i1 >= himl1->cCurImage)) {
1546 ERR (imagelist, "Index 1 out of range! %d\n", i1);
1550 if ((i2 < 0) || (i2 >= himl2->cCurImage)) {
1551 ERR (imagelist, "Index 2 out of range! %d\n", i2);
1556 cxDst = _MAX (himl1->cx, dx + himl2->cx);
1561 cxDst = _MAX (himl2->cx, himl1->cx - dx);
1566 cxDst = _MAX (himl1->cx, himl2->cx);
1572 cyDst = _MAX (himl1->cy, dy + himl2->cy);
1577 cyDst = _MAX (himl2->cy, himl1->cy - dy);
1582 cyDst = _MAX (himl1->cy, himl2->cy);
1587 himlDst = ImageList_Create (cxDst, cyDst, ILC_MASK | ILC_COLOR, 1, 1);
1590 hdcSrcImage = CreateCompatibleDC32 (0);
1591 hdcDstImage = CreateCompatibleDC32 (0);
1592 nX1 = i1 * himl1->cx;
1593 nX2 = i2 * himl2->cx;
1596 SelectObject32 (hdcSrcImage, himl1->hbmImage);
1597 SelectObject32 (hdcDstImage, himlDst->hbmImage);
1598 BitBlt32 (hdcDstImage, 0, 0, cxDst, cyDst,
1599 hdcSrcImage, 0, 0, BLACKNESS);
1600 BitBlt32 (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy,
1601 hdcSrcImage, nX1, 0, SRCCOPY);
1603 SelectObject32 (hdcSrcImage, himl2->hbmMask);
1604 BitBlt32 (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
1605 hdcSrcImage, nX2, 0, SRCAND);
1607 SelectObject32 (hdcSrcImage, himl2->hbmImage);
1608 BitBlt32 (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
1609 hdcSrcImage, nX2, 0, SRCPAINT);
1612 SelectObject32 (hdcSrcImage, himl1->hbmMask);
1613 SelectObject32 (hdcDstImage, himlDst->hbmMask);
1614 BitBlt32 (hdcDstImage, 0, 0, cxDst, cyDst,
1615 hdcSrcImage, 0, 0, WHITENESS);
1616 BitBlt32 (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy,
1617 hdcSrcImage, nX1, 0, SRCCOPY);
1619 SelectObject32 (hdcSrcImage, himl2->hbmMask);
1620 BitBlt32 (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
1621 hdcSrcImage, nX2, 0, SRCAND);
1623 DeleteDC32 (hdcSrcImage);
1624 DeleteDC32 (hdcDstImage);
1631 /*************************************************************************
1632 * ImageList_Read [COMCTL32.66]
1634 * Reads an image list from a stream.
1637 * pstm [I] pointer to a stream
1640 * Success: handle to image list
1644 * This function can not be implemented yet, because
1645 * IStream32::Read is not implemented yet.
1651 HIMAGELIST WINAPI ImageList_Read (LPSTREAM32 pstm)
1653 FIXME (imagelist, "empty stub!\n");
1660 /*************************************************************************
1661 * ImageList_Remove [COMCTL32.67] Removes an image from an image list
1664 * himl [I] image list handle
1673 ImageList_Remove (HIMAGELIST himl, INT32 i)
1675 HBITMAP32 hbmNewImage, hbmNewMask;
1676 HDC32 hdcSrc, hdcDst;
1677 INT32 cxNew, nCount;
1679 if ((i < -1) || (i >= himl->cCurImage)) {
1680 ERR (imagelist, "index out of range! %d\n", i);
1684 if (himl->cCurImage == 0) {
1685 ERR (imagelist, "image list is already empty!\n");
1691 TRACE (imagelist, "remove all!\n");
1693 himl->cMaxImage = himl->cInitial + himl->cGrow;
1694 himl->cCurImage = 0;
1695 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
1696 himl->nOvlIdx[nCount] = -1;
1698 DeleteObject32 (himl->hbmImage);
1700 CreateBitmap32 (himl->cMaxImage * himl->cx, himl->cy,
1701 1, himl->uBitsPixel, NULL);
1703 if (himl->hbmMask) {
1704 DeleteObject32 (himl->hbmMask);
1706 CreateBitmap32 (himl->cMaxImage * himl->cx, himl->cy,
1711 /* delete one image */
1712 TRACE (imagelist, "Remove single image! %d\n", i);
1714 /* create new bitmap(s) */
1715 cxNew = (himl->cCurImage + himl->cGrow - 1) * himl->cx;
1717 TRACE(imagelist, " - Number of images: %d / %d (Old/New)\n",
1718 himl->cCurImage, himl->cCurImage - 1);
1719 TRACE(imagelist, " - Max. number of images: %d / %d (Old/New)\n",
1720 himl->cMaxImage, himl->cCurImage + himl->cGrow - 1);
1723 CreateBitmap32 (cxNew, himl->cy, 1, himl->uBitsPixel, NULL);
1726 hbmNewMask = CreateBitmap32 (cxNew, himl->cy, 1, 1, NULL);
1728 hbmNewMask = 0; /* Just to keep compiler happy! */
1730 hdcSrc = CreateCompatibleDC32 (0);
1731 hdcDst = CreateCompatibleDC32 (0);
1733 /* copy all images and masks prior to the "removed" image */
1735 TRACE (imagelist, "Pre image copy: Copy %d images\n", i);
1737 SelectObject32 (hdcSrc, himl->hbmImage);
1738 SelectObject32 (hdcDst, hbmNewImage);
1739 BitBlt32 (hdcDst, 0, 0, i * himl->cx, himl->cy,
1740 hdcSrc, 0, 0, SRCCOPY);
1742 if (himl->hbmMask) {
1743 SelectObject32 (hdcSrc, himl->hbmMask);
1744 SelectObject32 (hdcDst, hbmNewMask);
1745 BitBlt32 (hdcDst, 0, 0, i * himl->cx, himl->cy,
1746 hdcSrc, 0, 0, SRCCOPY);
1750 /* copy all images and masks behind the removed image */
1751 if (i < himl->cCurImage - 1) {
1752 TRACE (imagelist, "Post image copy!\n");
1753 SelectObject32 (hdcSrc, himl->hbmImage);
1754 SelectObject32 (hdcDst, hbmNewImage);
1755 BitBlt32 (hdcDst, i * himl->cx, 0, (himl->cCurImage - i - 1) * himl->cx,
1756 himl->cy, hdcSrc, (i + 1) * himl->cx, 0, SRCCOPY);
1758 if (himl->hbmMask) {
1759 SelectObject32 (hdcSrc, himl->hbmMask);
1760 SelectObject32 (hdcDst, hbmNewMask);
1761 BitBlt32 (hdcDst, i * himl->cx, 0,
1762 (himl->cCurImage - i - 1) * himl->cx,
1763 himl->cy, hdcSrc, (i + 1) * himl->cx, 0, SRCCOPY);
1767 DeleteDC32 (hdcSrc);
1768 DeleteDC32 (hdcDst);
1770 /* delete old images and insert new ones */
1771 DeleteObject32 (himl->hbmImage);
1772 himl->hbmImage = hbmNewImage;
1773 if (himl->hbmMask) {
1774 DeleteObject32 (himl->hbmMask);
1775 himl->hbmMask = hbmNewMask;
1779 himl->cMaxImage = himl->cCurImage + himl->cGrow;
1786 /*************************************************************************
1787 * ImageList_Replace [COMCTL32.68]
1789 * Replaces an image in an image list with a new image.
1792 * himl [I] handle to image list
1794 * hbmImage [I] handle to image bitmap
1795 * hbmMask [I] handle to mask bitmap. Can be NULL.
1803 ImageList_Replace (HIMAGELIST himl, INT32 i, HBITMAP32 hbmImage,
1806 HDC32 hdcImageList, hdcImage;
1810 ERR (imagelist, "Invalid image list handle!\n");
1814 if ((i >= himl->cCurImage) || (i < 0)) {
1815 ERR (imagelist, "Invalid image index!\n");
1819 hdcImageList = CreateCompatibleDC32 (0);
1820 hdcImage = CreateCompatibleDC32 (0);
1821 GetObject32A (hbmImage, sizeof(BITMAP32), (LPVOID)&bmp);
1824 SelectObject32 (hdcImageList, himl->hbmImage);
1825 SelectObject32 (hdcImage, hbmImage);
1827 StretchBlt32 (hdcImageList, i * himl->cx, 0, himl->cx, himl->cy,
1828 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1833 SelectObject32 (hdcImageList, himl->hbmMask);
1834 SelectObject32 (hdcImage, hbmMask);
1836 StretchBlt32 (hdcImageList, i * himl->cx, 0, himl->cx, himl->cy,
1837 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1840 DeleteDC32 (hdcImage);
1841 DeleteDC32 (hdcImageList);
1847 /*************************************************************************
1848 * ImageList_ReplaceIcon [COMCTL32.69]
1850 * Replaces an image in an image list using an icon.
1853 * himl [I] handle to image list
1855 * hIcon [I] handle to icon
1858 * Success: index of the replaced image
1863 ImageList_ReplaceIcon (HIMAGELIST himl, INT32 i, HICON32 hIcon)
1865 HDC32 hdcImageList, hdcImage;
1867 HBITMAP32 hbmOldSrc, hbmOldDst;
1871 TRACE (imagelist, "(0x%lx 0x%x 0x%x)\n", (DWORD)himl, i, hIcon);
1875 if ((i >= himl->cCurImage) || (i < -1))
1878 GetIconInfo32 (hIcon, &ii);
1879 if (ii.hbmMask == 0)
1880 ERR (imagelist, "no mask!\n");
1881 if (ii.hbmColor == 0)
1882 ERR (imagelist, "no color!\n");
1883 GetObject32A (ii.hbmMask, sizeof(BITMAP32), (LPVOID)&bmp);
1886 if (himl->cCurImage + 1 >= himl->cMaxImage)
1887 IMAGELIST_InternalExpandBitmaps (himl, 1);
1889 nIndex = himl->cCurImage;
1895 hdcImageList = CreateCompatibleDC32 (0);
1896 TRACE (imagelist, "hdcImageList=0x%x!\n", hdcImageList);
1897 if (hdcImageList == 0)
1898 ERR (imagelist, "invalid hdcImageList!\n");
1900 hdcImage = CreateCompatibleDC32 (0);
1901 TRACE (imagelist, "hdcImage=0x%x!\n", hdcImage);
1903 ERR (imagelist, "invalid hdcImage!\n");
1905 hbmOldDst = SelectObject32 (hdcImageList, himl->hbmImage);
1906 SetTextColor32( hdcImageList, RGB(0,0,0));
1907 SetBkColor32( hdcImageList, RGB(255,255,255));
1908 hbmOldSrc = SelectObject32 (hdcImage, ii.hbmColor);
1909 StretchBlt32 (hdcImageList, nIndex * himl->cx, 0, himl->cx, himl->cy,
1910 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1912 if (himl->hbmMask) {
1913 SelectObject32 (hdcImageList, himl->hbmMask);
1914 SelectObject32 (hdcImage, ii.hbmMask);
1915 StretchBlt32 (hdcImageList, nIndex * himl->cx, 0, himl->cx, himl->cy,
1916 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1919 SelectObject32 (hdcImage, hbmOldSrc);
1920 SelectObject32 (hdcImageList, hbmOldDst);
1923 DeleteDC32 (hdcImageList);
1925 DeleteDC32 (hdcImage);
1927 DeleteObject32 (ii.hbmColor);
1929 DeleteObject32 (ii.hbmMask);
1935 /*************************************************************************
1936 * ImageList_SetBkColor [COMCTL32.70]
1938 * Sets the background color of an image list.
1941 * himl [I] handle to image list
1942 * clrBk [I] background color
1945 * Success: previous background color
1950 ImageList_SetBkColor (HIMAGELIST himl, COLORREF clrBk)
1957 clrOldBk = himl->clrBk;
1958 himl->clrBk = clrBk;
1963 /*************************************************************************
1964 * ImageList_SetDragCursorImage [COMCTL32.75]
1966 * Combines the specified image with the current drag image
1969 * himlDrag [I] handle to drag image list
1970 * iDrag [I] drag image index
1971 * dxHotspot [I] X position of the hot spot
1972 * dyHotspot [I] Y position of the hot spot
1983 ImageList_SetDragCursorImage (HIMAGELIST himlDrag, INT32 iDrag,
1984 INT32 dxHotspot, INT32 dyHotspot)
1986 HIMAGELIST himlTemp;
1988 FIXME (imagelist, "semi-stub!\n");
1990 if (himlInternalDrag == NULL)
1993 TRACE (imagelist, " dxH=%d dyH=%d nX=%d nY=%d\n",
1994 dxHotspot, dyHotspot, nInternalDragHotspotX, nInternalDragHotspotY);
1996 himlTemp = ImageList_Merge (himlInternalDrag, 0, himlDrag, iDrag,
1997 dxHotspot, dyHotspot);
1999 ImageList_Destroy (himlInternalDrag);
2000 himlInternalDrag = himlTemp;
2002 nInternalDragHotspotX = dxHotspot;
2003 nInternalDragHotspotY = dyHotspot;
2009 /*************************************************************************
2010 * ImageList_SetFilter [COMCTL32.76]
2012 * Sets a filter (or does something completely different)!!???
2015 * himl [I] handle to image list
2021 * Failure: FALSE ???
2024 * This is an UNDOCUMENTED function!!!!
2029 ImageList_SetFilter (HIMAGELIST himl, INT32 i, DWORD dwFilter)
2031 FIXME (imagelist, "(%p 0x%x 0x%lx):empty stub!\n",
2038 /*************************************************************************
2039 * ImageList_SetIconSize [COMCTL32.77]
2041 * Sets the image size of the bitmap and deletes all images.
2044 * himl [I] handle to image list
2045 * cx [I] image width
2046 * cy [I] image height
2054 ImageList_SetIconSize (HIMAGELIST himl, INT32 cx, INT32 cy)
2061 /* remove all images*/
2062 himl->cMaxImage = himl->cInitial + himl->cGrow;
2063 himl->cCurImage = 0;
2067 /* initialize overlay mask indices */
2068 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
2069 himl->nOvlIdx[nCount] = -1;
2071 DeleteObject32 (himl->hbmImage);
2073 CreateBitmap32 (himl->cMaxImage * himl->cx, himl->cy,
2074 1, himl->uBitsPixel, NULL);
2076 if (himl->hbmMask) {
2077 DeleteObject32 (himl->hbmMask);
2079 CreateBitmap32 (himl->cMaxImage * himl->cx, himl->cy,
2087 /*************************************************************************
2088 * ImageList_SetImageCount [COMCTL32.78]
2090 * Resizes an image list to the specified number of images.
2093 * himl [I] handle to image list
2094 * iImageCount [I] number of images in the image list
2102 ImageList_SetImageCount (HIMAGELIST himl, INT32 iImageCount)
2104 HDC32 hdcImageList, hdcBitmap;
2105 HBITMAP32 hbmNewBitmap;
2106 INT32 nNewCount, nCopyCount;
2110 if (himl->cCurImage <= iImageCount)
2112 if (himl->cMaxImage > iImageCount)
2115 nNewCount = iImageCount + himl->cGrow;
2116 nCopyCount = _MIN(himl->cCurImage, iImageCount);
2118 hdcImageList = CreateCompatibleDC32 (0);
2119 hdcBitmap = CreateCompatibleDC32 (0);
2121 hbmNewBitmap = CreateBitmap32 (nNewCount * himl->cx, himl->cy,
2122 1, himl->uBitsPixel, NULL);
2123 if (hbmNewBitmap == 0)
2125 SelectObject32 (hdcImageList, himl->hbmImage);
2126 SelectObject32 (hdcBitmap, hbmNewBitmap);
2129 BitBlt32 (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
2130 hdcImageList, 0, 0, SRCCOPY);
2132 /* delete 'empty' image space */
2133 SetBkColor32 (hdcBitmap, RGB(255, 255, 255));
2134 SetTextColor32 (hdcBitmap, RGB(0, 0, 0));
2135 PatBlt32 (hdcBitmap, nCopyCount * himl->cx, 0,
2136 (nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS);
2138 DeleteObject32 (himl->hbmImage);
2139 himl->hbmImage = hbmNewBitmap;
2142 ERR (imagelist, "Could not create new image bitmap !\n");
2146 hbmNewBitmap = CreateBitmap32 (nNewCount * himl->cx, himl->cy,
2148 if (hbmNewBitmap != 0)
2150 SelectObject32 (hdcImageList, himl->hbmMask);
2151 SelectObject32 (hdcBitmap, hbmNewBitmap);
2154 BitBlt32 (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
2155 hdcImageList, 0, 0, SRCCOPY);
2157 /* delete 'empty' image space */
2158 SetBkColor32 (hdcBitmap, RGB(255, 255, 255));
2159 SetTextColor32 (hdcBitmap, RGB(0, 0, 0));
2160 PatBlt32 (hdcBitmap, nCopyCount * himl->cx, 0,
2161 (nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS);
2163 DeleteObject32 (himl->hbmMask);
2164 himl->hbmMask = hbmNewBitmap;
2167 ERR (imagelist, "Could not create new mask bitmap!\n");
2170 DeleteDC32 (hdcImageList);
2171 DeleteDC32 (hdcBitmap);
2173 /* Update max image count and current image count */
2174 himl->cMaxImage = nNewCount;
2175 if (himl->cCurImage > nCopyCount)
2176 himl->cCurImage = nCopyCount;
2182 /*************************************************************************
2183 * ImageList_SetOverlayImage [COMCTL32.79]
2185 * Assigns an overlay mask index to an existing image in an image list.
2188 * himl [I] handle to image list
2189 * iImage [I] image index
2190 * iOverlay [I] overlay mask index
2198 ImageList_SetOverlayImage (HIMAGELIST himl, INT32 iImage, INT32 iOverlay)
2202 if ((iOverlay < 1) || (iOverlay > MAX_OVERLAYIMAGE))
2204 if ((iImage < 0) || (iImage > himl->cCurImage))
2207 himl->nOvlIdx[iOverlay - 1] = iImage;
2212 /*************************************************************************
2213 * ImageList_Write [COMCTL32.80]
2215 * Writes an image list to a stream.
2218 * himl [I] handle to image list
2219 * pstm [O] Pointer to a stream.
2226 * This function can not be implemented yet, because
2227 * IStream32::Write is not implemented.
2234 ImageList_Write (HIMAGELIST himl, LPSTREAM32 pstm)
2239 FIXME (imagelist, "empty stub!\n");