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"
37 #include "debugtools.h"
39 DEFAULT_DEBUG_CHANNEL(imagelist)
42 #define _MAX(a,b) (((a)>(b))?(a):(b))
43 #define _MIN(a,b) (((a)>(b))?(b):(a))
45 #define MAX_OVERLAYIMAGE 15
48 /* internal image list data used for Drag & Drop operations */
50 static HIMAGELIST himlInternalDrag = NULL;
51 static INT nInternalDragHotspotX = 0;
52 static INT nInternalDragHotspotY = 0;
54 static HWND hwndInternalDrag = 0;
55 static INT xInternalPos = 0;
56 static INT yInternalPos = 0;
58 static HDC hdcBackBuffer = 0;
59 static HBITMAP hbmBackBuffer = 0;
62 /*************************************************************************
63 * IMAGELIST_InternalExpandBitmaps [Internal]
65 * Expands the bitmaps of an image list by the given number of images.
68 * himl [I] handle to image list
69 * nImageCount [I] number of images to add
75 * This function can NOT be used to reduce the number of images.
79 IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl, INT nImageCount)
81 HDC hdcImageList, hdcBitmap;
83 INT nNewWidth, nNewCount;
85 TRACE("Create expanded bitmaps!\n");
87 nNewCount = himl->cCurImage + nImageCount + himl->cGrow;
88 nNewWidth = nNewCount * himl->cx;
90 hdcImageList = CreateCompatibleDC (0);
91 hdcBitmap = CreateCompatibleDC (0);
94 CreateBitmap (nNewWidth, himl->cy, 1, himl->uBitsPixel, NULL);
95 if (hbmNewBitmap == 0)
96 ERR("creating new image bitmap!\n");
98 SelectObject (hdcImageList, himl->hbmImage);
99 SelectObject (hdcBitmap, hbmNewBitmap);
100 BitBlt (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, himl->cy,
101 hdcImageList, 0, 0, SRCCOPY);
103 DeleteObject (himl->hbmImage);
104 himl->hbmImage = hbmNewBitmap;
108 CreateBitmap (nNewWidth, himl->cy, 1, 1, NULL);
110 if (hbmNewBitmap == 0)
111 ERR("creating new mask bitmap!");
113 SelectObject (hdcImageList, himl->hbmMask);
114 SelectObject (hdcBitmap, hbmNewBitmap);
115 BitBlt (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, himl->cy,
116 hdcImageList, 0, 0, SRCCOPY);
117 DeleteObject (himl->hbmMask);
118 himl->hbmMask = hbmNewBitmap;
121 himl->cMaxImage = nNewCount;
123 DeleteDC (hdcImageList);
124 DeleteDC (hdcBitmap);
128 /*************************************************************************
129 * ImageList_Add [COMCTL32.39]
131 * Add an image or images to an image list.
134 * himl [I] handle to image list
135 * hbmImage [I] handle to image bitmap
136 * hbmMask [I] handle to mask bitmap
139 * Success: Index of the first new image.
144 ImageList_Add (HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask)
147 INT nFirstIndex, nImageCount;
151 if (!himl || !hbmImage)
154 GetObjectA (hbmImage, sizeof(BITMAP), (LPVOID)&bmp);
155 nImageCount = bmp.bmWidth / himl->cx;
157 if (himl->cCurImage + nImageCount >= himl->cMaxImage)
158 IMAGELIST_InternalExpandBitmaps (himl, nImageCount);
160 nStartX = himl->cCurImage * himl->cx;
162 hdcSrc = CreateCompatibleDC (0);
163 hdcDst = CreateCompatibleDC (0);
165 /* copy image bitmap */
166 SelectObject (hdcDst, himl->hbmImage);
167 SelectObject (hdcSrc, hbmImage);
168 BitBlt (hdcDst, himl->cCurImage * himl->cx, 0,
169 bmp.bmWidth, himl->cy, hdcSrc, 0, 0, SRCCOPY);
173 /* copy mask bitmap */
174 SelectObject (hdcDst, himl->hbmMask);
175 SelectObject (hdcSrc, hbmMask);
176 BitBlt (hdcDst, nStartX, 0, bmp.bmWidth, himl->cy,
177 hdcSrc, 0, 0, SRCCOPY);
180 /* copy monochrome image to the mask bitmap */
181 SelectObject (hdcDst, himl->hbmMask);
182 SelectObject (hdcSrc, hbmImage);
183 SetBkColor (hdcSrc, GetNearestColor (hdcSrc,
184 GetPixel (hdcSrc, 0, 0)));
185 BitBlt (hdcDst, nStartX, 0, bmp.bmWidth, himl->cy,
186 hdcSrc, nStartX, 0, SRCCOPY);
193 nFirstIndex = himl->cCurImage;
194 himl->cCurImage += nImageCount;
200 /*************************************************************************
201 * ImageList_AddIcon [COMCTL32.40]
203 * Adds an icon to an image list.
206 * himl [I] handle to image list
207 * hIcon [I] handle to icon
210 * Success: index of the new image
215 ImageList_AddIcon (HIMAGELIST himl, HICON hIcon)
217 return ImageList_ReplaceIcon (himl, -1, hIcon);
221 /*************************************************************************
222 * ImageList_AddMasked [COMCTL32.41]
224 * Adds an image or images to an image list and creates a mask from the
225 * specified bitmap using the mask color.
228 * himl [I] handle to image list.
229 * hBitmap [I] handle to bitmap
230 * clrMask [I] mask color.
233 * Success: Index of the first new image.
238 ImageList_AddMasked (HIMAGELIST himl, HBITMAP hBitmap, COLORREF clrMask)
240 HDC hdcImage, hdcMask, hdcBitmap;
241 INT nIndex, nImageCount;
247 if (!GetObjectA (hBitmap, sizeof(BITMAP), &bmp))
250 nImageCount = bmp.bmWidth / himl->cx;
252 if (himl->cCurImage + nImageCount >= himl->cMaxImage)
253 IMAGELIST_InternalExpandBitmaps (himl, nImageCount);
255 nIndex = himl->cCurImage;
256 himl->cCurImage += nImageCount;
258 hdcImage = CreateCompatibleDC (0);
259 hdcBitmap = CreateCompatibleDC (0);
261 SelectObject (hdcBitmap, hBitmap);
262 SelectObject (hdcImage, himl->hbmImage);
263 BitBlt (hdcImage, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy,
264 hdcBitmap, 0, 0, SRCCOPY);
267 COLORREF bkColor = (clrMask != CLR_DEFAULT) ? clrMask :
268 GetNearestColor (hdcBitmap, GetPixel (hdcBitmap, 0, 0));
270 /* create mask from image */
271 hdcMask = CreateCompatibleDC (0);
272 SelectObject (hdcMask, himl->hbmMask);
274 /* create monochrome image to the mask bitmap */
275 SetBkColor (hdcBitmap, bkColor);
276 BitBlt (hdcMask, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy,
277 hdcBitmap, 0, 0, SRCCOPY);
283 DeleteDC (hdcBitmap);
289 /*************************************************************************
290 * ImageList_BeginDrag [COMCTL32.42]
292 * Creates a temporary image list that contains one image. It will be used
296 * himlTrack [I] handle to the source image list
297 * iTrack [I] index of the drag image in the source image list
298 * dxHotspot [I] X position of the hot spot of the drag image
299 * dyHotspot [I] Y position of the hot spot of the drag image
307 ImageList_BeginDrag (HIMAGELIST himlTrack, INT iTrack,
308 INT dxHotspot, INT dyHotspot)
312 FIXME("partially implemented!\n");
314 if (himlTrack == NULL)
317 if (himlInternalDrag)
318 ImageList_EndDrag ();
321 ImageList_Create (himlTrack->cx, himlTrack->cy,
322 himlTrack->flags, 1, 1);
323 if (himlInternalDrag == NULL) {
324 ERR("Error creating drag image list!\n");
328 nInternalDragHotspotX = dxHotspot;
329 nInternalDragHotspotY = dyHotspot;
331 hdcSrc = CreateCompatibleDC (0);
332 hdcDst = CreateCompatibleDC (0);
335 SelectObject (hdcSrc, himlTrack->hbmImage);
336 SelectObject (hdcDst, himlInternalDrag->hbmImage);
337 StretchBlt (hdcDst, 0, 0, himlInternalDrag->cx, himlInternalDrag->cy, hdcSrc,
338 iTrack * himlTrack->cx, 0, himlTrack->cx, himlTrack->cy, SRCCOPY);
341 SelectObject (hdcSrc, himlTrack->hbmMask);
342 SelectObject (hdcDst, himlInternalDrag->hbmMask);
343 StretchBlt (hdcDst, 0, 0, himlInternalDrag->cx, himlInternalDrag->cy, hdcSrc,
344 iTrack * himlTrack->cx, 0, himlTrack->cx, himlTrack->cy, SRCCOPY);
349 himlInternalDrag->cCurImage = 1;
355 /*************************************************************************
356 * ImageList_Copy [COMCTL32.43]
358 * Copies an image of the source image list to an image of the
359 * destination image list. Images can be copied or swapped.
362 * himlDst [I] handle to the destination image list
363 * iDst [I] destination image index.
364 * himlSrc [I] handle to the source image list
365 * iSrc [I] source image index
366 * uFlags [I] flags for the copy operation
373 * Copying from one image list to another is possible. The original
374 * implementation just copies or swapps within one image list.
375 * Could this feature become a bug??? ;-)
379 ImageList_Copy (HIMAGELIST himlDst, INT iDst, HIMAGELIST himlSrc,
380 INT iSrc, INT uFlags)
384 TRACE("iDst=%d iSrc=%d\n", iDst, iSrc);
386 if ((himlSrc == NULL) || (himlDst == NULL))
388 if ((iDst < 0) || (iDst >= himlDst->cCurImage))
390 if ((iSrc < 0) || (iSrc >= himlSrc->cCurImage))
393 hdcSrc = CreateCompatibleDC (0);
394 if (himlDst == himlSrc)
397 hdcDst = CreateCompatibleDC (0);
399 if (uFlags & ILCF_SWAP) {
401 HBITMAP hbmTempImage, hbmTempMask;
403 /* create temporary bitmaps */
404 hbmTempImage = CreateBitmap (himlSrc->cx, himlSrc->cy, 1,
405 himlSrc->uBitsPixel, NULL);
406 hbmTempMask = CreateBitmap (himlSrc->cx, himlSrc->cy, 1,
409 /* copy (and stretch) destination to temporary bitmaps.(save) */
411 SelectObject (hdcSrc, himlDst->hbmImage);
412 SelectObject (hdcDst, hbmTempImage);
413 StretchBlt (hdcDst, 0, 0, himlSrc->cx, himlSrc->cy,
414 hdcSrc, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
417 SelectObject (hdcSrc, himlDst->hbmMask);
418 SelectObject (hdcDst, hbmTempMask);
419 StretchBlt (hdcDst, 0, 0, himlSrc->cx, himlSrc->cy,
420 hdcSrc, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
423 /* copy (and stretch) source to destination */
425 SelectObject (hdcSrc, himlSrc->hbmImage);
426 SelectObject (hdcDst, himlDst->hbmImage);
427 StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
428 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
431 SelectObject (hdcSrc, himlSrc->hbmMask);
432 SelectObject (hdcDst, himlDst->hbmMask);
433 StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
434 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
437 /* copy (without stretching) temporary bitmaps to source (restore) */
439 SelectObject (hdcSrc, hbmTempImage);
440 SelectObject (hdcDst, himlSrc->hbmImage);
441 BitBlt (hdcDst, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
442 hdcSrc, 0, 0, SRCCOPY);
444 SelectObject (hdcSrc, hbmTempMask);
445 SelectObject (hdcDst, himlSrc->hbmMask);
446 BitBlt (hdcDst, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
447 hdcSrc, 0, 0, SRCCOPY);
449 /* delete temporary bitmaps */
450 DeleteObject (hbmTempMask);
451 DeleteObject (hbmTempImage);
455 SelectObject (hdcSrc, himlSrc->hbmImage);
456 if (himlSrc == himlDst)
459 SelectObject (hdcDst, himlDst->hbmImage);
460 StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
461 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
465 SelectObject (hdcSrc, himlSrc->hbmMask);
466 if (himlSrc == himlDst)
469 SelectObject (hdcDst, himlDst->hbmMask);
470 StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
471 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
476 if (himlSrc != himlDst)
483 /*************************************************************************
484 * ImageList_Create [COMCTL32.44] Creates a new image list.
487 * cx [I] image height
489 * flags [I] creation flags
490 * cInitial [I] initial number of images in the image list
491 * cGrow [I] number of images by which image list grows
494 * Success: Handle to the created image list
499 ImageList_Create (INT cx, INT cy, UINT flags,
500 INT cInitial, INT cGrow)
506 static WORD aBitBlend25[] =
507 {0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00};
509 static WORD aBitBlend50[] =
510 {0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA};
512 TRACE("(%d %d 0x%x %d %d)\n", cx, cy, flags, cInitial, cGrow);
514 himl = (HIMAGELIST)COMCTL32_Alloc (sizeof(struct _IMAGELIST));
521 himl->cMaxImage = cInitial + cGrow;
522 himl->cInitial = cInitial;
525 himl->clrFg = CLR_DEFAULT;
526 himl->clrBk = CLR_NONE;
528 /* initialize overlay mask indices */
529 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
530 himl->nOvlIdx[nCount] = -1;
532 hdc = CreateCompatibleDC (0);
533 himl->uBitsPixel = (UINT)GetDeviceCaps (hdc, BITSPIXEL);
536 TRACE("Image: %d Bits per Pixel\n", himl->uBitsPixel);
539 CreateBitmap (himl->cx * himl->cMaxImage, himl->cy,
540 1, himl->uBitsPixel, NULL);
541 if (himl->hbmImage == 0) {
542 ERR("Error creating image bitmap!\n");
546 if (himl->flags & ILC_MASK) {
547 himl->hbmMask = CreateBitmap (himl->cx * himl->cMaxImage, himl->cy,
549 if (himl->hbmMask == 0) {
550 ERR("Error creating mask bitmap!\n");
552 DeleteObject (himl->hbmImage);
559 /* create blending brushes */
560 hbmTemp = CreateBitmap (8, 8, 1, 1, &aBitBlend25);
561 himl->hbrBlend25 = CreatePatternBrush (hbmTemp);
562 DeleteObject (hbmTemp);
564 hbmTemp = CreateBitmap (8, 8, 1, 1, &aBitBlend50);
565 himl->hbrBlend50 = CreatePatternBrush (hbmTemp);
566 DeleteObject (hbmTemp);
572 /*************************************************************************
573 * ImageList_Destroy [COMCTL32.45]
575 * Destroys an image list.
578 * himl [I] handle to image list
586 ImageList_Destroy (HIMAGELIST himl)
591 /* delete image bitmaps */
593 DeleteObject (himl->hbmImage);
595 DeleteObject (himl->hbmMask);
597 /* delete blending brushes */
598 if (himl->hbrBlend25)
599 DeleteObject (himl->hbrBlend25);
600 if (himl->hbrBlend50)
601 DeleteObject (himl->hbrBlend50);
603 COMCTL32_Free (himl);
609 /*************************************************************************
610 * ImageList_DragEnter [COMCTL32.46]
612 * Locks window update and displays the drag image at the given position.
615 * hwndLock [I] handle of the window that owns the drag image.
616 * x [I] X position of the drag image.
617 * y [I] Y position of the drag image.
624 * The position of the drag image is relative to the window, not
629 ImageList_DragEnter (HWND hwndLock, INT x, INT y)
631 if (himlInternalDrag == NULL)
635 hwndInternalDrag = hwndLock;
637 hwndInternalDrag = GetDesktopWindow ();
642 hdcBackBuffer = CreateCompatibleDC (0);
643 hbmBackBuffer = CreateCompatibleBitmap (hdcBackBuffer,
644 himlInternalDrag->cx, himlInternalDrag->cy);
646 ImageList_DragShowNolock (TRUE);
652 /*************************************************************************
653 * ImageList_DragLeave [COMCTL32.47]
655 * Unlocks window update and hides the drag image.
658 * hwndLock [I] handle of the window that owns the drag image.
666 ImageList_DragLeave (HWND hwndLock)
669 hwndInternalDrag = hwndLock;
671 hwndInternalDrag = GetDesktopWindow ();
673 ImageList_DragShowNolock (FALSE);
675 DeleteDC (hdcBackBuffer);
676 DeleteObject (hbmBackBuffer);
682 /*************************************************************************
683 * ImageList_DragMove [COMCTL32.48]
685 * Moves the drag image.
688 * x [I] X position of the drag image.
689 * y [I] Y position of the drag image.
696 * The position of the drag image is relative to the window, not
701 ImageList_DragMove (INT x, INT y)
703 ImageList_DragShowNolock (FALSE);
708 ImageList_DragShowNolock (TRUE);
714 /*************************************************************************
715 * ImageList_DragShowNolock [COMCTL32.49]
717 * Shows or hides the drag image.
720 * bShow [I] TRUE shows the drag image, FALSE hides it.
731 ImageList_DragShowNolock (BOOL bShow)
735 FIXME("semi-stub!\n");
736 TRACE("bShow=0x%X!\n", bShow);
738 hdcDrag = GetDCEx (hwndInternalDrag, 0,
739 DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
742 /* show drag image */
744 /* save background */
746 /* draw drag image */
750 /* hide drag image */
752 /* restore background */
756 ReleaseDC (hwndInternalDrag, hdcDrag);
762 /*************************************************************************
763 * ImageList_Draw [COMCTL32.50] Draws an image.
766 * himl [I] handle to image list
768 * hdc [I] handle to device context
771 * fStyle [I] drawing flags
778 * Calls ImageList_DrawIndirect.
781 * ImageList_DrawIndirect.
785 ImageList_Draw (HIMAGELIST himl, INT i, HDC hdc,
786 INT x, INT y, UINT fStyle)
788 IMAGELISTDRAWPARAMS imldp;
790 imldp.cbSize = sizeof(IMAGELISTDRAWPARAMS);
800 imldp.rgbBk = CLR_DEFAULT;
801 imldp.rgbFg = CLR_DEFAULT;
802 imldp.fStyle = fStyle;
805 return ImageList_DrawIndirect (&imldp);
809 /*************************************************************************
810 * ImageList_DrawEx [COMCTL32.51]
812 * Draws an image and allows to use extended drawing features.
815 * himl [I] handle to image list
817 * hdc [I] handle to device context
822 * rgbBk [I] background color
823 * rgbFg [I] foreground color
824 * fStyle [I] drawing flags
831 * Calls ImageList_DrawIndirect.
834 * ImageList_DrawIndirect.
838 ImageList_DrawEx (HIMAGELIST himl, INT i, HDC hdc, INT x, INT y,
839 INT dx, INT dy, COLORREF rgbBk, COLORREF rgbFg,
842 IMAGELISTDRAWPARAMS imldp;
844 imldp.cbSize = sizeof(IMAGELISTDRAWPARAMS);
856 imldp.fStyle = fStyle;
859 return ImageList_DrawIndirect (&imldp);
863 /*************************************************************************
864 * ImageList_DrawIndirect [COMCTL32.52]
866 * Draws an image using ...
869 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
877 ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
879 HIMAGELIST himlLocal;
880 HDC hdcImageList, hdcTempImage;
881 HBITMAP hbmTempImage;
882 HBRUSH hBrush, hOldBrush;
886 BOOL bImage; /* draw image ? */
887 BOOL bImageTrans; /* draw image transparent ? */
888 BOOL bMask; /* draw mask ? */
889 BOOL bMaskTrans; /* draw mask transparent ? */
895 if (pimldp->cbSize < sizeof(IMAGELISTDRAWPARAMS))
897 if (pimldp->himl == NULL)
899 if ((pimldp->i < 0) || (pimldp->i > pimldp->himl->cCurImage))
902 himlLocal = pimldp->himl;
904 cx = (pimldp->cx == 0) ? himlLocal->cx : pimldp->cx;
905 cy = (pimldp->cy == 0) ? himlLocal->cy : pimldp->cy;
907 /* ILD_NORMAL state */
914 if ((himlLocal->clrBk == CLR_NONE) && (himlLocal->hbmMask))
921 /* ILD_IMAGE state (changes) */
922 if (pimldp->fStyle & ILD_IMAGE)
929 /* ILD_MASK state (changes) */
930 if ((pimldp->fStyle & ILD_MASK) && (himlLocal->hbmMask))
936 if ((pimldp->fStyle & ILD_TRANSPARENT) && (himlLocal->hbmMask))
941 if ((himlLocal->clrBk == CLR_NONE) && (himlLocal->hbmMask))
944 if (pimldp->fStyle & ILD_BLEND50)
946 else if (pimldp->fStyle & ILD_BLEND25)
949 hdcImageList = CreateCompatibleDC (0);
954 SelectObject (hdcImageList, himlLocal->hbmMask);
955 SetBkColor (hdcImageList, RGB(255, 255, 255));
956 SetTextColor (hdcImageList, RGB(0, 0, 0));
957 BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
958 hdcImageList, himlLocal->cx * pimldp->i, 0,
959 bMaskTrans ? SRCAND : SRCCOPY);
965 SelectObject (hdcImageList, himlLocal->hbmImage);
969 hBrush = CreateSolidBrush (himlLocal->clrBk);
970 hOldBrush = SelectObject (pimldp->hdcDst, hBrush);
971 PatBlt (pimldp->hdcDst, pimldp->x, pimldp->y,
973 DeleteObject (SelectObject (pimldp->hdcDst, hOldBrush));
976 BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
977 hdcImageList, himlLocal->cx * pimldp->i, 0, SRCPAINT);
979 if (bBlend25 || bBlend50)
981 if (pimldp->rgbFg == CLR_DEFAULT)
982 clrBlend = GetSysColor (COLOR_HIGHLIGHT);
984 clrBlend = pimldp->rgbFg;
986 hdcTempImage = CreateCompatibleDC (0);
987 hbmTempImage = CreateBitmap (himlLocal->cx, himlLocal->cy,
988 1, himlLocal->uBitsPixel, NULL);
989 SelectObject (hdcTempImage, hbmTempImage);
993 SelectObject (hdcTempImage,
994 bBlend50 ? himlLocal->hbrBlend50 : himlLocal->hbrBlend25);
995 PatBlt (hdcTempImage, 0, 0, himlLocal->cx, himlLocal->cy, PATCOPY);
997 SelectObject (hdcImageList, himlLocal->hbmMask);
998 BitBlt (hdcTempImage, 0, 0, himlLocal->cx,
999 himlLocal->cy, hdcImageList,
1000 pimldp->i * himlLocal->cx, 0, SRCPAINT);
1002 BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
1003 hdcTempImage, 0, 0, SRCAND);
1006 hBrush = CreateSolidBrush (clrBlend);
1007 SelectObject (hdcTempImage, hBrush);
1008 PatBlt (hdcTempImage, 0, 0, himlLocal->cx, himlLocal->cy, PATCOPY);
1009 DeleteObject (hBrush);
1011 SelectObject (hdcTempImage,
1012 bBlend50 ? himlLocal->hbrBlend50 : himlLocal->hbrBlend25);
1013 PatBlt (hdcTempImage, 0, 0, himlLocal->cx, himlLocal->cy, 0x0A0329);
1015 SelectObject (hdcImageList, himlLocal->hbmMask);
1016 BitBlt (hdcTempImage, 0, 0, himlLocal->cx,
1017 himlLocal->cy, hdcImageList,
1018 pimldp->i * himlLocal->cx, 0, SRCPAINT);
1020 BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
1021 hdcTempImage, 0, 0, SRCPAINT);
1023 DeleteObject (hbmTempImage);
1024 DeleteDC (hdcTempImage);
1028 /* Draw overlay image */
1029 if (pimldp->fStyle & 0x0700) {
1030 nOvlIdx = (pimldp->fStyle & 0x0700) >> 8;
1031 if ((nOvlIdx >= 1) && (nOvlIdx <= MAX_OVERLAYIMAGE)) {
1032 nOvlIdx = pimldp->himl->nOvlIdx[nOvlIdx - 1];
1033 if ((nOvlIdx >= 0) && (nOvlIdx <= pimldp->himl->cCurImage)) {
1034 if (pimldp->himl->hbmMask) {
1035 SelectObject (hdcImageList, pimldp->himl->hbmMask);
1036 BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
1037 hdcImageList, pimldp->himl->cx * nOvlIdx, 0,
1040 SelectObject (hdcImageList, pimldp->himl->hbmImage);
1041 BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y,
1042 cx, cy, hdcImageList,
1043 pimldp->himl->cx * nOvlIdx, 0, SRCPAINT);
1048 DeleteDC (hdcImageList);
1054 /*************************************************************************
1055 * ImageList_Duplicate [COMCTL32.53] Duplicates an image list.
1058 * himlSrc [I] source image list handle
1061 * Success: Handle of duplicated image list.
1066 ImageList_Duplicate (HIMAGELIST himlSrc)
1071 if (himlSrc == NULL) {
1072 ERR("Invalid image list handle!\n");
1076 himlDst = ImageList_Create (himlSrc->cx, himlSrc->cy, himlSrc->flags,
1077 himlSrc->cInitial, himlSrc->cGrow);
1081 hdcSrc = CreateCompatibleDC (0);
1082 hdcDst = CreateCompatibleDC (0);
1083 SelectObject (hdcSrc, himlSrc->hbmImage);
1084 SelectObject (hdcDst, himlDst->hbmImage);
1085 BitBlt (hdcDst, 0, 0, himlSrc->cCurImage * himlSrc->cx, himlSrc->cy,
1086 hdcSrc, 0, 0, SRCCOPY);
1088 if (himlDst->hbmMask)
1090 SelectObject (hdcSrc, himlSrc->hbmMask);
1091 SelectObject (hdcDst, himlDst->hbmMask);
1092 BitBlt (hdcDst, 0, 0, himlSrc->cCurImage * himlSrc->cx,
1093 himlSrc->cy, hdcSrc, 0, 0, SRCCOPY);
1104 /*************************************************************************
1105 * ImageList_EndDrag [COMCTL32.54] Finishes a drag operation.
1107 * Finishes a drag operation.
1121 ImageList_EndDrag (void)
1123 FIXME("semi-stub!\n");
1125 if (himlInternalDrag)
1128 ImageList_Destroy (himlInternalDrag);
1129 himlInternalDrag = NULL;
1131 nInternalDragHotspotX = 0;
1132 nInternalDragHotspotY = 0;
1140 /*************************************************************************
1141 * ImageList_GetBkColor [COMCTL32.55]
1143 * Returns the background color of an image list.
1146 * himl [I] Image list handle.
1149 * Success: background color
1154 ImageList_GetBkColor (HIMAGELIST himl)
1163 /*************************************************************************
1164 * ImageList_GetDragImage [COMCTL32.56]
1166 * Returns the handle to the internal drag image list.
1169 * ppt [O] Pointer to the drag position. Can be NULL.
1170 * pptHotspot [O] Pointer to the position of the hot spot. Can be NULL.
1173 * Success: Handle of the drag image list.
1181 ImageList_GetDragImage (POINT *ppt, POINT *pptHotspot)
1183 FIXME("semi-stub!\n");
1185 if (himlInternalDrag)
1186 return (himlInternalDrag);
1192 /*************************************************************************
1193 * ImageList_GetIcon [COMCTL32.57]
1195 * Creates an icon from a masked image of an image list.
1198 * himl [I] handle to image list
1200 * flags [I] drawing style flags
1203 * Success: icon handle
1208 ImageList_GetIcon (HIMAGELIST himl, INT i, UINT fStyle)
1214 if ((himl == NULL) || (i < 0) || (i >= himl->cCurImage))
1217 hdcSrc = CreateCompatibleDC(0);
1218 hdcDst = CreateCompatibleDC(0);
1221 ii.hbmMask = CreateCompatibleBitmap (hdcDst, himl->cx, himl->cy);
1224 SelectObject (hdcDst, ii.hbmMask);
1225 if (himl->hbmMask) {
1226 SelectObject (hdcSrc, himl->hbmMask);
1227 BitBlt (hdcDst, 0, 0, himl->cx, himl->cy,
1228 hdcSrc, i * himl->cx, 0, SRCCOPY);
1231 PatBlt (hdcDst, 0, 0, himl->cx, himl->cy, BLACKNESS);
1234 SelectObject (hdcSrc, himl->hbmImage);
1235 ii.hbmColor = CreateCompatibleBitmap (hdcSrc, himl->cx, himl->cy);
1236 SelectObject (hdcDst, ii.hbmColor);
1237 BitBlt (hdcDst, 0, 0, himl->cx, himl->cy,
1238 hdcSrc, i * himl->cx, 0, SRCCOPY);
1240 hIcon = CreateIconIndirect (&ii);
1244 DeleteObject (ii.hbmMask);
1245 DeleteObject (ii.hbmColor);
1251 /*************************************************************************
1252 * ImageList_GetIconSize [COMCTL32.58]
1254 * Retrieves the size of an image in an image list.
1257 * himl [I] handle to image list
1258 * cx [O] pointer to the image width.
1259 * cy [O] pointer to the image height.
1266 * All images in an image list have the same size.
1270 ImageList_GetIconSize (HIMAGELIST himl, INT *cx, INT *cy)
1274 if ((himl->cx <= 0) || (himl->cy <= 0))
1286 /*************************************************************************
1287 * ImageList_GetImageCount [COMCTL32.59]
1289 * Returns the number of images in an image list.
1292 * himl [I] handle to image list
1295 * Success: Number of images.
1300 ImageList_GetImageCount (HIMAGELIST himl)
1305 return himl->cCurImage;
1309 /*************************************************************************
1310 * ImageList_GetImageInfo [COMCTL32.60]
1312 * Returns information about an image in an image list.
1315 * himl [I] handle to image list
1317 * pImageInfo [O] pointer to the image information
1325 ImageList_GetImageInfo (HIMAGELIST himl, INT i, IMAGEINFO *pImageInfo)
1327 if ((himl == NULL) || (pImageInfo == NULL))
1329 if ((i < 0) || (i >= himl->cCurImage))
1332 pImageInfo->hbmImage = himl->hbmImage;
1333 pImageInfo->hbmMask = himl->hbmMask;
1335 pImageInfo->rcImage.top = 0;
1336 pImageInfo->rcImage.bottom = himl->cy;
1337 pImageInfo->rcImage.left = i * himl->cx;
1338 pImageInfo->rcImage.right = (i+1) * himl->cx;
1344 /*************************************************************************
1345 * ImageList_GetImageRect [COMCTL32.61]
1347 * Retrieves the rectangle of the specified image in an image list.
1350 * himl [I] handle to image list
1352 * lpRect [O] pointer to the image rectangle
1359 * This is an UNDOCUMENTED function!!!
1363 ImageList_GetImageRect (HIMAGELIST himl, INT i, LPRECT lpRect)
1365 if ((himl == NULL) || (lpRect == NULL))
1367 if ((i < 0) || (i >= himl->cCurImage))
1370 lpRect->left = i * himl->cx;
1372 lpRect->right = lpRect->left + himl->cx;
1373 lpRect->bottom = himl->cy;
1379 /*************************************************************************
1380 * ImageList_LoadImage32A [COMCTL32.63][COMCTL32.62]
1382 * Creates an image list from a bitmap, icon or cursor.
1385 * hi [I] instance handle
1386 * lpbmp [I] name or id of the image
1387 * cx [I] width of each image
1388 * cGrow [I] number of images to expand
1389 * clrMask [I] mask color
1390 * uType [I] type of image to load
1391 * uFlags [I] loading flags
1394 * Success: handle to the loaded image list
1402 ImageList_LoadImageA (HINSTANCE hi, LPCSTR lpbmp, INT cx, INT cGrow,
1403 COLORREF clrMask, UINT uType, UINT uFlags)
1405 HIMAGELIST himl = NULL;
1409 handle = LoadImageA (hi, lpbmp, uType, 0, 0, uFlags);
1411 ERR("Error loading image!\n");
1415 if (uType == IMAGE_BITMAP) {
1417 GetObjectA (handle, sizeof(BITMAP), &bmp);
1419 /* To match windows behavior, if cx is set to zero and
1420 the flag DI_DEFAULTSIZE is specified, cx becomes the
1421 system metric value for icons. If the flag is not specified
1422 the function sets the size to the height of the bitmap */
1425 if (uFlags & DI_DEFAULTSIZE)
1426 cx = GetSystemMetrics (SM_CXICON);
1431 nImageCount = bmp.bmWidth / cx;
1433 himl = ImageList_Create (cx, bmp.bmHeight, ILC_MASK | ILC_COLOR,
1434 nImageCount, cGrow);
1435 ImageList_AddMasked (himl, (HBITMAP)handle, clrMask);
1437 else if ((uType == IMAGE_ICON) || (uType == IMAGE_CURSOR)) {
1441 GetIconInfo (handle, &ii);
1442 GetObjectA (ii.hbmColor, sizeof(BITMAP), (LPVOID)&bmp);
1443 himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight,
1444 ILC_MASK | ILC_COLOR, 1, cGrow);
1445 ImageList_Add (himl, ii.hbmColor, ii.hbmMask);
1446 DeleteObject (ii.hbmColor);
1447 DeleteObject (ii.hbmMask);
1450 DeleteObject (handle);
1456 /*************************************************************************
1457 * ImageList_LoadImage32W [COMCTL32.64]
1459 * Creates an image list from a bitmap, icon or cursor.
1462 * hi [I] instance handle
1463 * lpbmp [I] name or id of the image
1464 * cx [I] width of each image
1465 * cGrow [I] number of images to expand
1466 * clrMask [I] mask color
1467 * uType [I] type of image to load
1468 * uFlags [I] loading flags
1471 * Success: handle to the loaded image list
1479 ImageList_LoadImageW (HINSTANCE hi, LPCWSTR lpbmp, INT cx, INT cGrow,
1480 COLORREF clrMask, UINT uType, UINT uFlags)
1482 HIMAGELIST himl = NULL;
1486 handle = LoadImageW (hi, lpbmp, uType, 0, 0, uFlags);
1488 ERR("Error loading image!\n");
1492 if (uType == IMAGE_BITMAP) {
1494 GetObjectA (handle, sizeof(BITMAP), &bmp);
1495 nImageCount = bmp.bmWidth / cx;
1497 himl = ImageList_Create (cx, bmp.bmHeight, ILC_MASK | ILC_COLOR,
1498 nImageCount, cGrow);
1499 ImageList_AddMasked (himl, (HBITMAP)handle, clrMask);
1501 else if ((uType == IMAGE_ICON) || (uType == IMAGE_CURSOR)) {
1505 GetIconInfo (handle, &ii);
1506 GetObjectA (ii.hbmMask, sizeof(BITMAP), (LPVOID)&bmp);
1507 himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight,
1508 ILC_MASK | ILC_COLOR, 1, cGrow);
1509 ImageList_Add (himl, ii.hbmColor, ii.hbmMask);
1510 DeleteObject (ii.hbmColor);
1511 DeleteObject (ii.hbmMask);
1514 DeleteObject (handle);
1520 /*************************************************************************
1521 * ImageList_Merge [COMCTL32.65]
1523 * Creates a new image list that contains a merged image from the specified
1524 * images of both source image lists.
1527 * himl1 [I] handle to first image list
1528 * i1 [I] first image index
1529 * himl2 [I] handle to second image list
1530 * i2 [I] second image index
1531 * dx [I] X offset of the second image relative to the first.
1532 * dy [I] Y offset of the second image relative to the first.
1535 * Success: handle of the merged image list.
1540 ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2,
1543 HIMAGELIST himlDst = NULL;
1544 HDC hdcSrcImage, hdcDstImage;
1546 INT xOff1, yOff1, xOff2, yOff2;
1549 if ((himl1 == NULL) || (himl2 == NULL))
1553 if ((i1 < 0) || (i1 >= himl1->cCurImage)) {
1554 ERR("Index 1 out of range! %d\n", i1);
1558 if ((i2 < 0) || (i2 >= himl2->cCurImage)) {
1559 ERR("Index 2 out of range! %d\n", i2);
1564 cxDst = _MAX (himl1->cx, dx + himl2->cx);
1569 cxDst = _MAX (himl2->cx, himl1->cx - dx);
1574 cxDst = _MAX (himl1->cx, himl2->cx);
1580 cyDst = _MAX (himl1->cy, dy + himl2->cy);
1585 cyDst = _MAX (himl2->cy, himl1->cy - dy);
1590 cyDst = _MAX (himl1->cy, himl2->cy);
1595 himlDst = ImageList_Create (cxDst, cyDst, ILC_MASK | ILC_COLOR, 1, 1);
1598 hdcSrcImage = CreateCompatibleDC (0);
1599 hdcDstImage = CreateCompatibleDC (0);
1600 nX1 = i1 * himl1->cx;
1601 nX2 = i2 * himl2->cx;
1604 SelectObject (hdcSrcImage, himl1->hbmImage);
1605 SelectObject (hdcDstImage, himlDst->hbmImage);
1606 BitBlt (hdcDstImage, 0, 0, cxDst, cyDst,
1607 hdcSrcImage, 0, 0, BLACKNESS);
1608 BitBlt (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy,
1609 hdcSrcImage, nX1, 0, SRCCOPY);
1611 SelectObject (hdcSrcImage, himl2->hbmMask);
1612 BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
1613 hdcSrcImage, nX2, 0, SRCAND);
1615 SelectObject (hdcSrcImage, himl2->hbmImage);
1616 BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
1617 hdcSrcImage, nX2, 0, SRCPAINT);
1620 SelectObject (hdcSrcImage, himl1->hbmMask);
1621 SelectObject (hdcDstImage, himlDst->hbmMask);
1622 BitBlt (hdcDstImage, 0, 0, cxDst, cyDst,
1623 hdcSrcImage, 0, 0, WHITENESS);
1624 BitBlt (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy,
1625 hdcSrcImage, nX1, 0, SRCCOPY);
1627 SelectObject (hdcSrcImage, himl2->hbmMask);
1628 BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
1629 hdcSrcImage, nX2, 0, SRCAND);
1631 DeleteDC (hdcSrcImage);
1632 DeleteDC (hdcDstImage);
1639 /*************************************************************************
1640 * ImageList_Read [COMCTL32.66]
1642 * Reads an image list from a stream.
1645 * pstm [I] pointer to a stream
1648 * Success: handle to image list
1652 * This function can not be implemented yet, because
1653 * IStream32::Read is not implemented yet.
1659 HIMAGELIST WINAPI ImageList_Read (LPSTREAM pstm)
1661 FIXME("empty stub!\n");
1668 /*************************************************************************
1669 * ImageList_Remove [COMCTL32.67] Removes an image from an image list
1672 * himl [I] image list handle
1681 ImageList_Remove (HIMAGELIST himl, INT i)
1683 HBITMAP hbmNewImage, hbmNewMask;
1687 if ((i < -1) || (i >= himl->cCurImage)) {
1688 ERR("index out of range! %d\n", i);
1692 if (himl->cCurImage == 0) {
1693 ERR("image list is already empty!\n");
1699 TRACE("remove all!\n");
1701 himl->cMaxImage = himl->cInitial + himl->cGrow;
1702 himl->cCurImage = 0;
1703 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
1704 himl->nOvlIdx[nCount] = -1;
1706 DeleteObject (himl->hbmImage);
1708 CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
1709 1, himl->uBitsPixel, NULL);
1711 if (himl->hbmMask) {
1712 DeleteObject (himl->hbmMask);
1714 CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
1719 /* delete one image */
1720 TRACE("Remove single image! %d\n", i);
1722 /* create new bitmap(s) */
1723 cxNew = (himl->cCurImage + himl->cGrow - 1) * himl->cx;
1725 TRACE(" - Number of images: %d / %d (Old/New)\n",
1726 himl->cCurImage, himl->cCurImage - 1);
1727 TRACE(" - Max. number of images: %d / %d (Old/New)\n",
1728 himl->cMaxImage, himl->cCurImage + himl->cGrow - 1);
1731 CreateBitmap (cxNew, himl->cy, 1, himl->uBitsPixel, NULL);
1734 hbmNewMask = CreateBitmap (cxNew, himl->cy, 1, 1, NULL);
1736 hbmNewMask = 0; /* Just to keep compiler happy! */
1738 hdcSrc = CreateCompatibleDC (0);
1739 hdcDst = CreateCompatibleDC (0);
1741 /* copy all images and masks prior to the "removed" image */
1743 TRACE("Pre image copy: Copy %d images\n", i);
1745 SelectObject (hdcSrc, himl->hbmImage);
1746 SelectObject (hdcDst, hbmNewImage);
1747 BitBlt (hdcDst, 0, 0, i * himl->cx, himl->cy,
1748 hdcSrc, 0, 0, SRCCOPY);
1750 if (himl->hbmMask) {
1751 SelectObject (hdcSrc, himl->hbmMask);
1752 SelectObject (hdcDst, hbmNewMask);
1753 BitBlt (hdcDst, 0, 0, i * himl->cx, himl->cy,
1754 hdcSrc, 0, 0, SRCCOPY);
1758 /* copy all images and masks behind the removed image */
1759 if (i < himl->cCurImage - 1) {
1760 TRACE("Post image copy!\n");
1761 SelectObject (hdcSrc, himl->hbmImage);
1762 SelectObject (hdcDst, hbmNewImage);
1763 BitBlt (hdcDst, i * himl->cx, 0, (himl->cCurImage - i - 1) * himl->cx,
1764 himl->cy, hdcSrc, (i + 1) * himl->cx, 0, SRCCOPY);
1766 if (himl->hbmMask) {
1767 SelectObject (hdcSrc, himl->hbmMask);
1768 SelectObject (hdcDst, hbmNewMask);
1769 BitBlt (hdcDst, i * himl->cx, 0,
1770 (himl->cCurImage - i - 1) * himl->cx,
1771 himl->cy, hdcSrc, (i + 1) * himl->cx, 0, SRCCOPY);
1778 /* delete old images and insert new ones */
1779 DeleteObject (himl->hbmImage);
1780 himl->hbmImage = hbmNewImage;
1781 if (himl->hbmMask) {
1782 DeleteObject (himl->hbmMask);
1783 himl->hbmMask = hbmNewMask;
1787 himl->cMaxImage = himl->cCurImage + himl->cGrow;
1794 /*************************************************************************
1795 * ImageList_Replace [COMCTL32.68]
1797 * Replaces an image in an image list with a new image.
1800 * himl [I] handle to image list
1802 * hbmImage [I] handle to image bitmap
1803 * hbmMask [I] handle to mask bitmap. Can be NULL.
1811 ImageList_Replace (HIMAGELIST himl, INT i, HBITMAP hbmImage,
1814 HDC hdcImageList, hdcImage;
1818 ERR("Invalid image list handle!\n");
1822 if ((i >= himl->cCurImage) || (i < 0)) {
1823 ERR("Invalid image index!\n");
1827 hdcImageList = CreateCompatibleDC (0);
1828 hdcImage = CreateCompatibleDC (0);
1829 GetObjectA (hbmImage, sizeof(BITMAP), (LPVOID)&bmp);
1832 SelectObject (hdcImageList, himl->hbmImage);
1833 SelectObject (hdcImage, hbmImage);
1835 StretchBlt (hdcImageList, i * himl->cx, 0, himl->cx, himl->cy,
1836 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1841 SelectObject (hdcImageList, himl->hbmMask);
1842 SelectObject (hdcImage, hbmMask);
1844 StretchBlt (hdcImageList, i * himl->cx, 0, himl->cx, himl->cy,
1845 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1848 DeleteDC (hdcImage);
1849 DeleteDC (hdcImageList);
1855 /*************************************************************************
1856 * ImageList_ReplaceIcon [COMCTL32.69]
1858 * Replaces an image in an image list using an icon.
1861 * himl [I] handle to image list
1863 * hIcon [I] handle to icon
1866 * Success: index of the replaced image
1871 ImageList_ReplaceIcon (HIMAGELIST himl, INT i, HICON hIcon)
1873 HDC hdcImageList, hdcImage;
1875 HBITMAP hbmOldSrc, hbmOldDst;
1879 TRACE("(0x%lx 0x%x 0x%x)\n", (DWORD)himl, i, hIcon);
1883 if ((i >= himl->cCurImage) || (i < -1))
1886 GetIconInfo (hIcon, &ii);
1887 if (ii.hbmMask == 0)
1889 if (ii.hbmColor == 0)
1891 GetObjectA (ii.hbmMask, sizeof(BITMAP), (LPVOID)&bmp);
1894 if (himl->cCurImage + 1 >= himl->cMaxImage)
1895 IMAGELIST_InternalExpandBitmaps (himl, 1);
1897 nIndex = himl->cCurImage;
1903 hdcImageList = CreateCompatibleDC (0);
1904 TRACE("hdcImageList=0x%x!\n", hdcImageList);
1905 if (hdcImageList == 0)
1906 ERR("invalid hdcImageList!\n");
1908 hdcImage = CreateCompatibleDC (0);
1909 TRACE("hdcImage=0x%x!\n", hdcImage);
1911 ERR("invalid hdcImage!\n");
1913 hbmOldDst = SelectObject (hdcImageList, himl->hbmImage);
1914 SetTextColor( hdcImageList, RGB(0,0,0));
1915 SetBkColor( hdcImageList, RGB(255,255,255));
1916 hbmOldSrc = SelectObject (hdcImage, ii.hbmColor);
1917 StretchBlt (hdcImageList, nIndex * himl->cx, 0, himl->cx, himl->cy,
1918 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1920 if (himl->hbmMask) {
1921 SelectObject (hdcImageList, himl->hbmMask);
1922 SelectObject (hdcImage, ii.hbmMask);
1923 StretchBlt (hdcImageList, nIndex * himl->cx, 0, himl->cx, himl->cy,
1924 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1927 SelectObject (hdcImage, hbmOldSrc);
1928 SelectObject (hdcImageList, hbmOldDst);
1931 DeleteDC (hdcImageList);
1933 DeleteDC (hdcImage);
1935 DeleteObject (ii.hbmColor);
1937 DeleteObject (ii.hbmMask);
1943 /*************************************************************************
1944 * ImageList_SetBkColor [COMCTL32.70]
1946 * Sets the background color of an image list.
1949 * himl [I] handle to image list
1950 * clrBk [I] background color
1953 * Success: previous background color
1958 ImageList_SetBkColor (HIMAGELIST himl, COLORREF clrBk)
1965 clrOldBk = himl->clrBk;
1966 himl->clrBk = clrBk;
1971 /*************************************************************************
1972 * ImageList_SetDragCursorImage [COMCTL32.75]
1974 * Combines the specified image with the current drag image
1977 * himlDrag [I] handle to drag image list
1978 * iDrag [I] drag image index
1979 * dxHotspot [I] X position of the hot spot
1980 * dyHotspot [I] Y position of the hot spot
1991 ImageList_SetDragCursorImage (HIMAGELIST himlDrag, INT iDrag,
1992 INT dxHotspot, INT dyHotspot)
1994 HIMAGELIST himlTemp;
1996 FIXME("semi-stub!\n");
1998 if (himlInternalDrag == NULL)
2001 TRACE(" dxH=%d dyH=%d nX=%d nY=%d\n",
2002 dxHotspot, dyHotspot, nInternalDragHotspotX, nInternalDragHotspotY);
2004 himlTemp = ImageList_Merge (himlInternalDrag, 0, himlDrag, iDrag,
2005 dxHotspot, dyHotspot);
2007 ImageList_Destroy (himlInternalDrag);
2008 himlInternalDrag = himlTemp;
2010 nInternalDragHotspotX = dxHotspot;
2011 nInternalDragHotspotY = dyHotspot;
2017 /*************************************************************************
2018 * ImageList_SetFilter [COMCTL32.76]
2020 * Sets a filter (or does something completely different)!!???
2023 * himl [I] handle to image list
2029 * Failure: FALSE ???
2032 * This is an UNDOCUMENTED function!!!!
2037 ImageList_SetFilter (HIMAGELIST himl, INT i, DWORD dwFilter)
2039 FIXME("(%p 0x%x 0x%lx):empty stub!\n",
2046 /*************************************************************************
2047 * ImageList_SetIconSize [COMCTL32.77]
2049 * Sets the image size of the bitmap and deletes all images.
2052 * himl [I] handle to image list
2053 * cx [I] image width
2054 * cy [I] image height
2062 ImageList_SetIconSize (HIMAGELIST himl, INT cx, INT cy)
2069 /* remove all images*/
2070 himl->cMaxImage = himl->cInitial + himl->cGrow;
2071 himl->cCurImage = 0;
2075 /* initialize overlay mask indices */
2076 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
2077 himl->nOvlIdx[nCount] = -1;
2079 DeleteObject (himl->hbmImage);
2081 CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
2082 1, himl->uBitsPixel, NULL);
2084 if (himl->hbmMask) {
2085 DeleteObject (himl->hbmMask);
2087 CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
2095 /*************************************************************************
2096 * ImageList_SetImageCount [COMCTL32.78]
2098 * Resizes an image list to the specified number of images.
2101 * himl [I] handle to image list
2102 * iImageCount [I] number of images in the image list
2110 ImageList_SetImageCount (HIMAGELIST himl, INT iImageCount)
2112 HDC hdcImageList, hdcBitmap;
2113 HBITMAP hbmNewBitmap;
2114 INT nNewCount, nCopyCount;
2118 if (himl->cCurImage >= iImageCount)
2120 if (himl->cMaxImage > iImageCount)
2123 nNewCount = iImageCount + himl->cGrow;
2124 nCopyCount = _MIN(himl->cCurImage, iImageCount);
2126 hdcImageList = CreateCompatibleDC (0);
2127 hdcBitmap = CreateCompatibleDC (0);
2129 hbmNewBitmap = CreateBitmap (nNewCount * himl->cx, himl->cy,
2130 1, himl->uBitsPixel, NULL);
2131 if (hbmNewBitmap != 0)
2133 SelectObject (hdcImageList, himl->hbmImage);
2134 SelectObject (hdcBitmap, hbmNewBitmap);
2137 BitBlt (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
2138 hdcImageList, 0, 0, SRCCOPY);
2140 /* delete 'empty' image space */
2141 SetBkColor (hdcBitmap, RGB(255, 255, 255));
2142 SetTextColor (hdcBitmap, RGB(0, 0, 0));
2143 PatBlt (hdcBitmap, nCopyCount * himl->cx, 0,
2144 (nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS);
2146 DeleteObject (himl->hbmImage);
2147 himl->hbmImage = hbmNewBitmap;
2150 ERR("Could not create new image bitmap !\n");
2154 hbmNewBitmap = CreateBitmap (nNewCount * himl->cx, himl->cy,
2156 if (hbmNewBitmap != 0)
2158 SelectObject (hdcImageList, himl->hbmMask);
2159 SelectObject (hdcBitmap, hbmNewBitmap);
2162 BitBlt (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
2163 hdcImageList, 0, 0, SRCCOPY);
2165 /* delete 'empty' image space */
2166 SetBkColor (hdcBitmap, RGB(255, 255, 255));
2167 SetTextColor (hdcBitmap, RGB(0, 0, 0));
2168 PatBlt (hdcBitmap, nCopyCount * himl->cx, 0,
2169 (nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS);
2171 DeleteObject (himl->hbmMask);
2172 himl->hbmMask = hbmNewBitmap;
2175 ERR("Could not create new mask bitmap!\n");
2178 DeleteDC (hdcImageList);
2179 DeleteDC (hdcBitmap);
2181 /* Update max image count and current image count */
2182 himl->cMaxImage = nNewCount;
2183 if (himl->cCurImage > nCopyCount)
2184 himl->cCurImage = nCopyCount;
2190 /*************************************************************************
2191 * ImageList_SetOverlayImage [COMCTL32.79]
2193 * Assigns an overlay mask index to an existing image in an image list.
2196 * himl [I] handle to image list
2197 * iImage [I] image index
2198 * iOverlay [I] overlay mask index
2206 ImageList_SetOverlayImage (HIMAGELIST himl, INT iImage, INT iOverlay)
2210 if ((iOverlay < 1) || (iOverlay > MAX_OVERLAYIMAGE))
2212 if ((iImage < 0) || (iImage > himl->cCurImage))
2215 himl->nOvlIdx[iOverlay - 1] = iImage;
2220 /*************************************************************************
2221 * ImageList_Write [COMCTL32.80]
2223 * Writes an image list to a stream.
2226 * himl [I] handle to image list
2227 * pstm [O] Pointer to a stream.
2234 * This function can not be implemented yet, because
2235 * IStream32::Write is not implemented.
2242 ImageList_Write (HIMAGELIST himl, LPSTREAM pstm)
2247 FIXME("empty stub!\n");