2 * ImageList implementation
4 * Copyright 1998 Eric Kohl
7 * - Fix xBitmap and yBitmap in ImageList_DrawIndirect.
8 * - Fix ILD_TRANSPARENT error in ImageList_DrawIndirect.
9 * - Fix ImageList_GetIcon (might be a result of the
10 * ILD_TRANSPARENT error in ImageList_DrawIndirect).
11 * - Fix drag functions.
12 * - Fix ImageList_Read and ImageList_Write.
13 * - Fix ImageList_SetFilter (undocumented).
14 * BTW does anybody know anything about this function???
15 * - It removes 12 Bytes from the stack (3 Parameters).
16 * - First parameter SHOULD be a HIMAGELIST.
17 * - Second parameter COULD be an index?????
18 * - Third parameter.... ?????????????????????
21 * - ImageList_Draw, ImageList_DrawEx and ImageList_GetIcon use
22 * ImageList_DrawIndirect. Since ImageList_DrawIndirect is still
23 * partially imlemented, the functions mentioned above will be
24 * limited in functionality too.
27 /* This must be defined because the HIMAGELIST type is just a pointer
28 * to the _IMAGELIST data structure. But M$ does not want us to know
29 * anything about its contents. Applications just see a pointer to
30 * an empty structure. It's just to keep compatibility.
32 #define __WINE_IMAGELIST_C
38 #include "imagelist.h"
43 #define _MAX(a,b) (((a)>(b))?(a):(b))
44 #define _MIN(a,b) (((a)>(b))?(b):(a))
46 #define MAX_OVERLAYIMAGE 15
49 /* internal image list data used for Drag & Drop operations */
51 static HIMAGELIST himlInternalDrag
= NULL
;
52 static INT32 nInternalDragHotspotX
= 0;
53 static INT32 nInternalDragHotspotY
= 0;
55 static HWND32 hwndInternalDrag
= 0;
56 static INT32 xInternalPos
= 0;
57 static INT32 yInternalPos
= 0;
59 static HDC32 hdcBackBuffer
= 0;
60 static HBITMAP32 hbmBackBuffer
= 0;
63 /*************************************************************************
64 * IMAGELIST_InternalExpandBitmaps [Internal]
66 * Expands the bitmaps of an image list by the given number of images.
69 * himl [I] image list handle
70 * nImageCount [I] Number of images to add.
76 * This function can NOT be used to reduce the number of images.
80 IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl
, INT32 nImageCount
)
82 HDC32 hdcImageList
, hdcBitmap
;
83 HBITMAP32 hbmNewBitmap
;
84 INT32 nNewWidth
, nNewCount
;
86 TRACE(imagelist
, "Create expanded bitmaps!\n");
88 nNewCount
= himl
->cCurImage
+ nImageCount
+ himl
->cGrow
;
89 nNewWidth
= nNewCount
* himl
->cx
;
91 hdcImageList
= CreateCompatibleDC32 (0);
92 hdcBitmap
= CreateCompatibleDC32 (0);
95 CreateBitmap32 (nNewWidth
, himl
->cy
, 1, himl
->uBitsPixel
, NULL
);
96 if (hbmNewBitmap
== 0)
97 ERR (imagelist
, "creating new image bitmap!\n");
99 SelectObject32 (hdcImageList
, himl
->hbmImage
);
100 SelectObject32 (hdcBitmap
, hbmNewBitmap
);
101 BitBlt32 (hdcBitmap
, 0, 0, himl
->cCurImage
* himl
->cx
, himl
->cy
,
102 hdcImageList
, 0, 0, SRCCOPY
);
104 DeleteObject32 (himl
->hbmImage
);
105 himl
->hbmImage
= hbmNewBitmap
;
109 CreateBitmap32 (nNewWidth
, himl
->cy
, 1, 1, NULL
);
111 if (hbmNewBitmap
== 0)
112 ERR (imagelist
, "creating new mask bitmap!");
114 SelectObject32 (hdcImageList
, himl
->hbmMask
);
115 SelectObject32 (hdcBitmap
, hbmNewBitmap
);
116 BitBlt32 (hdcBitmap
, 0, 0, himl
->cCurImage
* himl
->cx
, himl
->cy
,
117 hdcImageList
, 0, 0, SRCCOPY
);
118 DeleteObject32 (himl
->hbmMask
);
119 himl
->hbmMask
= hbmNewBitmap
;
122 himl
->cMaxImage
= nNewCount
;
124 DeleteDC32 (hdcImageList
);
125 DeleteDC32 (hdcBitmap
);
129 /*************************************************************************
130 * ImageList_Add [COMCTL32.39]
132 * Add an image or images to an image list.
135 * himl [I] image list handle
136 * hbmImage [I] image bitmap handle
137 * hbmMask [I] mask bitmap handle
140 * Success: Index of the first new image.
145 ImageList_Add (HIMAGELIST himl
, HBITMAP32 hbmImage
, HBITMAP32 hbmMask
)
147 HDC32 hdcSrc
, hdcDst
;
148 INT32 nFirstIndex
, nImageCount
;
149 INT32 nStartX
, nRunX
, nRunY
;
152 if (himl
== NULL
) return (-1);
153 if (hbmImage
== 0) return (-1);
155 GetObject32A (hbmImage
, sizeof(BITMAP32
), (LPVOID
)&bmp
);
156 nImageCount
= bmp
.bmWidth
/ himl
->cx
;
158 if (himl
->cCurImage
+ nImageCount
>= himl
->cMaxImage
)
159 IMAGELIST_InternalExpandBitmaps (himl
, nImageCount
);
161 hdcSrc
= CreateCompatibleDC32 (0);
162 hdcDst
= CreateCompatibleDC32 (0);
164 SelectObject32 (hdcDst
, himl
->hbmImage
);
165 SelectObject32 (hdcSrc
, hbmImage
);
167 BitBlt32 (hdcDst
, himl
->cCurImage
* himl
->cx
, 0,
168 bmp
.bmWidth
, himl
->cy
, hdcSrc
, 0, 0, SRCCOPY
);
172 SelectObject32 (hdcDst
, himl
->hbmMask
);
173 SelectObject32 (hdcSrc
, hbmMask
);
174 BitBlt32 (hdcDst
, himl
->cCurImage
* himl
->cx
, 0,
175 bmp
.bmWidth
, himl
->cy
, hdcSrc
, 0, 0, SRCCOPY
);
177 /* fix transparent areas of the image bitmap*/
178 SelectObject32 (hdcSrc
, himl
->hbmMask
);
179 SelectObject32 (hdcDst
, himl
->hbmImage
);
180 nStartX
= himl
->cCurImage
* himl
->cx
;
182 for (nRunY
= 0; nRunY
< himl
->cy
; nRunY
++) {
183 for (nRunX
= 0; nRunX
< bmp
.bmWidth
; nRunX
++) {
184 if (GetPixel32 (hdcSrc
, nStartX
+ nRunX
, nRunY
) !=
186 SetPixel32 (hdcDst
, nStartX
+ nRunX
, nRunY
,
192 /* create mask from the imagelist's background color */
193 SelectObject32 (hdcDst
, himl
->hbmMask
);
194 SelectObject32 (hdcSrc
, himl
->hbmImage
);
195 nStartX
= himl
->cCurImage
* himl
->cx
;
196 for (nRunY
= 0; nRunY
< himl
->cy
; nRunY
++) {
197 for (nRunX
= 0; nRunX
< bmp
.bmWidth
; nRunX
++) {
198 if (GetPixel32 (hdcSrc
, nStartX
+ nRunX
, nRunY
) ==
201 SetPixel32 (hdcSrc
, nStartX
+ nRunX
, nRunY
,
203 SetPixel32 (hdcDst
, nStartX
+ nRunX
, nRunY
,
207 SetPixel32 (hdcDst
, nStartX
+ nRunX
, nRunY
,
217 nFirstIndex
= himl
->cCurImage
;
218 himl
->cCurImage
+= nImageCount
;
220 return (nFirstIndex
);
224 /*************************************************************************
225 * ImageList_AddIcon [COMCTL32.40]
227 * Adds an icon to an image list.
230 * himl [I] image list handle
231 * hIcon [I] icon handle
234 * Success: index of the new image
239 ImageList_AddIcon (HIMAGELIST himl
, HICON32 hIcon
)
241 return (ImageList_ReplaceIcon (himl
, -1, hIcon
));
245 /*************************************************************************
246 * ImageList_AddMasked [COMCTL32.41]
248 * Adds an image or images to an image list and creates a mask from the
249 * specified bitmap using the mask color.
252 * himl [I] image list handle.
253 * hbmImage [I] image bitmap handle.
254 * clrMask [I] mask color.
257 * Success: Index of the first new image.
262 ImageList_AddMasked (HIMAGELIST himl
, HBITMAP32 hbmImage
, COLORREF clrMask
)
264 HDC32 hdcImageList
, hdcImage
, hdcMask
;
265 INT32 nIndex
, nImageCount
;
267 INT32 nStartX
, nRunX
, nRunY
;
273 bkColor
= (clrMask
== CLR_NONE
) ? himl
->clrBk
: clrMask
;
275 GetObject32A (hbmImage
, sizeof(BITMAP32
), &bmp
);
276 nImageCount
= bmp
.bmWidth
/ himl
->cx
;
278 if (himl
->cCurImage
+ nImageCount
>= himl
->cMaxImage
)
279 IMAGELIST_InternalExpandBitmaps (himl
, nImageCount
);
281 nIndex
= himl
->cCurImage
;
282 himl
->cCurImage
+= nImageCount
;
284 hdcImageList
= CreateCompatibleDC32 (0);
285 hdcImage
= CreateCompatibleDC32 (0);
287 SelectObject32 (hdcImageList
, himl
->hbmImage
);
288 SelectObject32 (hdcImage
, hbmImage
);
289 BitBlt32 (hdcImageList
, nIndex
* himl
->cx
, 0, bmp
.bmWidth
, himl
->cy
,
290 hdcImage
, 0, 0, SRCCOPY
);
294 hdcMask
= CreateCompatibleDC32 (0);
295 SelectObject32 (hdcMask
, himl
->hbmMask
);
296 nStartX
= nIndex
* himl
->cx
;
297 for (nRunY
= 0; nRunY
< himl
->cy
; nRunY
++) {
298 for (nRunX
= 0; nRunX
< bmp
.bmWidth
; nRunX
++) {
299 if (GetPixel32 (hdcImageList
, nStartX
+ nRunX
, nRunY
) ==
301 SetPixel32 (hdcImageList
, nStartX
+ nRunX
, nRunY
,
303 SetPixel32 (hdcMask
, nStartX
+ nRunX
, nRunY
,
307 SetPixel32 (hdcMask
, nStartX
+ nRunX
, nRunY
, RGB(0, 0, 0));
310 DeleteDC32 (hdcMask
);
313 DeleteDC32 (hdcImageList
);
314 DeleteDC32 (hdcImage
);
320 /*************************************************************************
321 * ImageList_BeginDrag [COMCTL32.42]
323 * Creates a temporary image list that contains one image. It will be used
327 * himlTrack [I] Handle of the source image list
328 * iTrack [I] Index of the drag image in the source image list
329 * dxHotspot [I] X position of the hot spot of the drag image
330 * dyHotspot [I] Y position of the hot spot of the drag image
338 ImageList_BeginDrag (HIMAGELIST himlTrack
, INT32 iTrack
,
339 INT32 dxHotspot
, INT32 dyHotspot
)
341 HDC32 hdcSrc
, hdcDst
;
343 FIXME(imagelist
, "partially implemented!\n");
345 if (himlTrack
== NULL
)
348 if (himlInternalDrag
)
349 ImageList_EndDrag ();
352 ImageList_Create (himlTrack
->cx
, himlTrack
->cy
,
353 himlTrack
->flags
, 1, 1);
354 if (himlInternalDrag
== NULL
) {
355 ERR(imagelist
, "Error creating drag image list!\n");
359 nInternalDragHotspotX
= dxHotspot
;
360 nInternalDragHotspotY
= dyHotspot
;
362 hdcSrc
= CreateCompatibleDC32 (0);
363 hdcDst
= CreateCompatibleDC32 (0);
366 SelectObject32 (hdcSrc
, himlTrack
->hbmImage
);
367 SelectObject32 (hdcDst
, himlInternalDrag
->hbmImage
);
368 StretchBlt32 (hdcDst
, 0, 0, himlInternalDrag
->cx
, himlInternalDrag
->cy
, hdcSrc
,
369 iTrack
* himlTrack
->cx
, 0, himlTrack
->cx
, himlTrack
->cy
, SRCCOPY
);
372 SelectObject32 (hdcSrc
, himlTrack
->hbmMask
);
373 SelectObject32 (hdcDst
, himlInternalDrag
->hbmMask
);
374 StretchBlt32 (hdcDst
, 0, 0, himlInternalDrag
->cx
, himlInternalDrag
->cy
, hdcSrc
,
375 iTrack
* himlTrack
->cx
, 0, himlTrack
->cx
, himlTrack
->cy
, SRCCOPY
);
380 himlInternalDrag
->cCurImage
= 1;
386 /*************************************************************************
387 * ImageList_Copy [COMCTL32.43]
389 * Copies an image of the source image list to an image of the
390 * destination image list. Images can be copied or swapped.
393 * himlDst [I] destination image list handle.
394 * iDst [I] destination image index.
395 * himlSrc [I] source image list handle
396 * iSrc [I] source image index
397 * uFlags [I] flags for the copy operation
404 * Copying from one image list to another is possible. The original
405 * implementation just copies or swapps within one image list.
406 * Could this feature become a bug??? ;-)
410 ImageList_Copy (HIMAGELIST himlDst
, INT32 iDst
, HIMAGELIST himlSrc
,
411 INT32 iSrc
, INT32 uFlags
)
413 HDC32 hdcSrc
, hdcDst
;
415 TRACE(imagelist
, "iDst=%d iSrc=%d\n", iDst
, iSrc
);
417 if ((himlSrc
== NULL
) || (himlDst
== NULL
)) return (FALSE
);
418 if ((iDst
< 0) || (iDst
>= himlDst
->cCurImage
)) return (FALSE
);
419 if ((iSrc
< 0) || (iSrc
>= himlSrc
->cCurImage
)) return (FALSE
);
421 hdcSrc
= CreateCompatibleDC32 (0);
422 if (himlDst
== himlSrc
)
425 hdcDst
= CreateCompatibleDC32 (0);
427 if (uFlags
& ILCF_SWAP
) {
429 HBITMAP32 hbmTempImage
, hbmTempMask
;
431 /* create temporary bitmaps */
432 hbmTempImage
= CreateBitmap32 (himlSrc
->cx
, himlSrc
->cy
, 1,
433 himlSrc
->uBitsPixel
, NULL
);
434 hbmTempMask
= CreateBitmap32 (himlSrc
->cx
, himlSrc
->cy
, 1,
437 /* copy (and stretch) destination to temporary bitmaps.(save) */
439 SelectObject32 (hdcSrc
, himlDst
->hbmImage
);
440 SelectObject32 (hdcDst
, hbmTempImage
);
441 StretchBlt32 (hdcDst
, 0, 0, himlSrc
->cx
, himlSrc
->cy
,
442 hdcSrc
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
445 SelectObject32 (hdcSrc
, himlDst
->hbmMask
);
446 SelectObject32 (hdcDst
, hbmTempMask
);
447 StretchBlt32 (hdcDst
, 0, 0, himlSrc
->cx
, himlSrc
->cy
,
448 hdcSrc
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
451 /* copy (and stretch) source to destination */
453 SelectObject32 (hdcSrc
, himlSrc
->hbmImage
);
454 SelectObject32 (hdcDst
, himlDst
->hbmImage
);
455 StretchBlt32 (hdcDst
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
456 hdcSrc
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
459 SelectObject32 (hdcSrc
, himlSrc
->hbmMask
);
460 SelectObject32 (hdcDst
, himlDst
->hbmMask
);
461 StretchBlt32 (hdcDst
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
462 hdcSrc
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
465 /* copy (without stretching) temporary bitmaps to source (restore) */
467 SelectObject32 (hdcSrc
, hbmTempImage
);
468 SelectObject32 (hdcDst
, himlSrc
->hbmImage
);
469 BitBlt32 (hdcDst
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
470 hdcSrc
, 0, 0, SRCCOPY
);
472 SelectObject32 (hdcSrc
, hbmTempMask
);
473 SelectObject32 (hdcDst
, himlSrc
->hbmMask
);
474 BitBlt32 (hdcDst
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
475 hdcSrc
, 0, 0, SRCCOPY
);
477 /* delete temporary bitmaps */
478 DeleteObject32 (hbmTempMask
);
479 DeleteObject32 (hbmTempImage
);
483 SelectObject32 (hdcSrc
, himlSrc
->hbmImage
);
484 if (himlSrc
== himlDst
)
487 SelectObject32 (hdcDst
, himlDst
->hbmImage
);
488 StretchBlt32 (hdcDst
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
489 hdcSrc
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
493 SelectObject32 (hdcSrc
, himlSrc
->hbmMask
);
494 if (himlSrc
== himlDst
)
497 SelectObject32 (hdcDst
, himlDst
->hbmMask
);
498 StretchBlt32 (hdcDst
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
499 hdcSrc
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
504 if (himlSrc
!= himlDst
)
511 /*************************************************************************
512 * ImageList_Create [COMCTL32.44]
514 * Creates a new image list.
517 * cx [I] image height
519 * flags [I] creation flags
520 * cInitial [I] initial number of images in the image list
521 * cGrow [I] number of images by which image list grows
524 * Success: Handle of the created image list
529 ImageList_Create (INT32 cx
, INT32 cy
, UINT32 flags
,
530 INT32 cInitial
, INT32 cGrow
)
536 WORD aBitBlend25
[16] =
537 {0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD,
538 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD};
539 WORD aBitBlend50
[16] =
540 {0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA,
541 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA};
543 TRACE (imagelist
, "(%d %d 0x%x %d %d)\n", cx
, cy
, flags
, cInitial
, cGrow
);
545 himl
= (HIMAGELIST
)LocalAlloc32 (LMEM_FIXED
| LMEM_ZEROINIT
,
546 sizeof(struct _IMAGELIST
));
552 himl
->cMaxImage
= cInitial
+ cGrow
;
553 himl
->cInitial
= cInitial
;
556 himl
->clrBk
= CLR_NONE
;
558 /* initialize overlay mask indices */
559 for (nCount
= 0; nCount
< MAX_OVERLAYIMAGE
; nCount
++)
560 himl
->nOvlIdx
[nCount
] = -1;
562 hdc
= CreateCompatibleDC32 (0);
563 himl
->uBitsPixel
= (UINT32
)GetDeviceCaps32 (hdc
, BITSPIXEL
);
566 TRACE(imagelist
, "Image: %d Bits per Pixel\n", himl
->uBitsPixel
);
569 CreateBitmap32 (himl
->cx
* himl
->cMaxImage
, himl
->cy
,
570 1, himl
->uBitsPixel
, NULL
);
571 if (himl
->hbmImage
== 0) {
572 ERR(imagelist
, "Error creating image bitmap!\n");
576 if (himl
->flags
& ILC_MASK
) {
577 himl
->hbmMask
= CreateBitmap32 (himl
->cx
* himl
->cMaxImage
, himl
->cy
,
579 if (himl
->hbmMask
== 0) {
580 ERR(imagelist
, "Error creating mask bitmap!\n");
582 DeleteObject32 (himl
->hbmImage
);
589 /* create blending brushes */
590 hbmTemp
= CreateBitmap32 (16, 16, 1, 1, &aBitBlend25
);
591 himl
->hbrBlend25
= CreatePatternBrush32 (hbmTemp
);
592 DeleteObject32 (hbmTemp
);
594 hbmTemp
= CreateBitmap32 (16, 16, 1, 1, &aBitBlend50
);
595 himl
->hbrBlend50
= CreatePatternBrush32 (hbmTemp
);
596 DeleteObject32 (hbmTemp
);
602 /*************************************************************************
603 * ImageList_Destroy [COMCTL32.45]
605 * Destroys an image list.
608 * himl [I] image list handle
616 ImageList_Destroy (HIMAGELIST himl
)
618 if (himl
== NULL
) return (FALSE
);
621 DeleteObject32 (himl
->hbmImage
);
623 DeleteObject32 (himl
->hbmMask
);
625 LocalFree32 ((HLOCAL32
)himl
);
630 /*************************************************************************
631 * ImageList_DragEnter [COMCTL32.46]
633 * Locks window update and displays the drag image at the given position.
636 * hwndLock [I] handle of the window that owns the drag image.
637 * x [I] X position of the drag image.
638 * y [I] Y position of the drag image.
645 * The position of the drag image is relative to the window, not
650 ImageList_DragEnter (HWND32 hwndLock
, INT32 x
, INT32 y
)
652 if (himlInternalDrag
== NULL
) return (FALSE
);
655 hwndInternalDrag
= hwndLock
;
657 hwndInternalDrag
= GetDesktopWindow32 ();
662 hdcBackBuffer
= CreateCompatibleDC32 (0);
663 hbmBackBuffer
= CreateCompatibleBitmap32 (hdcBackBuffer
,
664 himlInternalDrag
->cx
, himlInternalDrag
->cy
);
666 ImageList_DragShowNolock (TRUE
);
672 /*************************************************************************
673 * ImageList_DragLeave [COMCTL32.47]
675 * Unlocks window update and hides the drag image.
678 * hwndLock [I] handle of the window that owns the drag image.
686 ImageList_DragLeave (HWND32 hwndLock
)
689 hwndInternalDrag
= hwndLock
;
691 hwndInternalDrag
= GetDesktopWindow32 ();
693 ImageList_DragShowNolock (FALSE
);
695 DeleteDC32 (hdcBackBuffer
);
696 DeleteObject32 (hbmBackBuffer
);
702 /*************************************************************************
703 * ImageList_DragMove [COMCTL32.48]
705 * Moves the drag image.
708 * x [I] X position of the drag image.
709 * y [I] Y position of the drag image.
716 * The position of the drag image is relative to the window, not
721 ImageList_DragMove (INT32 x
, INT32 y
)
723 ImageList_DragShowNolock (FALSE
);
728 ImageList_DragShowNolock (TRUE
);
734 /*************************************************************************
735 * ImageList_DragShowNolock [COMCTL32.49]
737 * Shows or hides the drag image.
740 * bShow [I] TRUE shows the drag image, FALSE hides it.
751 ImageList_DragShowNolock (BOOL32 bShow
)
755 FIXME (imagelist
, "semi-stub!\n");
756 TRACE (imagelist
, "bShow=0x%X!\n", bShow
);
758 hdcDrag
= GetDCEx32 (hwndInternalDrag
, 0,
759 DCX_WINDOW
| DCX_CACHE
| DCX_LOCKWINDOWUPDATE
);
762 /* show drag image */
764 /* save background */
766 /* draw drag image */
770 /* hide drag image */
772 /* restore background */
776 ReleaseDC32 (hwndInternalDrag
, hdcDrag
);
782 /*************************************************************************
783 * ImageList_Draw [COMCTL32.50] Draws an image.
786 * himl [I] image list handle
788 * hdc [I] display context handle
791 * fStyle [I] drawing flags
798 * Calls ImageList_DrawIndirect.
801 * ImageList_DrawIndirect.
805 ImageList_Draw (HIMAGELIST himl
, INT32 i
, HDC32 hdc
,
806 INT32 x
, INT32 y
, UINT32 fStyle
)
808 IMAGELISTDRAWPARAMS imldp
;
810 imldp
.cbSize
= sizeof(IMAGELISTDRAWPARAMS
);
820 imldp
.rgbBk
= CLR_DEFAULT
;
821 imldp
.rgbFg
= CLR_DEFAULT
;
822 imldp
.fStyle
= fStyle
;
825 return (ImageList_DrawIndirect (&imldp
));
829 /*************************************************************************
830 * ImageList_DrawEx [COMCTL32.51]
832 * Draws an image and allows to use extended drawing features.
835 * himl [I] image list handle
837 * hdc [I] device context handle
842 * rgbBk [I] background color
843 * rgbFg [I] foreground color
844 * fStyle [I] drawing flags
851 * Calls ImageList_DrawIndirect.
854 * ImageList_DrawIndirect.
858 ImageList_DrawEx (HIMAGELIST himl
, INT32 i
, HDC32 hdc
, INT32 x
, INT32 y
,
859 INT32 dx
, INT32 dy
, COLORREF rgbBk
, COLORREF rgbFg
,
862 IMAGELISTDRAWPARAMS imldp
;
864 imldp
.cbSize
= sizeof(IMAGELISTDRAWPARAMS
);
876 imldp
.fStyle
= fStyle
;
879 return (ImageList_DrawIndirect (&imldp
));
883 /*************************************************************************
884 * ImageList_DrawIndirect [COMCTL32.52]
886 * Draws an image using ...
889 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
897 ImageList_DrawIndirect (IMAGELISTDRAWPARAMS
*pimldp
)
899 HIMAGELIST himlLocal
;
900 HDC32 hdcImageList
, hdcTempImage
;
901 HBITMAP32 hbmTempImage
;
902 HBRUSH32 hBrush
, hOldBrush
;
906 BOOL32 bImage
; /* draw image ? */
907 BOOL32 bImageTrans
; /* draw image transparent ? */
908 BOOL32 bMask
; /* draw mask ? */
909 BOOL32 bMaskTrans
; /* draw mask transparent ? */
913 if (pimldp
== NULL
) return (FALSE
);
914 if (pimldp
->cbSize
< sizeof(IMAGELISTDRAWPARAMS
)) return (FALSE
);
915 if (pimldp
->himl
== NULL
) return (FALSE
);
916 if ((pimldp
->i
< 0) || (pimldp
->i
>= pimldp
->himl
->cCurImage
))
919 himlLocal
= pimldp
->himl
;
921 cx
= (pimldp
->cx
== 0) ? himlLocal
->cx
: pimldp
->cx
;
922 cy
= (pimldp
->cy
== 0) ? himlLocal
->cy
: pimldp
->cy
;
924 /* ILD_NORMAL state */
931 if ((himlLocal
->clrBk
== CLR_NONE
) && (himlLocal
->hbmMask
))
938 /* ILD_IMAGE state (changes) */
939 if (pimldp
->fStyle
& ILD_IMAGE
)
946 /* ILD_MASK state (changes) */
947 if ((pimldp
->fStyle
& ILD_MASK
) && (himlLocal
->hbmMask
))
953 if ((pimldp
->fStyle
& ILD_TRANSPARENT
) && (himlLocal
->hbmMask
))
958 if ((himlLocal
->clrBk
== CLR_NONE
) && (himlLocal
->hbmMask
))
961 if (pimldp
->fStyle
& ILD_BLEND50
)
963 else if (pimldp
->fStyle
& ILD_BLEND25
)
966 hdcImageList
= CreateCompatibleDC32 (0);
971 SelectObject32 (hdcImageList
, himlLocal
->hbmMask
);
972 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
, cx
, cy
,
973 hdcImageList
, himlLocal
->cx
* pimldp
->i
, 0,
974 bMaskTrans
? SRCAND
: SRCCOPY
);
980 SelectObject32 (hdcImageList
, himlLocal
->hbmImage
);
984 hBrush
= CreateSolidBrush32 (himlLocal
->clrBk
);
985 hOldBrush
= SelectObject32 (pimldp
->hdcDst
, hBrush
);
986 PatBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
,
988 DeleteObject32 (SelectObject32 (pimldp
->hdcDst
, hOldBrush
));
991 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
, cx
, cy
,
992 hdcImageList
, himlLocal
->cx
* pimldp
->i
, 0,
995 if (bBlend25
|| bBlend50
)
997 if (pimldp
->rgbFg
== CLR_DEFAULT
)
998 clrBlend
= GetSysColor32 (COLOR_HIGHLIGHT
);
1000 clrBlend
= pimldp
->rgbFg
;
1002 hdcTempImage
= CreateCompatibleDC32 (0);
1003 hbmTempImage
= CreateBitmap32 (himlLocal
->cx
, himlLocal
->cy
,
1004 1, himlLocal
->uBitsPixel
, NULL
);
1005 SelectObject32 (hdcTempImage
, hbmTempImage
);
1009 SelectObject32 (hdcTempImage
,
1010 bBlend50
? himlLocal
->hbrBlend50
: himlLocal
->hbrBlend25
);
1011 PatBlt32 (hdcTempImage
, 0, 0, himlLocal
->cx
, himlLocal
->cy
, PATCOPY
);
1013 SelectObject32 (hdcImageList
, himlLocal
->hbmMask
);
1014 BitBlt32 (hdcTempImage
, 0, 0, himlLocal
->cx
,
1015 himlLocal
->cy
, hdcImageList
,
1016 pimldp
->i
* himlLocal
->cx
, 0, SRCPAINT
);
1018 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
, cx
, cy
,
1019 hdcTempImage
, 0, 0, SRCAND
);
1022 hBrush
= CreateSolidBrush32 (clrBlend
);
1023 SelectObject32 (hdcTempImage
, hBrush
);
1024 PatBlt32 (hdcTempImage
, 0, 0, himlLocal
->cx
, himlLocal
->cy
, PATCOPY
);
1025 DeleteObject32 (hBrush
);
1027 SelectObject32 (hdcTempImage
,
1028 bBlend50
? himlLocal
->hbrBlend50
: himlLocal
->hbrBlend25
);
1029 PatBlt32 (hdcTempImage
, 0, 0, himlLocal
->cx
, himlLocal
->cy
, 0x0A0329);
1031 SelectObject32 (hdcImageList
, himlLocal
->hbmMask
);
1032 BitBlt32 (hdcTempImage
, 0, 0, himlLocal
->cx
,
1033 himlLocal
->cy
, hdcImageList
,
1034 pimldp
->i
* himlLocal
->cx
, 0, SRCPAINT
);
1036 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
, cx
, cy
,
1037 hdcTempImage
, 0, 0, SRCPAINT
);
1039 DeleteObject32 (hbmTempImage
);
1040 DeleteDC32 (hdcTempImage
);
1044 /* Draw overlay image */
1045 if (pimldp
->fStyle
& 0x0700) {
1046 nOvlIdx
= (pimldp
->fStyle
& 0x0700) >> 8;
1047 if ((nOvlIdx
>= 1) && (nOvlIdx
<= MAX_OVERLAYIMAGE
)) {
1048 nOvlIdx
= pimldp
->himl
->nOvlIdx
[nOvlIdx
- 1];
1049 if ((nOvlIdx
>= 0) && (nOvlIdx
<= pimldp
->himl
->cCurImage
)) {
1050 if (pimldp
->himl
->hbmMask
) {
1051 SelectObject32 (hdcImageList
, pimldp
->himl
->hbmMask
);
1052 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
, cx
, cy
,
1053 hdcImageList
, pimldp
->himl
->cx
* nOvlIdx
, 0,
1056 SelectObject32 (hdcImageList
, pimldp
->himl
->hbmImage
);
1057 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
,
1058 cx
, cy
, hdcImageList
,
1059 pimldp
->himl
->cx
* nOvlIdx
, 0, SRCPAINT
);
1064 DeleteDC32 (hdcImageList
);
1070 /*************************************************************************
1071 * ImageList_Duplicate [COMCTL32.53] Duplicates an image list.
1074 * himlSrc [I] source image list handle
1077 * Success: Handle of duplicated image list.
1082 ImageList_Duplicate (HIMAGELIST himlSrc
)
1085 HDC32 hdcSrc
, hdcDst
;
1087 if (himlSrc
== NULL
) {
1088 ERR (imagelist
, "Invalid image list handle!\n");
1092 himlDst
= ImageList_Create (himlSrc
->cx
, himlSrc
->cy
, himlSrc
->flags
,
1093 himlSrc
->cInitial
, himlSrc
->cGrow
);
1097 hdcSrc
= CreateCompatibleDC32 (0);
1098 hdcDst
= CreateCompatibleDC32 (0);
1099 SelectObject32 (hdcSrc
, himlSrc
->hbmImage
);
1100 SelectObject32 (hdcDst
, himlDst
->hbmImage
);
1101 BitBlt32 (hdcDst
, 0, 0, himlSrc
->cCurImage
* himlSrc
->cx
, himlSrc
->cy
,
1102 hdcSrc
, 0, 0, SRCCOPY
);
1104 if (himlDst
->hbmMask
)
1106 SelectObject32 (hdcSrc
, himlSrc
->hbmMask
);
1107 SelectObject32 (hdcDst
, himlDst
->hbmMask
);
1108 BitBlt32 (hdcDst
, 0, 0, himlSrc
->cCurImage
* himlSrc
->cx
,
1109 himlSrc
->cy
, hdcSrc
, 0, 0, SRCCOPY
);
1112 DeleteDC32 (hdcDst
);
1113 DeleteDC32 (hdcSrc
);
1120 /*************************************************************************
1121 * ImageList_EndDrag [COMCTL32.54] Finishes a drag operation.
1123 * Finishes a drag operation.
1137 ImageList_EndDrag (VOID
)
1139 FIXME (imagelist
, "semi-stub!\n");
1141 if (himlInternalDrag
)
1144 ImageList_Destroy (himlInternalDrag
);
1145 himlInternalDrag
= NULL
;
1147 nInternalDragHotspotX
= 0;
1148 nInternalDragHotspotY
= 0;
1156 /*************************************************************************
1157 * ImageList_GetBkColor [COMCTL32.55]
1159 * Returns the background color of an image list.
1162 * himl [I] Image list handle.
1165 * Success: background color
1170 ImageList_GetBkColor (HIMAGELIST himl
)
1175 return (himl
->clrBk
);
1179 /*************************************************************************
1180 * ImageList_GetDragImage [COMCTL32.56]
1182 * Returns the handle to the internal drag image list.
1185 * ppt [O] Pointer to the drag position. Can be NULL.
1186 * pptHotspot [O] Pointer to the position of the hot spot. Can be NULL.
1189 * Success: Handle of the drag image list.
1197 ImageList_GetDragImage (POINT32
*ppt
, POINT32
*pptHotspot
)
1199 FIXME (imagelist
, "semi-stub!\n");
1201 if (himlInternalDrag
)
1202 return (himlInternalDrag
);
1208 /*************************************************************************
1209 * ImageList_GetIcon [COMCTL32.57]
1211 * Creates an icon from a masked image of an image list.
1214 * himl [I] image list handle
1216 * flags [I] drawing style flags
1219 * Success: icon handle
1224 ImageList_GetIcon (HIMAGELIST himl
, INT32 i
, UINT32 fStyle
)
1229 INT32 nWidth
, nHeight
;
1231 if (himl
== NULL
) return 0;
1232 if ((i
< 0) || (i
>= himl
->cCurImage
)) return 0;
1234 nWidth
= GetSystemMetrics32 (SM_CXICON
);
1235 nHeight
= GetSystemMetrics32 (SM_CYICON
);
1240 ii
.hbmMask
= CreateBitmap32 (nWidth
, nHeight
, 1, 1, NULL
);
1241 ii
.hbmColor
= CreateBitmap32 (nWidth
, nHeight
, 1, himl
->uBitsPixel
, NULL
);
1243 hdc
= CreateCompatibleDC32(0);
1246 SelectObject32 (hdc
, ii
.hbmColor
);
1247 PatBlt32 (hdc
, 0, 0, nWidth
, nHeight
, BLACKNESS
);
1248 ImageList_Draw (himl
, i
, hdc
, 0, 0, fStyle
| ILD_TRANSPARENT
);
1251 SelectObject32 (hdc
, ii
.hbmMask
);
1252 PatBlt32 (hdc
, 0, 0, nWidth
, nHeight
, WHITENESS
);
1253 ImageList_Draw (himl
, i
, hdc
, 0, 0, fStyle
| ILD_MASK
);
1255 hIcon
= CreateIconIndirect (&ii
);
1258 DeleteObject32 (ii
.hbmMask
);
1259 DeleteObject32 (ii
.hbmColor
);
1265 /*************************************************************************
1266 * ImageList_GetIconSize [COMCTL32.58]
1268 * Retrieves the size of an image in an image list.
1271 * himl [I] image list handle
1272 * cx [O] pointer to the image width.
1273 * cy [O] pointer to the image height.
1280 * All images in an image list have the same size.
1284 ImageList_GetIconSize (HIMAGELIST himl
, INT32
*cx
, INT32
*cy
)
1287 if (himl
== NULL
) return (FALSE
);
1298 /*************************************************************************
1299 * ImageList_GetImageCount [COMCTL32.59]
1301 * Returns the number of images in an image list.
1304 * himl [I] image list handle.
1307 * Success: Number of images.
1312 ImageList_GetImageCount (HIMAGELIST himl
)
1317 return (himl
->cCurImage
);
1321 /*************************************************************************
1322 * ImageList_GetImageInfo [COMCTL32.60]
1324 * Returns information about an image in an image list.
1327 * himl [I] image list handle.
1329 * pImageInfo [O] pointer to the image information.
1337 ImageList_GetImageInfo (HIMAGELIST himl
, INT32 i
, IMAGEINFO
*pImageInfo
)
1339 if ((himl
== NULL
) || (pImageInfo
== NULL
)) return (FALSE
);
1340 if ((i
< 0) || (i
>= himl
->cCurImage
)) return (FALSE
);
1342 pImageInfo
->hbmImage
= himl
->hbmImage
;
1343 pImageInfo
->hbmMask
= himl
->hbmMask
;
1345 pImageInfo
->rcImage
.top
= 0;
1346 pImageInfo
->rcImage
.bottom
= himl
->cy
;
1347 pImageInfo
->rcImage
.left
= i
* himl
->cx
;
1348 pImageInfo
->rcImage
.right
= (i
+1) * himl
->cx
;
1354 /*************************************************************************
1355 * ImageList_GetImageRect [COMCTL32.61]
1357 * Retrieves the rectangle of the specified image in an image list.
1360 * himl [I] image list handle
1362 * lpRect [O] pointer to the image rectangle
1369 * This is an UNDOCUMENTED function!!!
1373 ImageList_GetImageRect (HIMAGELIST himl
, INT32 i
, LPRECT32 lpRect
)
1375 if ((himl
== NULL
) || (lpRect
== NULL
)) return (FALSE
);
1376 if ((i
< 0) || (i
>= himl
->cCurImage
)) return (FALSE
);
1378 lpRect
->left
= i
* himl
->cx
;
1380 lpRect
->right
= lpRect
->left
+ himl
->cx
;
1381 lpRect
->bottom
= himl
->cy
;
1387 /*************************************************************************
1388 * ImageList_LoadImage32A [COMCTL32.62][COMCTL32.63]
1390 * Creates an image list from a bitmap, icon or cursor.
1393 * hi [I] instance handle
1394 * lpbmp [I] name or id of the image
1395 * cx [I] width of each image
1396 * cGrow [I] number of images to expand
1397 * clrMask [I] mask color
1398 * uType [I] type of image to load
1399 * uFlags [I] loading flags
1402 * Success: handle of the loaded image
1410 ImageList_LoadImage32A (HINSTANCE32 hi
, LPCSTR lpbmp
, INT32 cx
, INT32 cGrow
,
1411 COLORREF clrMask
, UINT32 uType
, UINT32 uFlags
)
1413 HIMAGELIST himl
= NULL
;
1417 handle
= LoadImage32A (hi
, lpbmp
, uType
, 0, 0, uFlags
);
1418 if (!handle
) return (NULL
);
1420 if (uType
== IMAGE_BITMAP
) {
1422 GetObject32A (handle
, sizeof(BITMAP32
), &bmp
);
1423 nImageCount
= bmp
.bmWidth
/ cx
;
1425 himl
= ImageList_Create (cx
, bmp
.bmHeight
, ILC_MASK
| ILC_COLOR
,
1426 nImageCount
, cGrow
);
1427 ImageList_AddMasked (himl
, (HBITMAP32
)handle
, clrMask
);
1429 else if ((uType
== IMAGE_ICON
) || (uType
== IMAGE_CURSOR
)) {
1433 GetIconInfo (handle
, &ii
);
1434 GetObject32A (ii
.hbmColor
, sizeof(BITMAP32
), (LPVOID
)&bmp
);
1435 himl
= ImageList_Create (bmp
.bmWidth
, bmp
.bmHeight
,
1436 ILC_MASK
| ILC_COLOR
, 1, cGrow
);
1437 ImageList_Add (himl
, ii
.hbmColor
, ii
.hbmMask
);
1438 DeleteObject32 (ii
.hbmColor
);
1439 DeleteObject32 (ii
.hbmMask
);
1442 DeleteObject32 (handle
);
1448 /*************************************************************************
1449 * ImageList_LoadImage32W [COMCTL32.64]
1451 * Creates an image list from a bitmap, icon or cursor.
1454 * hi [I] instance handle
1455 * lpbmp [I] name or id of the image
1456 * cx [I] width of each image
1457 * cGrow [I] number of images to expand
1458 * clrMask [I] mask color
1459 * uType [I] type of image to load
1460 * uFlags [I] loading flags
1463 * Success: handle of the loaded image
1471 ImageList_LoadImage32W (HINSTANCE32 hi
, LPCWSTR lpbmp
, INT32 cx
, INT32 cGrow
,
1472 COLORREF clrMask
, UINT32 uType
, UINT32 uFlags
)
1474 HIMAGELIST himl
= NULL
;
1478 handle
= LoadImage32W (hi
, lpbmp
, uType
, 0, 0, uFlags
);
1480 ERR (imagelist
, "Error loading image!\n");
1484 if (uType
== IMAGE_BITMAP
) {
1486 GetObject32A (handle
, sizeof(BITMAP32
), &bmp
);
1487 nImageCount
= bmp
.bmWidth
/ cx
;
1489 himl
= ImageList_Create (cx
, bmp
.bmHeight
, ILC_MASK
| ILC_COLOR
,
1490 nImageCount
, cGrow
);
1491 ImageList_AddMasked (himl
, (HBITMAP32
)handle
, clrMask
);
1493 else if ((uType
== IMAGE_ICON
) || (uType
== IMAGE_CURSOR
)) {
1497 GetIconInfo (handle
, &ii
);
1498 GetObject32A (ii
.hbmMask
, sizeof(BITMAP32
), (LPVOID
)&bmp
);
1499 himl
= ImageList_Create (bmp
.bmWidth
, bmp
.bmHeight
,
1500 ILC_MASK
| ILC_COLOR
, 1, cGrow
);
1501 ImageList_Add (himl
, ii
.hbmColor
, ii
.hbmMask
);
1502 DeleteObject32 (ii
.hbmColor
);
1503 DeleteObject32 (ii
.hbmMask
);
1506 DeleteObject32 (handle
);
1512 /*************************************************************************
1513 * ImageList_Merge [COMCTL32.65]
1515 * Creates a new image list that contains a merged image from the specified
1516 * images of both source image lists.
1519 * himl1 [I] first image list handle
1520 * i1 [I] first image index
1521 * himl2 [I] second image list handle
1522 * i2 [I] second image index
1523 * dx [I] X offset of the second image relative to the first.
1524 * dy [I] Y offset of the second image relative to the first.
1527 * Success: handle of the merged image list.
1532 ImageList_Merge (HIMAGELIST himl1
, INT32 i1
, HIMAGELIST himl2
, INT32 i2
,
1535 HIMAGELIST himlDst
= NULL
;
1536 HDC32 hdcSrcImage
, hdcDstImage
;
1538 INT32 xOff1
, yOff1
, xOff2
, yOff2
;
1541 if ((himl1
== NULL
) || (himl2
== NULL
)) return (NULL
);
1544 if ((i1
< 0) || (i1
>= himl1
->cCurImage
)) {
1545 ERR (imagelist
, "Index 1 out of range! %d\n", i1
);
1549 if ((i2
< 0) || (i2
>= himl2
->cCurImage
)) {
1550 ERR (imagelist
, "Index 2 out of range! %d\n", i2
);
1555 cxDst
= _MAX (himl1
->cx
, dx
+ himl2
->cx
);
1560 cxDst
= _MAX (himl2
->cx
, himl1
->cx
- dx
);
1565 cxDst
= _MAX (himl1
->cx
, himl2
->cx
);
1571 cyDst
= _MAX (himl1
->cy
, dy
+ himl2
->cy
);
1576 cyDst
= _MAX (himl2
->cy
, himl1
->cy
- dy
);
1581 cyDst
= _MAX (himl1
->cy
, himl2
->cy
);
1586 himlDst
= ImageList_Create (cxDst
, cyDst
, ILC_MASK
| ILC_COLOR
, 1, 1);
1589 hdcSrcImage
= CreateCompatibleDC32 (0);
1590 hdcDstImage
= CreateCompatibleDC32 (0);
1591 nX1
= i1
* himl1
->cx
;
1592 nX2
= i2
* himl2
->cx
;
1595 SelectObject32 (hdcSrcImage
, himl1
->hbmImage
);
1596 SelectObject32 (hdcDstImage
, himlDst
->hbmImage
);
1597 BitBlt32 (hdcDstImage
, 0, 0, cxDst
, cyDst
,
1598 hdcSrcImage
, 0, 0, BLACKNESS
);
1599 BitBlt32 (hdcDstImage
, xOff1
, yOff1
, himl1
->cx
, himl1
->cy
,
1600 hdcSrcImage
, nX1
, 0, SRCCOPY
);
1602 SelectObject32 (hdcSrcImage
, himl2
->hbmMask
);
1603 BitBlt32 (hdcDstImage
, xOff2
, yOff2
, himl2
->cx
, himl2
->cy
,
1604 hdcSrcImage
, nX2
, 0, SRCAND
);
1606 SelectObject32 (hdcSrcImage
, himl2
->hbmImage
);
1607 BitBlt32 (hdcDstImage
, xOff2
, yOff2
, himl2
->cx
, himl2
->cy
,
1608 hdcSrcImage
, nX2
, 0, SRCPAINT
);
1611 SelectObject32 (hdcSrcImage
, himl1
->hbmMask
);
1612 SelectObject32 (hdcDstImage
, himlDst
->hbmMask
);
1613 BitBlt32 (hdcDstImage
, 0, 0, cxDst
, cyDst
,
1614 hdcSrcImage
, 0, 0, WHITENESS
);
1615 BitBlt32 (hdcDstImage
, xOff1
, yOff1
, himl1
->cx
, himl1
->cy
,
1616 hdcSrcImage
, nX1
, 0, SRCCOPY
);
1618 SelectObject32 (hdcSrcImage
, himl2
->hbmMask
);
1619 BitBlt32 (hdcDstImage
, xOff2
, yOff2
, himl2
->cx
, himl2
->cy
,
1620 hdcSrcImage
, nX2
, 0, SRCAND
);
1622 DeleteDC32 (hdcSrcImage
);
1623 DeleteDC32 (hdcDstImage
);
1630 /*************************************************************************
1631 * ImageList_Read [COMCTL32.66]
1633 * Reads an image list from a stream.
1636 * pstm [I] pointer to a stream
1639 * Success: image list handle
1643 * This function can not be implemented yet, because
1644 * IStream32::Read is not implemented.
1650 HIMAGELIST WINAPI
ImageList_Read (LPSTREAM32 pstm
)
1652 FIXME (imagelist
, "empty stub!\n");
1659 /*************************************************************************
1660 * ImageList_Remove [COMCTL32.67] Removes an image from an image list
1663 * himl [I] image list handle
1672 ImageList_Remove (HIMAGELIST himl
, INT32 i
)
1674 HBITMAP32 hbmNewImage
, hbmNewMask
;
1675 HDC32 hdcSrc
, hdcDst
;
1676 INT32 cxNew
, nCount
;
1678 if ((i
< -1) || (i
>= himl
->cCurImage
)) {
1679 ERR (imagelist
, "index out of range! %d\n", i
);
1683 if (himl
->cCurImage
== 0) {
1684 ERR (imagelist
, "image list is already empty!\n");
1690 TRACE (imagelist
, "remove all!\n");
1692 himl
->cMaxImage
= himl
->cInitial
+ himl
->cGrow
;
1693 himl
->cCurImage
= 0;
1694 for (nCount
= 0; nCount
< MAX_OVERLAYIMAGE
; nCount
++)
1695 himl
->nOvlIdx
[nCount
] = -1;
1697 DeleteObject32 (himl
->hbmImage
);
1699 CreateBitmap32 (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
1700 1, himl
->uBitsPixel
, NULL
);
1702 if (himl
->hbmMask
) {
1703 DeleteObject32 (himl
->hbmMask
);
1705 CreateBitmap32 (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
1710 /* delete one image */
1711 TRACE (imagelist
, "Remove single image! %d\n", i
);
1713 /* create new bitmap(s) */
1714 cxNew
= (himl
->cCurImage
+ himl
->cGrow
- 1) * himl
->cx
;
1716 TRACE(imagelist
, " - Number of images: %d / %d (Old/New)\n",
1717 himl
->cCurImage
, himl
->cCurImage
- 1);
1718 TRACE(imagelist
, " - Max. number of images: %d / %d (Old/New)\n",
1719 himl
->cMaxImage
, himl
->cCurImage
+ himl
->cGrow
- 1);
1722 CreateBitmap32 (cxNew
, himl
->cy
, 1, himl
->uBitsPixel
, NULL
);
1725 hbmNewMask
= CreateBitmap32 (cxNew
, himl
->cy
, 1, 1, NULL
);
1727 hbmNewMask
= 0; /* Just to keep compiler happy! */
1729 hdcSrc
= CreateCompatibleDC32 (0);
1730 hdcDst
= CreateCompatibleDC32 (0);
1732 /* copy all images and masks prior to the "removed" image */
1734 TRACE (imagelist
, "Pre image copy: Copy %d images\n", i
);
1736 SelectObject32 (hdcSrc
, himl
->hbmImage
);
1737 SelectObject32 (hdcDst
, hbmNewImage
);
1738 BitBlt32 (hdcDst
, 0, 0, i
* himl
->cx
, himl
->cy
,
1739 hdcSrc
, 0, 0, SRCCOPY
);
1741 if (himl
->hbmMask
) {
1742 SelectObject32 (hdcSrc
, himl
->hbmMask
);
1743 SelectObject32 (hdcDst
, hbmNewMask
);
1744 BitBlt32 (hdcDst
, 0, 0, i
* himl
->cx
, himl
->cy
,
1745 hdcSrc
, 0, 0, SRCCOPY
);
1749 /* copy all images and masks behind the removed image */
1750 if (i
< himl
->cCurImage
- 1) {
1751 TRACE (imagelist
, "Post image copy!\n");
1752 SelectObject32 (hdcSrc
, himl
->hbmImage
);
1753 SelectObject32 (hdcDst
, hbmNewImage
);
1754 BitBlt32 (hdcDst
, i
* himl
->cx
, 0, (himl
->cCurImage
- i
- 1) * himl
->cx
,
1755 himl
->cy
, hdcSrc
, (i
+ 1) * himl
->cx
, 0, SRCCOPY
);
1757 if (himl
->hbmMask
) {
1758 SelectObject32 (hdcSrc
, himl
->hbmMask
);
1759 SelectObject32 (hdcDst
, hbmNewMask
);
1760 BitBlt32 (hdcDst
, i
* himl
->cx
, 0,
1761 (himl
->cCurImage
- i
- 1) * himl
->cx
,
1762 himl
->cy
, hdcSrc
, (i
+ 1) * himl
->cx
, 0, SRCCOPY
);
1766 DeleteDC32 (hdcSrc
);
1767 DeleteDC32 (hdcDst
);
1769 /* delete old images and insert new ones */
1770 DeleteObject32 (himl
->hbmImage
);
1771 himl
->hbmImage
= hbmNewImage
;
1772 if (himl
->hbmMask
) {
1773 DeleteObject32 (himl
->hbmMask
);
1774 himl
->hbmMask
= hbmNewMask
;
1778 himl
->cMaxImage
= himl
->cCurImage
+ himl
->cGrow
;
1785 /*************************************************************************
1786 * ImageList_Replace [COMCTL32.68]
1788 * Replaces an image in an image list with a new image.
1791 * himl [I] image list handle
1793 * hbmImage [I] image bitmap handle
1794 * hbmMask [I] mask bitmap handle. Can be NULL.
1802 ImageList_Replace (HIMAGELIST himl
, INT32 i
, HBITMAP32 hbmImage
,
1805 HDC32 hdcImageList
, hdcImage
;
1809 ERR (imagelist
, "Invalid image list handle!\n");
1813 if ((i
>= himl
->cCurImage
) || (i
< 0)) {
1814 ERR (imagelist
, "Invalid image index!\n");
1818 hdcImageList
= CreateCompatibleDC32 (0);
1819 hdcImage
= CreateCompatibleDC32 (0);
1820 GetObject32A (hbmImage
, sizeof(BITMAP32
), (LPVOID
)&bmp
);
1823 SelectObject32 (hdcImageList
, himl
->hbmImage
);
1824 SelectObject32 (hdcImage
, hbmImage
);
1826 StretchBlt32 (hdcImageList
, i
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
1827 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
1832 SelectObject32 (hdcImageList
, himl
->hbmMask
);
1833 SelectObject32 (hdcImage
, hbmMask
);
1835 StretchBlt32 (hdcImageList
, i
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
1836 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
1839 DeleteDC32 (hdcImage
);
1840 DeleteDC32 (hdcImageList
);
1846 /*************************************************************************
1847 * ImageList_ReplaceIcon [COMCTL32.69]
1849 * Replaces an image in an image list using an icon.
1852 * himl [I] image list handle
1854 * hIcon [I] icon handle
1857 * Success: index of the replaced image
1862 ImageList_ReplaceIcon (HIMAGELIST himl
, INT32 i
, HICON32 hIcon
)
1864 HDC32 hdcImageList
, hdcImage
;
1866 HBITMAP32 hbmOldSrc
, hbmOldDst
;
1870 TRACE (imagelist
, "(0x%lx 0x%x 0x%x)\n", (DWORD
)himl
, i
, hIcon
);
1872 if (himl
== NULL
) return (-1);
1873 if ((i
>= himl
->cCurImage
) || (i
< -1)) return (-1);
1875 GetIconInfo (hIcon
, &ii
);
1876 if (ii
.hbmMask
== 0)
1877 ERR (imagelist
, "no mask!\n");
1878 if (ii
.hbmColor
== 0)
1879 ERR (imagelist
, "no color!\n");
1880 GetObject32A (ii
.hbmMask
, sizeof(BITMAP32
), (LPVOID
)&bmp
);
1883 if (himl
->cCurImage
+ 1 >= himl
->cMaxImage
)
1884 IMAGELIST_InternalExpandBitmaps (himl
, 1);
1886 nIndex
= himl
->cCurImage
;
1892 hdcImageList
= CreateCompatibleDC32 (0);
1893 TRACE (imagelist
, "hdcImageList=0x%x!\n", hdcImageList
);
1894 if (hdcImageList
== 0)
1895 ERR (imagelist
, "invalid hdcImageList!\n");
1897 hdcImage
= CreateCompatibleDC32 (0);
1898 TRACE (imagelist
, "hdcImage=0x%x!\n", hdcImage
);
1900 ERR (imagelist
, "invalid hdcImage!\n");
1902 hbmOldDst
= SelectObject32 (hdcImageList
, himl
->hbmImage
);
1903 SetTextColor32( hdcImageList
, RGB(0,0,0));
1904 SetBkColor32( hdcImageList
, RGB(255,255,255));
1905 hbmOldSrc
= SelectObject32 (hdcImage
, ii
.hbmColor
);
1906 StretchBlt32 (hdcImageList
, nIndex
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
1907 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
1909 if (himl
->hbmMask
) {
1910 SelectObject32 (hdcImageList
, himl
->hbmMask
);
1911 SelectObject32 (hdcImage
, ii
.hbmMask
);
1912 StretchBlt32 (hdcImageList
, nIndex
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
1913 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
1916 SelectObject32 (hdcImage
, hbmOldSrc
);
1917 SelectObject32 (hdcImageList
, hbmOldDst
);
1920 DeleteDC32 (hdcImageList
);
1922 DeleteDC32 (hdcImage
);
1924 // FIXME (imagelist, "deleting hbmColor!\n");
1926 DeleteObject32 (ii
.hbmColor
);
1927 // FIXME (imagelist, "deleted hbmColor!\n");
1929 DeleteObject32 (ii
.hbmMask
);
1935 /*************************************************************************
1936 * ImageList_SetBkColor [COMCTL32.70]
1938 * Sets the background color of an image list.
1941 * himl [I] image list handle
1942 * clrBk [I] background color
1945 * Success: previous background color
1950 ImageList_SetBkColor (HIMAGELIST himl
, COLORREF clrBk
)
1957 clrOldBk
= himl
->clrBk
;
1958 himl
->clrBk
= clrBk
;
1963 /*************************************************************************
1964 * ImageList_SetDragCursorImage [COMCTL32.75]
1966 * Combines the specified image with the current drag image
1969 * himlDrag [I] drag image list handle
1970 * iDrag [I] drag image index
1971 * dxHotspot [I] X position of the hot spot
1972 * dyHotspot [I] Y position of the hot spot
1983 ImageList_SetDragCursorImage (HIMAGELIST himlDrag
, INT32 iDrag
,
1984 INT32 dxHotspot
, INT32 dyHotspot
)
1986 HIMAGELIST himlTemp
;
1988 FIXME (imagelist
, "semi-stub!\n");
1990 if (himlInternalDrag
== NULL
) return (FALSE
);
1992 TRACE (imagelist
, " dxH=%d dyH=%d nX=%d nY=%d\n",
1993 dxHotspot
, dyHotspot
, nInternalDragHotspotX
, nInternalDragHotspotY
);
1995 himlTemp
= ImageList_Merge (himlInternalDrag
, 0, himlDrag
, iDrag
,
1996 dxHotspot
, dyHotspot
);
1998 ImageList_Destroy (himlInternalDrag
);
1999 himlInternalDrag
= himlTemp
;
2001 nInternalDragHotspotX
= dxHotspot
;
2002 nInternalDragHotspotY
= dyHotspot
;
2008 /*************************************************************************
2009 * ImageList_SetFilter [COMCTL32.76]
2011 * Sets a filter (or does something completely different)!!???
2020 * Failure: FALSE ???
2023 * This is an UNDOCUMENTED function!!!!
2028 ImageList_SetFilter (HIMAGELIST himl
, INT32 i
, DWORD dwFilter
)
2030 FIXME (imagelist
, "(%p 0x%x 0x%lx):empty stub!\n",
2037 /*************************************************************************
2038 * ImageList_SetIconSize [COMCTL32.77]
2040 * Sets the image size of the bitmap and deletes all images.
2043 * himl [I] image list handle
2044 * cx [I] image width
2045 * cy [I] image height
2053 ImageList_SetIconSize (HIMAGELIST himl
, INT32 cx
, INT32 cy
)
2057 if (himl
== NULL
) return (FALSE
);
2059 /* remove all images*/
2060 himl
->cMaxImage
= himl
->cInitial
+ himl
->cGrow
;
2061 himl
->cCurImage
= 0;
2065 /* initialize overlay mask indices */
2066 for (nCount
= 0; nCount
< MAX_OVERLAYIMAGE
; nCount
++)
2067 himl
->nOvlIdx
[nCount
] = -1;
2069 DeleteObject32 (himl
->hbmImage
);
2071 CreateBitmap32 (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
2072 1, himl
->uBitsPixel
, NULL
);
2074 if (himl
->hbmMask
) {
2075 DeleteObject32 (himl
->hbmMask
);
2077 CreateBitmap32 (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
2085 /*************************************************************************
2086 * ImageList_SetImageCount [COMCTL32.78]
2088 * Resizes an image list to the specified number of images.
2091 * himl [I] image list handle
2092 * iImageCount [I] number of images in the image list
2100 ImageList_SetImageCount (HIMAGELIST himl
, INT32 iImageCount
)
2102 HDC32 hdcImageList
, hdcBitmap
;
2103 HBITMAP32 hbmNewBitmap
;
2104 INT32 nNewCount
, nCopyCount
;
2106 if (himl
== NULL
) return (FALSE
);
2107 if (himl
->cCurImage
<= iImageCount
) return (FALSE
);
2108 if (himl
->cMaxImage
> iImageCount
) return (TRUE
);
2110 nNewCount
= iImageCount
+ himl
->cGrow
;
2111 nCopyCount
= _MIN(himl
->cCurImage
, iImageCount
);
2113 hdcImageList
= CreateCompatibleDC32 (0);
2114 hdcBitmap
= CreateCompatibleDC32 (0);
2116 hbmNewBitmap
= CreateBitmap32 (nNewCount
* himl
->cx
, himl
->cy
,
2117 1, himl
->uBitsPixel
, NULL
);
2118 if (hbmNewBitmap
== 0)
2120 SelectObject32 (hdcImageList
, himl
->hbmImage
);
2121 SelectObject32 (hdcBitmap
, hbmNewBitmap
);
2122 BitBlt32 (hdcBitmap
, 0, 0, nCopyCount
* himl
->cx
, himl
->cy
,
2123 hdcImageList
, 0, 0, SRCCOPY
);
2124 DeleteObject32 (himl
->hbmImage
);
2125 himl
->hbmImage
= hbmNewBitmap
;
2129 WARN (imagelist
, "Could not create new image bitmap !\n");
2134 hbmNewBitmap
= CreateBitmap32 (nNewCount
* himl
->cx
, himl
->cy
,
2136 if (hbmNewBitmap
!= 0)
2138 SelectObject32 (hdcImageList
, himl
->hbmMask
);
2139 SelectObject32 (hdcBitmap
, hbmNewBitmap
);
2140 BitBlt32 (hdcBitmap
, 0, 0, nCopyCount
* himl
->cx
, himl
->cy
,
2141 hdcImageList
, 0, 0, SRCCOPY
);
2142 DeleteObject32 (himl
->hbmMask
);
2143 himl
->hbmMask
= hbmNewBitmap
;
2147 WARN (imagelist
, "Could not create new mask bitmap!\n");
2151 DeleteDC32 (hdcImageList
);
2152 DeleteDC32 (hdcBitmap
);
2154 /* Update max image count and current image count */
2155 himl
->cMaxImage
= nNewCount
;
2156 if (himl
->cCurImage
> nCopyCount
)
2157 himl
->cCurImage
= nCopyCount
;
2163 /*************************************************************************
2164 * ImageList_SetOverlayImage [COMCTL32.79]
2166 * Assigns an overlay mask index to an existing image in an image list.
2169 * himl [I] image list handle
2170 * iImage [I] image index
2171 * iOverlay [I] overlay mask index
2179 ImageList_SetOverlayImage (HIMAGELIST himl
, INT32 iImage
, INT32 iOverlay
)
2181 if ((iOverlay
< 1) || (iOverlay
> MAX_OVERLAYIMAGE
)) return (FALSE
);
2182 if ((iImage
< 0) || (iImage
> himl
->cCurImage
)) return (FALSE
);
2184 himl
->nOvlIdx
[iOverlay
- 1] = iImage
;
2189 /*************************************************************************
2190 * ImageList_Write [COMCTL32.80]
2192 * Writes an image list to a stream.
2195 * himl [I] Image list handle.
2196 * pstm [O] Pointer to a stream.
2203 * This function can not be implemented yet, because
2204 * IStream32::Write is not implemented.
2211 ImageList_Write (HIMAGELIST himl
, LPSTREAM32 pstm
)
2213 FIXME (imagelist
, "empty stub!\n");
2215 if (himl
== NULL
) return (FALSE
);