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 "winversion.h"
37 #include "imagelist.h"
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 INT32 nInternalDragHotspotX
= 0;
52 static INT32 nInternalDragHotspotY
= 0;
54 static HWND32 hwndInternalDrag
= 0;
55 static INT32 xInternalPos
= 0;
56 static INT32 yInternalPos
= 0;
58 static HDC32 hdcBackBuffer
= 0;
59 static HBITMAP32 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
, INT32 nImageCount
)
81 HDC32 hdcImageList
, hdcBitmap
;
82 HBITMAP32 hbmNewBitmap
;
83 INT32 nNewWidth
, nNewCount
;
85 TRACE(imagelist
, "Create expanded bitmaps!\n");
87 nNewCount
= himl
->cCurImage
+ nImageCount
+ himl
->cGrow
;
88 nNewWidth
= nNewCount
* himl
->cx
;
90 hdcImageList
= CreateCompatibleDC32 (0);
91 hdcBitmap
= CreateCompatibleDC32 (0);
94 CreateBitmap32 (nNewWidth
, himl
->cy
, 1, himl
->uBitsPixel
, NULL
);
95 if (hbmNewBitmap
== 0)
96 ERR (imagelist
, "creating new image bitmap!\n");
98 SelectObject32 (hdcImageList
, himl
->hbmImage
);
99 SelectObject32 (hdcBitmap
, hbmNewBitmap
);
100 BitBlt32 (hdcBitmap
, 0, 0, himl
->cCurImage
* himl
->cx
, himl
->cy
,
101 hdcImageList
, 0, 0, SRCCOPY
);
103 DeleteObject32 (himl
->hbmImage
);
104 himl
->hbmImage
= hbmNewBitmap
;
108 CreateBitmap32 (nNewWidth
, himl
->cy
, 1, 1, NULL
);
110 if (hbmNewBitmap
== 0)
111 ERR (imagelist
, "creating new mask bitmap!");
113 SelectObject32 (hdcImageList
, himl
->hbmMask
);
114 SelectObject32 (hdcBitmap
, hbmNewBitmap
);
115 BitBlt32 (hdcBitmap
, 0, 0, himl
->cCurImage
* himl
->cx
, himl
->cy
,
116 hdcImageList
, 0, 0, SRCCOPY
);
117 DeleteObject32 (himl
->hbmMask
);
118 himl
->hbmMask
= hbmNewBitmap
;
121 himl
->cMaxImage
= nNewCount
;
123 DeleteDC32 (hdcImageList
);
124 DeleteDC32 (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
, HBITMAP32 hbmImage
, HBITMAP32 hbmMask
)
146 HDC32 hdcSrc
, hdcDst
;
147 INT32 nFirstIndex
, nImageCount
;
151 if (!himl
|| !hbmImage
)
154 GetObject32A (hbmImage
, sizeof(BITMAP32
), (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
= CreateCompatibleDC32 (0);
163 hdcDst
= CreateCompatibleDC32 (0);
165 /* copy image bitmap */
166 SelectObject32 (hdcDst
, himl
->hbmImage
);
167 SelectObject32 (hdcSrc
, hbmImage
);
168 BitBlt32 (hdcDst
, himl
->cCurImage
* himl
->cx
, 0,
169 bmp
.bmWidth
, himl
->cy
, hdcSrc
, 0, 0, SRCCOPY
);
173 /* copy mask bitmap */
174 SelectObject32 (hdcDst
, himl
->hbmMask
);
175 SelectObject32 (hdcSrc
, hbmMask
);
176 BitBlt32 (hdcDst
, nStartX
, 0, bmp
.bmWidth
, himl
->cy
,
177 hdcSrc
, 0, 0, SRCCOPY
);
180 /* copy monochrome image to the mask bitmap */
181 SelectObject32 (hdcDst
, himl
->hbmMask
);
182 SelectObject32 (hdcSrc
, hbmImage
);
183 SetBkColor32 (hdcSrc
, GetNearestColor32 (hdcSrc
,
184 GetPixel32 (hdcSrc
, 0, 0)));
185 BitBlt32 (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
, HICON32 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
, HBITMAP32 hBitmap
, COLORREF clrMask
)
240 HDC32 hdcImage
, hdcMask
, hdcBitmap
;
241 INT32 nIndex
, nImageCount
;
247 if (!GetObject32A (hBitmap
, sizeof(BITMAP32
), &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
= CreateCompatibleDC32 (0);
259 hdcBitmap
= CreateCompatibleDC32 (0);
261 SelectObject32 (hdcBitmap
, hBitmap
);
262 SelectObject32 (hdcImage
, himl
->hbmImage
);
263 BitBlt32 (hdcImage
, nIndex
* himl
->cx
, 0, bmp
.bmWidth
, himl
->cy
,
264 hdcBitmap
, 0, 0, SRCCOPY
);
267 COLORREF bkColor
= (clrMask
!= CLR_DEFAULT
) ? clrMask
:
268 GetNearestColor32 (hdcBitmap
, GetPixel32 (hdcBitmap
, 0, 0));
270 /* create mask from image */
271 hdcMask
= CreateCompatibleDC32 (0);
272 SelectObject32 (hdcMask
, himl
->hbmMask
);
274 /* create monochrome image to the mask bitmap */
275 SetBkColor32 (hdcBitmap
, bkColor
);
276 BitBlt32 (hdcMask
, nIndex
* himl
->cx
, 0, bmp
.bmWidth
, himl
->cy
,
277 hdcBitmap
, 0, 0, SRCCOPY
);
279 DeleteDC32 (hdcMask
);
282 DeleteDC32 (hdcImage
);
283 DeleteDC32 (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
, INT32 iTrack
,
308 INT32 dxHotspot
, INT32 dyHotspot
)
310 HDC32 hdcSrc
, hdcDst
;
312 FIXME(imagelist
, "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(imagelist
, "Error creating drag image list!\n");
328 nInternalDragHotspotX
= dxHotspot
;
329 nInternalDragHotspotY
= dyHotspot
;
331 hdcSrc
= CreateCompatibleDC32 (0);
332 hdcDst
= CreateCompatibleDC32 (0);
335 SelectObject32 (hdcSrc
, himlTrack
->hbmImage
);
336 SelectObject32 (hdcDst
, himlInternalDrag
->hbmImage
);
337 StretchBlt32 (hdcDst
, 0, 0, himlInternalDrag
->cx
, himlInternalDrag
->cy
, hdcSrc
,
338 iTrack
* himlTrack
->cx
, 0, himlTrack
->cx
, himlTrack
->cy
, SRCCOPY
);
341 SelectObject32 (hdcSrc
, himlTrack
->hbmMask
);
342 SelectObject32 (hdcDst
, himlInternalDrag
->hbmMask
);
343 StretchBlt32 (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
, INT32 iDst
, HIMAGELIST himlSrc
,
380 INT32 iSrc
, INT32 uFlags
)
382 HDC32 hdcSrc
, hdcDst
;
384 TRACE(imagelist
, "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
= CreateCompatibleDC32 (0);
394 if (himlDst
== himlSrc
)
397 hdcDst
= CreateCompatibleDC32 (0);
399 if (uFlags
& ILCF_SWAP
) {
401 HBITMAP32 hbmTempImage
, hbmTempMask
;
403 /* create temporary bitmaps */
404 hbmTempImage
= CreateBitmap32 (himlSrc
->cx
, himlSrc
->cy
, 1,
405 himlSrc
->uBitsPixel
, NULL
);
406 hbmTempMask
= CreateBitmap32 (himlSrc
->cx
, himlSrc
->cy
, 1,
409 /* copy (and stretch) destination to temporary bitmaps.(save) */
411 SelectObject32 (hdcSrc
, himlDst
->hbmImage
);
412 SelectObject32 (hdcDst
, hbmTempImage
);
413 StretchBlt32 (hdcDst
, 0, 0, himlSrc
->cx
, himlSrc
->cy
,
414 hdcSrc
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
417 SelectObject32 (hdcSrc
, himlDst
->hbmMask
);
418 SelectObject32 (hdcDst
, hbmTempMask
);
419 StretchBlt32 (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 SelectObject32 (hdcSrc
, himlSrc
->hbmImage
);
426 SelectObject32 (hdcDst
, himlDst
->hbmImage
);
427 StretchBlt32 (hdcDst
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
428 hdcSrc
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
431 SelectObject32 (hdcSrc
, himlSrc
->hbmMask
);
432 SelectObject32 (hdcDst
, himlDst
->hbmMask
);
433 StretchBlt32 (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 SelectObject32 (hdcSrc
, hbmTempImage
);
440 SelectObject32 (hdcDst
, himlSrc
->hbmImage
);
441 BitBlt32 (hdcDst
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
442 hdcSrc
, 0, 0, SRCCOPY
);
444 SelectObject32 (hdcSrc
, hbmTempMask
);
445 SelectObject32 (hdcDst
, himlSrc
->hbmMask
);
446 BitBlt32 (hdcDst
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
447 hdcSrc
, 0, 0, SRCCOPY
);
449 /* delete temporary bitmaps */
450 DeleteObject32 (hbmTempMask
);
451 DeleteObject32 (hbmTempImage
);
455 SelectObject32 (hdcSrc
, himlSrc
->hbmImage
);
456 if (himlSrc
== himlDst
)
459 SelectObject32 (hdcDst
, himlDst
->hbmImage
);
460 StretchBlt32 (hdcDst
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
461 hdcSrc
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
465 SelectObject32 (hdcSrc
, himlSrc
->hbmMask
);
466 if (himlSrc
== himlDst
)
469 SelectObject32 (hdcDst
, himlDst
->hbmMask
);
470 StretchBlt32 (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 (INT32 cx
, INT32 cy
, UINT32 flags
,
500 INT32 cInitial
, INT32 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 (imagelist
, "(%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
= CreateCompatibleDC32 (0);
533 himl
->uBitsPixel
= (UINT32
)GetDeviceCaps32 (hdc
, BITSPIXEL
);
536 TRACE(imagelist
, "Image: %d Bits per Pixel\n", himl
->uBitsPixel
);
539 CreateBitmap32 (himl
->cx
* himl
->cMaxImage
, himl
->cy
,
540 1, himl
->uBitsPixel
, NULL
);
541 if (himl
->hbmImage
== 0) {
542 ERR(imagelist
, "Error creating image bitmap!\n");
546 if (himl
->flags
& ILC_MASK
) {
547 himl
->hbmMask
= CreateBitmap32 (himl
->cx
* himl
->cMaxImage
, himl
->cy
,
549 if (himl
->hbmMask
== 0) {
550 ERR(imagelist
, "Error creating mask bitmap!\n");
552 DeleteObject32 (himl
->hbmImage
);
559 /* create blending brushes */
560 hbmTemp
= CreateBitmap32 (8, 8, 1, 1, &aBitBlend25
);
561 himl
->hbrBlend25
= CreatePatternBrush32 (hbmTemp
);
562 DeleteObject32 (hbmTemp
);
564 hbmTemp
= CreateBitmap32 (8, 8, 1, 1, &aBitBlend50
);
565 himl
->hbrBlend50
= CreatePatternBrush32 (hbmTemp
);
566 DeleteObject32 (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 DeleteObject32 (himl
->hbmImage
);
595 DeleteObject32 (himl
->hbmMask
);
597 /* delete blending brushes */
598 if (himl
->hbrBlend25
)
599 DeleteObject32 (himl
->hbrBlend25
);
600 if (himl
->hbrBlend50
)
601 DeleteObject32 (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 (HWND32 hwndLock
, INT32 x
, INT32 y
)
631 if (himlInternalDrag
== NULL
)
635 hwndInternalDrag
= hwndLock
;
637 hwndInternalDrag
= GetDesktopWindow32 ();
642 hdcBackBuffer
= CreateCompatibleDC32 (0);
643 hbmBackBuffer
= CreateCompatibleBitmap32 (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 (HWND32 hwndLock
)
669 hwndInternalDrag
= hwndLock
;
671 hwndInternalDrag
= GetDesktopWindow32 ();
673 ImageList_DragShowNolock (FALSE
);
675 DeleteDC32 (hdcBackBuffer
);
676 DeleteObject32 (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 (INT32 x
, INT32 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 (BOOL32 bShow
)
735 FIXME (imagelist
, "semi-stub!\n");
736 TRACE (imagelist
, "bShow=0x%X!\n", bShow
);
738 hdcDrag
= GetDCEx32 (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 ReleaseDC32 (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
, INT32 i
, HDC32 hdc
,
786 INT32 x
, INT32 y
, UINT32 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
, INT32 i
, HDC32 hdc
, INT32 x
, INT32 y
,
839 INT32 dx
, INT32 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 HDC32 hdcImageList
, hdcTempImage
;
881 HBITMAP32 hbmTempImage
;
882 HBRUSH32 hBrush
, hOldBrush
;
886 BOOL32 bImage
; /* draw image ? */
887 BOOL32 bImageTrans
; /* draw image transparent ? */
888 BOOL32 bMask
; /* draw mask ? */
889 BOOL32 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
= CreateCompatibleDC32 (0);
954 SelectObject32 (hdcImageList
, himlLocal
->hbmMask
);
955 SetBkColor32 (hdcImageList
, RGB(255, 255, 255));
956 SetTextColor32 (hdcImageList
, RGB(0, 0, 0));
957 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
, cx
, cy
,
958 hdcImageList
, himlLocal
->cx
* pimldp
->i
, 0,
959 bMaskTrans
? SRCAND
: SRCCOPY
);
965 SelectObject32 (hdcImageList
, himlLocal
->hbmImage
);
969 hBrush
= CreateSolidBrush32 (himlLocal
->clrBk
);
970 hOldBrush
= SelectObject32 (pimldp
->hdcDst
, hBrush
);
971 PatBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
,
973 DeleteObject32 (SelectObject32 (pimldp
->hdcDst
, hOldBrush
));
976 BitBlt32 (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
= GetSysColor32 (COLOR_HIGHLIGHT
);
984 clrBlend
= pimldp
->rgbFg
;
986 hdcTempImage
= CreateCompatibleDC32 (0);
987 hbmTempImage
= CreateBitmap32 (himlLocal
->cx
, himlLocal
->cy
,
988 1, himlLocal
->uBitsPixel
, NULL
);
989 SelectObject32 (hdcTempImage
, hbmTempImage
);
993 SelectObject32 (hdcTempImage
,
994 bBlend50
? himlLocal
->hbrBlend50
: himlLocal
->hbrBlend25
);
995 PatBlt32 (hdcTempImage
, 0, 0, himlLocal
->cx
, himlLocal
->cy
, PATCOPY
);
997 SelectObject32 (hdcImageList
, himlLocal
->hbmMask
);
998 BitBlt32 (hdcTempImage
, 0, 0, himlLocal
->cx
,
999 himlLocal
->cy
, hdcImageList
,
1000 pimldp
->i
* himlLocal
->cx
, 0, SRCPAINT
);
1002 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
, cx
, cy
,
1003 hdcTempImage
, 0, 0, SRCAND
);
1006 hBrush
= CreateSolidBrush32 (clrBlend
);
1007 SelectObject32 (hdcTempImage
, hBrush
);
1008 PatBlt32 (hdcTempImage
, 0, 0, himlLocal
->cx
, himlLocal
->cy
, PATCOPY
);
1009 DeleteObject32 (hBrush
);
1011 SelectObject32 (hdcTempImage
,
1012 bBlend50
? himlLocal
->hbrBlend50
: himlLocal
->hbrBlend25
);
1013 PatBlt32 (hdcTempImage
, 0, 0, himlLocal
->cx
, himlLocal
->cy
, 0x0A0329);
1015 SelectObject32 (hdcImageList
, himlLocal
->hbmMask
);
1016 BitBlt32 (hdcTempImage
, 0, 0, himlLocal
->cx
,
1017 himlLocal
->cy
, hdcImageList
,
1018 pimldp
->i
* himlLocal
->cx
, 0, SRCPAINT
);
1020 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
, cx
, cy
,
1021 hdcTempImage
, 0, 0, SRCPAINT
);
1023 DeleteObject32 (hbmTempImage
);
1024 DeleteDC32 (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 SelectObject32 (hdcImageList
, pimldp
->himl
->hbmMask
);
1036 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
, cx
, cy
,
1037 hdcImageList
, pimldp
->himl
->cx
* nOvlIdx
, 0,
1040 SelectObject32 (hdcImageList
, pimldp
->himl
->hbmImage
);
1041 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
,
1042 cx
, cy
, hdcImageList
,
1043 pimldp
->himl
->cx
* nOvlIdx
, 0, SRCPAINT
);
1048 DeleteDC32 (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
)
1069 HDC32 hdcSrc
, hdcDst
;
1071 if (himlSrc
== NULL
) {
1072 ERR (imagelist
, "Invalid image list handle!\n");
1076 himlDst
= ImageList_Create (himlSrc
->cx
, himlSrc
->cy
, himlSrc
->flags
,
1077 himlSrc
->cInitial
, himlSrc
->cGrow
);
1081 hdcSrc
= CreateCompatibleDC32 (0);
1082 hdcDst
= CreateCompatibleDC32 (0);
1083 SelectObject32 (hdcSrc
, himlSrc
->hbmImage
);
1084 SelectObject32 (hdcDst
, himlDst
->hbmImage
);
1085 BitBlt32 (hdcDst
, 0, 0, himlSrc
->cCurImage
* himlSrc
->cx
, himlSrc
->cy
,
1086 hdcSrc
, 0, 0, SRCCOPY
);
1088 if (himlDst
->hbmMask
)
1090 SelectObject32 (hdcSrc
, himlSrc
->hbmMask
);
1091 SelectObject32 (hdcDst
, himlDst
->hbmMask
);
1092 BitBlt32 (hdcDst
, 0, 0, himlSrc
->cCurImage
* himlSrc
->cx
,
1093 himlSrc
->cy
, hdcSrc
, 0, 0, SRCCOPY
);
1096 DeleteDC32 (hdcDst
);
1097 DeleteDC32 (hdcSrc
);
1104 /*************************************************************************
1105 * ImageList_EndDrag [COMCTL32.54] Finishes a drag operation.
1107 * Finishes a drag operation.
1121 ImageList_EndDrag (VOID
)
1123 FIXME (imagelist
, "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 (POINT32
*ppt
, POINT32
*pptHotspot
)
1183 FIXME (imagelist
, "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
, INT32 i
, UINT32 fStyle
)
1212 HDC32 hdcSrc
, hdcDst
;
1213 INT32 nWidth
, nHeight
;
1215 if ((himl
== NULL
) || (i
< 0) || (i
>= himl
->cCurImage
))
1218 nWidth
= GetSystemMetrics32 (SM_CXICON
);
1219 nHeight
= GetSystemMetrics32 (SM_CYICON
);
1221 hdcSrc
= CreateCompatibleDC32(0);
1222 hdcDst
= CreateCompatibleDC32(0);
1225 ii
.xHotspot
= nWidth
/ 2;
1226 ii
.yHotspot
= nHeight
/ 2;
1227 ii
.hbmMask
= CreateCompatibleBitmap32 (hdcDst
, nWidth
, nHeight
);
1228 ii
.hbmColor
= CreateCompatibleBitmap32 (hdcDst
, nWidth
, nHeight
);
1232 SelectObject32 (hdcDst
, ii
.hbmMask
);
1233 if (himl
->hbmMask
) {
1234 SelectObject32 (hdcSrc
, himl
->hbmMask
);
1235 BitBlt32 (hdcDst
, 0, 0, nWidth
, nHeight
,
1236 hdcSrc
, i
* himl
->cx
, 0, SRCCOPY
);
1239 PatBlt32 (hdcDst
, 0, 0, nWidth
, nHeight
, BLACKNESS
);
1242 SelectObject32 (hdcDst
, ii
.hbmColor
);
1243 SelectObject32 (hdcSrc
, himl
->hbmImage
);
1244 BitBlt32 (hdcDst
, 0, 0, nWidth
, nHeight
,
1245 hdcSrc
, i
* himl
->cx
, 0, SRCCOPY
);
1247 hIcon
= CreateIconIndirect (&ii
);
1249 DeleteDC32 (hdcSrc
);
1250 DeleteDC32 (hdcDst
);
1251 DeleteObject32 (ii
.hbmMask
);
1252 DeleteObject32 (ii
.hbmColor
);
1258 /*************************************************************************
1259 * ImageList_GetIconSize [COMCTL32.58]
1261 * Retrieves the size of an image in an image list.
1264 * himl [I] handle to image list
1265 * cx [O] pointer to the image width.
1266 * cy [O] pointer to the image height.
1273 * All images in an image list have the same size.
1277 ImageList_GetIconSize (HIMAGELIST himl
, INT32
*cx
, INT32
*cy
)
1281 if ((himl
->cx
<= 0) || (himl
->cy
<= 0))
1293 /*************************************************************************
1294 * ImageList_GetImageCount [COMCTL32.59]
1296 * Returns the number of images in an image list.
1299 * himl [I] handle to image list
1302 * Success: Number of images.
1307 ImageList_GetImageCount (HIMAGELIST himl
)
1312 return himl
->cCurImage
;
1316 /*************************************************************************
1317 * ImageList_GetImageInfo [COMCTL32.60]
1319 * Returns information about an image in an image list.
1322 * himl [I] handle to image list
1324 * pImageInfo [O] pointer to the image information
1332 ImageList_GetImageInfo (HIMAGELIST himl
, INT32 i
, IMAGEINFO
*pImageInfo
)
1334 if ((himl
== NULL
) || (pImageInfo
== NULL
))
1336 if ((i
< 0) || (i
>= himl
->cCurImage
))
1339 pImageInfo
->hbmImage
= himl
->hbmImage
;
1340 pImageInfo
->hbmMask
= himl
->hbmMask
;
1342 pImageInfo
->rcImage
.top
= 0;
1343 pImageInfo
->rcImage
.bottom
= himl
->cy
;
1344 pImageInfo
->rcImage
.left
= i
* himl
->cx
;
1345 pImageInfo
->rcImage
.right
= (i
+1) * himl
->cx
;
1351 /*************************************************************************
1352 * ImageList_GetImageRect [COMCTL32.61]
1354 * Retrieves the rectangle of the specified image in an image list.
1357 * himl [I] handle to image list
1359 * lpRect [O] pointer to the image rectangle
1366 * This is an UNDOCUMENTED function!!!
1370 ImageList_GetImageRect (HIMAGELIST himl
, INT32 i
, LPRECT32 lpRect
)
1372 if ((himl
== NULL
) || (lpRect
== NULL
))
1374 if ((i
< 0) || (i
>= himl
->cCurImage
))
1377 lpRect
->left
= i
* himl
->cx
;
1379 lpRect
->right
= lpRect
->left
+ himl
->cx
;
1380 lpRect
->bottom
= himl
->cy
;
1386 /*************************************************************************
1387 * ImageList_LoadImage32A [COMCTL32.63]
1389 * Creates an image list from a bitmap, icon or cursor.
1392 * hi [I] instance handle
1393 * lpbmp [I] name or id of the image
1394 * cx [I] width of each image
1395 * cGrow [I] number of images to expand
1396 * clrMask [I] mask color
1397 * uType [I] type of image to load
1398 * uFlags [I] loading flags
1401 * Success: handle to image list
1409 ImageList_LoadImage32A (HINSTANCE32 hi
, LPCSTR lpbmp
, INT32 cx
, INT32 cGrow
,
1410 COLORREF clrMask
, UINT32 uType
, UINT32 uFlags
)
1412 HIMAGELIST himl
= NULL
;
1416 handle
= LoadImage32A (hi
, lpbmp
, uType
, 0, 0, uFlags
);
1418 ERR (imagelist
, "Error loading image!\n");
1422 if (uType
== IMAGE_BITMAP
) {
1424 GetObject32A (handle
, sizeof(BITMAP32
), &bmp
);
1425 nImageCount
= bmp
.bmWidth
/ cx
;
1427 himl
= ImageList_Create (cx
, bmp
.bmHeight
, ILC_MASK
| ILC_COLOR
,
1428 nImageCount
, cGrow
);
1429 ImageList_AddMasked (himl
, (HBITMAP32
)handle
, clrMask
);
1431 else if ((uType
== IMAGE_ICON
) || (uType
== IMAGE_CURSOR
)) {
1435 GetIconInfo (handle
, &ii
);
1436 GetObject32A (ii
.hbmColor
, sizeof(BITMAP32
), (LPVOID
)&bmp
);
1437 himl
= ImageList_Create (bmp
.bmWidth
, bmp
.bmHeight
,
1438 ILC_MASK
| ILC_COLOR
, 1, cGrow
);
1439 ImageList_Add (himl
, ii
.hbmColor
, ii
.hbmMask
);
1440 DeleteObject32 (ii
.hbmColor
);
1441 DeleteObject32 (ii
.hbmMask
);
1444 DeleteObject32 (handle
);
1450 /*************************************************************************
1451 * ImageList_LoadImage32W [COMCTL32.64]
1453 * Creates an image list from a bitmap, icon or cursor.
1456 * hi [I] instance handle
1457 * lpbmp [I] name or id of the image
1458 * cx [I] width of each image
1459 * cGrow [I] number of images to expand
1460 * clrMask [I] mask color
1461 * uType [I] type of image to load
1462 * uFlags [I] loading flags
1465 * Success: handle to image list
1473 ImageList_LoadImage32W (HINSTANCE32 hi
, LPCWSTR lpbmp
, INT32 cx
, INT32 cGrow
,
1474 COLORREF clrMask
, UINT32 uType
, UINT32 uFlags
)
1476 HIMAGELIST himl
= NULL
;
1480 handle
= LoadImage32W (hi
, lpbmp
, uType
, 0, 0, uFlags
);
1482 ERR (imagelist
, "Error loading image!\n");
1486 if (uType
== IMAGE_BITMAP
) {
1488 GetObject32A (handle
, sizeof(BITMAP32
), &bmp
);
1489 nImageCount
= bmp
.bmWidth
/ cx
;
1491 himl
= ImageList_Create (cx
, bmp
.bmHeight
, ILC_MASK
| ILC_COLOR
,
1492 nImageCount
, cGrow
);
1493 ImageList_AddMasked (himl
, (HBITMAP32
)handle
, clrMask
);
1495 else if ((uType
== IMAGE_ICON
) || (uType
== IMAGE_CURSOR
)) {
1499 GetIconInfo (handle
, &ii
);
1500 GetObject32A (ii
.hbmMask
, sizeof(BITMAP32
), (LPVOID
)&bmp
);
1501 himl
= ImageList_Create (bmp
.bmWidth
, bmp
.bmHeight
,
1502 ILC_MASK
| ILC_COLOR
, 1, cGrow
);
1503 ImageList_Add (himl
, ii
.hbmColor
, ii
.hbmMask
);
1504 DeleteObject32 (ii
.hbmColor
);
1505 DeleteObject32 (ii
.hbmMask
);
1508 DeleteObject32 (handle
);
1514 /*************************************************************************
1515 * ImageList_LoadImage32AW [COMCTL32.62]
1517 * Creates an image list from a bitmap, icon or cursor.
1520 * hi [I] instance handle
1521 * lpbmp [I] name or id of the image
1522 * cx [I] width of each image
1523 * cGrow [I] number of images to expand
1524 * clrMask [I] mask color
1525 * uType [I] type of image to load
1526 * uFlags [I] loading flags
1529 * Success: handle to image list
1537 ImageList_LoadImage32AW (HINSTANCE32 hi
, const LPVOID lpbmp
, INT32 cx
,
1538 INT32 cGrow
, COLORREF clrMask
, UINT32 uType
,
1541 if (VERSION_OsIsUnicode())
1542 return ImageList_LoadImage32W (hi
, (LPCWSTR
)lpbmp
, cx
, cGrow
,
1543 clrMask
, uType
, uFlags
);
1544 return ImageList_LoadImage32A (hi
, (LPCSTR
)lpbmp
, cx
, cGrow
,
1545 clrMask
, uType
, uFlags
);
1549 /*************************************************************************
1550 * ImageList_Merge [COMCTL32.65]
1552 * Creates a new image list that contains a merged image from the specified
1553 * images of both source image lists.
1556 * himl1 [I] handle to first image list
1557 * i1 [I] first image index
1558 * himl2 [I] handle to second image list
1559 * i2 [I] second image index
1560 * dx [I] X offset of the second image relative to the first.
1561 * dy [I] Y offset of the second image relative to the first.
1564 * Success: handle of the merged image list.
1569 ImageList_Merge (HIMAGELIST himl1
, INT32 i1
, HIMAGELIST himl2
, INT32 i2
,
1572 HIMAGELIST himlDst
= NULL
;
1573 HDC32 hdcSrcImage
, hdcDstImage
;
1575 INT32 xOff1
, yOff1
, xOff2
, yOff2
;
1578 if ((himl1
== NULL
) || (himl2
== NULL
))
1582 if ((i1
< 0) || (i1
>= himl1
->cCurImage
)) {
1583 ERR (imagelist
, "Index 1 out of range! %d\n", i1
);
1587 if ((i2
< 0) || (i2
>= himl2
->cCurImage
)) {
1588 ERR (imagelist
, "Index 2 out of range! %d\n", i2
);
1593 cxDst
= _MAX (himl1
->cx
, dx
+ himl2
->cx
);
1598 cxDst
= _MAX (himl2
->cx
, himl1
->cx
- dx
);
1603 cxDst
= _MAX (himl1
->cx
, himl2
->cx
);
1609 cyDst
= _MAX (himl1
->cy
, dy
+ himl2
->cy
);
1614 cyDst
= _MAX (himl2
->cy
, himl1
->cy
- dy
);
1619 cyDst
= _MAX (himl1
->cy
, himl2
->cy
);
1624 himlDst
= ImageList_Create (cxDst
, cyDst
, ILC_MASK
| ILC_COLOR
, 1, 1);
1627 hdcSrcImage
= CreateCompatibleDC32 (0);
1628 hdcDstImage
= CreateCompatibleDC32 (0);
1629 nX1
= i1
* himl1
->cx
;
1630 nX2
= i2
* himl2
->cx
;
1633 SelectObject32 (hdcSrcImage
, himl1
->hbmImage
);
1634 SelectObject32 (hdcDstImage
, himlDst
->hbmImage
);
1635 BitBlt32 (hdcDstImage
, 0, 0, cxDst
, cyDst
,
1636 hdcSrcImage
, 0, 0, BLACKNESS
);
1637 BitBlt32 (hdcDstImage
, xOff1
, yOff1
, himl1
->cx
, himl1
->cy
,
1638 hdcSrcImage
, nX1
, 0, SRCCOPY
);
1640 SelectObject32 (hdcSrcImage
, himl2
->hbmMask
);
1641 BitBlt32 (hdcDstImage
, xOff2
, yOff2
, himl2
->cx
, himl2
->cy
,
1642 hdcSrcImage
, nX2
, 0, SRCAND
);
1644 SelectObject32 (hdcSrcImage
, himl2
->hbmImage
);
1645 BitBlt32 (hdcDstImage
, xOff2
, yOff2
, himl2
->cx
, himl2
->cy
,
1646 hdcSrcImage
, nX2
, 0, SRCPAINT
);
1649 SelectObject32 (hdcSrcImage
, himl1
->hbmMask
);
1650 SelectObject32 (hdcDstImage
, himlDst
->hbmMask
);
1651 BitBlt32 (hdcDstImage
, 0, 0, cxDst
, cyDst
,
1652 hdcSrcImage
, 0, 0, WHITENESS
);
1653 BitBlt32 (hdcDstImage
, xOff1
, yOff1
, himl1
->cx
, himl1
->cy
,
1654 hdcSrcImage
, nX1
, 0, SRCCOPY
);
1656 SelectObject32 (hdcSrcImage
, himl2
->hbmMask
);
1657 BitBlt32 (hdcDstImage
, xOff2
, yOff2
, himl2
->cx
, himl2
->cy
,
1658 hdcSrcImage
, nX2
, 0, SRCAND
);
1660 DeleteDC32 (hdcSrcImage
);
1661 DeleteDC32 (hdcDstImage
);
1668 /*************************************************************************
1669 * ImageList_Read [COMCTL32.66]
1671 * Reads an image list from a stream.
1674 * pstm [I] pointer to a stream
1677 * Success: handle to image list
1681 * This function can not be implemented yet, because
1682 * IStream32::Read is not implemented yet.
1688 HIMAGELIST WINAPI
ImageList_Read (LPSTREAM32 pstm
)
1690 FIXME (imagelist
, "empty stub!\n");
1697 /*************************************************************************
1698 * ImageList_Remove [COMCTL32.67] Removes an image from an image list
1701 * himl [I] image list handle
1710 ImageList_Remove (HIMAGELIST himl
, INT32 i
)
1712 HBITMAP32 hbmNewImage
, hbmNewMask
;
1713 HDC32 hdcSrc
, hdcDst
;
1714 INT32 cxNew
, nCount
;
1716 if ((i
< -1) || (i
>= himl
->cCurImage
)) {
1717 ERR (imagelist
, "index out of range! %d\n", i
);
1721 if (himl
->cCurImage
== 0) {
1722 ERR (imagelist
, "image list is already empty!\n");
1728 TRACE (imagelist
, "remove all!\n");
1730 himl
->cMaxImage
= himl
->cInitial
+ himl
->cGrow
;
1731 himl
->cCurImage
= 0;
1732 for (nCount
= 0; nCount
< MAX_OVERLAYIMAGE
; nCount
++)
1733 himl
->nOvlIdx
[nCount
] = -1;
1735 DeleteObject32 (himl
->hbmImage
);
1737 CreateBitmap32 (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
1738 1, himl
->uBitsPixel
, NULL
);
1740 if (himl
->hbmMask
) {
1741 DeleteObject32 (himl
->hbmMask
);
1743 CreateBitmap32 (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
1748 /* delete one image */
1749 TRACE (imagelist
, "Remove single image! %d\n", i
);
1751 /* create new bitmap(s) */
1752 cxNew
= (himl
->cCurImage
+ himl
->cGrow
- 1) * himl
->cx
;
1754 TRACE(imagelist
, " - Number of images: %d / %d (Old/New)\n",
1755 himl
->cCurImage
, himl
->cCurImage
- 1);
1756 TRACE(imagelist
, " - Max. number of images: %d / %d (Old/New)\n",
1757 himl
->cMaxImage
, himl
->cCurImage
+ himl
->cGrow
- 1);
1760 CreateBitmap32 (cxNew
, himl
->cy
, 1, himl
->uBitsPixel
, NULL
);
1763 hbmNewMask
= CreateBitmap32 (cxNew
, himl
->cy
, 1, 1, NULL
);
1765 hbmNewMask
= 0; /* Just to keep compiler happy! */
1767 hdcSrc
= CreateCompatibleDC32 (0);
1768 hdcDst
= CreateCompatibleDC32 (0);
1770 /* copy all images and masks prior to the "removed" image */
1772 TRACE (imagelist
, "Pre image copy: Copy %d images\n", i
);
1774 SelectObject32 (hdcSrc
, himl
->hbmImage
);
1775 SelectObject32 (hdcDst
, hbmNewImage
);
1776 BitBlt32 (hdcDst
, 0, 0, i
* himl
->cx
, himl
->cy
,
1777 hdcSrc
, 0, 0, SRCCOPY
);
1779 if (himl
->hbmMask
) {
1780 SelectObject32 (hdcSrc
, himl
->hbmMask
);
1781 SelectObject32 (hdcDst
, hbmNewMask
);
1782 BitBlt32 (hdcDst
, 0, 0, i
* himl
->cx
, himl
->cy
,
1783 hdcSrc
, 0, 0, SRCCOPY
);
1787 /* copy all images and masks behind the removed image */
1788 if (i
< himl
->cCurImage
- 1) {
1789 TRACE (imagelist
, "Post image copy!\n");
1790 SelectObject32 (hdcSrc
, himl
->hbmImage
);
1791 SelectObject32 (hdcDst
, hbmNewImage
);
1792 BitBlt32 (hdcDst
, i
* himl
->cx
, 0, (himl
->cCurImage
- i
- 1) * himl
->cx
,
1793 himl
->cy
, hdcSrc
, (i
+ 1) * himl
->cx
, 0, SRCCOPY
);
1795 if (himl
->hbmMask
) {
1796 SelectObject32 (hdcSrc
, himl
->hbmMask
);
1797 SelectObject32 (hdcDst
, hbmNewMask
);
1798 BitBlt32 (hdcDst
, i
* himl
->cx
, 0,
1799 (himl
->cCurImage
- i
- 1) * himl
->cx
,
1800 himl
->cy
, hdcSrc
, (i
+ 1) * himl
->cx
, 0, SRCCOPY
);
1804 DeleteDC32 (hdcSrc
);
1805 DeleteDC32 (hdcDst
);
1807 /* delete old images and insert new ones */
1808 DeleteObject32 (himl
->hbmImage
);
1809 himl
->hbmImage
= hbmNewImage
;
1810 if (himl
->hbmMask
) {
1811 DeleteObject32 (himl
->hbmMask
);
1812 himl
->hbmMask
= hbmNewMask
;
1816 himl
->cMaxImage
= himl
->cCurImage
+ himl
->cGrow
;
1823 /*************************************************************************
1824 * ImageList_Replace [COMCTL32.68]
1826 * Replaces an image in an image list with a new image.
1829 * himl [I] handle to image list
1831 * hbmImage [I] handle to image bitmap
1832 * hbmMask [I] handle to mask bitmap. Can be NULL.
1840 ImageList_Replace (HIMAGELIST himl
, INT32 i
, HBITMAP32 hbmImage
,
1843 HDC32 hdcImageList
, hdcImage
;
1847 ERR (imagelist
, "Invalid image list handle!\n");
1851 if ((i
>= himl
->cCurImage
) || (i
< 0)) {
1852 ERR (imagelist
, "Invalid image index!\n");
1856 hdcImageList
= CreateCompatibleDC32 (0);
1857 hdcImage
= CreateCompatibleDC32 (0);
1858 GetObject32A (hbmImage
, sizeof(BITMAP32
), (LPVOID
)&bmp
);
1861 SelectObject32 (hdcImageList
, himl
->hbmImage
);
1862 SelectObject32 (hdcImage
, hbmImage
);
1864 StretchBlt32 (hdcImageList
, i
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
1865 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
1870 SelectObject32 (hdcImageList
, himl
->hbmMask
);
1871 SelectObject32 (hdcImage
, hbmMask
);
1873 StretchBlt32 (hdcImageList
, i
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
1874 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
1877 DeleteDC32 (hdcImage
);
1878 DeleteDC32 (hdcImageList
);
1884 /*************************************************************************
1885 * ImageList_ReplaceIcon [COMCTL32.69]
1887 * Replaces an image in an image list using an icon.
1890 * himl [I] handle to image list
1892 * hIcon [I] handle to icon
1895 * Success: index of the replaced image
1900 ImageList_ReplaceIcon (HIMAGELIST himl
, INT32 i
, HICON32 hIcon
)
1902 HDC32 hdcImageList
, hdcImage
;
1904 HBITMAP32 hbmOldSrc
, hbmOldDst
;
1908 TRACE (imagelist
, "(0x%lx 0x%x 0x%x)\n", (DWORD
)himl
, i
, hIcon
);
1912 if ((i
>= himl
->cCurImage
) || (i
< -1))
1915 GetIconInfo (hIcon
, &ii
);
1916 if (ii
.hbmMask
== 0)
1917 ERR (imagelist
, "no mask!\n");
1918 if (ii
.hbmColor
== 0)
1919 ERR (imagelist
, "no color!\n");
1920 GetObject32A (ii
.hbmMask
, sizeof(BITMAP32
), (LPVOID
)&bmp
);
1923 if (himl
->cCurImage
+ 1 >= himl
->cMaxImage
)
1924 IMAGELIST_InternalExpandBitmaps (himl
, 1);
1926 nIndex
= himl
->cCurImage
;
1932 hdcImageList
= CreateCompatibleDC32 (0);
1933 TRACE (imagelist
, "hdcImageList=0x%x!\n", hdcImageList
);
1934 if (hdcImageList
== 0)
1935 ERR (imagelist
, "invalid hdcImageList!\n");
1937 hdcImage
= CreateCompatibleDC32 (0);
1938 TRACE (imagelist
, "hdcImage=0x%x!\n", hdcImage
);
1940 ERR (imagelist
, "invalid hdcImage!\n");
1942 hbmOldDst
= SelectObject32 (hdcImageList
, himl
->hbmImage
);
1943 SetTextColor32( hdcImageList
, RGB(0,0,0));
1944 SetBkColor32( hdcImageList
, RGB(255,255,255));
1945 hbmOldSrc
= SelectObject32 (hdcImage
, ii
.hbmColor
);
1946 StretchBlt32 (hdcImageList
, nIndex
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
1947 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
1949 if (himl
->hbmMask
) {
1950 SelectObject32 (hdcImageList
, himl
->hbmMask
);
1951 SelectObject32 (hdcImage
, ii
.hbmMask
);
1952 StretchBlt32 (hdcImageList
, nIndex
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
1953 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
1956 SelectObject32 (hdcImage
, hbmOldSrc
);
1957 SelectObject32 (hdcImageList
, hbmOldDst
);
1960 DeleteDC32 (hdcImageList
);
1962 DeleteDC32 (hdcImage
);
1964 DeleteObject32 (ii
.hbmColor
);
1966 DeleteObject32 (ii
.hbmMask
);
1972 /*************************************************************************
1973 * ImageList_SetBkColor [COMCTL32.70]
1975 * Sets the background color of an image list.
1978 * himl [I] handle to image list
1979 * clrBk [I] background color
1982 * Success: previous background color
1987 ImageList_SetBkColor (HIMAGELIST himl
, COLORREF clrBk
)
1994 clrOldBk
= himl
->clrBk
;
1995 himl
->clrBk
= clrBk
;
2000 /*************************************************************************
2001 * ImageList_SetDragCursorImage [COMCTL32.75]
2003 * Combines the specified image with the current drag image
2006 * himlDrag [I] handle to drag image list
2007 * iDrag [I] drag image index
2008 * dxHotspot [I] X position of the hot spot
2009 * dyHotspot [I] Y position of the hot spot
2020 ImageList_SetDragCursorImage (HIMAGELIST himlDrag
, INT32 iDrag
,
2021 INT32 dxHotspot
, INT32 dyHotspot
)
2023 HIMAGELIST himlTemp
;
2025 FIXME (imagelist
, "semi-stub!\n");
2027 if (himlInternalDrag
== NULL
)
2030 TRACE (imagelist
, " dxH=%d dyH=%d nX=%d nY=%d\n",
2031 dxHotspot
, dyHotspot
, nInternalDragHotspotX
, nInternalDragHotspotY
);
2033 himlTemp
= ImageList_Merge (himlInternalDrag
, 0, himlDrag
, iDrag
,
2034 dxHotspot
, dyHotspot
);
2036 ImageList_Destroy (himlInternalDrag
);
2037 himlInternalDrag
= himlTemp
;
2039 nInternalDragHotspotX
= dxHotspot
;
2040 nInternalDragHotspotY
= dyHotspot
;
2046 /*************************************************************************
2047 * ImageList_SetFilter [COMCTL32.76]
2049 * Sets a filter (or does something completely different)!!???
2052 * himl [I] handle to image list
2058 * Failure: FALSE ???
2061 * This is an UNDOCUMENTED function!!!!
2066 ImageList_SetFilter (HIMAGELIST himl
, INT32 i
, DWORD dwFilter
)
2068 FIXME (imagelist
, "(%p 0x%x 0x%lx):empty stub!\n",
2075 /*************************************************************************
2076 * ImageList_SetIconSize [COMCTL32.77]
2078 * Sets the image size of the bitmap and deletes all images.
2081 * himl [I] handle to image list
2082 * cx [I] image width
2083 * cy [I] image height
2091 ImageList_SetIconSize (HIMAGELIST himl
, INT32 cx
, INT32 cy
)
2098 /* remove all images*/
2099 himl
->cMaxImage
= himl
->cInitial
+ himl
->cGrow
;
2100 himl
->cCurImage
= 0;
2104 /* initialize overlay mask indices */
2105 for (nCount
= 0; nCount
< MAX_OVERLAYIMAGE
; nCount
++)
2106 himl
->nOvlIdx
[nCount
] = -1;
2108 DeleteObject32 (himl
->hbmImage
);
2110 CreateBitmap32 (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
2111 1, himl
->uBitsPixel
, NULL
);
2113 if (himl
->hbmMask
) {
2114 DeleteObject32 (himl
->hbmMask
);
2116 CreateBitmap32 (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
2124 /*************************************************************************
2125 * ImageList_SetImageCount [COMCTL32.78]
2127 * Resizes an image list to the specified number of images.
2130 * himl [I] handle to image list
2131 * iImageCount [I] number of images in the image list
2139 ImageList_SetImageCount (HIMAGELIST himl
, INT32 iImageCount
)
2141 HDC32 hdcImageList
, hdcBitmap
;
2142 HBITMAP32 hbmNewBitmap
;
2143 INT32 nNewCount
, nCopyCount
;
2147 if (himl
->cCurImage
<= iImageCount
)
2149 if (himl
->cMaxImage
> iImageCount
)
2152 nNewCount
= iImageCount
+ himl
->cGrow
;
2153 nCopyCount
= _MIN(himl
->cCurImage
, iImageCount
);
2155 hdcImageList
= CreateCompatibleDC32 (0);
2156 hdcBitmap
= CreateCompatibleDC32 (0);
2158 hbmNewBitmap
= CreateBitmap32 (nNewCount
* himl
->cx
, himl
->cy
,
2159 1, himl
->uBitsPixel
, NULL
);
2160 if (hbmNewBitmap
== 0)
2162 SelectObject32 (hdcImageList
, himl
->hbmImage
);
2163 SelectObject32 (hdcBitmap
, hbmNewBitmap
);
2166 BitBlt32 (hdcBitmap
, 0, 0, nCopyCount
* himl
->cx
, himl
->cy
,
2167 hdcImageList
, 0, 0, SRCCOPY
);
2169 /* delete 'empty' image space */
2170 SetBkColor32 (hdcBitmap
, RGB(255, 255, 255));
2171 SetTextColor32 (hdcBitmap
, RGB(0, 0, 0));
2172 PatBlt32 (hdcBitmap
, nCopyCount
* himl
->cx
, 0,
2173 (nNewCount
- nCopyCount
) * himl
->cx
, himl
->cy
, BLACKNESS
);
2175 DeleteObject32 (himl
->hbmImage
);
2176 himl
->hbmImage
= hbmNewBitmap
;
2179 ERR (imagelist
, "Could not create new image bitmap !\n");
2183 hbmNewBitmap
= CreateBitmap32 (nNewCount
* himl
->cx
, himl
->cy
,
2185 if (hbmNewBitmap
!= 0)
2187 SelectObject32 (hdcImageList
, himl
->hbmMask
);
2188 SelectObject32 (hdcBitmap
, hbmNewBitmap
);
2191 BitBlt32 (hdcBitmap
, 0, 0, nCopyCount
* himl
->cx
, himl
->cy
,
2192 hdcImageList
, 0, 0, SRCCOPY
);
2194 /* delete 'empty' image space */
2195 SetBkColor32 (hdcBitmap
, RGB(255, 255, 255));
2196 SetTextColor32 (hdcBitmap
, RGB(0, 0, 0));
2197 PatBlt32 (hdcBitmap
, nCopyCount
* himl
->cx
, 0,
2198 (nNewCount
- nCopyCount
) * himl
->cx
, himl
->cy
, BLACKNESS
);
2200 DeleteObject32 (himl
->hbmMask
);
2201 himl
->hbmMask
= hbmNewBitmap
;
2204 ERR (imagelist
, "Could not create new mask bitmap!\n");
2207 DeleteDC32 (hdcImageList
);
2208 DeleteDC32 (hdcBitmap
);
2210 /* Update max image count and current image count */
2211 himl
->cMaxImage
= nNewCount
;
2212 if (himl
->cCurImage
> nCopyCount
)
2213 himl
->cCurImage
= nCopyCount
;
2219 /*************************************************************************
2220 * ImageList_SetOverlayImage [COMCTL32.79]
2222 * Assigns an overlay mask index to an existing image in an image list.
2225 * himl [I] handle to image list
2226 * iImage [I] image index
2227 * iOverlay [I] overlay mask index
2235 ImageList_SetOverlayImage (HIMAGELIST himl
, INT32 iImage
, INT32 iOverlay
)
2239 if ((iOverlay
< 1) || (iOverlay
> MAX_OVERLAYIMAGE
))
2241 if ((iImage
< 0) || (iImage
> himl
->cCurImage
))
2244 himl
->nOvlIdx
[iOverlay
- 1] = iImage
;
2249 /*************************************************************************
2250 * ImageList_Write [COMCTL32.80]
2252 * Writes an image list to a stream.
2255 * himl [I] handle to image list
2256 * pstm [O] Pointer to a stream.
2263 * This function can not be implemented yet, because
2264 * IStream32::Write is not implemented.
2271 ImageList_Write (HIMAGELIST himl
, LPSTREAM32 pstm
)
2276 FIXME (imagelist
, "empty stub!\n");