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 * - Add 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
34 /* This must be defined until "GetIconInfo" is implemented completely.
35 * To do that the cursor and icon code in objects/cursoricon.c must
38 #define __GET_ICON_INFO_HACK__
43 #include "imagelist.h"
47 #ifdef __GET_ICON_INFO_HACK__
52 #define _MAX(a,b) (((a)>(b))?(a):(b))
53 #define _MIN(a,b) (((a)>(b))?(b):(a))
55 #define MAX_OVERLAYIMAGE 15
58 /* internal image list data used for Drag & Drop operations */
60 static HIMAGELIST himlInternalDrag
= NULL
;
61 static INT32 nInternalDragHotspotX
= 0;
62 static INT32 nInternalDragHotspotY
= 0;
64 static HWND32 hwndInternalDrag
= 0;
65 static INT32 xInternalPos
= 0;
66 static INT32 yInternalPos
= 0;
68 static HDC32 hdcBackBuffer
= 0;
69 static HBITMAP32 hbmBackBuffer
= 0;
72 /*************************************************************************
73 * IMAGELIST_InternalExpandBitmaps [Internal]
75 * Expands the bitmaps of an image list by the given number of images.
78 * himl [I] image list handle
79 * nImageCount [I] Number of images to add.
85 * This function can NOT be used to reduce the number of images.
89 IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl
, INT32 nImageCount
)
91 HDC32 hdcImageList
, hdcBitmap
;
92 HBITMAP32 hbmNewBitmap
;
93 INT32 nNewWidth
, nNewCount
;
95 TRACE(imagelist
, "Create expanded bitmaps!\n");
97 nNewCount
= himl
->cCurImage
+ nImageCount
+ himl
->cGrow
;
98 nNewWidth
= nNewCount
* himl
->cx
;
100 hdcImageList
= CreateCompatibleDC32 (0);
101 hdcBitmap
= CreateCompatibleDC32 (0);
104 CreateBitmap32 (nNewWidth
, himl
->cy
, 1, himl
->uBitsPixel
, NULL
);
105 if (hbmNewBitmap
== 0)
106 ERR (imagelist
, "creating new image bitmap!\n");
108 SelectObject32 (hdcImageList
, himl
->hbmImage
);
109 SelectObject32 (hdcBitmap
, hbmNewBitmap
);
110 BitBlt32 (hdcBitmap
, 0, 0, himl
->cCurImage
* himl
->cx
, himl
->cy
,
111 hdcImageList
, 0, 0, SRCCOPY
);
113 DeleteObject32 (himl
->hbmImage
);
114 himl
->hbmImage
= hbmNewBitmap
;
118 CreateBitmap32 (nNewWidth
, himl
->cy
, 1, himl
->uBitsPixel
, NULL
);
120 if (hbmNewBitmap
== 0)
121 ERR (imagelist
, "creating new mask bitmap!");
123 SelectObject32 (hdcImageList
, himl
->hbmMask
);
124 SelectObject32 (hdcBitmap
, hbmNewBitmap
);
125 BitBlt32 (hdcBitmap
, 0, 0, himl
->cCurImage
* himl
->cx
, himl
->cy
,
126 hdcImageList
, 0, 0, SRCCOPY
);
127 DeleteObject32 (himl
->hbmMask
);
128 himl
->hbmMask
= hbmNewBitmap
;
131 himl
->cMaxImage
= nNewCount
;
133 DeleteDC32 (hdcImageList
);
134 DeleteDC32 (hdcBitmap
);
138 /*************************************************************************
139 * ImageList_Add [COMCTL32.39]
141 * Add an image or images to an image list.
144 * himl [I] image list handle
145 * hbmImage [I] image bitmap handle
146 * hbmMask [I] mask bitmap handle
149 * Success: Index of the first new image.
154 ImageList_Add (HIMAGELIST himl
, HBITMAP32 hbmImage
, HBITMAP32 hbmMask
)
156 HDC32 hdcSrc
, hdcDst
;
157 INT32 nFirstIndex
, nImageCount
;
158 INT32 nStartX
, nRunX
, nRunY
;
161 if (himl
== NULL
) return (-1);
162 if (hbmImage
== 0) return (-1);
164 GetObject32A (hbmImage
, sizeof(BITMAP32
), (LPVOID
)&bmp
);
165 nImageCount
= bmp
.bmWidth
/ himl
->cx
;
167 if (himl
->cCurImage
+ nImageCount
>= himl
->cMaxImage
)
168 IMAGELIST_InternalExpandBitmaps (himl
, nImageCount
);
170 hdcSrc
= CreateCompatibleDC32 (0);
171 hdcDst
= CreateCompatibleDC32 (0);
173 SelectObject32 (hdcDst
, himl
->hbmImage
);
174 SelectObject32 (hdcSrc
, hbmImage
);
176 BitBlt32 (hdcDst
, himl
->cCurImage
* himl
->cx
, 0,
177 bmp
.bmWidth
, himl
->cy
, hdcSrc
, 0, 0, SRCCOPY
);
181 SelectObject32 (hdcDst
, himl
->hbmMask
);
182 SelectObject32 (hdcSrc
, hbmMask
);
183 BitBlt32 (hdcDst
, himl
->cCurImage
* himl
->cx
, 0,
184 bmp
.bmWidth
, himl
->cy
, hdcSrc
, 0, 0, SRCCOPY
);
186 /* fix transparent areas of the image bitmap*/
187 SelectObject32 (hdcSrc
, himl
->hbmMask
);
188 SelectObject32 (hdcDst
, himl
->hbmImage
);
189 nStartX
= himl
->cCurImage
* himl
->cx
;
191 for (nRunY
= 0; nRunY
< himl
->cy
; nRunY
++) {
192 for (nRunX
= 0; nRunX
< bmp
.bmWidth
; nRunX
++) {
193 if (GetPixel32 (hdcSrc
, nStartX
+ nRunX
, nRunY
) !=
195 SetPixel32 (hdcDst
, nStartX
+ nRunX
, nRunY
,
201 /* create mask from the imagelist's background color */
202 SelectObject32 (hdcDst
, himl
->hbmMask
);
203 SelectObject32 (hdcSrc
, himl
->hbmImage
);
204 nStartX
= himl
->cCurImage
* himl
->cx
;
205 for (nRunY
= 0; nRunY
< himl
->cy
; nRunY
++) {
206 for (nRunX
= 0; nRunX
< bmp
.bmWidth
; nRunX
++) {
207 if (GetPixel32 (hdcSrc
, nStartX
+ nRunX
, nRunY
) ==
210 SetPixel32 (hdcSrc
, nStartX
+ nRunX
, nRunY
,
212 SetPixel32 (hdcDst
, nStartX
+ nRunX
, nRunY
,
216 SetPixel32 (hdcDst
, nStartX
+ nRunX
, nRunY
,
226 nFirstIndex
= himl
->cCurImage
;
227 himl
->cCurImage
+= nImageCount
;
229 return (nFirstIndex
);
233 /*************************************************************************
234 * ImageList_AddIcon [COMCTL32.40]
236 * Adds an icon to an image list.
239 * himl [I] image list handle
240 * hIcon [I] icon handle
243 * Success: index of the new image
248 ImageList_AddIcon (HIMAGELIST himl
, HICON32 hIcon
)
250 return (ImageList_ReplaceIcon (himl
, -1, hIcon
));
254 /*************************************************************************
255 * ImageList_AddMasked [COMCTL32.41]
257 * Adds an image or images to an image list and creates a mask from the
258 * specified bitmap using the mask color.
261 * himl [I] image list handle.
262 * hbmImage [I] image bitmap handle.
263 * clrMask [I] mask color.
266 * Success: Index of the first new image.
271 ImageList_AddMasked (HIMAGELIST himl
, HBITMAP32 hbmImage
, COLORREF clrMask
)
273 HDC32 hdcImageList
, hdcImage
, hdcMask
;
274 INT32 nIndex
, nImageCount
;
276 INT32 nStartX
, nRunX
, nRunY
;
282 bkColor
= (clrMask
== CLR_NONE
) ? himl
->clrBk
: clrMask
;
284 GetObject32A (hbmImage
, sizeof(BITMAP32
), &bmp
);
285 nImageCount
= bmp
.bmWidth
/ himl
->cx
;
287 if (himl
->cCurImage
+ nImageCount
>= himl
->cMaxImage
)
288 IMAGELIST_InternalExpandBitmaps (himl
, nImageCount
);
290 nIndex
= himl
->cCurImage
;
291 himl
->cCurImage
+= nImageCount
;
293 hdcImageList
= CreateCompatibleDC32 (0);
294 hdcImage
= CreateCompatibleDC32 (0);
296 SelectObject32 (hdcImageList
, himl
->hbmImage
);
297 SelectObject32 (hdcImage
, hbmImage
);
298 BitBlt32 (hdcImageList
, nIndex
* himl
->cx
, 0, bmp
.bmWidth
, himl
->cy
,
299 hdcImage
, 0, 0, SRCCOPY
);
303 hdcMask
= CreateCompatibleDC32 (0);
304 SelectObject32 (hdcMask
, himl
->hbmMask
);
305 nStartX
= nIndex
* himl
->cx
;
306 for (nRunY
= 0; nRunY
< himl
->cy
; nRunY
++) {
307 for (nRunX
= 0; nRunX
< bmp
.bmWidth
; nRunX
++) {
308 if (GetPixel32 (hdcImageList
, nStartX
+ nRunX
, nRunY
) ==
310 SetPixel32 (hdcImageList
, nStartX
+ nRunX
, nRunY
,
312 SetPixel32 (hdcMask
, nStartX
+ nRunX
, nRunY
,
316 SetPixel32 (hdcMask
, nStartX
+ nRunX
, nRunY
, RGB(0, 0, 0));
319 DeleteDC32 (hdcMask
);
322 DeleteDC32 (hdcImageList
);
323 DeleteDC32 (hdcImage
);
329 /*************************************************************************
330 * ImageList_BeginDrag [COMCTL32.42]
332 * Creates a temporary image list that contains one image. It will be used
336 * himlTrack [I] Handle of the source image list
337 * iTrack [I] Index of the drag image in the source image list
338 * dxHotspot [I] X position of the hot spot of the drag image
339 * dyHotspot [I] Y position of the hot spot of the drag image
347 ImageList_BeginDrag (HIMAGELIST himlTrack
, INT32 iTrack
,
348 INT32 dxHotspot
, INT32 dyHotspot
)
350 HDC32 hdcSrc
, hdcDst
;
352 FIXME(imagelist
, "partially implemented!\n");
354 if (himlTrack
== NULL
)
357 if (himlInternalDrag
)
358 ImageList_EndDrag ();
361 ImageList_Create (himlTrack
->cx
, himlTrack
->cy
,
362 himlTrack
->flags
, 1, 1);
363 if (himlInternalDrag
== NULL
) {
364 ERR(imagelist
, "Error creating drag image list!\n");
368 nInternalDragHotspotX
= dxHotspot
;
369 nInternalDragHotspotY
= dyHotspot
;
371 hdcSrc
= CreateCompatibleDC32 (0);
372 hdcDst
= CreateCompatibleDC32 (0);
375 SelectObject32 (hdcSrc
, himlTrack
->hbmImage
);
376 SelectObject32 (hdcDst
, himlInternalDrag
->hbmImage
);
377 StretchBlt32 (hdcDst
, 0, 0, himlInternalDrag
->cx
, himlInternalDrag
->cy
, hdcSrc
,
378 iTrack
* himlTrack
->cx
, 0, himlTrack
->cx
, himlTrack
->cy
, SRCCOPY
);
381 SelectObject32 (hdcSrc
, himlTrack
->hbmMask
);
382 SelectObject32 (hdcDst
, himlInternalDrag
->hbmMask
);
383 StretchBlt32 (hdcDst
, 0, 0, himlInternalDrag
->cx
, himlInternalDrag
->cy
, hdcSrc
,
384 iTrack
* himlTrack
->cx
, 0, himlTrack
->cx
, himlTrack
->cy
, SRCCOPY
);
389 himlInternalDrag
->cCurImage
= 1;
395 /*************************************************************************
396 * ImageList_Copy [COMCTL32.43]
398 * Copies an image of the source image list to an image of the
399 * destination image list. Images can be copied or swapped.
402 * himlDst [I] destination image list handle.
403 * iDst [I] destination image index.
404 * himlSrc [I] source image list handle
405 * iSrc [I] source image index
406 * uFlags [I] flags for the copy operation
413 * Copying from one image list to another is possible. The original
414 * implementation just copies or swapps within one image list.
415 * Could this feature become a bug??? ;-)
419 ImageList_Copy (HIMAGELIST himlDst
, INT32 iDst
, HIMAGELIST himlSrc
,
420 INT32 iSrc
, INT32 uFlags
)
422 HDC32 hdcSrc
, hdcDst
;
424 TRACE(imagelist
, "iDst=%d iSrc=%d\n", iDst
, iSrc
);
426 if ((himlSrc
== NULL
) || (himlDst
== NULL
)) return (FALSE
);
427 if ((iDst
< 0) || (iDst
>= himlDst
->cCurImage
)) return (FALSE
);
428 if ((iSrc
< 0) || (iSrc
>= himlSrc
->cCurImage
)) return (FALSE
);
430 hdcSrc
= CreateCompatibleDC32 (0);
431 if (himlDst
== himlSrc
)
434 hdcDst
= CreateCompatibleDC32 (0);
436 if (uFlags
& ILCF_SWAP
) {
438 HBITMAP32 hbmTempImage
, hbmTempMask
;
440 /* create temporary bitmaps */
441 hbmTempImage
= CreateBitmap32 (himlSrc
->cx
, himlSrc
->cy
, 1,
442 himlSrc
->uBitsPixel
, NULL
);
443 hbmTempMask
= CreateBitmap32 (himlSrc
->cx
, himlSrc
->cy
, 1,
444 himlSrc
->uBitsPixel
, NULL
);
446 /* copy (and stretch) destination to temporary bitmaps.(save) */
448 SelectObject32 (hdcSrc
, himlDst
->hbmImage
);
449 SelectObject32 (hdcDst
, hbmTempImage
);
450 StretchBlt32 (hdcDst
, 0, 0, himlSrc
->cx
, himlSrc
->cy
,
451 hdcSrc
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
454 SelectObject32 (hdcSrc
, himlDst
->hbmMask
);
455 SelectObject32 (hdcDst
, hbmTempMask
);
456 StretchBlt32 (hdcDst
, 0, 0, himlSrc
->cx
, himlSrc
->cy
,
457 hdcSrc
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
460 /* copy (and stretch) source to destination */
462 SelectObject32 (hdcSrc
, himlSrc
->hbmImage
);
463 SelectObject32 (hdcDst
, himlDst
->hbmImage
);
464 StretchBlt32 (hdcDst
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
465 hdcSrc
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
468 SelectObject32 (hdcSrc
, himlSrc
->hbmMask
);
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
,
474 /* copy (without stretching) temporary bitmaps to source (restore) */
476 SelectObject32 (hdcSrc
, hbmTempImage
);
477 SelectObject32 (hdcDst
, himlSrc
->hbmImage
);
478 BitBlt32 (hdcDst
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
479 hdcSrc
, 0, 0, SRCCOPY
);
481 SelectObject32 (hdcSrc
, hbmTempMask
);
482 SelectObject32 (hdcDst
, himlSrc
->hbmMask
);
483 BitBlt32 (hdcDst
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
484 hdcSrc
, 0, 0, SRCCOPY
);
486 /* delete temporary bitmaps */
487 DeleteObject32 (hbmTempMask
);
488 DeleteObject32 (hbmTempImage
);
492 SelectObject32 (hdcSrc
, himlSrc
->hbmImage
);
493 if (himlSrc
== himlDst
)
496 SelectObject32 (hdcDst
, himlDst
->hbmImage
);
497 StretchBlt32 (hdcDst
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
498 hdcSrc
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
502 SelectObject32 (hdcSrc
, himlSrc
->hbmMask
);
503 if (himlSrc
== himlDst
)
506 SelectObject32 (hdcDst
, himlDst
->hbmMask
);
507 StretchBlt32 (hdcDst
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
508 hdcSrc
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
513 if (himlSrc
!= himlDst
)
520 /*************************************************************************
521 * ImageList_Create [COMCTL32.44]
523 * Creates a new image list.
526 * cx [I] image height
528 * flags [I] creation flags
529 * cInitial [I] initial number of images in the image list
530 * cGrow [I] number of images by which image list grows
533 * Success: Handle of the created image list
538 ImageList_Create (INT32 cx
, INT32 cy
, UINT32 flags
,
539 INT32 cInitial
, INT32 cGrow
)
545 WORD aBitBlend25
[16] =
546 {0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD,
547 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD};
548 WORD aBitBlend50
[16] =
549 {0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA,
550 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA};
552 himl
= (HIMAGELIST
)LocalAlloc32 (LMEM_FIXED
| LMEM_ZEROINIT
,
553 sizeof(struct _IMAGELIST
));
559 himl
->cMaxImage
= cInitial
+ cGrow
;
560 himl
->cInitial
= cInitial
;
563 himl
->clrBk
= CLR_NONE
;
565 /* initialize overlay mask indices */
566 for (nCount
= 0; nCount
<= MAX_OVERLAYIMAGE
; nCount
++)
567 himl
->nOvlIdx
[nCount
] = -1;
569 hdc
= CreateCompatibleDC32 (0);
570 himl
->uBitsPixel
= (UINT32
)GetDeviceCaps32 (hdc
, BITSPIXEL
);
573 TRACE(imagelist
, "Image: %d Bits per Pixel\n", himl
->uBitsPixel
);
576 CreateBitmap32 (himl
->cx
* himl
->cMaxImage
, himl
->cy
,
577 1, himl
->uBitsPixel
, NULL
);
578 if (himl
->hbmImage
== 0) {
579 ERR(imagelist
, "Error creating image bitmap!\n");
583 if (himl
->flags
& ILC_MASK
) {
584 himl
->hbmMask
= CreateBitmap32 (himl
->cx
* himl
->cMaxImage
, himl
->cy
,
585 1, himl
->uBitsPixel
, NULL
);
586 if (himl
->hbmMask
== 0) {
587 ERR(imagelist
, "Error creating mask bitmap!\n");
589 DeleteObject32 (himl
->hbmImage
);
596 /* create blending brushes */
597 hbmTemp
= CreateBitmap32 (16, 16, 1, 1, &aBitBlend25
);
598 himl
->hbrBlend25
= CreatePatternBrush32 (hbmTemp
);
599 DeleteObject32 (hbmTemp
);
601 hbmTemp
= CreateBitmap32 (16, 16, 1, 1, &aBitBlend50
);
602 himl
->hbrBlend50
= CreatePatternBrush32 (hbmTemp
);
603 DeleteObject32 (hbmTemp
);
609 /*************************************************************************
610 * ImageList_Destroy [COMCTL32.45]
612 * Destroys an image list.
615 * himl [I] image list handle
623 ImageList_Destroy (HIMAGELIST himl
)
625 if (himl
== NULL
) return (FALSE
);
628 DeleteObject32 (himl
->hbmImage
);
630 DeleteObject32 (himl
->hbmMask
);
632 LocalFree32 ((HLOCAL32
)himl
);
637 /*************************************************************************
638 * ImageList_DragEnter [COMCTL32.46]
640 * Locks window update and displays the drag image at the given position.
643 * hwndLock [I] handle of the window that owns the drag image.
644 * x [I] X position of the drag image.
645 * y [I] Y position of the drag image.
652 * The position of the drag image is relative to the window, not
657 ImageList_DragEnter (HWND32 hwndLock
, INT32 x
, INT32 y
)
659 if (himlInternalDrag
== NULL
) return (FALSE
);
662 hwndInternalDrag
= hwndLock
;
664 hwndInternalDrag
= GetDesktopWindow32 ();
669 hdcBackBuffer
= CreateCompatibleDC32 (0);
670 hbmBackBuffer
= CreateCompatibleBitmap32 (hdcBackBuffer
,
671 himlInternalDrag
->cx
, himlInternalDrag
->cy
);
673 ImageList_DragShowNolock (TRUE
);
679 /*************************************************************************
680 * ImageList_DragLeave [COMCTL32.47]
682 * Unlocks window update and hides the drag image.
685 * hwndLock [I] handle of the window that owns the drag image.
693 ImageList_DragLeave (HWND32 hwndLock
)
696 hwndInternalDrag
= hwndLock
;
698 hwndInternalDrag
= GetDesktopWindow32 ();
700 ImageList_DragShowNolock (FALSE
);
702 DeleteDC32 (hdcBackBuffer
);
703 DeleteObject32 (hbmBackBuffer
);
709 /*************************************************************************
710 * ImageList_DragMove [COMCTL32.48]
712 * Moves the drag image.
715 * x [I] X position of the drag image.
716 * y [I] Y position of the drag image.
723 * The position of the drag image is relative to the window, not
728 ImageList_DragMove (INT32 x
, INT32 y
)
730 ImageList_DragShowNolock (FALSE
);
735 ImageList_DragShowNolock (TRUE
);
741 /*************************************************************************
742 * ImageList_DragShowNolock [COMCTL32.49]
744 * Shows or hides the drag image.
747 * bShow [I] TRUE shows the drag image, FALSE hides it.
758 ImageList_DragShowNolock (BOOL32 bShow
)
762 FIXME (imagelist
, "semi-stub!\n");
763 TRACE (imagelist
, "bShow=0x%X!\n", bShow
);
765 hdcDrag
= GetDCEx32 (hwndInternalDrag
, 0,
766 DCX_WINDOW
| DCX_CACHE
| DCX_LOCKWINDOWUPDATE
);
769 /* show drag image */
771 /* save background */
773 /* draw drag image */
777 /* hide drag image */
779 /* restore background */
783 ReleaseDC32 (hwndInternalDrag
, hdcDrag
);
789 /*************************************************************************
790 * ImageList_Draw [COMCTL32.50] Draws an image.
793 * himl [I] image list handle
795 * hdc [I] display context handle
798 * fStyle [I] drawing flags
805 * Calls ImageList_DrawIndirect.
808 * ImageList_DrawIndirect.
812 ImageList_Draw (HIMAGELIST himl
, INT32 i
, HDC32 hdc
,
813 INT32 x
, INT32 y
, UINT32 fStyle
)
815 IMAGELISTDRAWPARAMS imldp
;
817 imldp
.cbSize
= sizeof(IMAGELISTDRAWPARAMS
);
827 imldp
.rgbBk
= CLR_DEFAULT
;
828 imldp
.rgbFg
= CLR_DEFAULT
;
829 imldp
.fStyle
= fStyle
;
832 return (ImageList_DrawIndirect (&imldp
));
836 /*************************************************************************
837 * ImageList_DrawEx [COMCTL32.51]
839 * Draws an image and allows to use extended drawing features.
842 * himl [I] image list handle
844 * hdc [I] device context handle
849 * rgbBk [I] background color
850 * rgbFg [I] foreground color
851 * fStyle [I] drawing flags
858 * Calls ImageList_DrawIndirect.
861 * ImageList_DrawIndirect.
865 ImageList_DrawEx (HIMAGELIST himl
, INT32 i
, HDC32 hdc
, INT32 x
, INT32 y
,
866 INT32 dx
, INT32 dy
, COLORREF rgbBk
, COLORREF rgbFg
,
869 IMAGELISTDRAWPARAMS imldp
;
871 imldp
.cbSize
= sizeof(IMAGELISTDRAWPARAMS
);
883 imldp
.fStyle
= fStyle
;
886 return (ImageList_DrawIndirect (&imldp
));
890 /*************************************************************************
891 * ImageList_DrawIndirect [COMCTL32.52]
893 * Draws an image using ...
896 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
904 ImageList_DrawIndirect (IMAGELISTDRAWPARAMS
*pimldp
)
906 HIMAGELIST himlLocal
;
907 HDC32 hdcImageList
, hdcTempImage
;
908 HBITMAP32 hbmTempImage
;
909 HBRUSH32 hBrush
, hOldBrush
;
913 BOOL32 bImage
; /* draw image ? */
914 BOOL32 bImageTrans
; /* draw image transparent ? */
915 BOOL32 bMask
; /* draw mask ? */
916 BOOL32 bMaskTrans
; /* draw mask transparent ? */
920 if (pimldp
== NULL
) return (FALSE
);
921 if (pimldp
->cbSize
< sizeof(IMAGELISTDRAWPARAMS
)) return (FALSE
);
922 if (pimldp
->himl
== NULL
) return (FALSE
);
923 if ((pimldp
->i
< 0) || (pimldp
->i
>= pimldp
->himl
->cCurImage
))
926 himlLocal
= pimldp
->himl
;
928 cx
= (pimldp
->cx
== 0) ? himlLocal
->cx
: pimldp
->cx
;
929 cy
= (pimldp
->cy
== 0) ? himlLocal
->cy
: pimldp
->cy
;
931 /* ILD_NORMAL state */
938 if ((himlLocal
->clrBk
== CLR_NONE
) && (himlLocal
->hbmMask
))
945 /* ILD_IMAGE state (changes) */
946 if (pimldp
->fStyle
& ILD_IMAGE
)
953 /* ILD_MASK state (changes) */
954 if ((pimldp
->fStyle
& ILD_MASK
) && (himlLocal
->hbmMask
))
960 if ((pimldp
->fStyle
& ILD_TRANSPARENT
) && (himlLocal
->hbmMask
))
965 if ((himlLocal
->clrBk
== CLR_NONE
) && (himlLocal
->hbmMask
))
968 if (pimldp
->fStyle
& ILD_BLEND50
)
970 else if (pimldp
->fStyle
& ILD_BLEND25
)
973 hdcImageList
= CreateCompatibleDC32 (0);
978 SelectObject32 (hdcImageList
, himlLocal
->hbmMask
);
979 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
, cx
, cy
,
980 hdcImageList
, himlLocal
->cx
* pimldp
->i
, 0,
981 bMaskTrans
? SRCAND
: SRCCOPY
);
987 SelectObject32 (hdcImageList
, himlLocal
->hbmImage
);
991 hBrush
= CreateSolidBrush32 (himlLocal
->clrBk
);
992 hOldBrush
= SelectObject32 (pimldp
->hdcDst
, hBrush
);
993 PatBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
,
995 DeleteObject32 (SelectObject32 (pimldp
->hdcDst
, hOldBrush
));
998 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
, cx
, cy
,
999 hdcImageList
, himlLocal
->cx
* pimldp
->i
, 0,
1002 if (bBlend25
|| bBlend50
)
1004 if (pimldp
->rgbFg
== CLR_DEFAULT
)
1005 clrBlend
= GetSysColor32 (COLOR_HIGHLIGHT
);
1007 clrBlend
= pimldp
->rgbFg
;
1009 hdcTempImage
= CreateCompatibleDC32 (0);
1010 hbmTempImage
= CreateBitmap32 (himlLocal
->cx
, himlLocal
->cy
,
1011 1, himlLocal
->uBitsPixel
, NULL
);
1012 SelectObject32 (hdcTempImage
, hbmTempImage
);
1016 SelectObject32 (hdcTempImage
,
1017 bBlend50
? himlLocal
->hbrBlend50
: himlLocal
->hbrBlend25
);
1018 PatBlt32 (hdcTempImage
, 0, 0, himlLocal
->cx
, himlLocal
->cy
, PATCOPY
);
1020 SelectObject32 (hdcImageList
, himlLocal
->hbmMask
);
1021 BitBlt32 (hdcTempImage
, 0, 0, himlLocal
->cx
,
1022 himlLocal
->cy
, hdcImageList
,
1023 pimldp
->i
* himlLocal
->cx
, 0, SRCPAINT
);
1025 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
, cx
, cy
,
1026 hdcTempImage
, 0, 0, SRCAND
);
1029 hBrush
= CreateSolidBrush32 (clrBlend
);
1030 SelectObject32 (hdcTempImage
, hBrush
);
1031 PatBlt32 (hdcTempImage
, 0, 0, himlLocal
->cx
, himlLocal
->cy
, PATCOPY
);
1032 DeleteObject32 (hBrush
);
1034 SelectObject32 (hdcTempImage
,
1035 bBlend50
? himlLocal
->hbrBlend50
: himlLocal
->hbrBlend25
);
1036 PatBlt32 (hdcTempImage
, 0, 0, himlLocal
->cx
, himlLocal
->cy
, 0x0A0329);
1038 SelectObject32 (hdcImageList
, himlLocal
->hbmMask
);
1039 BitBlt32 (hdcTempImage
, 0, 0, himlLocal
->cx
,
1040 himlLocal
->cy
, hdcImageList
,
1041 pimldp
->i
* himlLocal
->cx
, 0, SRCPAINT
);
1043 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
, cx
, cy
,
1044 hdcTempImage
, 0, 0, SRCPAINT
);
1046 DeleteObject32 (hbmTempImage
);
1047 DeleteDC32 (hdcTempImage
);
1051 /* Draw overlay image */
1052 if (pimldp
->fStyle
& 0x0700) {
1053 nOvlIdx
= (pimldp
->fStyle
& 0x0700) >> 8;
1054 if ((nOvlIdx
>= 1) && (nOvlIdx
<= MAX_OVERLAYIMAGE
)) {
1055 nOvlIdx
= pimldp
->himl
->nOvlIdx
[nOvlIdx
- 1];
1056 if ((nOvlIdx
>= 0) && (nOvlIdx
<= pimldp
->himl
->cCurImage
)) {
1057 if (pimldp
->himl
->hbmMask
) {
1058 SelectObject32 (hdcImageList
, pimldp
->himl
->hbmMask
);
1059 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
, cx
, cy
,
1060 hdcImageList
, pimldp
->himl
->cx
* nOvlIdx
, 0,
1063 SelectObject32 (hdcImageList
, pimldp
->himl
->hbmImage
);
1064 BitBlt32 (pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
,
1065 cx
, cy
, hdcImageList
,
1066 pimldp
->himl
->cx
* nOvlIdx
, 0, SRCPAINT
);
1071 DeleteDC32 (hdcImageList
);
1077 /*************************************************************************
1078 * ImageList_Duplicate [COMCTL32.53] Duplicates an image list.
1081 * himlSrc [I] source image list handle
1084 * Success: Handle of duplicated image list.
1089 ImageList_Duplicate (HIMAGELIST himlSrc
)
1092 HDC32 hdcSrc
, hdcDst
;
1094 if (himlSrc
== NULL
) {
1095 ERR (imagelist
, "Invalid image list handle!\n");
1099 himlDst
= ImageList_Create (himlSrc
->cx
, himlSrc
->cy
, himlSrc
->flags
,
1100 himlSrc
->cInitial
, himlSrc
->cGrow
);
1104 hdcSrc
= CreateCompatibleDC32 (0);
1105 hdcDst
= CreateCompatibleDC32 (0);
1106 SelectObject32 (hdcSrc
, himlSrc
->hbmImage
);
1107 SelectObject32 (hdcDst
, himlDst
->hbmImage
);
1108 BitBlt32 (hdcDst
, 0, 0, himlSrc
->cCurImage
* himlSrc
->cx
, himlSrc
->cy
,
1109 hdcSrc
, 0, 0, SRCCOPY
);
1111 if (himlDst
->hbmMask
)
1113 SelectObject32 (hdcSrc
, himlSrc
->hbmMask
);
1114 SelectObject32 (hdcDst
, himlDst
->hbmMask
);
1115 BitBlt32 (hdcDst
, 0, 0, himlSrc
->cCurImage
* himlSrc
->cx
,
1116 himlSrc
->cy
, hdcSrc
, 0, 0, SRCCOPY
);
1119 DeleteDC32 (hdcDst
);
1120 DeleteDC32 (hdcSrc
);
1127 /*************************************************************************
1128 * ImageList_EndDrag [COMCTL32.54] Finishes a drag operation.
1130 * Finishes a drag operation.
1144 ImageList_EndDrag (VOID
)
1146 FIXME (imagelist
, "semi-stub!\n");
1148 if (himlInternalDrag
)
1151 ImageList_Destroy (himlInternalDrag
);
1152 himlInternalDrag
= NULL
;
1154 nInternalDragHotspotX
= 0;
1155 nInternalDragHotspotY
= 0;
1163 /*************************************************************************
1164 * ImageList_GetBkColor [COMCTL32.55]
1166 * Returns the background color of an image list.
1169 * himl [I] Image list handle.
1172 * Success: background color
1177 ImageList_GetBkColor (HIMAGELIST himl
)
1182 return (himl
->clrBk
);
1186 /*************************************************************************
1187 * ImageList_GetDragImage [COMCTL32.56]
1189 * Returns the handle to the internal drag image list.
1192 * ppt [O] Pointer to the drag position. Can be NULL.
1193 * pptHotspot [O] Pointer to the position of the hot spot. Can be NULL.
1196 * Success: Handle of the drag image list.
1204 ImageList_GetDragImage (POINT32
*ppt
, POINT32
*pptHotspot
)
1206 FIXME (imagelist
, "semi-stub!\n");
1208 if (himlInternalDrag
)
1209 return (himlInternalDrag
);
1215 /*************************************************************************
1216 * ImageList_GetIcon [COMCTL32.57]
1218 * Creates an icon from a masked image of an image list.
1221 * himl [I] image list handle
1223 * flags [I] drawing style flags
1226 * Success: icon handle
1231 ImageList_GetIcon (HIMAGELIST himl
, INT32 i
, UINT32 fStyle
)
1236 INT32 nWidth
, nHeight
;
1238 if (himl
== NULL
) return 0;
1239 if ((i
< 0) || (i
>= himl
->cCurImage
)) return 0;
1241 nWidth
= GetSystemMetrics32 (SM_CXICON
);
1242 nHeight
= GetSystemMetrics32 (SM_CYICON
);
1247 ii
.hbmMask
= CreateBitmap32 (nWidth
, nHeight
, 1, 1, NULL
);
1248 ii
.hbmColor
= CreateBitmap32 (nWidth
, nHeight
, 1, 1, NULL
);
1250 hdc
= CreateCompatibleDC32(0);
1253 SelectObject32 (hdc
, ii
.hbmColor
);
1254 PatBlt32 (hdc
, 0, 0, nWidth
, nHeight
, BLACKNESS
);
1255 ImageList_Draw (himl
, i
, hdc
, 0, 0, fStyle
| ILD_TRANSPARENT
);
1258 SelectObject32 (hdc
, ii
.hbmMask
);
1259 PatBlt32 (hdc
, 0, 0, nWidth
, nHeight
, WHITENESS
);
1260 ImageList_Draw (himl
, i
, hdc
, 0, 0, fStyle
| ILD_MASK
);
1262 hIcon
= CreateIconIndirect (&ii
);
1265 DeleteObject32 (ii
.hbmMask
);
1266 DeleteObject32 (ii
.hbmColor
);
1272 /*************************************************************************
1273 * ImageList_GetIconSize [COMCTL32.58]
1275 * Retrieves the size of an image in an image list.
1278 * himl [I] image list handle
1279 * cx [O] pointer to the image width.
1280 * cy [O] pointer to the image height.
1287 * All images in an image list have the same size.
1291 ImageList_GetIconSize (HIMAGELIST himl
, INT32
*cx
, INT32
*cy
)
1294 if (himl
== NULL
) return (FALSE
);
1305 /*************************************************************************
1306 * ImageList_GetImageCount [COMCTL32.59]
1308 * Returns the number of images in an image list.
1311 * himl [I] image list handle.
1314 * Success: Number of images.
1319 ImageList_GetImageCount (HIMAGELIST himl
)
1324 return (himl
->cCurImage
);
1328 /*************************************************************************
1329 * ImageList_GetImageInfo [COMCTL32.60]
1331 * Returns information about an image in an image list.
1334 * himl [I] image list handle.
1336 * pImageInfo [O] pointer to the image information.
1344 ImageList_GetImageInfo (HIMAGELIST himl
, INT32 i
, IMAGEINFO
*pImageInfo
)
1346 if ((himl
== NULL
) || (pImageInfo
== NULL
)) return (FALSE
);
1347 if ((i
< 0) || (i
>= himl
->cCurImage
)) return (FALSE
);
1349 pImageInfo
->hbmImage
= himl
->hbmImage
;
1350 pImageInfo
->hbmMask
= himl
->hbmMask
;
1352 pImageInfo
->rcImage
.top
= 0;
1353 pImageInfo
->rcImage
.bottom
= himl
->cy
;
1354 pImageInfo
->rcImage
.left
= i
* himl
->cx
;
1355 pImageInfo
->rcImage
.right
= (i
+1) * himl
->cx
;
1361 /*************************************************************************
1362 * ImageList_GetImageRect [COMCTL32.61]
1364 * Retrieves the rectangle of the specified image in an image list.
1367 * himl [I] image list handle
1369 * lpRect [O] pointer to the image rectangle
1376 * This is an UNDOCUMENTED function!!!
1380 ImageList_GetImageRect (HIMAGELIST himl
, INT32 i
, LPRECT32 lpRect
)
1382 if ((himl
== NULL
) || (lpRect
== NULL
)) return (FALSE
);
1383 if ((i
< 0) || (i
>= himl
->cCurImage
)) return (FALSE
);
1385 lpRect
->left
= i
* himl
->cx
;
1387 lpRect
->right
= lpRect
->left
+ himl
->cx
;
1388 lpRect
->bottom
= himl
->cy
;
1394 /*************************************************************************
1395 * ImageList_LoadImage32A [COMCTL32.62][COMCTL32.63]
1397 * Creates an image list from a bitmap, icon or cursor.
1400 * hi [I] instance handle
1401 * lpbmp [I] name or id of the image
1402 * cx [I] width of each image
1403 * cGrow [I] number of images to expand
1404 * clrMask [I] mask color
1405 * uType [I] type of image to load
1406 * uFlags [I] loading flags
1409 * Success: handle of the loaded image
1417 ImageList_LoadImage32A (HINSTANCE32 hi
, LPCSTR lpbmp
, INT32 cx
, INT32 cGrow
,
1418 COLORREF clrMask
, UINT32 uType
, UINT32 uFlags
)
1420 HIMAGELIST himl
= NULL
;
1424 handle
= LoadImage32A (hi
, lpbmp
, uType
, 0, 0, uFlags
);
1425 if (!handle
) return (NULL
);
1427 if (uType
== IMAGE_BITMAP
) {
1429 GetObject32A (handle
, sizeof(BITMAP32
), &bmp
);
1430 nImageCount
= bmp
.bmWidth
/ cx
;
1432 himl
= ImageList_Create (cx
, bmp
.bmHeight
, ILC_MASK
| ILC_COLOR
,
1433 nImageCount
, cGrow
);
1434 ImageList_AddMasked (himl
, (HBITMAP32
)handle
, clrMask
);
1436 else if ((uType
== IMAGE_ICON
) || (uType
== IMAGE_CURSOR
)) {
1437 #ifdef __GET_ICON_INFO_HACK__
1440 CURSORICONINFO
*ptr
;
1442 if (!(ptr
= (CURSORICONINFO
*)GlobalLock16(handle
))) return (NULL
);
1443 hbmMask
= CreateBitmap32 (ptr
->nWidth
, ptr
->nHeight
, 1, 1,
1445 hbmImage
= CreateBitmap32 (ptr
->nWidth
, ptr
->nHeight
, ptr
->bPlanes
,
1447 (char *)(ptr
+ 1) + ptr
->nHeight
*
1448 BITMAP_WIDTH_BYTES(ptr
->nWidth
, 1));
1449 himl
= ImageList_Create (ptr
->nWidth
, ptr
->nHeight
,
1450 ILC_MASK
| ILC_COLOR
, 1, cGrow
);
1451 ImageList_Add (himl
, hbmImage
, hbmMask
);
1452 DeleteObject32 (hbmImage
);
1453 DeleteObject32 (hbmMask
);
1454 GlobalUnlock16 (handle
);
1459 GetIconInfo (hIcon
, &ii
);
1460 GetObject32A (ii
->hbmMask
, sizeof(BITMAP32
), (LPVOID
)&bmp
);
1461 himl
= ImageList_Create (bmp
.bmWidth
, bmp
.bmHeight
,
1462 ILC_MASK
| ILC_COLOR
, 1, cGrow
);
1463 ImageList_Add (himl
, ii
->hbmColor
, ii
->hbmMask
);
1467 DeleteObject32 (handle
);
1473 /*************************************************************************
1474 * ImageList_LoadImage32W [COMCTL32.64]
1476 * Creates an image list from a bitmap, icon or cursor.
1479 * hi [I] instance handle
1480 * lpbmp [I] name or id of the image
1481 * cx [I] width of each image
1482 * cGrow [I] number of images to expand
1483 * clrMask [I] mask color
1484 * uType [I] type of image to load
1485 * uFlags [I] loading flags
1488 * Success: handle of the loaded image
1496 ImageList_LoadImage32W (HINSTANCE32 hi
, LPCWSTR lpbmp
, INT32 cx
, INT32 cGrow
,
1497 COLORREF clrMask
, UINT32 uType
, UINT32 uFlags
)
1499 HIMAGELIST himl
= NULL
;
1503 handle
= LoadImage32W (hi
, lpbmp
, uType
, 0, 0, uFlags
);
1505 ERR (imagelist
, "Error loading image!\n");
1509 if (uType
== IMAGE_BITMAP
) {
1511 GetObject32A (handle
, sizeof(BITMAP32
), &bmp
);
1512 nImageCount
= bmp
.bmWidth
/ cx
;
1514 himl
= ImageList_Create (cx
, bmp
.bmHeight
, ILC_MASK
| ILC_COLOR
,
1515 nImageCount
, cGrow
);
1516 ImageList_AddMasked (himl
, (HBITMAP32
)handle
, clrMask
);
1518 else if ((uType
== IMAGE_ICON
) || (uType
== IMAGE_CURSOR
)) {
1519 #ifdef __GET_ICON_INFO_HACK__
1522 CURSORICONINFO
*ptr
;
1524 if (!(ptr
= (CURSORICONINFO
*)GlobalLock16(handle
))) return (NULL
);
1525 hbmMask
= CreateBitmap32 (ptr
->nWidth
, ptr
->nHeight
, 1, 1,
1527 hbmImage
= CreateBitmap32 (ptr
->nWidth
, ptr
->nHeight
, ptr
->bPlanes
,
1529 (char *)(ptr
+ 1) + ptr
->nHeight
*
1530 BITMAP_WIDTH_BYTES(ptr
->nWidth
, 1));
1531 himl
= ImageList_Create (ptr
->nWidth
, ptr
->nHeight
,
1532 ILC_MASK
| ILC_COLOR
, 1, cGrow
);
1533 ImageList_Add (himl
, hbmImage
, hbmMask
);
1534 DeleteObject32 (hbmImage
);
1535 DeleteObject32 (hbmMask
);
1536 GlobalUnlock16 (handle
);
1541 GetIconInfo (hIcon
, &ii
);
1542 GetObject32A (ii
->hbmMask
, sizeof(BITMAP32
), (LPVOID
)&bmp
);
1543 himl
= ImageList_Create (bmp
.bmWidth
, bmp
.bmHeight
,
1544 ILC_MASK
| ILC_COLOR
, 1, cGrow
);
1545 ImageList_Add (himl
, ii
->hbmColor
, ii
->hbmMask
);
1549 DeleteObject32 (handle
);
1555 /*************************************************************************
1556 * ImageList_Merge [COMCTL32.65]
1558 * Creates a new image list that contains a merged image from the specified
1559 * images of both source image lists.
1562 * himl1 [I] first image list handle
1563 * i1 [I] first image index
1564 * himl2 [I] second image list handle
1565 * i2 [I] second image index
1566 * dx [I] X offset of the second image relative to the first.
1567 * dy [I] Y offset of the second image relative to the first.
1570 * Success: handle of the merged image list.
1575 ImageList_Merge (HIMAGELIST himl1
, INT32 i1
, HIMAGELIST himl2
, INT32 i2
,
1578 HIMAGELIST himlDst
= NULL
;
1579 HDC32 hdcSrcImage
, hdcDstImage
;
1581 INT32 xOff1
, yOff1
, xOff2
, yOff2
;
1584 if ((himl1
== NULL
) || (himl2
== NULL
)) return (NULL
);
1587 if ((i1
< 0) || (i1
>= himl1
->cCurImage
)) {
1588 ERR (imagelist
, "Index 1 out of range! %d\n", i1
);
1592 if ((i2
< 0) || (i2
>= himl2
->cCurImage
)) {
1593 ERR (imagelist
, "Index 2 out of range! %d\n", i2
);
1598 cxDst
= _MAX (himl1
->cx
, dx
+ himl2
->cx
);
1603 cxDst
= _MAX (himl2
->cx
, himl1
->cx
- dx
);
1608 cxDst
= _MAX (himl1
->cx
, himl2
->cx
);
1614 cyDst
= _MAX (himl1
->cy
, dy
+ himl2
->cy
);
1619 cyDst
= _MAX (himl2
->cy
, himl1
->cy
- dy
);
1624 cyDst
= _MAX (himl1
->cy
, himl2
->cy
);
1629 himlDst
= ImageList_Create (cxDst
, cyDst
, ILC_MASK
| ILC_COLOR
, 1, 1);
1632 hdcSrcImage
= CreateCompatibleDC32 (0);
1633 hdcDstImage
= CreateCompatibleDC32 (0);
1634 nX1
= i1
* himl1
->cx
;
1635 nX2
= i2
* himl2
->cx
;
1638 SelectObject32 (hdcSrcImage
, himl1
->hbmImage
);
1639 SelectObject32 (hdcDstImage
, himlDst
->hbmImage
);
1640 BitBlt32 (hdcDstImage
, 0, 0, cxDst
, cyDst
,
1641 hdcSrcImage
, 0, 0, BLACKNESS
);
1642 BitBlt32 (hdcDstImage
, xOff1
, yOff1
, himl1
->cx
, himl1
->cy
,
1643 hdcSrcImage
, nX1
, 0, SRCCOPY
);
1645 SelectObject32 (hdcSrcImage
, himl2
->hbmMask
);
1646 BitBlt32 (hdcDstImage
, xOff2
, yOff2
, himl2
->cx
, himl2
->cy
,
1647 hdcSrcImage
, nX2
, 0, SRCAND
);
1649 SelectObject32 (hdcSrcImage
, himl2
->hbmImage
);
1650 BitBlt32 (hdcDstImage
, xOff2
, yOff2
, himl2
->cx
, himl2
->cy
,
1651 hdcSrcImage
, nX2
, 0, SRCPAINT
);
1654 SelectObject32 (hdcSrcImage
, himl1
->hbmMask
);
1655 SelectObject32 (hdcDstImage
, himlDst
->hbmMask
);
1656 BitBlt32 (hdcDstImage
, 0, 0, cxDst
, cyDst
,
1657 hdcSrcImage
, 0, 0, WHITENESS
);
1658 BitBlt32 (hdcDstImage
, xOff1
, yOff1
, himl1
->cx
, himl1
->cy
,
1659 hdcSrcImage
, nX1
, 0, SRCCOPY
);
1661 SelectObject32 (hdcSrcImage
, himl2
->hbmMask
);
1662 BitBlt32 (hdcDstImage
, xOff2
, yOff2
, himl2
->cx
, himl2
->cy
,
1663 hdcSrcImage
, nX2
, 0, SRCAND
);
1665 DeleteDC32 (hdcSrcImage
);
1666 DeleteDC32 (hdcDstImage
);
1673 /*************************************************************************
1674 * ImageList_Read [COMCTL32.66]
1676 * Reads an image list from a stream.
1679 * pstm [I] pointer to a stream
1682 * Success: image list handle
1686 * This function can not be implemented yet, because
1687 * IStream32::Read is not implemented.
1693 HIMAGELIST WINAPI
ImageList_Read (LPSTREAM32 pstm
)
1695 FIXME (imagelist
, "empty stub!\n");
1702 /*************************************************************************
1703 * ImageList_Remove [COMCTL32.67] Removes an image from an image list
1706 * himl [I] image list handle
1715 ImageList_Remove (HIMAGELIST himl
, INT32 i
)
1717 HBITMAP32 hbmNewImage
, hbmNewMask
;
1718 HDC32 hdcSrc
, hdcDst
;
1719 INT32 cxNew
, nCount
;
1721 if ((i
< -1) || (i
>= himl
->cCurImage
)) {
1722 ERR (imagelist
, "index out of range! %d\n", i
);
1726 if (himl
->cCurImage
== 0) {
1727 ERR (imagelist
, "image list is already empty!\n");
1733 TRACE (imagelist
, "remove all!\n");
1735 himl
->cMaxImage
= himl
->cInitial
+ himl
->cGrow
;
1736 himl
->cCurImage
= 0;
1737 for (nCount
= 0; nCount
<= MAX_OVERLAYIMAGE
; nCount
++)
1738 himl
->nOvlIdx
[nCount
] = -1;
1740 DeleteObject32 (himl
->hbmImage
);
1742 CreateBitmap32 (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
1743 1, himl
->uBitsPixel
, NULL
);
1745 if (himl
->hbmMask
) {
1746 DeleteObject32 (himl
->hbmMask
);
1748 CreateBitmap32 (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
1749 1, himl
->uBitsPixel
, NULL
);
1753 /* delete one image */
1754 TRACE (imagelist
, "Remove single image! %d\n", i
);
1756 /* create new bitmap(s) */
1757 cxNew
= (himl
->cCurImage
+ himl
->cGrow
- 1) * himl
->cx
;
1759 TRACE(imagelist
, " - Number of images: %d / %d (Old/New)\n",
1760 himl
->cCurImage
, himl
->cCurImage
- 1);
1761 TRACE(imagelist
, " - Max. number of images: %d / %d (Old/New)\n",
1762 himl
->cMaxImage
, himl
->cCurImage
+ himl
->cGrow
- 1);
1765 CreateBitmap32 (cxNew
, himl
->cy
, 1, himl
->uBitsPixel
, NULL
);
1768 hbmNewMask
= CreateBitmap32 (cxNew
, himl
->cy
, 1, himl
->uBitsPixel
, NULL
);
1770 hbmNewMask
= 0; /* Just to keep compiler happy! */
1772 hdcSrc
= CreateCompatibleDC32 (0);
1773 hdcDst
= CreateCompatibleDC32 (0);
1775 /* copy all images and masks prior to the "removed" image */
1777 TRACE (imagelist
, "Pre image copy: Copy %d images\n", i
);
1779 SelectObject32 (hdcSrc
, himl
->hbmImage
);
1780 SelectObject32 (hdcDst
, hbmNewImage
);
1781 BitBlt32 (hdcDst
, 0, 0, i
* himl
->cx
, himl
->cy
,
1782 hdcSrc
, 0, 0, SRCCOPY
);
1784 if (himl
->hbmMask
) {
1785 SelectObject32 (hdcSrc
, himl
->hbmMask
);
1786 SelectObject32 (hdcDst
, hbmNewMask
);
1787 BitBlt32 (hdcDst
, 0, 0, i
* himl
->cx
, himl
->cy
,
1788 hdcSrc
, 0, 0, SRCCOPY
);
1792 /* copy all images and masks behind the removed image */
1793 if (i
< himl
->cCurImage
- 1) {
1794 TRACE (imagelist
, "Post image copy!\n");
1795 SelectObject32 (hdcSrc
, himl
->hbmImage
);
1796 SelectObject32 (hdcDst
, hbmNewImage
);
1797 BitBlt32 (hdcDst
, i
* himl
->cx
, 0, (himl
->cCurImage
- i
- 1) * himl
->cx
,
1798 himl
->cy
, hdcSrc
, (i
+ 1) * himl
->cx
, 0, SRCCOPY
);
1800 if (himl
->hbmMask
) {
1801 SelectObject32 (hdcSrc
, himl
->hbmMask
);
1802 SelectObject32 (hdcDst
, hbmNewMask
);
1803 BitBlt32 (hdcDst
, i
* himl
->cx
, 0,
1804 (himl
->cCurImage
- i
- 1) * himl
->cx
,
1805 himl
->cy
, hdcSrc
, (i
+ 1) * himl
->cx
, 0, SRCCOPY
);
1809 DeleteDC32 (hdcSrc
);
1810 DeleteDC32 (hdcDst
);
1812 /* delete old images and insert new ones */
1813 DeleteObject32 (himl
->hbmImage
);
1814 himl
->hbmImage
= hbmNewImage
;
1815 if (himl
->hbmMask
) {
1816 DeleteObject32 (himl
->hbmMask
);
1817 himl
->hbmMask
= hbmNewMask
;
1821 himl
->cMaxImage
= himl
->cCurImage
+ himl
->cGrow
;
1828 /*************************************************************************
1829 * ImageList_Replace [COMCTL32.68]
1831 * Replaces an image in an image list with a new image.
1834 * himl [I] image list handle
1836 * hbmImage [I] image bitmap handle
1837 * hbmMask [I] mask bitmap handle. Can be NULL.
1845 ImageList_Replace (HIMAGELIST himl
, INT32 i
, HBITMAP32 hbmImage
,
1848 HDC32 hdcImageList
, hdcImage
;
1852 ERR (imagelist
, "Invalid image list handle!\n");
1856 if ((i
>= himl
->cCurImage
) || (i
< 0)) {
1857 ERR (imagelist
, "Invalid image index!\n");
1861 hdcImageList
= CreateCompatibleDC32 (0);
1862 hdcImage
= CreateCompatibleDC32 (0);
1863 GetObject32A (hbmImage
, sizeof(BITMAP32
), (LPVOID
)&bmp
);
1866 SelectObject32 (hdcImageList
, himl
->hbmImage
);
1867 SelectObject32 (hdcImage
, hbmImage
);
1869 StretchBlt32 (hdcImageList
, i
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
1870 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
1875 SelectObject32 (hdcImageList
, himl
->hbmMask
);
1876 SelectObject32 (hdcImage
, hbmMask
);
1878 StretchBlt32 (hdcImageList
, i
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
1879 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
1882 DeleteDC32 (hdcImage
);
1883 DeleteDC32 (hdcImageList
);
1889 /*************************************************************************
1890 * ImageList_ReplaceIcon [COMCTL32.69]
1892 * Replaces an image in an image list using an icon.
1895 * himl [I] image list handle
1897 * hIcon [I] icon handle
1900 * Success: index of the replaced image
1905 ImageList_ReplaceIcon (HIMAGELIST himl
, INT32 i
, HICON32 hIcon
)
1907 HDC32 hdcImageList
, hdcImage
;
1909 #ifdef __GET_ICON_INFO_HACK__
1912 CURSORICONINFO
*ptr
;
1918 if (himl
== NULL
) return (-1);
1919 if ((i
>= himl
->cCurImage
) || (i
< -1)) return (-1);
1921 #ifdef __GET_ICON_INFO_HACK__
1922 if (!(ptr
= (CURSORICONINFO
*)GlobalLock16(hIcon
))) return (-1);
1923 hbmMask
= CreateBitmap32 (ptr
->nWidth
, ptr
->nHeight
, 1, 1,
1925 hbmImage
= CreateBitmap32 (ptr
->nWidth
, ptr
->nHeight
, ptr
->bPlanes
,
1927 (char *)(ptr
+ 1) + ptr
->nHeight
*
1928 BITMAP_WIDTH_BYTES(ptr
->nWidth
, 1));
1930 GetIconInfo (hIcon
, &ii
);
1931 GetObject32A (ii
->hbmMask
, sizeof(BITMAP32
), (LPVOID
)&bmp
);
1935 if (himl
->cCurImage
+ 1 >= himl
->cMaxImage
)
1936 IMAGELIST_InternalExpandBitmaps (himl
, 1);
1938 nIndex
= himl
->cCurImage
;
1944 hdcImageList
= CreateCompatibleDC32 (0);
1945 hdcImage
= CreateCompatibleDC32 (0);
1947 #ifdef __GET_ICON_INFO_HACK__
1948 SelectObject32 (hdcImageList
, himl
->hbmImage
);
1949 SelectObject32 (hdcImage
, hbmImage
);
1950 StretchBlt32 (hdcImageList
, nIndex
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
1951 hdcImage
, 0, 0, ptr
->nWidth
, ptr
->nHeight
, SRCCOPY
);
1953 SelectObject32 (hdcImage
, ii
->hbmColor
);
1954 StretchBlt32 (hdcImageList
, nIndex
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
1955 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
1958 if (himl
->hbmMask
) {
1959 #ifdef __GET_ICON_INFO_HACK__
1960 SelectObject32 (hdcImageList
, himl
->hbmMask
);
1961 SelectObject32 (hdcImage
, hbmMask
);
1962 StretchBlt32 (hdcImageList
, nIndex
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
1963 hdcImage
, 0, 0, ptr
->nWidth
, ptr
->nHeight
, SRCCOPY
);
1965 SelectObject32 (hdcImage
, ii
->hbmMask
);
1966 StretchBlt32 (hdcImageList
, nIndex
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
1967 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
1971 DeleteDC32 (hdcImageList
);
1972 DeleteDC32 (hdcImage
);
1973 #ifdef __GET_ICON_INFO_HACK
1974 DeleteObject32 (hbmImage
);
1975 DeleteObject32 (hbmMask
);
1976 GlobalUnlock16 (hIcon
);
1982 /*************************************************************************
1983 * ImageList_SetBkColor [COMCTL32.70]
1985 * Sets the background color of an image list.
1988 * himl [I] image list handle
1989 * clrBk [I] background color
1992 * Success: previous background color
1997 ImageList_SetBkColor (HIMAGELIST himl
, COLORREF clrBk
)
2004 clrOldBk
= himl
->clrBk
;
2005 himl
->clrBk
= clrBk
;
2010 /*************************************************************************
2011 * ImageList_SetDragCursorImage [COMCTL32.75]
2013 * Combines the specified image with the current drag image
2016 * himlDrag [I] drag image list handle
2017 * iDrag [I] drag image index
2018 * dxHotspot [I] X position of the hot spot
2019 * dyHotspot [I] Y position of the hot spot
2030 ImageList_SetDragCursorImage (HIMAGELIST himlDrag
, INT32 iDrag
,
2031 INT32 dxHotspot
, INT32 dyHotspot
)
2033 HIMAGELIST himlTemp
;
2035 FIXME (imagelist
, "semi-stub!\n");
2037 if (himlInternalDrag
== NULL
) return (FALSE
);
2039 TRACE (imagelist
, " dxH=%d dyH=%d nX=%d nY=%d\n",
2040 dxHotspot
, dyHotspot
, nInternalDragHotspotX
, nInternalDragHotspotY
);
2042 himlTemp
= ImageList_Merge (himlInternalDrag
, 0, himlDrag
, iDrag
,
2043 dxHotspot
, dyHotspot
);
2045 ImageList_Destroy (himlInternalDrag
);
2046 himlInternalDrag
= himlTemp
;
2048 nInternalDragHotspotX
= dxHotspot
;
2049 nInternalDragHotspotY
= dyHotspot
;
2055 /*************************************************************************
2056 * ImageList_SetFilter [COMCTL32.76]
2058 * Sets a filter (or does something completely different)!!???
2067 * Failure: FALSE ???
2070 * This is an UNDOCUMENTED function!!!!
2076 ImageList_SetFilter (HIMAGELIST himl
, INT32 i
, DWORD dwFilter
)
2078 FIXME (imagelist
, "empty stub!\n");
2085 /*************************************************************************
2086 * ImageList_SetIconSize [COMCTL32.77]
2088 * Sets the image size of the bitmap and deletes all images.
2091 * himl [I] image list handle
2092 * cx [I] image width
2093 * cy [I] image height
2101 ImageList_SetIconSize (HIMAGELIST himl
, INT32 cx
, INT32 cy
)
2105 if (himl
== NULL
) return (FALSE
);
2107 /* remove all images*/
2108 himl
->cMaxImage
= himl
->cInitial
+ himl
->cGrow
;
2109 himl
->cCurImage
= 0;
2113 /* initialize overlay mask indices */
2114 for (nCount
= 0; nCount
< MAX_OVERLAYIMAGE
; nCount
++)
2115 himl
->nOvlIdx
[nCount
] = -1;
2117 DeleteObject32 (himl
->hbmImage
);
2119 CreateBitmap32 (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
2120 1, himl
->uBitsPixel
, NULL
);
2122 if (himl
->hbmMask
) {
2123 DeleteObject32 (himl
->hbmMask
);
2125 CreateBitmap32 (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
2126 1, himl
->uBitsPixel
, NULL
);
2133 /*************************************************************************
2134 * ImageList_SetImageCount [COMCTL32.78]
2136 * Resizes an image list to the specified number of images.
2139 * himl [I] image list handle
2140 * iImageCount [I] number of images in the image list
2148 ImageList_SetImageCount (HIMAGELIST himl
, INT32 iImageCount
)
2150 HDC32 hdcImageList
, hdcBitmap
;
2151 HBITMAP32 hbmNewBitmap
;
2152 INT32 nNewCount
, nCopyCount
;
2154 if (himl
== NULL
) return (FALSE
);
2155 if (himl
->cCurImage
<= iImageCount
) return (FALSE
);
2156 if (himl
->cMaxImage
> iImageCount
) return (TRUE
);
2158 nNewCount
= iImageCount
+ himl
->cGrow
;
2159 nCopyCount
= _MIN(himl
->cCurImage
, iImageCount
);
2161 hdcImageList
= CreateCompatibleDC32 (0);
2162 hdcBitmap
= CreateCompatibleDC32 (0);
2164 hbmNewBitmap
= CreateBitmap32 (nNewCount
* himl
->cx
, himl
->cy
,
2165 1, himl
->uBitsPixel
, NULL
);
2166 if (hbmNewBitmap
== 0)
2168 SelectObject32 (hdcImageList
, himl
->hbmImage
);
2169 SelectObject32 (hdcBitmap
, hbmNewBitmap
);
2170 BitBlt32 (hdcBitmap
, 0, 0, nCopyCount
* himl
->cx
, himl
->cy
,
2171 hdcImageList
, 0, 0, SRCCOPY
);
2172 DeleteObject32 (himl
->hbmImage
);
2173 himl
->hbmImage
= hbmNewBitmap
;
2177 WARN (imagelist
, "Could not create new image bitmap !\n");
2182 hbmNewBitmap
= CreateBitmap32 (nNewCount
* himl
->cx
, himl
->cy
,
2183 1, himl
->uBitsPixel
, NULL
);
2184 if (hbmNewBitmap
!= 0)
2186 SelectObject32 (hdcImageList
, himl
->hbmMask
);
2187 SelectObject32 (hdcBitmap
, hbmNewBitmap
);
2188 BitBlt32 (hdcBitmap
, 0, 0, nCopyCount
* himl
->cx
, himl
->cy
,
2189 hdcImageList
, 0, 0, SRCCOPY
);
2190 DeleteObject32 (himl
->hbmMask
);
2191 himl
->hbmMask
= hbmNewBitmap
;
2195 WARN (imagelist
, "Could not create new mask bitmap!\n");
2199 DeleteDC32 (hdcImageList
);
2200 DeleteDC32 (hdcBitmap
);
2202 /* Update max image count and current image count */
2203 himl
->cMaxImage
= nNewCount
;
2204 if (himl
->cCurImage
> nCopyCount
)
2205 himl
->cCurImage
= nCopyCount
;
2211 /*************************************************************************
2212 * ImageList_SetOverlayImage [COMCTL32.79]
2214 * Assigns an overlay mask index to an existing image in an image list.
2217 * himl [I] image list handle
2218 * iImage [I] image index
2219 * iOverlay [I] overlay mask index
2227 ImageList_SetOverlayImage (HIMAGELIST himl
, INT32 iImage
, INT32 iOverlay
)
2229 if ((iOverlay
< 1) || (iOverlay
> MAX_OVERLAYIMAGE
)) return (FALSE
);
2230 if ((iImage
< 0) || (iImage
> himl
->cCurImage
)) return (FALSE
);
2232 himl
->nOvlIdx
[iOverlay
- 1] = iImage
;
2237 /*************************************************************************
2238 * ImageList_Write [COMCTL32.80]
2240 * Writes an image list to a stream.
2243 * himl [I] Image list handle.
2244 * pstm [O] Pointer to a stream.
2251 * This function can not be implemented yet, because
2252 * IStream32::Write is not implemented.
2259 ImageList_Write (HIMAGELIST himl
, LPSTREAM32 pstm
)
2261 FIXME (imagelist
, "empty stub!\n");
2263 if (himl
== NULL
) return (FALSE
);