2 * ImageList implementation
4 * Copyright 1998 Eric Kohl
7 * - Fix ImageList_DrawIndirect (xBitmap, yBitmap, rgbFg, rgbBk, dwRop).
8 * - Fix ImageList_GetIcon.
9 * - Fix drag functions.
10 * - Fix ImageList_Write.
11 * - Fix ImageList_SetFilter (undocumented).
12 * BTW does anybody know anything about this function???
13 * - It removes 12 Bytes from the stack (3 Parameters).
14 * - First parameter SHOULD be a HIMAGELIST.
15 * - Second parameter COULD be an index?????
16 * - Third parameter.... ?????????????????????
19 * - ImageList_Draw, ImageList_DrawEx and ImageList_GetIcon use
20 * ImageList_DrawIndirect. Since ImageList_DrawIndirect is still
21 * partially imlemented, the functions mentioned above will be
22 * limited in functionality too.
25 /* This must be defined because the HIMAGELIST type is just a pointer
26 * to the _IMAGELIST data structure. But M$ does not want us to know
27 * anything about its contents. Applications just see a pointer to
28 * an empty structure. It's just to keep compatibility.
30 #define __WINE_IMAGELIST_C
33 #include "wine/obj_base.h"
34 #include "wine/obj_storage.h"
35 #include "imagelist.h"
37 #include "debugtools.h"
40 DEFAULT_DEBUG_CHANNEL(imagelist
)
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 INT nInternalDragHotspotX
= 0;
53 static INT nInternalDragHotspotY
= 0;
55 static HWND hwndInternalDrag
= 0;
56 static INT xInternalPos
= 0;
57 static INT yInternalPos
= 0;
59 static HDC hdcBackBuffer
= 0;
60 static HBITMAP hbmBackBuffer
= 0;
63 /*************************************************************************
64 * IMAGELIST_InternalExpandBitmaps [Internal]
66 * Expands the bitmaps of an image list by the given number of images.
69 * himl [I] handle to image list
70 * nImageCount [I] number of images to add
76 * This function can NOT be used to reduce the number of images.
79 IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl
, INT nImageCount
)
81 HDC hdcImageList
, hdcBitmap
;
83 INT nNewWidth
, nNewCount
;
85 TRACE("Create expanded bitmaps!\n");
87 nNewCount
= himl
->cCurImage
+ nImageCount
+ himl
->cGrow
;
88 nNewWidth
= nNewCount
* himl
->cx
;
90 hdcImageList
= CreateCompatibleDC (0);
91 hdcBitmap
= CreateCompatibleDC (0);
94 CreateBitmap (nNewWidth
, himl
->cy
, 1, himl
->uBitsPixel
, NULL
);
95 if (hbmNewBitmap
== 0)
96 ERR("creating new image bitmap!\n");
98 SelectObject (hdcImageList
, himl
->hbmImage
);
99 SelectObject (hdcBitmap
, hbmNewBitmap
);
100 BitBlt (hdcBitmap
, 0, 0, himl
->cCurImage
* himl
->cx
, himl
->cy
,
101 hdcImageList
, 0, 0, SRCCOPY
);
103 DeleteObject (himl
->hbmImage
);
104 himl
->hbmImage
= hbmNewBitmap
;
108 CreateBitmap (nNewWidth
, himl
->cy
, 1, 1, NULL
);
110 if (hbmNewBitmap
== 0)
111 ERR("creating new mask bitmap!");
113 SelectObject (hdcImageList
, himl
->hbmMask
);
114 SelectObject (hdcBitmap
, hbmNewBitmap
);
115 BitBlt (hdcBitmap
, 0, 0, himl
->cCurImage
* himl
->cx
, himl
->cy
,
116 hdcImageList
, 0, 0, SRCCOPY
);
117 DeleteObject (himl
->hbmMask
);
118 himl
->hbmMask
= hbmNewBitmap
;
121 himl
->cMaxImage
= nNewCount
;
123 DeleteDC (hdcImageList
);
124 DeleteDC (hdcBitmap
);
128 /*************************************************************************
129 * IMAGELIST_InternalDraw [Internal]
131 * Draws the image in the ImageList (without the mask)
134 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
135 * cx [I] the width of the image to display
136 * cy............[I] the height of the image to display
142 * This functions is used by ImageList_DrawIndirect, when it is
143 * required to draw only the Image (without the mask) to the screen.
145 * Blending and Overlays styles are accomplised by another function
148 IMAGELIST_InternalDraw(IMAGELISTDRAWPARAMS
*pimldp
, INT cx
, INT cy
)
153 hImageDC
= CreateCompatibleDC(0);
154 hOldBitmap
= SelectObject(hImageDC
, pimldp
->himl
->hbmImage
);
155 BitBlt(pimldp
->hdcDst
,
156 pimldp
->x
, pimldp
->y
, cx
, cy
,
158 pimldp
->himl
->cx
* pimldp
->i
, 0,
161 SelectObject(hImageDC
, hOldBitmap
);
166 /*************************************************************************
167 * IMAGELIST_InternalDrawMask [Internal]
169 * Draws the image in the ImageList witht the mask
172 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
173 * cx [I] the width of the image to display
174 * cy............[I] the height of the image to display
180 * This functions is used by ImageList_DrawIndirect, when it is
181 * required to draw the Image with the mask to the screen.
183 * Blending and Overlays styles are accomplised by another function.
186 IMAGELIST_InternalDrawMask(IMAGELISTDRAWPARAMS
*pimldp
, INT cx
, INT cy
)
188 HDC hMaskDC
, hImageDC
;
189 BOOL bUseCustomBackground
, bBlendFlag
;
190 HBRUSH hBrush
, hOldBrush
;
191 HBITMAP hOldBitmapImage
, hOldBitmapMask
;
192 HIMAGELIST himlLocal
= pimldp
->himl
;
193 COLORREF oldBkColor
, oldFgColor
;
194 UINT fStyle
= pimldp
->fStyle
& (~ILD_OVERLAYMASK
);
196 bUseCustomBackground
= (himlLocal
->clrBk
!= CLR_NONE
);
197 bBlendFlag
= (fStyle
& ILD_BLEND50
) || (fStyle
& ILD_BLEND25
);
199 hImageDC
= CreateCompatibleDC(0);
200 hMaskDC
= CreateCompatibleDC(0);
202 hOldBitmapImage
= SelectObject(hImageDC
, himlLocal
->hbmImage
);
203 hOldBitmapMask
= SelectObject(hMaskDC
, himlLocal
->hbmMask
);
204 /* Draw the Background for the appropriate Styles
206 if( bUseCustomBackground
&&
207 (fStyle
== ILD_NORMAL
|| fStyle
& ILD_IMAGE
|| bBlendFlag
))
209 hBrush
= CreateSolidBrush (himlLocal
->clrBk
);
210 hOldBrush
= SelectObject (pimldp
->hdcDst
, hBrush
);
211 PatBlt (pimldp
->hdcDst
,
212 pimldp
->x
, pimldp
->y
, cx
, cy
,
215 DeleteObject (SelectObject (pimldp
->hdcDst
, hOldBrush
));
218 /* Draw Image Transparently over the current background
220 if(fStyle
== ILD_NORMAL
221 || (fStyle
& ILD_TRANSPARENT
)
222 || ((fStyle
& ILD_IMAGE
) && bUseCustomBackground
)
225 /* to obtain a transparent look, background color should be set
226 to white and foreground color to black when blting the
228 oldBkColor
= SetBkColor(pimldp
->hdcDst
, RGB(0xff, 0xff, 0xff));
229 oldFgColor
= SetTextColor(pimldp
->hdcDst
, RGB(0, 0, 0));
231 BitBlt(pimldp
->hdcDst
,
232 pimldp
->x
, pimldp
->y
, cx
, cy
,
234 himlLocal
->cx
* pimldp
->i
, 0,
237 BitBlt(pimldp
->hdcDst
,
238 pimldp
->x
, pimldp
->y
, cx
, cy
,
240 himlLocal
->cx
* pimldp
->i
, 0,
243 SetBkColor(pimldp
->hdcDst
, oldBkColor
);
244 SetTextColor(pimldp
->hdcDst
, oldFgColor
);
246 /* Draw the image when no Background is specified
248 else if((fStyle
& ILD_IMAGE
) && !bUseCustomBackground
)
250 BitBlt(pimldp
->hdcDst
,
251 pimldp
->x
, pimldp
->y
, cx
, cy
,
253 himlLocal
->cx
* pimldp
->i
, 0,
256 /* Draw the mask with or without a background
258 else if(fStyle
& ILD_MASK
)
260 BitBlt(pimldp
->hdcDst
,
261 pimldp
->x
, pimldp
->y
, cx
, cy
,
263 himlLocal
->cx
* pimldp
->i
, 0,
264 bUseCustomBackground
? SRCCOPY
: SRCAND
);
266 SelectObject(hImageDC
, hOldBitmapImage
);
267 SelectObject(hMaskDC
, hOldBitmapMask
);
272 /*************************************************************************
273 * IMAGELIST_InternalDrawBlend [Internal]
275 * Draws the Blend over the current image
278 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
279 * cx [I] the width of the image to display
280 * cy............[I] the height of the image to display
286 * This functions is used by ImageList_DrawIndirect, when it is
287 * required to add the blend to the current image.
291 IMAGELIST_InternalDrawBlend(IMAGELISTDRAWPARAMS
*pimldp
, INT cx
, INT cy
)
294 HDC hBlendMaskDC
,hMaskDC
;
295 HBRUSH hBlendColorBrush
, hBlendBrush
, hOldBrush
;
296 HBITMAP hBlendMaskBitmap
, hOldBitmap
;
297 COLORREF clrBlend
, OldTextColor
, OldBkColor
;
298 HIMAGELIST himlLocal
= pimldp
->himl
;
300 clrBlend
= GetSysColor (COLOR_HIGHLIGHT
);
301 if (!(pimldp
->rgbFg
== CLR_DEFAULT
))
303 clrBlend
= pimldp
->rgbFg
;
305 /* Create the blend Mask
307 hBlendMaskDC
= CreateCompatibleDC(0);
308 hBlendBrush
= pimldp
->fStyle
& ILD_BLEND50
?
309 himlLocal
->hbrBlend50
: himlLocal
->hbrBlend25
;
311 hBlendMaskBitmap
= CreateBitmap(cx
, cy
, 1, 1, NULL
);
312 hOldBitmap
= SelectObject(hBlendMaskDC
, hBlendMaskBitmap
);
314 hOldBrush
= (HBRUSH
) SelectObject(hBlendMaskDC
, hBlendBrush
);
315 PatBlt(hBlendMaskDC
, 0, 0, cx
, cy
, PATCOPY
);
316 SelectObject(hBlendMaskDC
, hOldBrush
);
318 /* Modify the blend mask if an Image Mask exist
320 if(pimldp
->himl
->hbmMask
!= 0)
322 HBITMAP hOldMaskBitmap
;
323 hMaskDC
= CreateCompatibleDC(0);
324 hOldMaskBitmap
= (HBITMAP
) SelectObject(hMaskDC
, himlLocal
->hbmMask
);
329 himlLocal
->cx
* pimldp
->i
,0,
330 0x220326); /* NOTSRCAND */
338 SelectObject(hMaskDC
, hOldMaskBitmap
);
342 /* Apply blend to the current image given the BlendMask
344 OldTextColor
= SetTextColor(pimldp
->hdcDst
, 0);
345 OldBkColor
= SetBkColor(pimldp
->hdcDst
, RGB(255,255,255));
346 hBlendColorBrush
= CreateSolidBrush(clrBlend
);
347 hOldBrush
= (HBRUSH
) SelectObject (pimldp
->hdcDst
, hBlendColorBrush
);
349 BitBlt (pimldp
->hdcDst
,
350 pimldp
->x
, pimldp
->y
, cx
, cy
,
353 0xB8074A); /* PSDPxax */
355 SelectObject(pimldp
->hdcDst
, hOldBrush
);
356 SetTextColor(pimldp
->hdcDst
, OldTextColor
);
357 SetBkColor(pimldp
->hdcDst
, OldBkColor
);
358 SelectObject(hBlendMaskDC
, hOldBitmap
);
359 DeleteDC(hBlendMaskDC
);
360 DeleteObject(hBlendMaskBitmap
);
361 DeleteObject(hBlendColorBrush
);
364 /*************************************************************************
365 * IMAGELIST_InternalDrawOverlay [Internal]
367 * Draws the overlay image
370 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
371 * cx [I] the width of the image to display
372 * cy............[I] the height of the image to display
378 * This functions is used by ImageList_DrawIndirect, when it is
379 * required to draw the overlay
384 IMAGELIST_InternalDrawOverlay(IMAGELISTDRAWPARAMS
*pimldp
, INT cx
, INT cy
)
390 nOvlIdx
= (pimldp
->fStyle
& ILD_OVERLAYMASK
) >> 8;
391 if ((nOvlIdx
>= 1) && (nOvlIdx
<= MAX_OVERLAYIMAGE
))
393 nOvlIdx
= pimldp
->himl
->nOvlIdx
[nOvlIdx
- 1];
394 if ((nOvlIdx
>= 0) && (nOvlIdx
<= pimldp
->himl
->cCurImage
))
396 hImageDC
= CreateCompatibleDC(0);
397 if (pimldp
->himl
->hbmMask
)
399 hOldBitmap
= (HBITMAP
) SelectObject (hImageDC
,
400 pimldp
->himl
->hbmMask
);
402 BitBlt (pimldp
->hdcDst
,
403 pimldp
->x
, pimldp
->y
, cx
, cy
,
404 hImageDC
, pimldp
->himl
->cx
* nOvlIdx
, 0,
407 SelectObject(hImageDC
, hOldBitmap
);
409 hOldBitmap
= (HBITMAP
) SelectObject (hImageDC
,
410 pimldp
->himl
->hbmImage
);
412 BitBlt (pimldp
->hdcDst
,
413 pimldp
->x
, pimldp
->y
, cx
, cy
,
415 pimldp
->himl
->cx
* nOvlIdx
, 0,
418 SelectObject(hImageDC
, hOldBitmap
);
428 /*************************************************************************
429 * ImageList_Add [COMCTL32.39]
431 * Add an image or images to an image list.
434 * himl [I] handle to image list
435 * hbmImage [I] handle to image bitmap
436 * hbmMask [I] handle to mask bitmap
439 * Success: Index of the first new image.
444 ImageList_Add (HIMAGELIST himl
, HBITMAP hbmImage
, HBITMAP hbmMask
)
446 HDC hdcImage
, hdcBitmap
;
447 INT nFirstIndex
, nImageCount
;
450 HBITMAP hOldBitmapImage
, hOldBitmap
;
452 if (!himl
|| !hbmImage
)
455 GetObjectA (hbmImage
, sizeof(BITMAP
), (LPVOID
)&bmp
);
456 nImageCount
= bmp
.bmWidth
/ himl
->cx
;
458 if (himl
->cCurImage
+ nImageCount
>= himl
->cMaxImage
)
459 IMAGELIST_InternalExpandBitmaps (himl
, nImageCount
);
461 nStartX
= himl
->cCurImage
* himl
->cx
;
463 hdcImage
= CreateCompatibleDC(0);
464 hdcBitmap
= CreateCompatibleDC(0);
466 hOldBitmapImage
= SelectObject(hdcImage
, himl
->hbmImage
);
467 hOldBitmap
= SelectObject(hdcBitmap
, hbmImage
);
469 /* Copy result to the imagelist
471 BitBlt (hdcImage
, nStartX
, 0, bmp
.bmWidth
, himl
->cy
,
472 hdcBitmap
, 0, 0, SRCCOPY
);
476 HDC hdcMask
, hdcTemp
, hOldBitmapMask
, hOldBitmapTemp
;
478 hdcMask
= CreateCompatibleDC (0);
479 hdcTemp
= CreateCompatibleDC(0);
480 hOldBitmapMask
= (HBITMAP
) SelectObject(hdcMask
, himl
->hbmMask
);
481 hOldBitmapTemp
= (HBITMAP
) SelectObject(hdcTemp
, hbmMask
);
484 nStartX
, 0, bmp
.bmWidth
, himl
->cy
,
489 SelectObject(hdcTemp
, hOldBitmapTemp
);
492 /* Remove the background from the image
495 nStartX
, 0, bmp
.bmWidth
, himl
->cy
,
498 0x220326); /* NOTSRCAND */
500 SelectObject(hdcMask
, hOldBitmapMask
);
504 SelectObject(hdcImage
, hOldBitmapImage
);
505 SelectObject(hdcBitmap
, hOldBitmap
);
509 nFirstIndex
= himl
->cCurImage
;
510 himl
->cCurImage
+= nImageCount
;
516 /*************************************************************************
517 * ImageList_AddIcon [COMCTL32.40]
519 * Adds an icon to an image list.
522 * himl [I] handle to image list
523 * hIcon [I] handle to icon
526 * Success: index of the new image
531 ImageList_AddIcon (HIMAGELIST himl
, HICON hIcon
)
533 return ImageList_ReplaceIcon (himl
, -1, hIcon
);
537 /*************************************************************************
538 * ImageList_AddMasked [COMCTL32.41]
540 * Adds an image or images to an image list and creates a mask from the
541 * specified bitmap using the mask color.
544 * himl [I] handle to image list.
545 * hBitmap [I] handle to bitmap
546 * clrMask [I] mask color.
549 * Success: Index of the first new image.
554 ImageList_AddMasked (HIMAGELIST himl
, HBITMAP hBitmap
, COLORREF clrMask
)
556 HDC hdcImage
, hdcMask
, hdcBitmap
;
557 INT nIndex
, nImageCount
, nMaskXOffset
=0;
559 HBITMAP hOldBitmap
, hOldBitmapMask
, hOldBitmapImage
;
560 HBITMAP hMaskBitmap
=0;
566 if (!GetObjectA (hBitmap
, sizeof(BITMAP
), &bmp
))
569 nImageCount
= bmp
.bmWidth
/ himl
->cx
;
571 if (himl
->cCurImage
+ nImageCount
>= himl
->cMaxImage
)
573 IMAGELIST_InternalExpandBitmaps (himl
, nImageCount
);
576 nIndex
= himl
->cCurImage
;
577 himl
->cCurImage
+= nImageCount
;
579 hdcMask
= CreateCompatibleDC (0);
580 hdcImage
= CreateCompatibleDC(0);
581 hdcBitmap
= CreateCompatibleDC(0);
584 hOldBitmapImage
= SelectObject(hdcImage
, himl
->hbmImage
);
585 hOldBitmap
= SelectObject(hdcBitmap
, hBitmap
);
588 hOldBitmapMask
= SelectObject(hdcMask
, himl
->hbmMask
);
589 nMaskXOffset
= nIndex
* himl
->cx
;
594 Create a temp Mask so we can remove the background of
595 the Image (Windows does this even if there is no mask)
597 hMaskBitmap
= CreateBitmap(bmp
.bmWidth
, himl
->cy
, 1, 1, NULL
);
598 hOldBitmapMask
= SelectObject(hdcMask
, hMaskBitmap
);
601 /* create monochrome image to the mask bitmap */
602 bkColor
= (clrMask
!= CLR_DEFAULT
) ? clrMask
:
603 GetPixel (hdcBitmap
, 0, 0);
604 SetBkColor (hdcBitmap
, bkColor
);
606 nMaskXOffset
, 0, bmp
.bmWidth
, himl
->cy
,
610 SetBkColor(hdcBitmap
, RGB(255,255,255));
611 /*Remove the background from the image
614 WINDOWS BUG ALERT!!!!!!
615 The statement below should not be done in common practice
616 but this is how ImageList_AddMasked works in Windows.
617 It overwrites the original bitmap passed, this was discovered
618 by using the same bitmap to itterated the different styles
619 on windows where it failed (BUT ImageList_Add is OK)
620 This is here in case some apps really on this bug
623 0, 0, bmp
.bmWidth
, himl
->cy
,
626 0x220326); /* NOTSRCAND */
627 /* Copy result to the imagelist
630 nIndex
* himl
->cx
, 0, bmp
.bmWidth
, himl
->cy
,
636 SelectObject(hdcMask
,hOldBitmapMask
);
637 SelectObject(hdcImage
, hOldBitmapImage
);
638 SelectObject(hdcBitmap
, hOldBitmap
);
644 DeleteObject(hMaskBitmap
);
651 /*************************************************************************
652 * ImageList_BeginDrag [COMCTL32.42]
654 * Creates a temporary image list that contains one image. It will be used
658 * himlTrack [I] handle to the source image list
659 * iTrack [I] index of the drag image in the source image list
660 * dxHotspot [I] X position of the hot spot of the drag image
661 * dyHotspot [I] Y position of the hot spot of the drag image
669 ImageList_BeginDrag (HIMAGELIST himlTrack
, INT iTrack
,
670 INT dxHotspot
, INT dyHotspot
)
674 FIXME("partially implemented!\n");
676 if (himlTrack
== NULL
)
679 if (himlInternalDrag
)
680 ImageList_EndDrag ();
683 ImageList_Create (himlTrack
->cx
, himlTrack
->cy
,
684 himlTrack
->flags
, 1, 1);
685 if (himlInternalDrag
== NULL
) {
686 ERR("Error creating drag image list!\n");
690 nInternalDragHotspotX
= dxHotspot
;
691 nInternalDragHotspotY
= dyHotspot
;
693 hdcSrc
= CreateCompatibleDC (0);
694 hdcDst
= CreateCompatibleDC (0);
697 SelectObject (hdcSrc
, himlTrack
->hbmImage
);
698 SelectObject (hdcDst
, himlInternalDrag
->hbmImage
);
699 StretchBlt (hdcDst
, 0, 0, himlInternalDrag
->cx
, himlInternalDrag
->cy
, hdcSrc
,
700 iTrack
* himlTrack
->cx
, 0, himlTrack
->cx
, himlTrack
->cy
, SRCCOPY
);
703 SelectObject (hdcSrc
, himlTrack
->hbmMask
);
704 SelectObject (hdcDst
, himlInternalDrag
->hbmMask
);
705 StretchBlt (hdcDst
, 0, 0, himlInternalDrag
->cx
, himlInternalDrag
->cy
, hdcSrc
,
706 iTrack
* himlTrack
->cx
, 0, himlTrack
->cx
, himlTrack
->cy
, SRCCOPY
);
711 himlInternalDrag
->cCurImage
= 1;
717 /*************************************************************************
718 * ImageList_Copy [COMCTL32.43]
720 * Copies an image of the source image list to an image of the
721 * destination image list. Images can be copied or swapped.
724 * himlDst [I] handle to the destination image list
725 * iDst [I] destination image index.
726 * himlSrc [I] handle to the source image list
727 * iSrc [I] source image index
728 * uFlags [I] flags for the copy operation
735 * Copying from one image list to another is possible. The original
736 * implementation just copies or swapps within one image list.
737 * Could this feature become a bug??? ;-)
741 ImageList_Copy (HIMAGELIST himlDst
, INT iDst
, HIMAGELIST himlSrc
,
742 INT iSrc
, INT uFlags
)
746 TRACE("iDst=%d iSrc=%d\n", iDst
, iSrc
);
748 if ((himlSrc
== NULL
) || (himlDst
== NULL
))
750 if ((iDst
< 0) || (iDst
>= himlDst
->cCurImage
))
752 if ((iSrc
< 0) || (iSrc
>= himlSrc
->cCurImage
))
755 hdcSrc
= CreateCompatibleDC (0);
756 if (himlDst
== himlSrc
)
759 hdcDst
= CreateCompatibleDC (0);
761 if (uFlags
& ILCF_SWAP
) {
763 HBITMAP hbmTempImage
, hbmTempMask
;
765 /* create temporary bitmaps */
766 hbmTempImage
= CreateBitmap (himlSrc
->cx
, himlSrc
->cy
, 1,
767 himlSrc
->uBitsPixel
, NULL
);
768 hbmTempMask
= CreateBitmap (himlSrc
->cx
, himlSrc
->cy
, 1,
771 /* copy (and stretch) destination to temporary bitmaps.(save) */
773 SelectObject (hdcSrc
, himlDst
->hbmImage
);
774 SelectObject (hdcDst
, hbmTempImage
);
775 StretchBlt (hdcDst
, 0, 0, himlSrc
->cx
, himlSrc
->cy
,
776 hdcSrc
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
779 SelectObject (hdcSrc
, himlDst
->hbmMask
);
780 SelectObject (hdcDst
, hbmTempMask
);
781 StretchBlt (hdcDst
, 0, 0, himlSrc
->cx
, himlSrc
->cy
,
782 hdcSrc
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
785 /* copy (and stretch) source to destination */
787 SelectObject (hdcSrc
, himlSrc
->hbmImage
);
788 SelectObject (hdcDst
, himlDst
->hbmImage
);
789 StretchBlt (hdcDst
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
790 hdcSrc
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
793 SelectObject (hdcSrc
, himlSrc
->hbmMask
);
794 SelectObject (hdcDst
, himlDst
->hbmMask
);
795 StretchBlt (hdcDst
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
796 hdcSrc
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
799 /* copy (without stretching) temporary bitmaps to source (restore) */
801 SelectObject (hdcSrc
, hbmTempImage
);
802 SelectObject (hdcDst
, himlSrc
->hbmImage
);
803 BitBlt (hdcDst
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
804 hdcSrc
, 0, 0, SRCCOPY
);
806 SelectObject (hdcSrc
, hbmTempMask
);
807 SelectObject (hdcDst
, himlSrc
->hbmMask
);
808 BitBlt (hdcDst
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
809 hdcSrc
, 0, 0, SRCCOPY
);
811 /* delete temporary bitmaps */
812 DeleteObject (hbmTempMask
);
813 DeleteObject (hbmTempImage
);
817 SelectObject (hdcSrc
, himlSrc
->hbmImage
);
818 if (himlSrc
== himlDst
)
821 SelectObject (hdcDst
, himlDst
->hbmImage
);
822 StretchBlt (hdcDst
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
823 hdcSrc
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
827 SelectObject (hdcSrc
, himlSrc
->hbmMask
);
828 if (himlSrc
== himlDst
)
831 SelectObject (hdcDst
, himlDst
->hbmMask
);
832 StretchBlt (hdcDst
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
833 hdcSrc
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
838 if (himlSrc
!= himlDst
)
845 /*************************************************************************
846 * ImageList_Create [COMCTL32.44] Creates a new image list.
849 * cx [I] image height
851 * flags [I] creation flags
852 * cInitial [I] initial number of images in the image list
853 * cGrow [I] number of images by which image list grows
856 * Success: Handle to the created image list
861 ImageList_Create (INT cx
, INT cy
, UINT flags
,
862 INT cInitial
, INT cGrow
)
868 static WORD aBitBlend25
[] =
869 {0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00};
871 static WORD aBitBlend50
[] =
872 {0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA};
874 TRACE("(%d %d 0x%x %d %d)\n", cx
, cy
, flags
, cInitial
, cGrow
);
876 himl
= (HIMAGELIST
)COMCTL32_Alloc (sizeof(struct _IMAGELIST
));
883 himl
->cMaxImage
= cInitial
+ cGrow
;
884 himl
->cInitial
= cInitial
;
887 himl
->clrFg
= CLR_DEFAULT
;
888 himl
->clrBk
= CLR_NONE
;
890 /* initialize overlay mask indices */
891 for (nCount
= 0; nCount
< MAX_OVERLAYIMAGE
; nCount
++)
892 himl
->nOvlIdx
[nCount
] = -1;
894 hdc
= CreateCompatibleDC (0);
895 himl
->uBitsPixel
= (UINT
)GetDeviceCaps (hdc
, BITSPIXEL
);
898 TRACE("Image: %d Bits per Pixel\n", himl
->uBitsPixel
);
900 if (himl
->cMaxImage
> 0) {
902 CreateBitmap (himl
->cx
* himl
->cMaxImage
, himl
->cy
,
903 1, himl
->uBitsPixel
, NULL
);
904 if (himl
->hbmImage
== 0) {
905 ERR("Error creating image bitmap!\n");
912 if ( (himl
->cMaxImage
> 0) && (himl
->flags
& ILC_MASK
)) {
913 himl
->hbmMask
= CreateBitmap (himl
->cx
* himl
->cMaxImage
, himl
->cy
,
915 if (himl
->hbmMask
== 0) {
916 ERR("Error creating mask bitmap!\n");
918 DeleteObject (himl
->hbmImage
);
925 /* create blending brushes */
926 hbmTemp
= CreateBitmap (8, 8, 1, 1, &aBitBlend25
);
927 himl
->hbrBlend25
= CreatePatternBrush (hbmTemp
);
928 DeleteObject (hbmTemp
);
930 hbmTemp
= CreateBitmap (8, 8, 1, 1, &aBitBlend50
);
931 himl
->hbrBlend50
= CreatePatternBrush (hbmTemp
);
932 DeleteObject (hbmTemp
);
938 /*************************************************************************
939 * ImageList_Destroy [COMCTL32.45]
941 * Destroys an image list.
944 * himl [I] handle to image list
952 ImageList_Destroy (HIMAGELIST himl
)
957 /* delete image bitmaps */
959 DeleteObject (himl
->hbmImage
);
961 DeleteObject (himl
->hbmMask
);
963 /* delete blending brushes */
964 if (himl
->hbrBlend25
)
965 DeleteObject (himl
->hbrBlend25
);
966 if (himl
->hbrBlend50
)
967 DeleteObject (himl
->hbrBlend50
);
969 COMCTL32_Free (himl
);
975 /*************************************************************************
976 * ImageList_DragEnter [COMCTL32.46]
978 * Locks window update and displays the drag image at the given position.
981 * hwndLock [I] handle of the window that owns the drag image.
982 * x [I] X position of the drag image.
983 * y [I] Y position of the drag image.
990 * The position of the drag image is relative to the window, not
995 ImageList_DragEnter (HWND hwndLock
, INT x
, INT y
)
997 if (himlInternalDrag
== NULL
)
1001 hwndInternalDrag
= hwndLock
;
1003 hwndInternalDrag
= GetDesktopWindow ();
1008 hdcBackBuffer
= CreateCompatibleDC (0);
1009 hbmBackBuffer
= CreateCompatibleBitmap (hdcBackBuffer
,
1010 himlInternalDrag
->cx
, himlInternalDrag
->cy
);
1012 ImageList_DragShowNolock (TRUE
);
1018 /*************************************************************************
1019 * ImageList_DragLeave [COMCTL32.47]
1021 * Unlocks window update and hides the drag image.
1024 * hwndLock [I] handle of the window that owns the drag image.
1032 ImageList_DragLeave (HWND hwndLock
)
1035 hwndInternalDrag
= hwndLock
;
1037 hwndInternalDrag
= GetDesktopWindow ();
1039 ImageList_DragShowNolock (FALSE
);
1041 DeleteDC (hdcBackBuffer
);
1042 DeleteObject (hbmBackBuffer
);
1048 /*************************************************************************
1049 * ImageList_DragMove [COMCTL32.48]
1051 * Moves the drag image.
1054 * x [I] X position of the drag image.
1055 * y [I] Y position of the drag image.
1062 * The position of the drag image is relative to the window, not
1067 ImageList_DragMove (INT x
, INT y
)
1069 ImageList_DragShowNolock (FALSE
);
1074 ImageList_DragShowNolock (TRUE
);
1080 /*************************************************************************
1081 * ImageList_DragShowNolock [COMCTL32.49]
1083 * Shows or hides the drag image.
1086 * bShow [I] TRUE shows the drag image, FALSE hides it.
1097 ImageList_DragShowNolock (BOOL bShow
)
1101 FIXME("semi-stub!\n");
1102 TRACE("bShow=0x%X!\n", bShow
);
1104 hdcDrag
= GetDCEx (hwndInternalDrag
, 0,
1105 DCX_WINDOW
| DCX_CACHE
| DCX_LOCKWINDOWUPDATE
);
1108 /* show drag image */
1110 /* save background */
1112 /* draw drag image */
1116 /* hide drag image */
1118 /* restore background */
1122 ReleaseDC (hwndInternalDrag
, hdcDrag
);
1128 /*************************************************************************
1129 * ImageList_Draw [COMCTL32.50] Draws an image.
1132 * himl [I] handle to image list
1134 * hdc [I] handle to device context
1137 * fStyle [I] drawing flags
1144 * Calls ImageList_DrawIndirect.
1147 * ImageList_DrawIndirect.
1151 ImageList_Draw (HIMAGELIST himl
, INT i
, HDC hdc
,
1152 INT x
, INT y
, UINT fStyle
)
1154 IMAGELISTDRAWPARAMS imldp
;
1156 imldp
.cbSize
= sizeof(IMAGELISTDRAWPARAMS
);
1166 imldp
.rgbBk
= CLR_DEFAULT
;
1167 imldp
.rgbFg
= CLR_DEFAULT
;
1168 imldp
.fStyle
= fStyle
;
1171 return ImageList_DrawIndirect (&imldp
);
1175 /*************************************************************************
1176 * ImageList_DrawEx [COMCTL32.51]
1178 * Draws an image and allows to use extended drawing features.
1181 * himl [I] handle to image list
1183 * hdc [I] handle to device context
1186 * xOffs [I] X offset
1187 * yOffs [I] Y offset
1188 * rgbBk [I] background color
1189 * rgbFg [I] foreground color
1190 * fStyle [I] drawing flags
1197 * Calls ImageList_DrawIndirect.
1200 * ImageList_DrawIndirect.
1204 ImageList_DrawEx (HIMAGELIST himl
, INT i
, HDC hdc
, INT x
, INT y
,
1205 INT dx
, INT dy
, COLORREF rgbBk
, COLORREF rgbFg
,
1208 IMAGELISTDRAWPARAMS imldp
;
1210 imldp
.cbSize
= sizeof(IMAGELISTDRAWPARAMS
);
1220 imldp
.rgbBk
= rgbBk
;
1221 imldp
.rgbFg
= rgbFg
;
1222 imldp
.fStyle
= fStyle
;
1225 return ImageList_DrawIndirect (&imldp
);
1229 /*************************************************************************
1230 * ImageList_DrawIndirect [COMCTL32.52]
1232 * Draws an image using ...
1235 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
1243 ImageList_DrawIndirect (IMAGELISTDRAWPARAMS
*pimldp
)
1247 Do some Error Checking
1251 if (pimldp
->cbSize
< sizeof(IMAGELISTDRAWPARAMS
))
1253 if (pimldp
->himl
== NULL
)
1255 if ((pimldp
->i
< 0) || (pimldp
->i
> pimldp
->himl
->cCurImage
)) {
1256 ERR("%d not within range (max %d)\n",pimldp
->i
,pimldp
->himl
->cCurImage
);
1260 Get the Height and Width to display
1262 cx
= (pimldp
->cx
== 0) ? pimldp
->himl
->cx
: pimldp
->cx
;
1263 cy
= (pimldp
->cy
== 0) ? pimldp
->himl
->cy
: pimldp
->cy
;
1267 if(pimldp
->himl
->hbmMask
!= 0)
1269 IMAGELIST_InternalDrawMask(pimldp
, cx
, cy
);
1273 IMAGELIST_InternalDraw(pimldp
, cx
, cy
);
1276 Apply the blend if needed to the Image
1278 if((pimldp
->fStyle
& ILD_BLEND50
)
1279 || (pimldp
->fStyle
& ILD_BLEND25
))
1281 IMAGELIST_InternalDrawBlend(pimldp
, cx
, cy
);
1284 Apply the Overlay if needed
1286 if (pimldp
->fStyle
& ILD_OVERLAYMASK
)
1288 IMAGELIST_InternalDrawOverlay(pimldp
, cx
, cy
);
1295 /*************************************************************************
1296 * ImageList_Duplicate [COMCTL32.53] Duplicates an image list.
1299 * himlSrc [I] source image list handle
1302 * Success: Handle of duplicated image list.
1307 ImageList_Duplicate (HIMAGELIST himlSrc
)
1312 if (himlSrc
== NULL
) {
1313 ERR("Invalid image list handle!\n");
1317 himlDst
= ImageList_Create (himlSrc
->cx
, himlSrc
->cy
, himlSrc
->flags
,
1318 himlSrc
->cInitial
, himlSrc
->cGrow
);
1322 hdcSrc
= CreateCompatibleDC (0);
1323 hdcDst
= CreateCompatibleDC (0);
1324 SelectObject (hdcSrc
, himlSrc
->hbmImage
);
1325 SelectObject (hdcDst
, himlDst
->hbmImage
);
1326 BitBlt (hdcDst
, 0, 0, himlSrc
->cCurImage
* himlSrc
->cx
, himlSrc
->cy
,
1327 hdcSrc
, 0, 0, SRCCOPY
);
1329 if (himlDst
->hbmMask
)
1331 SelectObject (hdcSrc
, himlSrc
->hbmMask
);
1332 SelectObject (hdcDst
, himlDst
->hbmMask
);
1333 BitBlt (hdcDst
, 0, 0, himlSrc
->cCurImage
* himlSrc
->cx
,
1334 himlSrc
->cy
, hdcSrc
, 0, 0, SRCCOPY
);
1340 himlDst
->cCurImage
= himlSrc
->cCurImage
;
1341 himlDst
->cMaxImage
= himlSrc
->cMaxImage
;
1347 /*************************************************************************
1348 * ImageList_EndDrag [COMCTL32.54] Finishes a drag operation.
1350 * Finishes a drag operation.
1364 ImageList_EndDrag (void)
1366 FIXME("semi-stub!\n");
1368 if (himlInternalDrag
)
1371 ImageList_Destroy (himlInternalDrag
);
1372 himlInternalDrag
= NULL
;
1374 nInternalDragHotspotX
= 0;
1375 nInternalDragHotspotY
= 0;
1383 /*************************************************************************
1384 * ImageList_GetBkColor [COMCTL32.55]
1386 * Returns the background color of an image list.
1389 * himl [I] Image list handle.
1392 * Success: background color
1397 ImageList_GetBkColor (HIMAGELIST himl
)
1406 /*************************************************************************
1407 * ImageList_GetDragImage [COMCTL32.56]
1409 * Returns the handle to the internal drag image list.
1412 * ppt [O] Pointer to the drag position. Can be NULL.
1413 * pptHotspot [O] Pointer to the position of the hot spot. Can be NULL.
1416 * Success: Handle of the drag image list.
1424 ImageList_GetDragImage (POINT
*ppt
, POINT
*pptHotspot
)
1426 FIXME("semi-stub!\n");
1428 if (himlInternalDrag
)
1429 return (himlInternalDrag
);
1435 /*************************************************************************
1436 * ImageList_GetIcon [COMCTL32.57]
1438 * Creates an icon from a masked image of an image list.
1441 * himl [I] handle to image list
1443 * flags [I] drawing style flags
1446 * Success: icon handle
1451 ImageList_GetIcon (HIMAGELIST himl
, INT i
, UINT fStyle
)
1455 HBITMAP hOldSrcBitmap
,hOldDstBitmap
;
1458 if ((himl
== NULL
) || (i
< 0) || (i
>= himl
->cCurImage
)) {
1459 FIXME("(%p,%d,%x), params out of range!\n",himl
,i
,fStyle
);
1463 hdcSrc
= CreateCompatibleDC(0);
1464 hdcDst
= CreateCompatibleDC(0);
1467 ii
.hbmMask
= CreateCompatibleBitmap (hdcDst
, himl
->cx
, himl
->cy
);
1470 hOldDstBitmap
= (HBITMAP
)SelectObject (hdcDst
, ii
.hbmMask
);
1471 if (himl
->hbmMask
) {
1472 SelectObject (hdcSrc
, himl
->hbmMask
);
1473 BitBlt (hdcDst
, 0, 0, himl
->cx
, himl
->cy
,
1474 hdcSrc
, i
* himl
->cx
, 0, SRCCOPY
);
1477 PatBlt (hdcDst
, 0, 0, himl
->cx
, himl
->cy
, BLACKNESS
);
1480 hOldSrcBitmap
= (HBITMAP
)SelectObject (hdcSrc
, himl
->hbmImage
);
1481 ii
.hbmColor
= CreateCompatibleBitmap (hdcSrc
, himl
->cx
, himl
->cy
);
1482 SelectObject (hdcDst
, ii
.hbmColor
);
1483 BitBlt (hdcDst
, 0, 0, himl
->cx
, himl
->cy
,
1484 hdcSrc
, i
* himl
->cx
, 0, SRCCOPY
);
1487 * CreateIconIndirect requires us to deselect the bitmaps from
1488 * the DCs before calling
1490 SelectObject(hdcSrc
, hOldSrcBitmap
);
1491 SelectObject(hdcDst
, hOldDstBitmap
);
1493 hIcon
= CreateIconIndirect (&ii
);
1497 DeleteObject (ii
.hbmMask
);
1498 DeleteObject (ii
.hbmColor
);
1504 /*************************************************************************
1505 * ImageList_GetIconSize [COMCTL32.58]
1507 * Retrieves the size of an image in an image list.
1510 * himl [I] handle to image list
1511 * cx [O] pointer to the image width.
1512 * cy [O] pointer to the image height.
1519 * All images in an image list have the same size.
1523 ImageList_GetIconSize (HIMAGELIST himl
, INT
*cx
, INT
*cy
)
1527 if ((himl
->cx
<= 0) || (himl
->cy
<= 0))
1539 /*************************************************************************
1540 * ImageList_GetImageCount [COMCTL32.59]
1542 * Returns the number of images in an image list.
1545 * himl [I] handle to image list
1548 * Success: Number of images.
1553 ImageList_GetImageCount (HIMAGELIST himl
)
1558 return himl
->cCurImage
;
1562 /*************************************************************************
1563 * ImageList_GetImageInfo [COMCTL32.60]
1565 * Returns information about an image in an image list.
1568 * himl [I] handle to image list
1570 * pImageInfo [O] pointer to the image information
1578 ImageList_GetImageInfo (HIMAGELIST himl
, INT i
, IMAGEINFO
*pImageInfo
)
1580 if ((himl
== NULL
) || (pImageInfo
== NULL
))
1582 if ((i
< 0) || (i
>= himl
->cCurImage
))
1585 pImageInfo
->hbmImage
= himl
->hbmImage
;
1586 pImageInfo
->hbmMask
= himl
->hbmMask
;
1588 pImageInfo
->rcImage
.top
= 0;
1589 pImageInfo
->rcImage
.bottom
= himl
->cy
;
1590 pImageInfo
->rcImage
.left
= i
* himl
->cx
;
1591 pImageInfo
->rcImage
.right
= (i
+1) * himl
->cx
;
1597 /*************************************************************************
1598 * ImageList_GetImageRect [COMCTL32.61]
1600 * Retrieves the rectangle of the specified image in an image list.
1603 * himl [I] handle to image list
1605 * lpRect [O] pointer to the image rectangle
1612 * This is an UNDOCUMENTED function!!!
1616 ImageList_GetImageRect (HIMAGELIST himl
, INT i
, LPRECT lpRect
)
1618 if ((himl
== NULL
) || (lpRect
== NULL
))
1620 if ((i
< 0) || (i
>= himl
->cCurImage
))
1623 lpRect
->left
= i
* himl
->cx
;
1625 lpRect
->right
= lpRect
->left
+ himl
->cx
;
1626 lpRect
->bottom
= himl
->cy
;
1632 /*************************************************************************
1633 * ImageList_LoadImageA [COMCTL32.63][COMCTL32.62]
1635 * Creates an image list from a bitmap, icon or cursor.
1638 * hi [I] instance handle
1639 * lpbmp [I] name or id of the image
1640 * cx [I] width of each image
1641 * cGrow [I] number of images to expand
1642 * clrMask [I] mask color
1643 * uType [I] type of image to load
1644 * uFlags [I] loading flags
1647 * Success: handle to the loaded image list
1655 ImageList_LoadImageA (HINSTANCE hi
, LPCSTR lpbmp
, INT cx
, INT cGrow
,
1656 COLORREF clrMask
, UINT uType
, UINT uFlags
)
1658 HIMAGELIST himl
= NULL
;
1662 handle
= LoadImageA (hi
, lpbmp
, uType
, 0, 0, uFlags
);
1664 ERR("Error loading image!\n");
1668 if (uType
== IMAGE_BITMAP
) {
1670 GetObjectA (handle
, sizeof(BITMAP
), &bmp
);
1672 /* To match windows behavior, if cx is set to zero and
1673 the flag DI_DEFAULTSIZE is specified, cx becomes the
1674 system metric value for icons. If the flag is not specified
1675 the function sets the size to the height of the bitmap */
1678 if (uFlags
& DI_DEFAULTSIZE
)
1679 cx
= GetSystemMetrics (SM_CXICON
);
1684 nImageCount
= bmp
.bmWidth
/ cx
;
1686 himl
= ImageList_Create (cx
, bmp
.bmHeight
, ILC_MASK
| ILC_COLOR
,
1687 nImageCount
, cGrow
);
1688 ImageList_AddMasked (himl
, (HBITMAP
)handle
, clrMask
);
1690 else if ((uType
== IMAGE_ICON
) || (uType
== IMAGE_CURSOR
)) {
1694 GetIconInfo (handle
, &ii
);
1695 GetObjectA (ii
.hbmColor
, sizeof(BITMAP
), (LPVOID
)&bmp
);
1696 himl
= ImageList_Create (bmp
.bmWidth
, bmp
.bmHeight
,
1697 ILC_MASK
| ILC_COLOR
, 1, cGrow
);
1698 ImageList_Add (himl
, ii
.hbmColor
, ii
.hbmMask
);
1699 DeleteObject (ii
.hbmColor
);
1700 DeleteObject (ii
.hbmMask
);
1703 DeleteObject (handle
);
1709 /*************************************************************************
1710 * ImageList_LoadImageW [COMCTL32.64]
1712 * Creates an image list from a bitmap, icon or cursor.
1715 * hi [I] instance handle
1716 * lpbmp [I] name or id of the image
1717 * cx [I] width of each image
1718 * cGrow [I] number of images to expand
1719 * clrMask [I] mask color
1720 * uType [I] type of image to load
1721 * uFlags [I] loading flags
1724 * Success: handle to the loaded image list
1732 ImageList_LoadImageW (HINSTANCE hi
, LPCWSTR lpbmp
, INT cx
, INT cGrow
,
1733 COLORREF clrMask
, UINT uType
, UINT uFlags
)
1735 HIMAGELIST himl
= NULL
;
1739 handle
= LoadImageW (hi
, lpbmp
, uType
, 0, 0, uFlags
);
1741 ERR("Error loading image!\n");
1745 if (uType
== IMAGE_BITMAP
) {
1747 GetObjectA (handle
, sizeof(BITMAP
), &bmp
);
1748 nImageCount
= bmp
.bmWidth
/ cx
;
1750 himl
= ImageList_Create (cx
, bmp
.bmHeight
, ILC_MASK
| ILC_COLOR
,
1751 nImageCount
, cGrow
);
1752 ImageList_AddMasked (himl
, (HBITMAP
)handle
, clrMask
);
1754 else if ((uType
== IMAGE_ICON
) || (uType
== IMAGE_CURSOR
)) {
1758 GetIconInfo (handle
, &ii
);
1759 GetObjectA (ii
.hbmMask
, sizeof(BITMAP
), (LPVOID
)&bmp
);
1760 himl
= ImageList_Create (bmp
.bmWidth
, bmp
.bmHeight
,
1761 ILC_MASK
| ILC_COLOR
, 1, cGrow
);
1762 ImageList_Add (himl
, ii
.hbmColor
, ii
.hbmMask
);
1763 DeleteObject (ii
.hbmColor
);
1764 DeleteObject (ii
.hbmMask
);
1767 DeleteObject (handle
);
1773 /*************************************************************************
1774 * ImageList_Merge [COMCTL32.65]
1776 * Creates a new image list that contains a merged image from the specified
1777 * images of both source image lists.
1780 * himl1 [I] handle to first image list
1781 * i1 [I] first image index
1782 * himl2 [I] handle to second image list
1783 * i2 [I] second image index
1784 * dx [I] X offset of the second image relative to the first.
1785 * dy [I] Y offset of the second image relative to the first.
1788 * Success: handle of the merged image list.
1793 ImageList_Merge (HIMAGELIST himl1
, INT i1
, HIMAGELIST himl2
, INT i2
,
1796 HIMAGELIST himlDst
= NULL
;
1797 HDC hdcSrcImage
, hdcDstImage
;
1799 INT xOff1
, yOff1
, xOff2
, yOff2
;
1802 if ((himl1
== NULL
) || (himl2
== NULL
))
1806 if ((i1
< 0) || (i1
>= himl1
->cCurImage
)) {
1807 ERR("Index 1 out of range! %d\n", i1
);
1811 if ((i2
< 0) || (i2
>= himl2
->cCurImage
)) {
1812 ERR("Index 2 out of range! %d\n", i2
);
1817 cxDst
= _MAX (himl1
->cx
, dx
+ himl2
->cx
);
1822 cxDst
= _MAX (himl2
->cx
, himl1
->cx
- dx
);
1827 cxDst
= _MAX (himl1
->cx
, himl2
->cx
);
1833 cyDst
= _MAX (himl1
->cy
, dy
+ himl2
->cy
);
1838 cyDst
= _MAX (himl2
->cy
, himl1
->cy
- dy
);
1843 cyDst
= _MAX (himl1
->cy
, himl2
->cy
);
1848 himlDst
= ImageList_Create (cxDst
, cyDst
, ILC_MASK
| ILC_COLOR
, 1, 1);
1851 hdcSrcImage
= CreateCompatibleDC (0);
1852 hdcDstImage
= CreateCompatibleDC (0);
1853 nX1
= i1
* himl1
->cx
;
1854 nX2
= i2
* himl2
->cx
;
1857 SelectObject (hdcSrcImage
, himl1
->hbmImage
);
1858 SelectObject (hdcDstImage
, himlDst
->hbmImage
);
1859 BitBlt (hdcDstImage
, 0, 0, cxDst
, cyDst
,
1860 hdcSrcImage
, 0, 0, BLACKNESS
);
1861 BitBlt (hdcDstImage
, xOff1
, yOff1
, himl1
->cx
, himl1
->cy
,
1862 hdcSrcImage
, nX1
, 0, SRCCOPY
);
1864 SelectObject (hdcSrcImage
, himl2
->hbmMask
);
1865 BitBlt (hdcDstImage
, xOff2
, yOff2
, himl2
->cx
, himl2
->cy
,
1866 hdcSrcImage
, nX2
, 0, SRCAND
);
1868 SelectObject (hdcSrcImage
, himl2
->hbmImage
);
1869 BitBlt (hdcDstImage
, xOff2
, yOff2
, himl2
->cx
, himl2
->cy
,
1870 hdcSrcImage
, nX2
, 0, SRCPAINT
);
1873 SelectObject (hdcSrcImage
, himl1
->hbmMask
);
1874 SelectObject (hdcDstImage
, himlDst
->hbmMask
);
1875 BitBlt (hdcDstImage
, 0, 0, cxDst
, cyDst
,
1876 hdcSrcImage
, 0, 0, WHITENESS
);
1877 BitBlt (hdcDstImage
, xOff1
, yOff1
, himl1
->cx
, himl1
->cy
,
1878 hdcSrcImage
, nX1
, 0, SRCCOPY
);
1880 SelectObject (hdcSrcImage
, himl2
->hbmMask
);
1881 BitBlt (hdcDstImage
, xOff2
, yOff2
, himl2
->cx
, himl2
->cy
,
1882 hdcSrcImage
, nX2
, 0, SRCAND
);
1884 DeleteDC (hdcSrcImage
);
1885 DeleteDC (hdcDstImage
);
1892 /* helper for _read_bitmap currently unused */
1894 static int may_use_dibsection(HDC hdc
) {
1895 int bitspixel
= GetDeviceCaps(hdc
,BITSPIXEL
)*GetDeviceCaps(hdc
,PLANES
);
1900 return GetDeviceCaps(hdc
,94) & 0x10;
1904 /* helper for ImageList_Read, see comments below */
1905 static HBITMAP
_read_bitmap(LPSTREAM pstm
,int ilcFlag
,int cx
,int cy
) {
1907 BITMAPFILEHEADER bmfh
;
1908 BITMAPINFOHEADER bmih
;
1909 int bitsperpixel
,palspace
,longsperline
,width
,height
;
1910 LPBITMAPINFOHEADER bmihc
= NULL
;
1912 HBITMAP hbitmap
= 0;
1913 LPBYTE bits
= NULL
,nbits
= NULL
;
1914 int nbytesperline
,bytesperline
;
1916 if (!SUCCEEDED(IStream_Read ( pstm
, &bmfh
, sizeof(bmfh
), NULL
)) ||
1917 (bmfh
.bfType
!= (('M'<<8)|'B')) ||
1918 !SUCCEEDED(IStream_Read ( pstm
, &bmih
, sizeof(bmih
), NULL
)) ||
1919 (bmih
.biSize
!= sizeof(bmih
))
1923 bitsperpixel
= bmih
.biPlanes
* bmih
.biBitCount
;
1924 if (bitsperpixel
<=8)
1925 palspace
= (1<<bitsperpixel
)*sizeof(RGBQUAD
);
1928 width
= bmih
.biWidth
;
1929 height
= bmih
.biHeight
;
1930 bmihc
= (LPBITMAPINFOHEADER
)LocalAlloc(LMEM_ZEROINIT
,sizeof(bmih
)+palspace
);
1931 memcpy(bmihc
,&bmih
,sizeof(bmih
));
1932 longsperline
= ((width
*bitsperpixel
+31)&~0x1f)>>5;
1933 bmihc
->biSizeImage
= (longsperline
*height
)<<2;
1935 /* read the palette right after the end of the bitmapinfoheader */
1937 if (!SUCCEEDED(IStream_Read ( pstm
, bmihc
+1, palspace
, NULL
)))
1941 #if 0 /* Magic for NxM -> 1x(N*M) not implemented for DIB Sections */
1942 if ((bitsperpixel
>1) &&
1943 ((ilcFlag
!=ILC_COLORDDB
) && (!ilcFlag
|| may_use_dibsection(xdc
)))
1945 hbitmap
= CreateDIBSection(xdc
,(BITMAPINFO
*)bmihc
,0,(LPVOID
*)&bits
,0,0);
1948 if (!SUCCEEDED(IStream_Read( pstm
, bits
, bmihc
->biSizeImage
, NULL
)))
1954 int i
,nwidth
,nheight
;
1956 nwidth
= width
*(height
/cy
);
1959 if (bitsperpixel
==1)
1960 hbitmap
= CreateBitmap(nwidth
,nheight
,1,1,NULL
);
1962 hbitmap
= CreateCompatibleBitmap(xdc
,nwidth
,nheight
);
1964 /* Might be a bit excessive memory use here */
1965 bits
= (LPBYTE
)LocalAlloc(LMEM_ZEROINIT
,bmihc
->biSizeImage
);
1966 nbits
= (LPBYTE
)LocalAlloc(LMEM_ZEROINIT
,bmihc
->biSizeImage
);
1967 if (!SUCCEEDED(IStream_Read ( pstm
, bits
, bmihc
->biSizeImage
, NULL
)))
1970 /* Copy the NxM bitmap into a 1x(N*M) bitmap we need, linewise */
1971 /* Do not forget that windows bitmaps are bottom->top */
1972 bytesperline
= longsperline
*4;
1973 nbytesperline
= (height
/cy
)*bytesperline
;
1974 for (i
=0;i
<height
;i
++) {
1976 nbits
+((height
-1-i
)%cy
)*nbytesperline
+(i
/cy
)*bytesperline
,
1977 bits
+bytesperline
*(height
-1-i
),
1981 bmihc
->biWidth
= nwidth
;
1982 bmihc
->biHeight
= nheight
;
1983 if (!SetDIBits(xdc
,hbitmap
,0,nheight
,nbits
,(BITMAPINFO
*)bmihc
,0))
1985 LocalFree((HLOCAL
)nbits
);
1986 LocalFree((HLOCAL
)bits
);
1990 if (xdc
) ReleaseDC(0,xdc
);
1991 if (bmihc
) LocalFree((HLOCAL
)bmihc
);
1994 DeleteObject(hbitmap
);
2001 /*************************************************************************
2002 * ImageList_Read [COMCTL32.66]
2004 * Reads an image list from a stream.
2007 * pstm [I] pointer to a stream
2010 * Success: handle to image list
2013 * The format is like this:
2014 * ILHEAD ilheadstruct;
2016 * for the color image part:
2017 * BITMAPFILEHEADER bmfh;
2018 * BITMAPINFOHEADER bmih;
2019 * only if it has a palette:
2020 * RGBQUAD rgbs[nr_of_paletted_colors];
2022 * BYTE colorbits[imagesize];
2024 * the following only if the ILC_MASK bit is set in ILHEAD.ilFlags:
2025 * BITMAPFILEHEADER bmfh_mask;
2026 * BITMAPINFOHEADER bmih_mask;
2027 * only if it has a palette (it usually does not):
2028 * RGBQUAD rgbs[nr_of_paletted_colors];
2030 * BYTE maskbits[imagesize];
2032 * CAVEAT: Those images are within a NxM bitmap, not the 1xN we expect.
2033 * _read_bitmap needs to convert them.
2035 HIMAGELIST WINAPI
ImageList_Read (LPSTREAM pstm
)
2039 HBITMAP hbmColor
=0,hbmMask
=0;
2042 if (!SUCCEEDED(IStream_Read (pstm
, &ilHead
, sizeof(ILHEAD
), NULL
)))
2044 if (ilHead
.usMagic
!= (('L' << 8) | 'I'))
2046 if (ilHead
.usVersion
!= 0x101) /* probably version? */
2050 FIXME(" ilHead.cCurImage = %d\n",ilHead
.cCurImage
);
2051 FIXME(" ilHead.cMaxImage = %d\n",ilHead
.cMaxImage
);
2052 FIXME(" ilHead.cGrow = %d\n",ilHead
.cGrow
);
2053 FIXME(" ilHead.cx = %d\n",ilHead
.cx
);
2054 FIXME(" ilHead.cy = %d\n",ilHead
.cy
);
2055 FIXME(" ilHead.flags = %x\n",ilHead
.flags
);
2056 FIXME(" ilHead.ovls[0] = %d\n",ilHead
.ovls
[0]);
2057 FIXME(" ilHead.ovls[1] = %d\n",ilHead
.ovls
[1]);
2058 FIXME(" ilHead.ovls[2] = %d\n",ilHead
.ovls
[2]);
2059 FIXME(" ilHead.ovls[3] = %d\n",ilHead
.ovls
[3]);
2062 hbmColor
= _read_bitmap(pstm
,ilHead
.flags
& ~ILC_MASK
,ilHead
.cx
,ilHead
.cy
);
2065 if (ilHead
.flags
& ILC_MASK
) {
2066 hbmMask
= _read_bitmap(pstm
,0,ilHead
.cx
,ilHead
.cy
);
2068 DeleteObject(hbmColor
);
2073 himl
= ImageList_Create (
2081 DeleteObject(hbmColor
);
2082 DeleteObject(hbmMask
);
2085 himl
->hbmImage
= hbmColor
;
2086 himl
->hbmMask
= hbmMask
;
2087 himl
->cCurImage
= ilHead
.cCurImage
;
2088 himl
->cMaxImage
= ilHead
.cMaxImage
;
2090 ImageList_SetBkColor(himl
,ilHead
.bkcolor
);
2092 ImageList_SetOverlayImage(himl
,ilHead
.ovls
[i
],i
+1);
2097 /*************************************************************************
2098 * ImageList_Remove [COMCTL32.67] Removes an image from an image list
2101 * himl [I] image list handle
2110 ImageList_Remove (HIMAGELIST himl
, INT i
)
2112 HBITMAP hbmNewImage
, hbmNewMask
;
2116 if ((i
< -1) || (i
>= himl
->cCurImage
)) {
2117 ERR("index out of range! %d\n", i
);
2121 if (himl
->cCurImage
== 0) {
2122 ERR("image list is already empty!\n");
2128 TRACE("remove all!\n");
2130 himl
->cMaxImage
= himl
->cInitial
+ himl
->cGrow
;
2131 himl
->cCurImage
= 0;
2132 for (nCount
= 0; nCount
< MAX_OVERLAYIMAGE
; nCount
++)
2133 himl
->nOvlIdx
[nCount
] = -1;
2135 DeleteObject (himl
->hbmImage
);
2137 CreateBitmap (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
2138 1, himl
->uBitsPixel
, NULL
);
2140 if (himl
->hbmMask
) {
2141 DeleteObject (himl
->hbmMask
);
2143 CreateBitmap (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
2148 /* delete one image */
2149 TRACE("Remove single image! %d\n", i
);
2151 /* create new bitmap(s) */
2152 cxNew
= (himl
->cCurImage
+ himl
->cGrow
- 1) * himl
->cx
;
2154 TRACE(" - Number of images: %d / %d (Old/New)\n",
2155 himl
->cCurImage
, himl
->cCurImage
- 1);
2156 TRACE(" - Max. number of images: %d / %d (Old/New)\n",
2157 himl
->cMaxImage
, himl
->cCurImage
+ himl
->cGrow
- 1);
2160 CreateBitmap (cxNew
, himl
->cy
, 1, himl
->uBitsPixel
, NULL
);
2163 hbmNewMask
= CreateBitmap (cxNew
, himl
->cy
, 1, 1, NULL
);
2165 hbmNewMask
= 0; /* Just to keep compiler happy! */
2167 hdcSrc
= CreateCompatibleDC (0);
2168 hdcDst
= CreateCompatibleDC (0);
2170 /* copy all images and masks prior to the "removed" image */
2172 TRACE("Pre image copy: Copy %d images\n", i
);
2174 SelectObject (hdcSrc
, himl
->hbmImage
);
2175 SelectObject (hdcDst
, hbmNewImage
);
2176 BitBlt (hdcDst
, 0, 0, i
* himl
->cx
, himl
->cy
,
2177 hdcSrc
, 0, 0, SRCCOPY
);
2179 if (himl
->hbmMask
) {
2180 SelectObject (hdcSrc
, himl
->hbmMask
);
2181 SelectObject (hdcDst
, hbmNewMask
);
2182 BitBlt (hdcDst
, 0, 0, i
* himl
->cx
, himl
->cy
,
2183 hdcSrc
, 0, 0, SRCCOPY
);
2187 /* copy all images and masks behind the removed image */
2188 if (i
< himl
->cCurImage
- 1) {
2189 TRACE("Post image copy!\n");
2190 SelectObject (hdcSrc
, himl
->hbmImage
);
2191 SelectObject (hdcDst
, hbmNewImage
);
2192 BitBlt (hdcDst
, i
* himl
->cx
, 0, (himl
->cCurImage
- i
- 1) * himl
->cx
,
2193 himl
->cy
, hdcSrc
, (i
+ 1) * himl
->cx
, 0, SRCCOPY
);
2195 if (himl
->hbmMask
) {
2196 SelectObject (hdcSrc
, himl
->hbmMask
);
2197 SelectObject (hdcDst
, hbmNewMask
);
2198 BitBlt (hdcDst
, i
* himl
->cx
, 0,
2199 (himl
->cCurImage
- i
- 1) * himl
->cx
,
2200 himl
->cy
, hdcSrc
, (i
+ 1) * himl
->cx
, 0, SRCCOPY
);
2207 /* delete old images and insert new ones */
2208 DeleteObject (himl
->hbmImage
);
2209 himl
->hbmImage
= hbmNewImage
;
2210 if (himl
->hbmMask
) {
2211 DeleteObject (himl
->hbmMask
);
2212 himl
->hbmMask
= hbmNewMask
;
2216 himl
->cMaxImage
= himl
->cCurImage
+ himl
->cGrow
;
2223 /*************************************************************************
2224 * ImageList_Replace [COMCTL32.68]
2226 * Replaces an image in an image list with a new image.
2229 * himl [I] handle to image list
2231 * hbmImage [I] handle to image bitmap
2232 * hbmMask [I] handle to mask bitmap. Can be NULL.
2240 ImageList_Replace (HIMAGELIST himl
, INT i
, HBITMAP hbmImage
,
2243 HDC hdcImageList
, hdcImage
;
2247 ERR("Invalid image list handle!\n");
2251 if ((i
>= himl
->cCurImage
) || (i
< 0)) {
2252 ERR("Invalid image index!\n");
2256 hdcImageList
= CreateCompatibleDC (0);
2257 hdcImage
= CreateCompatibleDC (0);
2258 GetObjectA (hbmImage
, sizeof(BITMAP
), (LPVOID
)&bmp
);
2261 SelectObject (hdcImageList
, himl
->hbmImage
);
2262 SelectObject (hdcImage
, hbmImage
);
2264 StretchBlt (hdcImageList
, i
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
2265 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
2270 SelectObject (hdcImageList
, himl
->hbmMask
);
2271 SelectObject (hdcImage
, hbmMask
);
2273 StretchBlt (hdcImageList
, i
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
2274 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
2277 DeleteDC (hdcImage
);
2278 DeleteDC (hdcImageList
);
2284 /*************************************************************************
2285 * ImageList_ReplaceIcon [COMCTL32.69]
2287 * Replaces an image in an image list using an icon.
2290 * himl [I] handle to image list
2292 * hIcon [I] handle to icon
2295 * Success: index of the replaced image
2300 ImageList_ReplaceIcon (HIMAGELIST himl
, INT i
, HICON hIcon
)
2302 HDC hdcImageList
, hdcImage
;
2305 HBITMAP hbmOldSrc
, hbmOldDst
;
2309 TRACE("(0x%lx 0x%x 0x%x)\n", (DWORD
)himl
, i
, hIcon
);
2313 if ((i
>= himl
->cCurImage
) || (i
< -1))
2316 hBestFitIcon
= CopyImage(
2319 LR_COPYFROMRESOURCE
);
2321 GetIconInfo (hBestFitIcon
, &ii
);
2322 if (ii
.hbmMask
== 0)
2324 if (ii
.hbmColor
== 0)
2326 GetObjectA (ii
.hbmMask
, sizeof(BITMAP
), (LPVOID
)&bmp
);
2329 if (himl
->cCurImage
+ 1 >= himl
->cMaxImage
)
2330 IMAGELIST_InternalExpandBitmaps (himl
, 1);
2332 nIndex
= himl
->cCurImage
;
2338 hdcImageList
= CreateCompatibleDC (0);
2339 TRACE("hdcImageList=0x%x!\n", hdcImageList
);
2340 if (hdcImageList
== 0)
2341 ERR("invalid hdcImageList!\n");
2343 hdcImage
= CreateCompatibleDC (0);
2344 TRACE("hdcImage=0x%x!\n", hdcImage
);
2346 ERR("invalid hdcImage!\n");
2348 hbmOldDst
= SelectObject (hdcImageList
, himl
->hbmImage
);
2349 SetTextColor( hdcImageList
, RGB(0,0,0));
2350 SetBkColor( hdcImageList
, RGB(255,255,255));
2351 hbmOldSrc
= SelectObject (hdcImage
, ii
.hbmColor
);
2352 StretchBlt (hdcImageList
, nIndex
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
2353 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
2355 if (himl
->hbmMask
) {
2356 SelectObject (hdcImageList
, himl
->hbmMask
);
2357 SelectObject (hdcImage
, ii
.hbmMask
);
2358 StretchBlt (hdcImageList
, nIndex
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
2359 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
2362 SelectObject (hdcImage
, hbmOldSrc
);
2363 SelectObject (hdcImageList
, hbmOldDst
);
2366 DestroyIcon(hBestFitIcon
);
2368 DeleteDC (hdcImageList
);
2370 DeleteDC (hdcImage
);
2372 DeleteObject (ii
.hbmColor
);
2374 DeleteObject (ii
.hbmMask
);
2380 /*************************************************************************
2381 * ImageList_SetBkColor [COMCTL32.70]
2383 * Sets the background color of an image list.
2386 * himl [I] handle to image list
2387 * clrBk [I] background color
2390 * Success: previous background color
2395 ImageList_SetBkColor (HIMAGELIST himl
, COLORREF clrBk
)
2402 clrOldBk
= himl
->clrBk
;
2403 himl
->clrBk
= clrBk
;
2408 /*************************************************************************
2409 * ImageList_SetDragCursorImage [COMCTL32.75]
2411 * Combines the specified image with the current drag image
2414 * himlDrag [I] handle to drag image list
2415 * iDrag [I] drag image index
2416 * dxHotspot [I] X position of the hot spot
2417 * dyHotspot [I] Y position of the hot spot
2428 ImageList_SetDragCursorImage (HIMAGELIST himlDrag
, INT iDrag
,
2429 INT dxHotspot
, INT dyHotspot
)
2431 HIMAGELIST himlTemp
;
2433 FIXME("semi-stub!\n");
2435 if (himlInternalDrag
== NULL
)
2438 TRACE(" dxH=%d dyH=%d nX=%d nY=%d\n",
2439 dxHotspot
, dyHotspot
, nInternalDragHotspotX
, nInternalDragHotspotY
);
2441 himlTemp
= ImageList_Merge (himlInternalDrag
, 0, himlDrag
, iDrag
,
2442 dxHotspot
, dyHotspot
);
2444 ImageList_Destroy (himlInternalDrag
);
2445 himlInternalDrag
= himlTemp
;
2447 nInternalDragHotspotX
= dxHotspot
;
2448 nInternalDragHotspotY
= dyHotspot
;
2454 /*************************************************************************
2455 * ImageList_SetFilter [COMCTL32.76]
2457 * Sets a filter (or does something completely different)!!???
2460 * himl [I] handle to image list
2466 * Failure: FALSE ???
2469 * This is an UNDOCUMENTED function!!!!
2474 ImageList_SetFilter (HIMAGELIST himl
, INT i
, DWORD dwFilter
)
2476 FIXME("(%p 0x%x 0x%lx):empty stub!\n",
2483 /*************************************************************************
2484 * ImageList_SetIconSize [COMCTL32.77]
2486 * Sets the image size of the bitmap and deletes all images.
2489 * himl [I] handle to image list
2490 * cx [I] image width
2491 * cy [I] image height
2499 ImageList_SetIconSize (HIMAGELIST himl
, INT cx
, INT cy
)
2506 /* remove all images*/
2507 himl
->cMaxImage
= himl
->cInitial
+ himl
->cGrow
;
2508 himl
->cCurImage
= 0;
2512 /* initialize overlay mask indices */
2513 for (nCount
= 0; nCount
< MAX_OVERLAYIMAGE
; nCount
++)
2514 himl
->nOvlIdx
[nCount
] = -1;
2516 DeleteObject (himl
->hbmImage
);
2518 CreateBitmap (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
2519 1, himl
->uBitsPixel
, NULL
);
2521 if (himl
->hbmMask
) {
2522 DeleteObject (himl
->hbmMask
);
2524 CreateBitmap (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
2532 /*************************************************************************
2533 * ImageList_SetImageCount [COMCTL32.78]
2535 * Resizes an image list to the specified number of images.
2538 * himl [I] handle to image list
2539 * iImageCount [I] number of images in the image list
2547 ImageList_SetImageCount (HIMAGELIST himl
, INT iImageCount
)
2549 HDC hdcImageList
, hdcBitmap
;
2550 HBITMAP hbmNewBitmap
;
2551 INT nNewCount
, nCopyCount
;
2555 if (himl
->cCurImage
>= iImageCount
)
2557 if (himl
->cMaxImage
> iImageCount
)
2560 nNewCount
= iImageCount
+ himl
->cGrow
;
2561 nCopyCount
= _MIN(himl
->cCurImage
, iImageCount
);
2563 hdcImageList
= CreateCompatibleDC (0);
2564 hdcBitmap
= CreateCompatibleDC (0);
2566 hbmNewBitmap
= CreateBitmap (nNewCount
* himl
->cx
, himl
->cy
,
2567 1, himl
->uBitsPixel
, NULL
);
2568 if (hbmNewBitmap
!= 0)
2570 SelectObject (hdcImageList
, himl
->hbmImage
);
2571 SelectObject (hdcBitmap
, hbmNewBitmap
);
2574 BitBlt (hdcBitmap
, 0, 0, nCopyCount
* himl
->cx
, himl
->cy
,
2575 hdcImageList
, 0, 0, SRCCOPY
);
2577 /* delete 'empty' image space */
2578 SetBkColor (hdcBitmap
, RGB(255, 255, 255));
2579 SetTextColor (hdcBitmap
, RGB(0, 0, 0));
2580 PatBlt (hdcBitmap
, nCopyCount
* himl
->cx
, 0,
2581 (nNewCount
- nCopyCount
) * himl
->cx
, himl
->cy
, BLACKNESS
);
2583 DeleteObject (himl
->hbmImage
);
2584 himl
->hbmImage
= hbmNewBitmap
;
2587 ERR("Could not create new image bitmap !\n");
2591 hbmNewBitmap
= CreateBitmap (nNewCount
* himl
->cx
, himl
->cy
,
2593 if (hbmNewBitmap
!= 0)
2595 SelectObject (hdcImageList
, himl
->hbmMask
);
2596 SelectObject (hdcBitmap
, hbmNewBitmap
);
2599 BitBlt (hdcBitmap
, 0, 0, nCopyCount
* himl
->cx
, himl
->cy
,
2600 hdcImageList
, 0, 0, SRCCOPY
);
2602 /* delete 'empty' image space */
2603 SetBkColor (hdcBitmap
, RGB(255, 255, 255));
2604 SetTextColor (hdcBitmap
, RGB(0, 0, 0));
2605 PatBlt (hdcBitmap
, nCopyCount
* himl
->cx
, 0,
2606 (nNewCount
- nCopyCount
) * himl
->cx
, himl
->cy
, BLACKNESS
);
2608 DeleteObject (himl
->hbmMask
);
2609 himl
->hbmMask
= hbmNewBitmap
;
2612 ERR("Could not create new mask bitmap!\n");
2615 DeleteDC (hdcImageList
);
2616 DeleteDC (hdcBitmap
);
2618 /* Update max image count and current image count */
2619 himl
->cMaxImage
= nNewCount
;
2620 if (himl
->cCurImage
> nCopyCount
)
2621 himl
->cCurImage
= nCopyCount
;
2627 /*************************************************************************
2628 * ImageList_SetOverlayImage [COMCTL32.79]
2630 * Assigns an overlay mask index to an existing image in an image list.
2633 * himl [I] handle to image list
2634 * iImage [I] image index
2635 * iOverlay [I] overlay mask index
2643 ImageList_SetOverlayImage (HIMAGELIST himl
, INT iImage
, INT iOverlay
)
2647 if ((iOverlay
< 1) || (iOverlay
> MAX_OVERLAYIMAGE
))
2649 if ((iImage
!=-1) && ((iImage
< 0) || (iImage
> himl
->cCurImage
)))
2651 himl
->nOvlIdx
[iOverlay
- 1] = iImage
;
2656 /*************************************************************************
2657 * ImageList_Write [COMCTL32.80]
2659 * Writes an image list to a stream.
2662 * himl [I] handle to image list
2663 * pstm [O] Pointer to a stream.
2670 * This function can not be implemented yet, because
2671 * IStream32::Write is not implemented.
2678 ImageList_Write (HIMAGELIST himl
, LPSTREAM pstm
)
2683 FIXME("empty stub!\n");