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
34 #include "wine/obj_base.h"
35 #include "wine/obj_storage.h"
36 #include "imagelist.h"
41 #define _MAX(a,b) (((a)>(b))?(a):(b))
42 #define _MIN(a,b) (((a)>(b))?(b):(a))
44 #define MAX_OVERLAYIMAGE 15
47 /* internal image list data used for Drag & Drop operations */
49 static HIMAGELIST himlInternalDrag = NULL;
50 static INT32 nInternalDragHotspotX = 0;
51 static INT32 nInternalDragHotspotY = 0;
53 static HWND32 hwndInternalDrag = 0;
54 static INT32 xInternalPos = 0;
55 static INT32 yInternalPos = 0;
57 static HDC32 hdcBackBuffer = 0;
58 static HBITMAP32 hbmBackBuffer = 0;
61 /*************************************************************************
62 * IMAGELIST_InternalExpandBitmaps [Internal]
64 * Expands the bitmaps of an image list by the given number of images.
67 * himl [I] handle to image list
68 * nImageCount [I] number of images to add
74 * This function can NOT be used to reduce the number of images.
78 IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl, INT32 nImageCount)
80 HDC32 hdcImageList, hdcBitmap;
81 HBITMAP32 hbmNewBitmap;
82 INT32 nNewWidth, nNewCount;
84 TRACE(imagelist, "Create expanded bitmaps!\n");
86 nNewCount = himl->cCurImage + nImageCount + himl->cGrow;
87 nNewWidth = nNewCount * himl->cx;
89 hdcImageList = CreateCompatibleDC32 (0);
90 hdcBitmap = CreateCompatibleDC32 (0);
93 CreateBitmap32 (nNewWidth, himl->cy, 1, himl->uBitsPixel, NULL);
94 if (hbmNewBitmap == 0)
95 ERR (imagelist, "creating new image bitmap!\n");
97 SelectObject32 (hdcImageList, himl->hbmImage);
98 SelectObject32 (hdcBitmap, hbmNewBitmap);
99 BitBlt32 (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, himl->cy,
100 hdcImageList, 0, 0, SRCCOPY);
102 DeleteObject32 (himl->hbmImage);
103 himl->hbmImage = hbmNewBitmap;
107 CreateBitmap32 (nNewWidth, himl->cy, 1, 1, NULL);
109 if (hbmNewBitmap == 0)
110 ERR (imagelist, "creating new mask bitmap!");
112 SelectObject32 (hdcImageList, himl->hbmMask);
113 SelectObject32 (hdcBitmap, hbmNewBitmap);
114 BitBlt32 (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, himl->cy,
115 hdcImageList, 0, 0, SRCCOPY);
116 DeleteObject32 (himl->hbmMask);
117 himl->hbmMask = hbmNewBitmap;
120 himl->cMaxImage = nNewCount;
122 DeleteDC32 (hdcImageList);
123 DeleteDC32 (hdcBitmap);
127 /*************************************************************************
128 * ImageList_Add [COMCTL32.39]
130 * Add an image or images to an image list.
133 * himl [I] handle to image list
134 * hbmImage [I] handle to image bitmap
135 * hbmMask [I] handle to mask bitmap
138 * Success: Index of the first new image.
143 ImageList_Add (HIMAGELIST himl, HBITMAP32 hbmImage, HBITMAP32 hbmMask)
145 HDC32 hdcSrc, hdcDst;
146 INT32 nFirstIndex, nImageCount;
150 if (!himl || !hbmImage)
153 GetObject32A (hbmImage, sizeof(BITMAP32), (LPVOID)&bmp);
154 nImageCount = bmp.bmWidth / himl->cx;
156 if (himl->cCurImage + nImageCount >= himl->cMaxImage)
157 IMAGELIST_InternalExpandBitmaps (himl, nImageCount);
159 nStartX = himl->cCurImage * himl->cx;
161 hdcSrc = CreateCompatibleDC32 (0);
162 hdcDst = CreateCompatibleDC32 (0);
164 /* copy image bitmap */
165 SelectObject32 (hdcDst, himl->hbmImage);
166 SelectObject32 (hdcSrc, hbmImage);
167 BitBlt32 (hdcDst, himl->cCurImage * himl->cx, 0,
168 bmp.bmWidth, himl->cy, hdcSrc, 0, 0, SRCCOPY);
172 /* copy mask bitmap */
173 SelectObject32 (hdcDst, himl->hbmMask);
174 SelectObject32 (hdcSrc, hbmMask);
175 BitBlt32 (hdcDst, nStartX, 0, bmp.bmWidth, himl->cy,
176 hdcSrc, 0, 0, SRCCOPY);
179 /* copy monochrome image to the mask bitmap */
180 SelectObject32 (hdcDst, himl->hbmMask);
181 SelectObject32 (hdcSrc, hbmImage);
182 SetBkColor32 (hdcSrc, GetNearestColor32 (hdcSrc,
183 GetPixel32 (hdcSrc, 0, 0)));
184 BitBlt32 (hdcDst, nStartX, 0, bmp.bmWidth, himl->cy,
185 hdcSrc, nStartX, 0, SRCCOPY);
192 nFirstIndex = himl->cCurImage;
193 himl->cCurImage += nImageCount;
199 /*************************************************************************
200 * ImageList_AddIcon [COMCTL32.40]
202 * Adds an icon to an image list.
205 * himl [I] handle to image list
206 * hIcon [I] handle to icon
209 * Success: index of the new image
214 ImageList_AddIcon (HIMAGELIST himl, HICON32 hIcon)
216 return ImageList_ReplaceIcon (himl, -1, hIcon);
220 /*************************************************************************
221 * ImageList_AddMasked [COMCTL32.41]
223 * Adds an image or images to an image list and creates a mask from the
224 * specified bitmap using the mask color.
227 * himl [I] handle to image list.
228 * hBitmap [I] handle to bitmap
229 * clrMask [I] mask color.
232 * Success: Index of the first new image.
237 ImageList_AddMasked (HIMAGELIST himl, HBITMAP32 hBitmap, COLORREF clrMask)
239 HDC32 hdcImage, hdcMask, hdcBitmap;
240 INT32 nIndex, nImageCount;
246 if (!GetObject32A (hBitmap, sizeof(BITMAP32), &bmp))
249 nImageCount = bmp.bmWidth / himl->cx;
251 if (himl->cCurImage + nImageCount >= himl->cMaxImage)
252 IMAGELIST_InternalExpandBitmaps (himl, nImageCount);
254 nIndex = himl->cCurImage;
255 himl->cCurImage += nImageCount;
257 hdcImage = CreateCompatibleDC32 (0);
258 hdcBitmap = CreateCompatibleDC32 (0);
260 SelectObject32 (hdcBitmap, hBitmap);
261 SelectObject32 (hdcImage, himl->hbmImage);
262 BitBlt32 (hdcImage, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy,
263 hdcBitmap, 0, 0, SRCCOPY);
266 COLORREF bkColor = (clrMask != CLR_DEFAULT) ? clrMask :
267 GetNearestColor32 (hdcBitmap, GetPixel32 (hdcBitmap, 0, 0));
269 /* create mask from image */
270 hdcMask = CreateCompatibleDC32 (0);
271 SelectObject32 (hdcMask, himl->hbmMask);
273 /* create monochrome image to the mask bitmap */
274 SetBkColor32 (hdcBitmap, bkColor);
275 BitBlt32 (hdcMask, nIndex * himl->cx, 0, bmp.bmWidth, himl->cy,
276 hdcBitmap, 0, 0, SRCCOPY);
278 DeleteDC32 (hdcMask);
281 DeleteDC32 (hdcImage);
282 DeleteDC32 (hdcBitmap);
288 /*************************************************************************
289 * ImageList_BeginDrag [COMCTL32.42]
291 * Creates a temporary image list that contains one image. It will be used
295 * himlTrack [I] handle to the source image list
296 * iTrack [I] index of the drag image in the source image list
297 * dxHotspot [I] X position of the hot spot of the drag image
298 * dyHotspot [I] Y position of the hot spot of the drag image
306 ImageList_BeginDrag (HIMAGELIST himlTrack, INT32 iTrack,
307 INT32 dxHotspot, INT32 dyHotspot)
309 HDC32 hdcSrc, hdcDst;
311 FIXME(imagelist, "partially implemented!\n");
313 if (himlTrack == NULL)
316 if (himlInternalDrag)
317 ImageList_EndDrag ();
320 ImageList_Create (himlTrack->cx, himlTrack->cy,
321 himlTrack->flags, 1, 1);
322 if (himlInternalDrag == NULL) {
323 ERR(imagelist, "Error creating drag image list!\n");
327 nInternalDragHotspotX = dxHotspot;
328 nInternalDragHotspotY = dyHotspot;
330 hdcSrc = CreateCompatibleDC32 (0);
331 hdcDst = CreateCompatibleDC32 (0);
334 SelectObject32 (hdcSrc, himlTrack->hbmImage);
335 SelectObject32 (hdcDst, himlInternalDrag->hbmImage);
336 StretchBlt32 (hdcDst, 0, 0, himlInternalDrag->cx, himlInternalDrag->cy, hdcSrc,
337 iTrack * himlTrack->cx, 0, himlTrack->cx, himlTrack->cy, SRCCOPY);
340 SelectObject32 (hdcSrc, himlTrack->hbmMask);
341 SelectObject32 (hdcDst, himlInternalDrag->hbmMask);
342 StretchBlt32 (hdcDst, 0, 0, himlInternalDrag->cx, himlInternalDrag->cy, hdcSrc,
343 iTrack * himlTrack->cx, 0, himlTrack->cx, himlTrack->cy, SRCCOPY);
348 himlInternalDrag->cCurImage = 1;
354 /*************************************************************************
355 * ImageList_Copy [COMCTL32.43]
357 * Copies an image of the source image list to an image of the
358 * destination image list. Images can be copied or swapped.
361 * himlDst [I] handle to the destination image list
362 * iDst [I] destination image index.
363 * himlSrc [I] handle to the source image list
364 * iSrc [I] source image index
365 * uFlags [I] flags for the copy operation
372 * Copying from one image list to another is possible. The original
373 * implementation just copies or swapps within one image list.
374 * Could this feature become a bug??? ;-)
378 ImageList_Copy (HIMAGELIST himlDst, INT32 iDst, HIMAGELIST himlSrc,
379 INT32 iSrc, INT32 uFlags)
381 HDC32 hdcSrc, hdcDst;
383 TRACE(imagelist, "iDst=%d iSrc=%d\n", iDst, iSrc);
385 if ((himlSrc == NULL) || (himlDst == NULL))
387 if ((iDst < 0) || (iDst >= himlDst->cCurImage))
389 if ((iSrc < 0) || (iSrc >= himlSrc->cCurImage))
392 hdcSrc = CreateCompatibleDC32 (0);
393 if (himlDst == himlSrc)
396 hdcDst = CreateCompatibleDC32 (0);
398 if (uFlags & ILCF_SWAP) {
400 HBITMAP32 hbmTempImage, hbmTempMask;
402 /* create temporary bitmaps */
403 hbmTempImage = CreateBitmap32 (himlSrc->cx, himlSrc->cy, 1,
404 himlSrc->uBitsPixel, NULL);
405 hbmTempMask = CreateBitmap32 (himlSrc->cx, himlSrc->cy, 1,
408 /* copy (and stretch) destination to temporary bitmaps.(save) */
410 SelectObject32 (hdcSrc, himlDst->hbmImage);
411 SelectObject32 (hdcDst, hbmTempImage);
412 StretchBlt32 (hdcDst, 0, 0, himlSrc->cx, himlSrc->cy,
413 hdcSrc, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
416 SelectObject32 (hdcSrc, himlDst->hbmMask);
417 SelectObject32 (hdcDst, hbmTempMask);
418 StretchBlt32 (hdcDst, 0, 0, himlSrc->cx, himlSrc->cy,
419 hdcSrc, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
422 /* copy (and stretch) source to destination */
424 SelectObject32 (hdcSrc, himlSrc->hbmImage);
425 SelectObject32 (hdcDst, himlDst->hbmImage);
426 StretchBlt32 (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
427 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
430 SelectObject32 (hdcSrc, himlSrc->hbmMask);
431 SelectObject32 (hdcDst, himlDst->hbmMask);
432 StretchBlt32 (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
433 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
436 /* copy (without stretching) temporary bitmaps to source (restore) */
438 SelectObject32 (hdcSrc, hbmTempImage);
439 SelectObject32 (hdcDst, himlSrc->hbmImage);
440 BitBlt32 (hdcDst, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
441 hdcSrc, 0, 0, SRCCOPY);
443 SelectObject32 (hdcSrc, hbmTempMask);
444 SelectObject32 (hdcDst, himlSrc->hbmMask);
445 BitBlt32 (hdcDst, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
446 hdcSrc, 0, 0, SRCCOPY);
448 /* delete temporary bitmaps */
449 DeleteObject32 (hbmTempMask);
450 DeleteObject32 (hbmTempImage);
454 SelectObject32 (hdcSrc, himlSrc->hbmImage);
455 if (himlSrc == himlDst)
458 SelectObject32 (hdcDst, himlDst->hbmImage);
459 StretchBlt32 (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
460 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
464 SelectObject32 (hdcSrc, himlSrc->hbmMask);
465 if (himlSrc == himlDst)
468 SelectObject32 (hdcDst, himlDst->hbmMask);
469 StretchBlt32 (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
470 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
475 if (himlSrc != himlDst)
482 /*************************************************************************
483 * ImageList_Create [COMCTL32.44] Creates a new image list.
486 * cx [I] image height
488 * flags [I] creation flags
489 * cInitial [I] initial number of images in the image list
490 * cGrow [I] number of images by which image list grows
493 * Success: Handle to the created image list
498 ImageList_Create (INT32 cx, INT32 cy, UINT32 flags,
499 INT32 cInitial, INT32 cGrow)
505 static WORD aBitBlend25[] =
506 {0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00};
508 static WORD aBitBlend50[] =
509 {0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA};
511 TRACE (imagelist, "(%d %d 0x%x %d %d)\n", cx, cy, flags, cInitial, cGrow);
513 himl = (HIMAGELIST)COMCTL32_Alloc (sizeof(struct _IMAGELIST));
520 himl->cMaxImage = cInitial + cGrow;
521 himl->cInitial = cInitial;
524 himl->clrFg = CLR_DEFAULT;
525 himl->clrBk = CLR_NONE;
527 /* initialize overlay mask indices */
528 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
529 himl->nOvlIdx[nCount] = -1;
531 hdc = CreateCompatibleDC32 (0);
532 himl->uBitsPixel = (UINT32)GetDeviceCaps32 (hdc, BITSPIXEL);
535 TRACE(imagelist, "Image: %d Bits per Pixel\n", himl->uBitsPixel);
538 CreateBitmap32 (himl->cx * himl->cMaxImage, himl->cy,
539 1, himl->uBitsPixel, NULL);
540 if (himl->hbmImage == 0) {
541 ERR(imagelist, "Error creating image bitmap!\n");
545 if (himl->flags & ILC_MASK) {
546 himl->hbmMask = CreateBitmap32 (himl->cx * himl->cMaxImage, himl->cy,
548 if (himl->hbmMask == 0) {
549 ERR(imagelist, "Error creating mask bitmap!\n");
551 DeleteObject32 (himl->hbmImage);
558 /* create blending brushes */
559 hbmTemp = CreateBitmap32 (8, 8, 1, 1, &aBitBlend25);
560 himl->hbrBlend25 = CreatePatternBrush32 (hbmTemp);
561 DeleteObject32 (hbmTemp);
563 hbmTemp = CreateBitmap32 (8, 8, 1, 1, &aBitBlend50);
564 himl->hbrBlend50 = CreatePatternBrush32 (hbmTemp);
565 DeleteObject32 (hbmTemp);
571 /*************************************************************************
572 * ImageList_Destroy [COMCTL32.45]
574 * Destroys an image list.
577 * himl [I] handle to image list
585 ImageList_Destroy (HIMAGELIST himl)
590 /* delete image bitmaps */
592 DeleteObject32 (himl->hbmImage);
594 DeleteObject32 (himl->hbmMask);
596 /* delete blending brushes */
597 if (himl->hbrBlend25)
598 DeleteObject32 (himl->hbrBlend25);
599 if (himl->hbrBlend50)
600 DeleteObject32 (himl->hbrBlend50);
602 COMCTL32_Free (himl);
608 /*************************************************************************
609 * ImageList_DragEnter [COMCTL32.46]
611 * Locks window update and displays the drag image at the given position.
614 * hwndLock [I] handle of the window that owns the drag image.
615 * x [I] X position of the drag image.
616 * y [I] Y position of the drag image.
623 * The position of the drag image is relative to the window, not
628 ImageList_DragEnter (HWND32 hwndLock, INT32 x, INT32 y)
630 if (himlInternalDrag == NULL)
634 hwndInternalDrag = hwndLock;
636 hwndInternalDrag = GetDesktopWindow32 ();
641 hdcBackBuffer = CreateCompatibleDC32 (0);
642 hbmBackBuffer = CreateCompatibleBitmap32 (hdcBackBuffer,
643 himlInternalDrag->cx, himlInternalDrag->cy);
645 ImageList_DragShowNolock (TRUE);
651 /*************************************************************************
652 * ImageList_DragLeave [COMCTL32.47]
654 * Unlocks window update and hides the drag image.
657 * hwndLock [I] handle of the window that owns the drag image.
665 ImageList_DragLeave (HWND32 hwndLock)
668 hwndInternalDrag = hwndLock;
670 hwndInternalDrag = GetDesktopWindow32 ();
672 ImageList_DragShowNolock (FALSE);
674 DeleteDC32 (hdcBackBuffer);
675 DeleteObject32 (hbmBackBuffer);
681 /*************************************************************************
682 * ImageList_DragMove [COMCTL32.48]
684 * Moves the drag image.
687 * x [I] X position of the drag image.
688 * y [I] Y position of the drag image.
695 * The position of the drag image is relative to the window, not
700 ImageList_DragMove (INT32 x, INT32 y)
702 ImageList_DragShowNolock (FALSE);
707 ImageList_DragShowNolock (TRUE);
713 /*************************************************************************
714 * ImageList_DragShowNolock [COMCTL32.49]
716 * Shows or hides the drag image.
719 * bShow [I] TRUE shows the drag image, FALSE hides it.
730 ImageList_DragShowNolock (BOOL32 bShow)
734 FIXME (imagelist, "semi-stub!\n");
735 TRACE (imagelist, "bShow=0x%X!\n", bShow);
737 hdcDrag = GetDCEx32 (hwndInternalDrag, 0,
738 DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
741 /* show drag image */
743 /* save background */
745 /* draw drag image */
749 /* hide drag image */
751 /* restore background */
755 ReleaseDC32 (hwndInternalDrag, hdcDrag);
761 /*************************************************************************
762 * ImageList_Draw [COMCTL32.50] Draws an image.
765 * himl [I] handle to image list
767 * hdc [I] handle to device context
770 * fStyle [I] drawing flags
777 * Calls ImageList_DrawIndirect.
780 * ImageList_DrawIndirect.
784 ImageList_Draw (HIMAGELIST himl, INT32 i, HDC32 hdc,
785 INT32 x, INT32 y, UINT32 fStyle)
787 IMAGELISTDRAWPARAMS imldp;
789 imldp.cbSize = sizeof(IMAGELISTDRAWPARAMS);
799 imldp.rgbBk = CLR_DEFAULT;
800 imldp.rgbFg = CLR_DEFAULT;
801 imldp.fStyle = fStyle;
804 return ImageList_DrawIndirect (&imldp);
808 /*************************************************************************
809 * ImageList_DrawEx [COMCTL32.51]
811 * Draws an image and allows to use extended drawing features.
814 * himl [I] handle to image list
816 * hdc [I] handle to device context
821 * rgbBk [I] background color
822 * rgbFg [I] foreground color
823 * fStyle [I] drawing flags
830 * Calls ImageList_DrawIndirect.
833 * ImageList_DrawIndirect.
837 ImageList_DrawEx (HIMAGELIST himl, INT32 i, HDC32 hdc, INT32 x, INT32 y,
838 INT32 dx, INT32 dy, COLORREF rgbBk, COLORREF rgbFg,
841 IMAGELISTDRAWPARAMS imldp;
843 imldp.cbSize = sizeof(IMAGELISTDRAWPARAMS);
855 imldp.fStyle = fStyle;
858 return ImageList_DrawIndirect (&imldp);
862 /*************************************************************************
863 * ImageList_DrawIndirect [COMCTL32.52]
865 * Draws an image using ...
868 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
876 ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
878 HIMAGELIST himlLocal;
879 HDC32 hdcImageList, hdcTempImage;
880 HBITMAP32 hbmTempImage;
881 HBRUSH32 hBrush, hOldBrush;
885 BOOL32 bImage; /* draw image ? */
886 BOOL32 bImageTrans; /* draw image transparent ? */
887 BOOL32 bMask; /* draw mask ? */
888 BOOL32 bMaskTrans; /* draw mask transparent ? */
894 if (pimldp->cbSize < sizeof(IMAGELISTDRAWPARAMS))
896 if (pimldp->himl == NULL)
898 if ((pimldp->i < 0) || (pimldp->i >= pimldp->himl->cCurImage))
901 himlLocal = pimldp->himl;
903 cx = (pimldp->cx == 0) ? himlLocal->cx : pimldp->cx;
904 cy = (pimldp->cy == 0) ? himlLocal->cy : pimldp->cy;
906 /* ILD_NORMAL state */
913 if ((himlLocal->clrBk == CLR_NONE) && (himlLocal->hbmMask))
920 /* ILD_IMAGE state (changes) */
921 if (pimldp->fStyle & ILD_IMAGE)
928 /* ILD_MASK state (changes) */
929 if ((pimldp->fStyle & ILD_MASK) && (himlLocal->hbmMask))
935 if ((pimldp->fStyle & ILD_TRANSPARENT) && (himlLocal->hbmMask))
940 if ((himlLocal->clrBk == CLR_NONE) && (himlLocal->hbmMask))
943 if (pimldp->fStyle & ILD_BLEND50)
945 else if (pimldp->fStyle & ILD_BLEND25)
948 hdcImageList = CreateCompatibleDC32 (0);
953 SelectObject32 (hdcImageList, himlLocal->hbmMask);
954 SetBkColor32 (hdcImageList, RGB(255, 255, 255));
955 SetTextColor32 (hdcImageList, RGB(0, 0, 0));
956 BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
957 hdcImageList, himlLocal->cx * pimldp->i, 0,
958 bMaskTrans ? SRCAND : SRCCOPY);
964 SelectObject32 (hdcImageList, himlLocal->hbmImage);
968 hBrush = CreateSolidBrush32 (himlLocal->clrBk);
969 hOldBrush = SelectObject32 (pimldp->hdcDst, hBrush);
970 PatBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y,
972 DeleteObject32 (SelectObject32 (pimldp->hdcDst, hOldBrush));
975 BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
976 hdcImageList, himlLocal->cx * pimldp->i, 0, SRCPAINT);
978 if (bBlend25 || bBlend50)
980 if (pimldp->rgbFg == CLR_DEFAULT)
981 clrBlend = GetSysColor32 (COLOR_HIGHLIGHT);
983 clrBlend = pimldp->rgbFg;
985 hdcTempImage = CreateCompatibleDC32 (0);
986 hbmTempImage = CreateBitmap32 (himlLocal->cx, himlLocal->cy,
987 1, himlLocal->uBitsPixel, NULL);
988 SelectObject32 (hdcTempImage, hbmTempImage);
992 SelectObject32 (hdcTempImage,
993 bBlend50 ? himlLocal->hbrBlend50 : himlLocal->hbrBlend25);
994 PatBlt32 (hdcTempImage, 0, 0, himlLocal->cx, himlLocal->cy, PATCOPY);
996 SelectObject32 (hdcImageList, himlLocal->hbmMask);
997 BitBlt32 (hdcTempImage, 0, 0, himlLocal->cx,
998 himlLocal->cy, hdcImageList,
999 pimldp->i * himlLocal->cx, 0, SRCPAINT);
1001 BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
1002 hdcTempImage, 0, 0, SRCAND);
1005 hBrush = CreateSolidBrush32 (clrBlend);
1006 SelectObject32 (hdcTempImage, hBrush);
1007 PatBlt32 (hdcTempImage, 0, 0, himlLocal->cx, himlLocal->cy, PATCOPY);
1008 DeleteObject32 (hBrush);
1010 SelectObject32 (hdcTempImage,
1011 bBlend50 ? himlLocal->hbrBlend50 : himlLocal->hbrBlend25);
1012 PatBlt32 (hdcTempImage, 0, 0, himlLocal->cx, himlLocal->cy, 0x0A0329);
1014 SelectObject32 (hdcImageList, himlLocal->hbmMask);
1015 BitBlt32 (hdcTempImage, 0, 0, himlLocal->cx,
1016 himlLocal->cy, hdcImageList,
1017 pimldp->i * himlLocal->cx, 0, SRCPAINT);
1019 BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
1020 hdcTempImage, 0, 0, SRCPAINT);
1022 DeleteObject32 (hbmTempImage);
1023 DeleteDC32 (hdcTempImage);
1027 /* Draw overlay image */
1028 if (pimldp->fStyle & 0x0700) {
1029 nOvlIdx = (pimldp->fStyle & 0x0700) >> 8;
1030 if ((nOvlIdx >= 1) && (nOvlIdx <= MAX_OVERLAYIMAGE)) {
1031 nOvlIdx = pimldp->himl->nOvlIdx[nOvlIdx - 1];
1032 if ((nOvlIdx >= 0) && (nOvlIdx <= pimldp->himl->cCurImage)) {
1033 if (pimldp->himl->hbmMask) {
1034 SelectObject32 (hdcImageList, pimldp->himl->hbmMask);
1035 BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy,
1036 hdcImageList, pimldp->himl->cx * nOvlIdx, 0,
1039 SelectObject32 (hdcImageList, pimldp->himl->hbmImage);
1040 BitBlt32 (pimldp->hdcDst, pimldp->x, pimldp->y,
1041 cx, cy, hdcImageList,
1042 pimldp->himl->cx * nOvlIdx, 0, SRCPAINT);
1047 DeleteDC32 (hdcImageList);
1053 /*************************************************************************
1054 * ImageList_Duplicate [COMCTL32.53] Duplicates an image list.
1057 * himlSrc [I] source image list handle
1060 * Success: Handle of duplicated image list.
1065 ImageList_Duplicate (HIMAGELIST himlSrc)
1068 HDC32 hdcSrc, hdcDst;
1070 if (himlSrc == NULL) {
1071 ERR (imagelist, "Invalid image list handle!\n");
1075 himlDst = ImageList_Create (himlSrc->cx, himlSrc->cy, himlSrc->flags,
1076 himlSrc->cInitial, himlSrc->cGrow);
1080 hdcSrc = CreateCompatibleDC32 (0);
1081 hdcDst = CreateCompatibleDC32 (0);
1082 SelectObject32 (hdcSrc, himlSrc->hbmImage);
1083 SelectObject32 (hdcDst, himlDst->hbmImage);
1084 BitBlt32 (hdcDst, 0, 0, himlSrc->cCurImage * himlSrc->cx, himlSrc->cy,
1085 hdcSrc, 0, 0, SRCCOPY);
1087 if (himlDst->hbmMask)
1089 SelectObject32 (hdcSrc, himlSrc->hbmMask);
1090 SelectObject32 (hdcDst, himlDst->hbmMask);
1091 BitBlt32 (hdcDst, 0, 0, himlSrc->cCurImage * himlSrc->cx,
1092 himlSrc->cy, hdcSrc, 0, 0, SRCCOPY);
1095 DeleteDC32 (hdcDst);
1096 DeleteDC32 (hdcSrc);
1103 /*************************************************************************
1104 * ImageList_EndDrag [COMCTL32.54] Finishes a drag operation.
1106 * Finishes a drag operation.
1120 ImageList_EndDrag (VOID)
1122 FIXME (imagelist, "semi-stub!\n");
1124 if (himlInternalDrag)
1127 ImageList_Destroy (himlInternalDrag);
1128 himlInternalDrag = NULL;
1130 nInternalDragHotspotX = 0;
1131 nInternalDragHotspotY = 0;
1139 /*************************************************************************
1140 * ImageList_GetBkColor [COMCTL32.55]
1142 * Returns the background color of an image list.
1145 * himl [I] Image list handle.
1148 * Success: background color
1153 ImageList_GetBkColor (HIMAGELIST himl)
1162 /*************************************************************************
1163 * ImageList_GetDragImage [COMCTL32.56]
1165 * Returns the handle to the internal drag image list.
1168 * ppt [O] Pointer to the drag position. Can be NULL.
1169 * pptHotspot [O] Pointer to the position of the hot spot. Can be NULL.
1172 * Success: Handle of the drag image list.
1180 ImageList_GetDragImage (POINT32 *ppt, POINT32 *pptHotspot)
1182 FIXME (imagelist, "semi-stub!\n");
1184 if (himlInternalDrag)
1185 return (himlInternalDrag);
1191 /*************************************************************************
1192 * ImageList_GetIcon [COMCTL32.57]
1194 * Creates an icon from a masked image of an image list.
1197 * himl [I] handle to image list
1199 * flags [I] drawing style flags
1202 * Success: icon handle
1207 ImageList_GetIcon (HIMAGELIST himl, INT32 i, UINT32 fStyle)
1211 HDC32 hdcSrc, hdcDst;
1212 INT32 nWidth, nHeight;
1214 if ((himl == NULL) || (i < 0) || (i >= himl->cCurImage))
1217 nWidth = GetSystemMetrics32 (SM_CXICON);
1218 nHeight = GetSystemMetrics32 (SM_CYICON);
1220 hdcSrc = CreateCompatibleDC32(0);
1221 hdcDst = CreateCompatibleDC32(0);
1224 ii.xHotspot = nWidth / 2;
1225 ii.yHotspot = nHeight / 2;
1226 ii.hbmMask = CreateCompatibleBitmap32 (hdcDst, nWidth, nHeight);
1227 ii.hbmColor = CreateCompatibleBitmap32 (hdcDst, nWidth, nHeight);
1231 SelectObject32 (hdcDst, ii.hbmMask);
1232 if (himl->hbmMask) {
1233 SelectObject32 (hdcSrc, himl->hbmMask);
1234 BitBlt32 (hdcDst, 0, 0, nWidth, nHeight,
1235 hdcSrc, i * himl->cx, 0, SRCCOPY);
1238 PatBlt32 (hdcDst, 0, 0, nWidth, nHeight, BLACKNESS);
1241 SelectObject32 (hdcDst, ii.hbmColor);
1242 SelectObject32 (hdcSrc, himl->hbmImage);
1243 BitBlt32 (hdcDst, 0, 0, nWidth, nHeight,
1244 hdcSrc, i * himl->cx, 0, SRCCOPY);
1246 hIcon = CreateIconIndirect (&ii);
1248 DeleteDC32 (hdcSrc);
1249 DeleteDC32 (hdcDst);
1250 DeleteObject32 (ii.hbmMask);
1251 DeleteObject32 (ii.hbmColor);
1257 /*************************************************************************
1258 * ImageList_GetIconSize [COMCTL32.58]
1260 * Retrieves the size of an image in an image list.
1263 * himl [I] handle to image list
1264 * cx [O] pointer to the image width.
1265 * cy [O] pointer to the image height.
1272 * All images in an image list have the same size.
1276 ImageList_GetIconSize (HIMAGELIST himl, INT32 *cx, INT32 *cy)
1280 if ((himl->cx <= 0) || (himl->cy <= 0))
1292 /*************************************************************************
1293 * ImageList_GetImageCount [COMCTL32.59]
1295 * Returns the number of images in an image list.
1298 * himl [I] handle to image list
1301 * Success: Number of images.
1306 ImageList_GetImageCount (HIMAGELIST himl)
1311 return himl->cCurImage;
1315 /*************************************************************************
1316 * ImageList_GetImageInfo [COMCTL32.60]
1318 * Returns information about an image in an image list.
1321 * himl [I] handle to image list
1323 * pImageInfo [O] pointer to the image information
1331 ImageList_GetImageInfo (HIMAGELIST himl, INT32 i, IMAGEINFO *pImageInfo)
1333 if ((himl == NULL) || (pImageInfo == NULL))
1335 if ((i < 0) || (i >= himl->cCurImage))
1338 pImageInfo->hbmImage = himl->hbmImage;
1339 pImageInfo->hbmMask = himl->hbmMask;
1341 pImageInfo->rcImage.top = 0;
1342 pImageInfo->rcImage.bottom = himl->cy;
1343 pImageInfo->rcImage.left = i * himl->cx;
1344 pImageInfo->rcImage.right = (i+1) * himl->cx;
1350 /*************************************************************************
1351 * ImageList_GetImageRect [COMCTL32.61]
1353 * Retrieves the rectangle of the specified image in an image list.
1356 * himl [I] handle to image list
1358 * lpRect [O] pointer to the image rectangle
1365 * This is an UNDOCUMENTED function!!!
1369 ImageList_GetImageRect (HIMAGELIST himl, INT32 i, LPRECT32 lpRect)
1371 if ((himl == NULL) || (lpRect == NULL))
1373 if ((i < 0) || (i >= himl->cCurImage))
1376 lpRect->left = i * himl->cx;
1378 lpRect->right = lpRect->left + himl->cx;
1379 lpRect->bottom = himl->cy;
1385 /*************************************************************************
1386 * ImageList_LoadImage32A [COMCTL32.63][COMCTL32.62]
1388 * Creates an image list from a bitmap, icon or cursor.
1391 * hi [I] instance handle
1392 * lpbmp [I] name or id of the image
1393 * cx [I] width of each image
1394 * cGrow [I] number of images to expand
1395 * clrMask [I] mask color
1396 * uType [I] type of image to load
1397 * uFlags [I] loading flags
1400 * Success: handle to the loaded image list
1408 ImageList_LoadImage32A (HINSTANCE32 hi, LPCSTR lpbmp, INT32 cx, INT32 cGrow,
1409 COLORREF clrMask, UINT32 uType, UINT32 uFlags)
1411 HIMAGELIST himl = NULL;
1415 handle = LoadImage32A (hi, lpbmp, uType, 0, 0, uFlags);
1417 ERR (imagelist, "Error loading image!\n");
1421 if (uType == IMAGE_BITMAP) {
1423 GetObject32A (handle, sizeof(BITMAP32), &bmp);
1424 nImageCount = bmp.bmWidth / cx;
1426 himl = ImageList_Create (cx, bmp.bmHeight, ILC_MASK | ILC_COLOR,
1427 nImageCount, cGrow);
1428 ImageList_AddMasked (himl, (HBITMAP32)handle, clrMask);
1430 else if ((uType == IMAGE_ICON) || (uType == IMAGE_CURSOR)) {
1434 GetIconInfo (handle, &ii);
1435 GetObject32A (ii.hbmColor, sizeof(BITMAP32), (LPVOID)&bmp);
1436 himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight,
1437 ILC_MASK | ILC_COLOR, 1, cGrow);
1438 ImageList_Add (himl, ii.hbmColor, ii.hbmMask);
1439 DeleteObject32 (ii.hbmColor);
1440 DeleteObject32 (ii.hbmMask);
1443 DeleteObject32 (handle);
1449 /*************************************************************************
1450 * ImageList_LoadImage32W [COMCTL32.64]
1452 * Creates an image list from a bitmap, icon or cursor.
1455 * hi [I] instance handle
1456 * lpbmp [I] name or id of the image
1457 * cx [I] width of each image
1458 * cGrow [I] number of images to expand
1459 * clrMask [I] mask color
1460 * uType [I] type of image to load
1461 * uFlags [I] loading flags
1464 * Success: handle to the loaded image list
1472 ImageList_LoadImage32W (HINSTANCE32 hi, LPCWSTR lpbmp, INT32 cx, INT32 cGrow,
1473 COLORREF clrMask, UINT32 uType, UINT32 uFlags)
1475 HIMAGELIST himl = NULL;
1479 handle = LoadImage32W (hi, lpbmp, uType, 0, 0, uFlags);
1481 ERR (imagelist, "Error loading image!\n");
1485 if (uType == IMAGE_BITMAP) {
1487 GetObject32A (handle, sizeof(BITMAP32), &bmp);
1488 nImageCount = bmp.bmWidth / cx;
1490 himl = ImageList_Create (cx, bmp.bmHeight, ILC_MASK | ILC_COLOR,
1491 nImageCount, cGrow);
1492 ImageList_AddMasked (himl, (HBITMAP32)handle, clrMask);
1494 else if ((uType == IMAGE_ICON) || (uType == IMAGE_CURSOR)) {
1498 GetIconInfo (handle, &ii);
1499 GetObject32A (ii.hbmMask, sizeof(BITMAP32), (LPVOID)&bmp);
1500 himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight,
1501 ILC_MASK | ILC_COLOR, 1, cGrow);
1502 ImageList_Add (himl, ii.hbmColor, ii.hbmMask);
1503 DeleteObject32 (ii.hbmColor);
1504 DeleteObject32 (ii.hbmMask);
1507 DeleteObject32 (handle);
1513 /*************************************************************************
1514 * ImageList_Merge [COMCTL32.65]
1516 * Creates a new image list that contains a merged image from the specified
1517 * images of both source image lists.
1520 * himl1 [I] handle to first image list
1521 * i1 [I] first image index
1522 * himl2 [I] handle to second image list
1523 * i2 [I] second image index
1524 * dx [I] X offset of the second image relative to the first.
1525 * dy [I] Y offset of the second image relative to the first.
1528 * Success: handle of the merged image list.
1533 ImageList_Merge (HIMAGELIST himl1, INT32 i1, HIMAGELIST himl2, INT32 i2,
1536 HIMAGELIST himlDst = NULL;
1537 HDC32 hdcSrcImage, hdcDstImage;
1539 INT32 xOff1, yOff1, xOff2, yOff2;
1542 if ((himl1 == NULL) || (himl2 == NULL))
1546 if ((i1 < 0) || (i1 >= himl1->cCurImage)) {
1547 ERR (imagelist, "Index 1 out of range! %d\n", i1);
1551 if ((i2 < 0) || (i2 >= himl2->cCurImage)) {
1552 ERR (imagelist, "Index 2 out of range! %d\n", i2);
1557 cxDst = _MAX (himl1->cx, dx + himl2->cx);
1562 cxDst = _MAX (himl2->cx, himl1->cx - dx);
1567 cxDst = _MAX (himl1->cx, himl2->cx);
1573 cyDst = _MAX (himl1->cy, dy + himl2->cy);
1578 cyDst = _MAX (himl2->cy, himl1->cy - dy);
1583 cyDst = _MAX (himl1->cy, himl2->cy);
1588 himlDst = ImageList_Create (cxDst, cyDst, ILC_MASK | ILC_COLOR, 1, 1);
1591 hdcSrcImage = CreateCompatibleDC32 (0);
1592 hdcDstImage = CreateCompatibleDC32 (0);
1593 nX1 = i1 * himl1->cx;
1594 nX2 = i2 * himl2->cx;
1597 SelectObject32 (hdcSrcImage, himl1->hbmImage);
1598 SelectObject32 (hdcDstImage, himlDst->hbmImage);
1599 BitBlt32 (hdcDstImage, 0, 0, cxDst, cyDst,
1600 hdcSrcImage, 0, 0, BLACKNESS);
1601 BitBlt32 (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy,
1602 hdcSrcImage, nX1, 0, SRCCOPY);
1604 SelectObject32 (hdcSrcImage, himl2->hbmMask);
1605 BitBlt32 (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
1606 hdcSrcImage, nX2, 0, SRCAND);
1608 SelectObject32 (hdcSrcImage, himl2->hbmImage);
1609 BitBlt32 (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
1610 hdcSrcImage, nX2, 0, SRCPAINT);
1613 SelectObject32 (hdcSrcImage, himl1->hbmMask);
1614 SelectObject32 (hdcDstImage, himlDst->hbmMask);
1615 BitBlt32 (hdcDstImage, 0, 0, cxDst, cyDst,
1616 hdcSrcImage, 0, 0, WHITENESS);
1617 BitBlt32 (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy,
1618 hdcSrcImage, nX1, 0, SRCCOPY);
1620 SelectObject32 (hdcSrcImage, himl2->hbmMask);
1621 BitBlt32 (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
1622 hdcSrcImage, nX2, 0, SRCAND);
1624 DeleteDC32 (hdcSrcImage);
1625 DeleteDC32 (hdcDstImage);
1632 /*************************************************************************
1633 * ImageList_Read [COMCTL32.66]
1635 * Reads an image list from a stream.
1638 * pstm [I] pointer to a stream
1641 * Success: handle to image list
1645 * This function can not be implemented yet, because
1646 * IStream32::Read is not implemented yet.
1652 HIMAGELIST WINAPI ImageList_Read (LPSTREAM32 pstm)
1654 FIXME (imagelist, "empty stub!\n");
1661 /*************************************************************************
1662 * ImageList_Remove [COMCTL32.67] Removes an image from an image list
1665 * himl [I] image list handle
1674 ImageList_Remove (HIMAGELIST himl, INT32 i)
1676 HBITMAP32 hbmNewImage, hbmNewMask;
1677 HDC32 hdcSrc, hdcDst;
1678 INT32 cxNew, nCount;
1680 if ((i < -1) || (i >= himl->cCurImage)) {
1681 ERR (imagelist, "index out of range! %d\n", i);
1685 if (himl->cCurImage == 0) {
1686 ERR (imagelist, "image list is already empty!\n");
1692 TRACE (imagelist, "remove all!\n");
1694 himl->cMaxImage = himl->cInitial + himl->cGrow;
1695 himl->cCurImage = 0;
1696 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
1697 himl->nOvlIdx[nCount] = -1;
1699 DeleteObject32 (himl->hbmImage);
1701 CreateBitmap32 (himl->cMaxImage * himl->cx, himl->cy,
1702 1, himl->uBitsPixel, NULL);
1704 if (himl->hbmMask) {
1705 DeleteObject32 (himl->hbmMask);
1707 CreateBitmap32 (himl->cMaxImage * himl->cx, himl->cy,
1712 /* delete one image */
1713 TRACE (imagelist, "Remove single image! %d\n", i);
1715 /* create new bitmap(s) */
1716 cxNew = (himl->cCurImage + himl->cGrow - 1) * himl->cx;
1718 TRACE(imagelist, " - Number of images: %d / %d (Old/New)\n",
1719 himl->cCurImage, himl->cCurImage - 1);
1720 TRACE(imagelist, " - Max. number of images: %d / %d (Old/New)\n",
1721 himl->cMaxImage, himl->cCurImage + himl->cGrow - 1);
1724 CreateBitmap32 (cxNew, himl->cy, 1, himl->uBitsPixel, NULL);
1727 hbmNewMask = CreateBitmap32 (cxNew, himl->cy, 1, 1, NULL);
1729 hbmNewMask = 0; /* Just to keep compiler happy! */
1731 hdcSrc = CreateCompatibleDC32 (0);
1732 hdcDst = CreateCompatibleDC32 (0);
1734 /* copy all images and masks prior to the "removed" image */
1736 TRACE (imagelist, "Pre image copy: Copy %d images\n", i);
1738 SelectObject32 (hdcSrc, himl->hbmImage);
1739 SelectObject32 (hdcDst, hbmNewImage);
1740 BitBlt32 (hdcDst, 0, 0, i * himl->cx, himl->cy,
1741 hdcSrc, 0, 0, SRCCOPY);
1743 if (himl->hbmMask) {
1744 SelectObject32 (hdcSrc, himl->hbmMask);
1745 SelectObject32 (hdcDst, hbmNewMask);
1746 BitBlt32 (hdcDst, 0, 0, i * himl->cx, himl->cy,
1747 hdcSrc, 0, 0, SRCCOPY);
1751 /* copy all images and masks behind the removed image */
1752 if (i < himl->cCurImage - 1) {
1753 TRACE (imagelist, "Post image copy!\n");
1754 SelectObject32 (hdcSrc, himl->hbmImage);
1755 SelectObject32 (hdcDst, hbmNewImage);
1756 BitBlt32 (hdcDst, i * himl->cx, 0, (himl->cCurImage - i - 1) * himl->cx,
1757 himl->cy, hdcSrc, (i + 1) * himl->cx, 0, SRCCOPY);
1759 if (himl->hbmMask) {
1760 SelectObject32 (hdcSrc, himl->hbmMask);
1761 SelectObject32 (hdcDst, hbmNewMask);
1762 BitBlt32 (hdcDst, i * himl->cx, 0,
1763 (himl->cCurImage - i - 1) * himl->cx,
1764 himl->cy, hdcSrc, (i + 1) * himl->cx, 0, SRCCOPY);
1768 DeleteDC32 (hdcSrc);
1769 DeleteDC32 (hdcDst);
1771 /* delete old images and insert new ones */
1772 DeleteObject32 (himl->hbmImage);
1773 himl->hbmImage = hbmNewImage;
1774 if (himl->hbmMask) {
1775 DeleteObject32 (himl->hbmMask);
1776 himl->hbmMask = hbmNewMask;
1780 himl->cMaxImage = himl->cCurImage + himl->cGrow;
1787 /*************************************************************************
1788 * ImageList_Replace [COMCTL32.68]
1790 * Replaces an image in an image list with a new image.
1793 * himl [I] handle to image list
1795 * hbmImage [I] handle to image bitmap
1796 * hbmMask [I] handle to mask bitmap. Can be NULL.
1804 ImageList_Replace (HIMAGELIST himl, INT32 i, HBITMAP32 hbmImage,
1807 HDC32 hdcImageList, hdcImage;
1811 ERR (imagelist, "Invalid image list handle!\n");
1815 if ((i >= himl->cCurImage) || (i < 0)) {
1816 ERR (imagelist, "Invalid image index!\n");
1820 hdcImageList = CreateCompatibleDC32 (0);
1821 hdcImage = CreateCompatibleDC32 (0);
1822 GetObject32A (hbmImage, sizeof(BITMAP32), (LPVOID)&bmp);
1825 SelectObject32 (hdcImageList, himl->hbmImage);
1826 SelectObject32 (hdcImage, hbmImage);
1828 StretchBlt32 (hdcImageList, i * himl->cx, 0, himl->cx, himl->cy,
1829 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1834 SelectObject32 (hdcImageList, himl->hbmMask);
1835 SelectObject32 (hdcImage, hbmMask);
1837 StretchBlt32 (hdcImageList, i * himl->cx, 0, himl->cx, himl->cy,
1838 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1841 DeleteDC32 (hdcImage);
1842 DeleteDC32 (hdcImageList);
1848 /*************************************************************************
1849 * ImageList_ReplaceIcon [COMCTL32.69]
1851 * Replaces an image in an image list using an icon.
1854 * himl [I] handle to image list
1856 * hIcon [I] handle to icon
1859 * Success: index of the replaced image
1864 ImageList_ReplaceIcon (HIMAGELIST himl, INT32 i, HICON32 hIcon)
1866 HDC32 hdcImageList, hdcImage;
1868 HBITMAP32 hbmOldSrc, hbmOldDst;
1872 TRACE (imagelist, "(0x%lx 0x%x 0x%x)\n", (DWORD)himl, i, hIcon);
1876 if ((i >= himl->cCurImage) || (i < -1))
1879 GetIconInfo (hIcon, &ii);
1880 if (ii.hbmMask == 0)
1881 ERR (imagelist, "no mask!\n");
1882 if (ii.hbmColor == 0)
1883 ERR (imagelist, "no color!\n");
1884 GetObject32A (ii.hbmMask, sizeof(BITMAP32), (LPVOID)&bmp);
1887 if (himl->cCurImage + 1 >= himl->cMaxImage)
1888 IMAGELIST_InternalExpandBitmaps (himl, 1);
1890 nIndex = himl->cCurImage;
1896 hdcImageList = CreateCompatibleDC32 (0);
1897 TRACE (imagelist, "hdcImageList=0x%x!\n", hdcImageList);
1898 if (hdcImageList == 0)
1899 ERR (imagelist, "invalid hdcImageList!\n");
1901 hdcImage = CreateCompatibleDC32 (0);
1902 TRACE (imagelist, "hdcImage=0x%x!\n", hdcImage);
1904 ERR (imagelist, "invalid hdcImage!\n");
1906 hbmOldDst = SelectObject32 (hdcImageList, himl->hbmImage);
1907 SetTextColor32( hdcImageList, RGB(0,0,0));
1908 SetBkColor32( hdcImageList, RGB(255,255,255));
1909 hbmOldSrc = SelectObject32 (hdcImage, ii.hbmColor);
1910 StretchBlt32 (hdcImageList, nIndex * himl->cx, 0, himl->cx, himl->cy,
1911 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1913 if (himl->hbmMask) {
1914 SelectObject32 (hdcImageList, himl->hbmMask);
1915 SelectObject32 (hdcImage, ii.hbmMask);
1916 StretchBlt32 (hdcImageList, nIndex * himl->cx, 0, himl->cx, himl->cy,
1917 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
1920 SelectObject32 (hdcImage, hbmOldSrc);
1921 SelectObject32 (hdcImageList, hbmOldDst);
1924 DeleteDC32 (hdcImageList);
1926 DeleteDC32 (hdcImage);
1928 DeleteObject32 (ii.hbmColor);
1930 DeleteObject32 (ii.hbmMask);
1936 /*************************************************************************
1937 * ImageList_SetBkColor [COMCTL32.70]
1939 * Sets the background color of an image list.
1942 * himl [I] handle to image list
1943 * clrBk [I] background color
1946 * Success: previous background color
1951 ImageList_SetBkColor (HIMAGELIST himl, COLORREF clrBk)
1958 clrOldBk = himl->clrBk;
1959 himl->clrBk = clrBk;
1964 /*************************************************************************
1965 * ImageList_SetDragCursorImage [COMCTL32.75]
1967 * Combines the specified image with the current drag image
1970 * himlDrag [I] handle to drag image list
1971 * iDrag [I] drag image index
1972 * dxHotspot [I] X position of the hot spot
1973 * dyHotspot [I] Y position of the hot spot
1984 ImageList_SetDragCursorImage (HIMAGELIST himlDrag, INT32 iDrag,
1985 INT32 dxHotspot, INT32 dyHotspot)
1987 HIMAGELIST himlTemp;
1989 FIXME (imagelist, "semi-stub!\n");
1991 if (himlInternalDrag == NULL)
1994 TRACE (imagelist, " dxH=%d dyH=%d nX=%d nY=%d\n",
1995 dxHotspot, dyHotspot, nInternalDragHotspotX, nInternalDragHotspotY);
1997 himlTemp = ImageList_Merge (himlInternalDrag, 0, himlDrag, iDrag,
1998 dxHotspot, dyHotspot);
2000 ImageList_Destroy (himlInternalDrag);
2001 himlInternalDrag = himlTemp;
2003 nInternalDragHotspotX = dxHotspot;
2004 nInternalDragHotspotY = dyHotspot;
2010 /*************************************************************************
2011 * ImageList_SetFilter [COMCTL32.76]
2013 * Sets a filter (or does something completely different)!!???
2016 * himl [I] handle to image list
2022 * Failure: FALSE ???
2025 * This is an UNDOCUMENTED function!!!!
2030 ImageList_SetFilter (HIMAGELIST himl, INT32 i, DWORD dwFilter)
2032 FIXME (imagelist, "(%p 0x%x 0x%lx):empty stub!\n",
2039 /*************************************************************************
2040 * ImageList_SetIconSize [COMCTL32.77]
2042 * Sets the image size of the bitmap and deletes all images.
2045 * himl [I] handle to image list
2046 * cx [I] image width
2047 * cy [I] image height
2055 ImageList_SetIconSize (HIMAGELIST himl, INT32 cx, INT32 cy)
2062 /* remove all images*/
2063 himl->cMaxImage = himl->cInitial + himl->cGrow;
2064 himl->cCurImage = 0;
2068 /* initialize overlay mask indices */
2069 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
2070 himl->nOvlIdx[nCount] = -1;
2072 DeleteObject32 (himl->hbmImage);
2074 CreateBitmap32 (himl->cMaxImage * himl->cx, himl->cy,
2075 1, himl->uBitsPixel, NULL);
2077 if (himl->hbmMask) {
2078 DeleteObject32 (himl->hbmMask);
2080 CreateBitmap32 (himl->cMaxImage * himl->cx, himl->cy,
2088 /*************************************************************************
2089 * ImageList_SetImageCount [COMCTL32.78]
2091 * Resizes an image list to the specified number of images.
2094 * himl [I] handle to image list
2095 * iImageCount [I] number of images in the image list
2103 ImageList_SetImageCount (HIMAGELIST himl, INT32 iImageCount)
2105 HDC32 hdcImageList, hdcBitmap;
2106 HBITMAP32 hbmNewBitmap;
2107 INT32 nNewCount, nCopyCount;
2111 if (himl->cCurImage <= iImageCount)
2113 if (himl->cMaxImage > iImageCount)
2116 nNewCount = iImageCount + himl->cGrow;
2117 nCopyCount = _MIN(himl->cCurImage, iImageCount);
2119 hdcImageList = CreateCompatibleDC32 (0);
2120 hdcBitmap = CreateCompatibleDC32 (0);
2122 hbmNewBitmap = CreateBitmap32 (nNewCount * himl->cx, himl->cy,
2123 1, himl->uBitsPixel, NULL);
2124 if (hbmNewBitmap == 0)
2126 SelectObject32 (hdcImageList, himl->hbmImage);
2127 SelectObject32 (hdcBitmap, hbmNewBitmap);
2130 BitBlt32 (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
2131 hdcImageList, 0, 0, SRCCOPY);
2133 /* delete 'empty' image space */
2134 SetBkColor32 (hdcBitmap, RGB(255, 255, 255));
2135 SetTextColor32 (hdcBitmap, RGB(0, 0, 0));
2136 PatBlt32 (hdcBitmap, nCopyCount * himl->cx, 0,
2137 (nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS);
2139 DeleteObject32 (himl->hbmImage);
2140 himl->hbmImage = hbmNewBitmap;
2143 ERR (imagelist, "Could not create new image bitmap !\n");
2147 hbmNewBitmap = CreateBitmap32 (nNewCount * himl->cx, himl->cy,
2149 if (hbmNewBitmap != 0)
2151 SelectObject32 (hdcImageList, himl->hbmMask);
2152 SelectObject32 (hdcBitmap, hbmNewBitmap);
2155 BitBlt32 (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
2156 hdcImageList, 0, 0, SRCCOPY);
2158 /* delete 'empty' image space */
2159 SetBkColor32 (hdcBitmap, RGB(255, 255, 255));
2160 SetTextColor32 (hdcBitmap, RGB(0, 0, 0));
2161 PatBlt32 (hdcBitmap, nCopyCount * himl->cx, 0,
2162 (nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS);
2164 DeleteObject32 (himl->hbmMask);
2165 himl->hbmMask = hbmNewBitmap;
2168 ERR (imagelist, "Could not create new mask bitmap!\n");
2171 DeleteDC32 (hdcImageList);
2172 DeleteDC32 (hdcBitmap);
2174 /* Update max image count and current image count */
2175 himl->cMaxImage = nNewCount;
2176 if (himl->cCurImage > nCopyCount)
2177 himl->cCurImage = nCopyCount;
2183 /*************************************************************************
2184 * ImageList_SetOverlayImage [COMCTL32.79]
2186 * Assigns an overlay mask index to an existing image in an image list.
2189 * himl [I] handle to image list
2190 * iImage [I] image index
2191 * iOverlay [I] overlay mask index
2199 ImageList_SetOverlayImage (HIMAGELIST himl, INT32 iImage, INT32 iOverlay)
2203 if ((iOverlay < 1) || (iOverlay > MAX_OVERLAYIMAGE))
2205 if ((iImage < 0) || (iImage > himl->cCurImage))
2208 himl->nOvlIdx[iOverlay - 1] = iImage;
2213 /*************************************************************************
2214 * ImageList_Write [COMCTL32.80]
2216 * Writes an image list to a stream.
2219 * himl [I] handle to image list
2220 * pstm [O] Pointer to a stream.
2227 * This function can not be implemented yet, because
2228 * IStream32::Write is not implemented.
2235 ImageList_Write (HIMAGELIST himl, LPSTREAM32 pstm)
2240 FIXME (imagelist, "empty stub!\n");