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 INT nInternalDragHotspotX = 0;
50 static INT nInternalDragHotspotY = 0;
52 static HWND hwndInternalDrag = 0;
53 static INT xInternalPos = 0;
54 static INT yInternalPos = 0;
56 static HDC hdcBackBuffer = 0;
57 static HBITMAP 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, INT nImageCount)
79 HDC hdcImageList, hdcBitmap;
81 INT nNewWidth, nNewCount;
83 TRACE(imagelist, "Create expanded bitmaps!\n");
85 nNewCount = himl->cCurImage + nImageCount + himl->cGrow;
86 nNewWidth = nNewCount * himl->cx;
88 hdcImageList = CreateCompatibleDC (0);
89 hdcBitmap = CreateCompatibleDC (0);
92 CreateBitmap (nNewWidth, himl->cy, 1, himl->uBitsPixel, NULL);
93 if (hbmNewBitmap == 0)
94 ERR (imagelist, "creating new image bitmap!\n");
96 SelectObject (hdcImageList, himl->hbmImage);
97 SelectObject (hdcBitmap, hbmNewBitmap);
98 BitBlt (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, himl->cy,
99 hdcImageList, 0, 0, SRCCOPY);
101 DeleteObject (himl->hbmImage);
102 himl->hbmImage = hbmNewBitmap;
106 CreateBitmap (nNewWidth, himl->cy, 1, 1, NULL);
108 if (hbmNewBitmap == 0)
109 ERR (imagelist, "creating new mask bitmap!");
111 SelectObject (hdcImageList, himl->hbmMask);
112 SelectObject (hdcBitmap, hbmNewBitmap);
113 BitBlt (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, himl->cy,
114 hdcImageList, 0, 0, SRCCOPY);
115 DeleteObject (himl->hbmMask);
116 himl->hbmMask = hbmNewBitmap;
119 himl->cMaxImage = nNewCount;
121 DeleteDC (hdcImageList);
122 DeleteDC (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, HBITMAP hbmImage, HBITMAP hbmMask)
145 INT nFirstIndex, nImageCount;
149 if (!himl || !hbmImage)
152 GetObjectA (hbmImage, sizeof(BITMAP), (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 = CreateCompatibleDC (0);
161 hdcDst = CreateCompatibleDC (0);
163 /* copy image bitmap */
164 SelectObject (hdcDst, himl->hbmImage);
165 SelectObject (hdcSrc, hbmImage);
166 BitBlt (hdcDst, himl->cCurImage * himl->cx, 0,
167 bmp.bmWidth, himl->cy, hdcSrc, 0, 0, SRCCOPY);
171 /* copy mask bitmap */
172 SelectObject (hdcDst, himl->hbmMask);
173 SelectObject (hdcSrc, hbmMask);
174 BitBlt (hdcDst, nStartX, 0, bmp.bmWidth, himl->cy,
175 hdcSrc, 0, 0, SRCCOPY);
178 /* copy monochrome image to the mask bitmap */
179 SelectObject (hdcDst, himl->hbmMask);
180 SelectObject (hdcSrc, hbmImage);
181 SetBkColor (hdcSrc, GetNearestColor (hdcSrc,
182 GetPixel (hdcSrc, 0, 0)));
183 BitBlt (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, HICON 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, HBITMAP hBitmap, COLORREF clrMask)
238 HDC hdcImage, hdcMask, hdcBitmap;
239 INT nIndex, nImageCount;
245 if (!GetObjectA (hBitmap, sizeof(BITMAP), &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 = CreateCompatibleDC (0);
257 hdcBitmap = CreateCompatibleDC (0);
259 SelectObject (hdcBitmap, hBitmap);
260 SelectObject (hdcImage, himl->hbmImage);
261 BitBlt (hdcImage, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy,
262 hdcBitmap, 0, 0, SRCCOPY);
265 COLORREF bkColor = (clrMask != CLR_DEFAULT) ? clrMask :
266 GetNearestColor (hdcBitmap, GetPixel (hdcBitmap, 0, 0));
268 /* create mask from image */
269 hdcMask = CreateCompatibleDC (0);
270 SelectObject (hdcMask, himl->hbmMask);
272 /* create monochrome image to the mask bitmap */
273 SetBkColor (hdcBitmap, bkColor);
274 BitBlt (hdcMask, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy,
275 hdcBitmap, 0, 0, SRCCOPY);
281 DeleteDC (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, INT iTrack,
306 INT dxHotspot, INT dyHotspot)
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 = CreateCompatibleDC (0);
330 hdcDst = CreateCompatibleDC (0);
333 SelectObject (hdcSrc, himlTrack->hbmImage);
334 SelectObject (hdcDst, himlInternalDrag->hbmImage);
335 StretchBlt (hdcDst, 0, 0, himlInternalDrag->cx, himlInternalDrag->cy, hdcSrc,
336 iTrack * himlTrack->cx, 0, himlTrack->cx, himlTrack->cy, SRCCOPY);
339 SelectObject (hdcSrc, himlTrack->hbmMask);
340 SelectObject (hdcDst, himlInternalDrag->hbmMask);
341 StretchBlt (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, INT iDst, HIMAGELIST himlSrc,
378 INT iSrc, INT uFlags)
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 = CreateCompatibleDC (0);
392 if (himlDst == himlSrc)
395 hdcDst = CreateCompatibleDC (0);
397 if (uFlags & ILCF_SWAP) {
399 HBITMAP hbmTempImage, hbmTempMask;
401 /* create temporary bitmaps */
402 hbmTempImage = CreateBitmap (himlSrc->cx, himlSrc->cy, 1,
403 himlSrc->uBitsPixel, NULL);
404 hbmTempMask = CreateBitmap (himlSrc->cx, himlSrc->cy, 1,
407 /* copy (and stretch) destination to temporary bitmaps.(save) */
409 SelectObject (hdcSrc, himlDst->hbmImage);
410 SelectObject (hdcDst, hbmTempImage);
411 StretchBlt (hdcDst, 0, 0, himlSrc->cx, himlSrc->cy,
412 hdcSrc, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
415 SelectObject (hdcSrc, himlDst->hbmMask);
416 SelectObject (hdcDst, hbmTempMask);
417 StretchBlt (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 SelectObject (hdcSrc, himlSrc->hbmImage);
424 SelectObject (hdcDst, himlDst->hbmImage);
425 StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
426 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
429 SelectObject (hdcSrc, himlSrc->hbmMask);
430 SelectObject (hdcDst, himlDst->hbmMask);
431 StretchBlt (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 SelectObject (hdcSrc, hbmTempImage);
438 SelectObject (hdcDst, himlSrc->hbmImage);
439 BitBlt (hdcDst, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
440 hdcSrc, 0, 0, SRCCOPY);
442 SelectObject (hdcSrc, hbmTempMask);
443 SelectObject (hdcDst, himlSrc->hbmMask);
444 BitBlt (hdcDst, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
445 hdcSrc, 0, 0, SRCCOPY);
447 /* delete temporary bitmaps */
448 DeleteObject (hbmTempMask);
449 DeleteObject (hbmTempImage);
453 SelectObject (hdcSrc, himlSrc->hbmImage);
454 if (himlSrc == himlDst)
457 SelectObject (hdcDst, himlDst->hbmImage);
458 StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
459 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
463 SelectObject (hdcSrc, himlSrc->hbmMask);
464 if (himlSrc == himlDst)
467 SelectObject (hdcDst, himlDst->hbmMask);
468 StretchBlt (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 (INT cx, INT cy, UINT flags,
498 INT cInitial, INT 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 = CreateCompatibleDC (0);
531 himl->uBitsPixel = (UINT)GetDeviceCaps (hdc, BITSPIXEL);
534 TRACE(imagelist, "Image: %d Bits per Pixel\n", himl->uBitsPixel);
537 CreateBitmap (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 = CreateBitmap (himl->cx * himl->cMaxImage, himl->cy,
547 if (himl->hbmMask == 0) {
548 ERR(imagelist, "Error creating mask bitmap!\n");
550 DeleteObject (himl->hbmImage);
557 /* create blending brushes */
558 hbmTemp = CreateBitmap (8, 8, 1, 1, &aBitBlend25);
559 himl->hbrBlend25 = CreatePatternBrush (hbmTemp);
560 DeleteObject (hbmTemp);
562 hbmTemp = CreateBitmap (8, 8, 1, 1, &aBitBlend50);
563 himl->hbrBlend50 = CreatePatternBrush (hbmTemp);
564 DeleteObject (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 DeleteObject (himl->hbmImage);
593 DeleteObject (himl->hbmMask);
595 /* delete blending brushes */
596 if (himl->hbrBlend25)
597 DeleteObject (himl->hbrBlend25);
598 if (himl->hbrBlend50)
599 DeleteObject (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 (HWND hwndLock, INT x, INT y)
629 if (himlInternalDrag == NULL)
633 hwndInternalDrag = hwndLock;
635 hwndInternalDrag = GetDesktopWindow ();
640 hdcBackBuffer = CreateCompatibleDC (0);
641 hbmBackBuffer = CreateCompatibleBitmap (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 (HWND hwndLock)
667 hwndInternalDrag = hwndLock;
669 hwndInternalDrag = GetDesktopWindow ();
671 ImageList_DragShowNolock (FALSE);
673 DeleteDC (hdcBackBuffer);
674 DeleteObject (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 (INT x, INT 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 (BOOL bShow)
733 FIXME (imagelist, "semi-stub!\n");
734 TRACE (imagelist, "bShow=0x%X!\n", bShow);
736 hdcDrag = GetDCEx (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 ReleaseDC (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, INT i, HDC hdc,
784 INT x, INT y, UINT 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, INT i, HDC hdc, INT x, INT y,
837 INT dx, INT 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 HDC hdcImageList, hdcTempImage;
879 HBITMAP hbmTempImage;
880 HBRUSH hBrush, hOldBrush;
884 BOOL bImage; /* draw image ? */
885 BOOL bImageTrans; /* draw image transparent ? */
886 BOOL bMask; /* draw mask ? */
887 BOOL 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 = CreateCompatibleDC (0);
952 SelectObject (hdcImageList, himlLocal->hbmMask);
953 SetBkColor (hdcImageList, RGB(255, 255, 255));
954 SetTextColor (hdcImageList, RGB(0, 0, 0));
955 BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
956 hdcImageList, himlLocal->cx * pimldp->i, 0,
957 bMaskTrans ? SRCAND : SRCCOPY);
963 SelectObject (hdcImageList, himlLocal->hbmImage);
967 hBrush = CreateSolidBrush (himlLocal->clrBk);
968 hOldBrush = SelectObject (pimldp->hdcDst, hBrush);
969 PatBlt (pimldp->hdcDst, pimldp->x, pimldp->y,
971 DeleteObject (SelectObject (pimldp->hdcDst, hOldBrush));
974 BitBlt (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 = GetSysColor (COLOR_HIGHLIGHT);
982 clrBlend = pimldp->rgbFg;
984 hdcTempImage = CreateCompatibleDC (0);
985 hbmTempImage = CreateBitmap (himlLocal->cx, himlLocal->cy,
986 1, himlLocal->uBitsPixel, NULL);
987 SelectObject (hdcTempImage, hbmTempImage);
991 SelectObject (hdcTempImage,
992 bBlend50 ? himlLocal->hbrBlend50 : himlLocal->hbrBlend25);
993 PatBlt (hdcTempImage, 0, 0, himlLocal->cx, himlLocal->cy, PATCOPY);
995 SelectObject (hdcImageList, himlLocal->hbmMask);
996 BitBlt (hdcTempImage, 0, 0, himlLocal->cx,
997 himlLocal->cy, hdcImageList,
998 pimldp->i * himlLocal->cx, 0, SRCPAINT);
1000 BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
1001 hdcTempImage, 0, 0, SRCAND);
1004 hBrush = CreateSolidBrush (clrBlend);
1005 SelectObject (hdcTempImage, hBrush);
1006 PatBlt (hdcTempImage, 0, 0, himlLocal->cx, himlLocal->cy, PATCOPY);
1007 DeleteObject (hBrush);
1009 SelectObject (hdcTempImage,
1010 bBlend50 ? himlLocal->hbrBlend50 : himlLocal->hbrBlend25);
1011 PatBlt (hdcTempImage, 0, 0, himlLocal->cx, himlLocal->cy, 0x0A0329);
1013 SelectObject (hdcImageList, himlLocal->hbmMask);
1014 BitBlt (hdcTempImage, 0, 0, himlLocal->cx,
1015 himlLocal->cy, hdcImageList,
1016 pimldp->i * himlLocal->cx, 0, SRCPAINT);
1018 BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
1019 hdcTempImage, 0, 0, SRCPAINT);
1021 DeleteObject (hbmTempImage);
1022 DeleteDC (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 SelectObject (hdcImageList, pimldp->himl->hbmMask);
1034 BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
1035 hdcImageList, pimldp->himl->cx * nOvlIdx, 0,
1038 SelectObject (hdcImageList, pimldp->himl->hbmImage);
1039 BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y,
1040 cx, cy, hdcImageList,
1041 pimldp->himl->cx * nOvlIdx, 0, SRCPAINT);
1046 DeleteDC (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)
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 = CreateCompatibleDC (0);
1080 hdcDst = CreateCompatibleDC (0);
1081 SelectObject (hdcSrc, himlSrc->hbmImage);
1082 SelectObject (hdcDst, himlDst->hbmImage);
1083 BitBlt (hdcDst, 0, 0, himlSrc->cCurImage * himlSrc->cx, himlSrc->cy,
1084 hdcSrc, 0, 0, SRCCOPY);
1086 if (himlDst->hbmMask)
1088 SelectObject (hdcSrc, himlSrc->hbmMask);
1089 SelectObject (hdcDst, himlDst->hbmMask);
1090 BitBlt (hdcDst, 0, 0, himlSrc->cCurImage * himlSrc->cx,
1091 himlSrc->cy, hdcSrc, 0, 0, SRCCOPY);
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 (POINT *ppt, POINT *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, INT i, UINT fStyle)
1211 INT nWidth, nHeight;
1213 if ((himl == NULL) || (i < 0) || (i >= himl->cCurImage))
1216 nWidth = GetSystemMetrics (SM_CXICON);
1217 nHeight = GetSystemMetrics (SM_CYICON);
1219 hdcSrc = CreateCompatibleDC(0);
1220 hdcDst = CreateCompatibleDC(0);
1223 ii.xHotspot = nWidth / 2;
1224 ii.yHotspot = nHeight / 2;
1225 ii.hbmMask = CreateCompatibleBitmap (hdcDst, nWidth, nHeight);
1226 ii.hbmColor = CreateCompatibleBitmap (hdcDst, nWidth, nHeight);
1230 SelectObject (hdcDst, ii.hbmMask);
1231 if (himl->hbmMask) {
1232 SelectObject (hdcSrc, himl->hbmMask);
1233 BitBlt (hdcDst, 0, 0, nWidth, nHeight,
1234 hdcSrc, i * himl->cx, 0, SRCCOPY);
1237 PatBlt (hdcDst, 0, 0, nWidth, nHeight, BLACKNESS);
1240 SelectObject (hdcDst, ii.hbmColor);
1241 SelectObject (hdcSrc, himl->hbmImage);
1242 BitBlt (hdcDst, 0, 0, nWidth, nHeight,
1243 hdcSrc, i * himl->cx, 0, SRCCOPY);
1245 hIcon = CreateIconIndirect (&ii);
1249 DeleteObject (ii.hbmMask);
1250 DeleteObject (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, INT *cx, INT *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, INT 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, INT i, LPRECT 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_LoadImageA (HINSTANCE hi, LPCSTR lpbmp, INT cx, INT cGrow,
1408 COLORREF clrMask, UINT uType, UINT uFlags)
1410 HIMAGELIST himl = NULL;
1414 handle = LoadImageA (hi, lpbmp, uType, 0, 0, uFlags);
1416 ERR (imagelist, "Error loading image!\n");
1420 if (uType == IMAGE_BITMAP) {
1422 GetObjectA (handle, sizeof(BITMAP), &bmp);
1423 nImageCount = bmp.bmWidth / cx;
1425 himl = ImageList_Create (cx, bmp.bmHeight, ILC_MASK | ILC_COLOR,
1426 nImageCount, cGrow);
1427 ImageList_AddMasked (himl, (HBITMAP)handle, clrMask);
1429 else if ((uType == IMAGE_ICON) || (uType == IMAGE_CURSOR)) {
1433 GetIconInfo (handle, &ii);
1434 GetObjectA (ii.hbmColor, sizeof(BITMAP), (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 DeleteObject (ii.hbmColor);
1439 DeleteObject (ii.hbmMask);
1442 DeleteObject (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_LoadImageW (HINSTANCE hi, LPCWSTR lpbmp, INT cx, INT cGrow,
1472 COLORREF clrMask, UINT uType, UINT uFlags)
1474 HIMAGELIST himl = NULL;
1478 handle = LoadImageW (hi, lpbmp, uType, 0, 0, uFlags);
1480 ERR (imagelist, "Error loading image!\n");
1484 if (uType == IMAGE_BITMAP) {
1486 GetObjectA (handle, sizeof(BITMAP), &bmp);
1487 nImageCount = bmp.bmWidth / cx;
1489 himl = ImageList_Create (cx, bmp.bmHeight, ILC_MASK | ILC_COLOR,
1490 nImageCount, cGrow);
1491 ImageList_AddMasked (himl, (HBITMAP)handle, clrMask);
1493 else if ((uType == IMAGE_ICON) || (uType == IMAGE_CURSOR)) {
1497 GetIconInfo (handle, &ii);
1498 GetObjectA (ii.hbmMask, sizeof(BITMAP), (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 DeleteObject (ii.hbmColor);
1503 DeleteObject (ii.hbmMask);
1506 DeleteObject (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, INT i1, HIMAGELIST himl2, INT i2,
1535 HIMAGELIST himlDst = NULL;
1536 HDC hdcSrcImage, hdcDstImage;
1538 INT 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 = CreateCompatibleDC (0);
1591 hdcDstImage = CreateCompatibleDC (0);
1592 nX1 = i1 * himl1->cx;
1593 nX2 = i2 * himl2->cx;
1596 SelectObject (hdcSrcImage, himl1->hbmImage);
1597 SelectObject (hdcDstImage, himlDst->hbmImage);
1598 BitBlt (hdcDstImage, 0, 0, cxDst, cyDst,
1599 hdcSrcImage, 0, 0, BLACKNESS);
1600 BitBlt (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy,
1601 hdcSrcImage, nX1, 0, SRCCOPY);
1603 SelectObject (hdcSrcImage, himl2->hbmMask);
1604 BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
1605 hdcSrcImage, nX2, 0, SRCAND);
1607 SelectObject (hdcSrcImage, himl2->hbmImage);
1608 BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
1609 hdcSrcImage, nX2, 0, SRCPAINT);
1612 SelectObject (hdcSrcImage, himl1->hbmMask);
1613 SelectObject (hdcDstImage, himlDst->hbmMask);
1614 BitBlt (hdcDstImage, 0, 0, cxDst, cyDst,
1615 hdcSrcImage, 0, 0, WHITENESS);
1616 BitBlt (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy,
1617 hdcSrcImage, nX1, 0, SRCCOPY);
1619 SelectObject (hdcSrcImage, himl2->hbmMask);
1620 BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
1621 hdcSrcImage, nX2, 0, SRCAND);
1623 DeleteDC (hdcSrcImage);
1624 DeleteDC (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 (LPSTREAM 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, INT i)
1675 HBITMAP hbmNewImage, hbmNewMask;
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 DeleteObject (himl->hbmImage);
1700 CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
1701 1, himl->uBitsPixel, NULL);
1703 if (himl->hbmMask) {
1704 DeleteObject (himl->hbmMask);
1706 CreateBitmap (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 CreateBitmap (cxNew, himl->cy, 1, himl->uBitsPixel, NULL);
1726 hbmNewMask = CreateBitmap (cxNew, himl->cy, 1, 1, NULL);
1728 hbmNewMask = 0; /* Just to keep compiler happy! */
1730 hdcSrc = CreateCompatibleDC (0);
1731 hdcDst = CreateCompatibleDC (0);
1733 /* copy all images and masks prior to the "removed" image */
1735 TRACE (imagelist, "Pre image copy: Copy %d images\n", i);
1737 SelectObject (hdcSrc, himl->hbmImage);
1738 SelectObject (hdcDst, hbmNewImage);
1739 BitBlt (hdcDst, 0, 0, i * himl->cx, himl->cy,
1740 hdcSrc, 0, 0, SRCCOPY);
1742 if (himl->hbmMask) {
1743 SelectObject (hdcSrc, himl->hbmMask);
1744 SelectObject (hdcDst, hbmNewMask);
1745 BitBlt (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 SelectObject (hdcSrc, himl->hbmImage);
1754 SelectObject (hdcDst, hbmNewImage);
1755 BitBlt (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 SelectObject (hdcSrc, himl->hbmMask);
1760 SelectObject (hdcDst, hbmNewMask);
1761 BitBlt (hdcDst, i * himl->cx, 0,
1762 (himl->cCurImage - i - 1) * himl->cx,
1763 himl->cy, hdcSrc, (i + 1) * himl->cx, 0, SRCCOPY);
1770 /* delete old images and insert new ones */
1771 DeleteObject (himl->hbmImage);
1772 himl->hbmImage = hbmNewImage;
1773 if (himl->hbmMask) {
1774 DeleteObject (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, INT i, HBITMAP hbmImage,
1806 HDC 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 = CreateCompatibleDC (0);
1820 hdcImage = CreateCompatibleDC (0);
1821 GetObjectA (hbmImage, sizeof(BITMAP), (LPVOID)&bmp);
1824 SelectObject (hdcImageList, himl->hbmImage);
1825 SelectObject (hdcImage, hbmImage);
1827 StretchBlt (hdcImageList, i * himl->cx, 0, himl->cx, himl->cy,
1828 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1833 SelectObject (hdcImageList, himl->hbmMask);
1834 SelectObject (hdcImage, hbmMask);
1836 StretchBlt (hdcImageList, i * himl->cx, 0, himl->cx, himl->cy,
1837 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1840 DeleteDC (hdcImage);
1841 DeleteDC (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, INT i, HICON hIcon)
1865 HDC hdcImageList, hdcImage;
1867 HBITMAP hbmOldSrc, hbmOldDst;
1871 TRACE (imagelist, "(0x%lx 0x%x 0x%x)\n", (DWORD)himl, i, hIcon);
1875 if ((i >= himl->cCurImage) || (i < -1))
1878 GetIconInfo (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 GetObjectA (ii.hbmMask, sizeof(BITMAP), (LPVOID)&bmp);
1886 if (himl->cCurImage + 1 >= himl->cMaxImage)
1887 IMAGELIST_InternalExpandBitmaps (himl, 1);
1889 nIndex = himl->cCurImage;
1895 hdcImageList = CreateCompatibleDC (0);
1896 TRACE (imagelist, "hdcImageList=0x%x!\n", hdcImageList);
1897 if (hdcImageList == 0)
1898 ERR (imagelist, "invalid hdcImageList!\n");
1900 hdcImage = CreateCompatibleDC (0);
1901 TRACE (imagelist, "hdcImage=0x%x!\n", hdcImage);
1903 ERR (imagelist, "invalid hdcImage!\n");
1905 hbmOldDst = SelectObject (hdcImageList, himl->hbmImage);
1906 SetTextColor( hdcImageList, RGB(0,0,0));
1907 SetBkColor( hdcImageList, RGB(255,255,255));
1908 hbmOldSrc = SelectObject (hdcImage, ii.hbmColor);
1909 StretchBlt (hdcImageList, nIndex * himl->cx, 0, himl->cx, himl->cy,
1910 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1912 if (himl->hbmMask) {
1913 SelectObject (hdcImageList, himl->hbmMask);
1914 SelectObject (hdcImage, ii.hbmMask);
1915 StretchBlt (hdcImageList, nIndex * himl->cx, 0, himl->cx, himl->cy,
1916 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1919 SelectObject (hdcImage, hbmOldSrc);
1920 SelectObject (hdcImageList, hbmOldDst);
1923 DeleteDC (hdcImageList);
1925 DeleteDC (hdcImage);
1927 DeleteObject (ii.hbmColor);
1929 DeleteObject (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, INT iDrag,
1984 INT dxHotspot, INT 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, INT 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, INT cx, INT 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 DeleteObject (himl->hbmImage);
2073 CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
2074 1, himl->uBitsPixel, NULL);
2076 if (himl->hbmMask) {
2077 DeleteObject (himl->hbmMask);
2079 CreateBitmap (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, INT iImageCount)
2104 HDC hdcImageList, hdcBitmap;
2105 HBITMAP hbmNewBitmap;
2106 INT 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 = CreateCompatibleDC (0);
2119 hdcBitmap = CreateCompatibleDC (0);
2121 hbmNewBitmap = CreateBitmap (nNewCount * himl->cx, himl->cy,
2122 1, himl->uBitsPixel, NULL);
2123 if (hbmNewBitmap == 0)
2125 SelectObject (hdcImageList, himl->hbmImage);
2126 SelectObject (hdcBitmap, hbmNewBitmap);
2129 BitBlt (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
2130 hdcImageList, 0, 0, SRCCOPY);
2132 /* delete 'empty' image space */
2133 SetBkColor (hdcBitmap, RGB(255, 255, 255));
2134 SetTextColor (hdcBitmap, RGB(0, 0, 0));
2135 PatBlt (hdcBitmap, nCopyCount * himl->cx, 0,
2136 (nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS);
2138 DeleteObject (himl->hbmImage);
2139 himl->hbmImage = hbmNewBitmap;
2142 ERR (imagelist, "Could not create new image bitmap !\n");
2146 hbmNewBitmap = CreateBitmap (nNewCount * himl->cx, himl->cy,
2148 if (hbmNewBitmap != 0)
2150 SelectObject (hdcImageList, himl->hbmMask);
2151 SelectObject (hdcBitmap, hbmNewBitmap);
2154 BitBlt (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
2155 hdcImageList, 0, 0, SRCCOPY);
2157 /* delete 'empty' image space */
2158 SetBkColor (hdcBitmap, RGB(255, 255, 255));
2159 SetTextColor (hdcBitmap, RGB(0, 0, 0));
2160 PatBlt (hdcBitmap, nCopyCount * himl->cx, 0,
2161 (nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS);
2163 DeleteObject (himl->hbmMask);
2164 himl->hbmMask = hbmNewBitmap;
2167 ERR (imagelist, "Could not create new mask bitmap!\n");
2170 DeleteDC (hdcImageList);
2171 DeleteDC (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, INT iImage, INT 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, LPSTREAM pstm)
2239 FIXME (imagelist, "empty stub!\n");