2 * ImageList implementation
4 * Copyright 1998 Eric Kohl
8 * - Fix ImageList_DrawIndirect (xBitmap, yBitmap, rgbFg, rgbBk, dwRop).
9 * - Fix ImageList_GetIcon.
10 * - Fix drag functions.
11 * - Fix ImageList_Write.
12 * - Fix ImageList_SetFilter (undocumented).
13 * BTW does anybody know anything about this function???
14 * - It removes 12 Bytes from the stack (3 Parameters).
15 * - First parameter SHOULD be a HIMAGELIST.
16 * - Second parameter COULD be an index?????
17 * - Third parameter.... ?????????????????????
20 * - ImageList_Draw, ImageList_DrawEx and ImageList_GetIcon use
21 * ImageList_DrawIndirect. Since ImageList_DrawIndirect is still
22 * partially implemented, the functions mentioned above will be
23 * limited in functionality too.
29 #include "wine/obj_base.h"
30 #include "wine/obj_storage.h"
32 #include "imagelist.h"
33 #include "debugtools.h"
35 DEFAULT_DEBUG_CHANNEL(imagelist
);
38 #define MAX_OVERLAYIMAGE 15
41 /* internal image list data used for Drag & Drop operations */
43 static HIMAGELIST himlInternalDrag
= NULL
;
44 static INT nInternalDragHotspotX
= 0;
45 static INT nInternalDragHotspotY
= 0;
47 static HWND hwndInternalDrag
= 0;
48 static INT xInternalPos
= 0;
49 static INT yInternalPos
= 0;
51 static HDC hdcBackBuffer
= 0;
52 static HBITMAP hbmBackBuffer
= 0;
55 /*************************************************************************
56 * IMAGELIST_InternalExpandBitmaps [Internal]
58 * Expands the bitmaps of an image list by the given number of images.
61 * himl [I] handle to image list
62 * nImageCount [I] number of images to add
68 * This function can NOT be used to reduce the number of images.
71 IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl
, INT nImageCount
, INT cx
, INT cy
)
73 HDC hdcImageList
, hdcBitmap
;
75 INT nNewWidth
, nNewCount
;
77 if ((himl
->cCurImage
+ nImageCount
< himl
->cMaxImage
)
81 if (cy
== 0) cy
= himl
->cy
;
82 nNewCount
= himl
->cCurImage
+ nImageCount
+ himl
->cGrow
;
83 nNewWidth
= nNewCount
* himl
->cx
;
85 TRACE("Create expanded bitmaps : himl=%p x=%d y=%d count=%d\n", himl
, nNewWidth
, cy
, nNewCount
);
86 hdcImageList
= CreateCompatibleDC (0);
87 hdcBitmap
= CreateCompatibleDC (0);
90 CreateBitmap (nNewWidth
, cy
, 1, himl
->uBitsPixel
, NULL
);
91 if (hbmNewBitmap
== 0)
92 ERR("creating new image bitmap (x=%d y=%d)!\n", nNewWidth
, cy
);
94 SelectObject (hdcImageList
, himl
->hbmImage
);
95 SelectObject (hdcBitmap
, hbmNewBitmap
);
96 BitBlt (hdcBitmap
, 0, 0, himl
->cCurImage
* himl
->cx
, cy
,
97 hdcImageList
, 0, 0, SRCCOPY
);
99 DeleteObject (himl
->hbmImage
);
100 himl
->hbmImage
= hbmNewBitmap
;
104 CreateBitmap (nNewWidth
, cy
, 1, 1, NULL
);
106 if (hbmNewBitmap
== 0)
107 ERR("creating new mask bitmap!\n");
109 SelectObject (hdcImageList
, himl
->hbmMask
);
110 SelectObject (hdcBitmap
, hbmNewBitmap
);
111 BitBlt (hdcBitmap
, 0, 0, himl
->cCurImage
* himl
->cx
, cy
,
112 hdcImageList
, 0, 0, SRCCOPY
);
113 DeleteObject (himl
->hbmMask
);
114 himl
->hbmMask
= hbmNewBitmap
;
117 himl
->cMaxImage
= nNewCount
;
119 DeleteDC (hdcImageList
);
120 DeleteDC (hdcBitmap
);
124 /*************************************************************************
125 * IMAGELIST_InternalDraw [Internal]
127 * Draws the image in the ImageList (without the mask)
130 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
131 * cx [I] the width of the image to display
132 * cy............[I] the height of the image to display
138 * This function is used by ImageList_DrawIndirect, when it is
139 * required to draw only the Image (without the mask) to the screen.
141 * Blending and Overlays styles are accomplished by another function
144 IMAGELIST_InternalDraw(IMAGELISTDRAWPARAMS
*pimldp
, INT cx
, INT cy
)
149 hImageDC
= CreateCompatibleDC(0);
150 hOldBitmap
= SelectObject(hImageDC
, pimldp
->himl
->hbmImage
);
151 BitBlt(pimldp
->hdcDst
,
152 pimldp
->x
, pimldp
->y
, cx
, cy
,
154 pimldp
->himl
->cx
* pimldp
->i
, 0,
157 SelectObject(hImageDC
, hOldBitmap
);
162 /*************************************************************************
163 * IMAGELIST_InternalDrawMask [Internal]
165 * Draws the image in the ImageList with the mask
168 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
169 * cx [I] the width of the image to display
170 * cy............[I] the height of the image to display
176 * This function is used by ImageList_DrawIndirect, when it is
177 * required to draw the Image with the mask to the screen.
179 * Blending and Overlays styles are accomplished by another function.
182 IMAGELIST_InternalDrawMask(IMAGELISTDRAWPARAMS
*pimldp
, INT cx
, INT cy
)
184 BOOL bUseCustomBackground
, bBlendFlag
;
185 HBRUSH hBrush
, hOldBrush
;
186 HDC hMaskDC
, hImageDC
;
187 HBITMAP hOldBitmapImage
, hOldBitmapMask
;
188 HIMAGELIST himlLocal
= pimldp
->himl
;
189 COLORREF oldBkColor
, oldFgColor
;
190 UINT fStyle
= pimldp
->fStyle
& (~ILD_OVERLAYMASK
);
193 * We need a dc and bitmap to draw on that is
196 HDC hOffScreenDC
= 0;
197 HBITMAP hOffScreenBmp
= 0;
199 bUseCustomBackground
= (himlLocal
->clrBk
!= CLR_NONE
);
200 bBlendFlag
= (fStyle
& ILD_BLEND50
) || (fStyle
& ILD_BLEND25
);
202 hImageDC
= CreateCompatibleDC(0);
203 hMaskDC
= CreateCompatibleDC(0);
205 /* Create a compatible DC. */
206 hOffScreenDC
= CreateCompatibleDC( pimldp
->hdcDst
);
210 hOffScreenBmp
= CreateCompatibleBitmap( pimldp
->hdcDst
, cx
, cy
);
213 SelectObject( hOffScreenDC
, hOffScreenBmp
);
220 hOldBitmapImage
= SelectObject(hImageDC
, himlLocal
->hbmImage
);
221 hOldBitmapMask
= SelectObject(hMaskDC
, himlLocal
->hbmMask
);
224 * Get a copy of the image for the masking operations.
225 * We will use the copy, and this dc for all the various
226 * blitting, and then do one final blit to the screen dc.
227 * This should clean up most of the flickering.
229 BitBlt( hOffScreenDC
, 0, 0, cx
, cy
, pimldp
->hdcDst
, pimldp
->x
,
233 * Draw the Background for the appropriate Styles
235 if( bUseCustomBackground
&& (fStyle
== ILD_NORMAL
|| fStyle
& ILD_IMAGE
239 hBrush
= CreateSolidBrush (himlLocal
->clrBk
);
240 hOldBrush
= SelectObject (pimldp
->hdcDst
, hBrush
);
242 PatBlt( hOffScreenDC
, pimldp
->x
, pimldp
->y
, cx
, cy
, PATCOPY
);
244 DeleteObject (SelectObject (pimldp
->hdcDst
, hOldBrush
));
248 * Draw Image Transparently over the current background
250 if(fStyle
== ILD_NORMAL
|| (fStyle
& ILD_TRANSPARENT
) ||
251 ((fStyle
& ILD_IMAGE
) && bUseCustomBackground
) || bBlendFlag
)
253 * To obtain a transparent look, background color should be set
254 * to white and foreground color to black when blting the
258 oldBkColor
= SetBkColor( hOffScreenDC
, RGB( 0xff, 0xff, 0xff ) );
259 oldFgColor
= SetTextColor( hOffScreenDC
, RGB( 0, 0, 0 ) );
261 BitBlt( hOffScreenDC
, 0, 0, cx
, cy
,hMaskDC
, himlLocal
->cx
* pimldp
->i
,
264 BitBlt( hOffScreenDC
, 0, 0, cx
, cy
, hImageDC
,himlLocal
->cx
* pimldp
->i
,
270 * Draw the image when no Background is specified
272 else if((fStyle
& ILD_IMAGE
) && !bUseCustomBackground
)
274 BitBlt( hOffScreenDC
, 0, 0, cx
, cy
, hImageDC
,
275 himlLocal
->cx
* pimldp
->i
, 0, SRCCOPY
);
278 * Draw the mask with or without a background
280 else if(fStyle
& ILD_MASK
)
282 BitBlt( hOffScreenDC
, 0, 0, cx
, cy
, hMaskDC
, himlLocal
->cx
* pimldp
->i
,
283 0, bUseCustomBackground
? SRCCOPY
: SRCAND
);
287 * Blit the bitmap to the screen now.
289 BitBlt( pimldp
->hdcDst
, pimldp
->x
, pimldp
->y
, cx
, cy
,
290 hOffScreenDC
, 0, 0, SRCCOPY
);
293 SelectObject(hImageDC
, hOldBitmapImage
);
294 SelectObject(hMaskDC
, hOldBitmapMask
);
301 DeleteDC( hOffScreenDC
);
302 DeleteObject( hOffScreenBmp
);
307 /*************************************************************************
308 * IMAGELIST_InternalDrawBlend [Internal]
310 * Draws the Blend over the current image
313 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
314 * cx [I] the width of the image to display
315 * cy............[I] the height of the image to display
321 * This functions is used by ImageList_DrawIndirect, when it is
322 * required to add the blend to the current image.
326 IMAGELIST_InternalDrawBlend(IMAGELISTDRAWPARAMS
*pimldp
, INT cx
, INT cy
)
329 HDC hBlendMaskDC
,hMaskDC
;
330 HBRUSH hBlendColorBrush
, hBlendBrush
, hOldBrush
;
331 HBITMAP hBlendMaskBitmap
, hOldBitmap
;
332 COLORREF clrBlend
, OldTextColor
, OldBkColor
;
333 HIMAGELIST himlLocal
= pimldp
->himl
;
335 clrBlend
= GetSysColor (COLOR_HIGHLIGHT
);
336 if (!(pimldp
->rgbFg
== CLR_DEFAULT
))
338 clrBlend
= pimldp
->rgbFg
;
340 /* Create the blend Mask
342 hBlendMaskDC
= CreateCompatibleDC(0);
343 hBlendBrush
= pimldp
->fStyle
& ILD_BLEND50
?
344 himlLocal
->hbrBlend50
: himlLocal
->hbrBlend25
;
346 hBlendMaskBitmap
= CreateBitmap(cx
, cy
, 1, 1, NULL
);
347 hOldBitmap
= SelectObject(hBlendMaskDC
, hBlendMaskBitmap
);
349 hOldBrush
= (HBRUSH
) SelectObject(hBlendMaskDC
, hBlendBrush
);
350 PatBlt(hBlendMaskDC
, 0, 0, cx
, cy
, PATCOPY
);
351 SelectObject(hBlendMaskDC
, hOldBrush
);
353 /* Modify the blend mask if an Image Mask exist
355 if(pimldp
->himl
->hbmMask
!= 0)
357 HBITMAP hOldMaskBitmap
;
358 hMaskDC
= CreateCompatibleDC(0);
359 hOldMaskBitmap
= (HBITMAP
) SelectObject(hMaskDC
, himlLocal
->hbmMask
);
364 himlLocal
->cx
* pimldp
->i
,0,
365 0x220326); /* NOTSRCAND */
373 SelectObject(hMaskDC
, hOldMaskBitmap
);
377 /* Apply blend to the current image given the BlendMask
379 OldTextColor
= SetTextColor(pimldp
->hdcDst
, 0);
380 OldBkColor
= SetBkColor(pimldp
->hdcDst
, RGB(255,255,255));
381 hBlendColorBrush
= CreateSolidBrush(clrBlend
);
382 hOldBrush
= (HBRUSH
) SelectObject (pimldp
->hdcDst
, hBlendColorBrush
);
384 BitBlt (pimldp
->hdcDst
,
385 pimldp
->x
, pimldp
->y
, cx
, cy
,
388 0xB8074A); /* PSDPxax */
390 SelectObject(pimldp
->hdcDst
, hOldBrush
);
391 SetTextColor(pimldp
->hdcDst
, OldTextColor
);
392 SetBkColor(pimldp
->hdcDst
, OldBkColor
);
393 SelectObject(hBlendMaskDC
, hOldBitmap
);
394 DeleteDC(hBlendMaskDC
);
395 DeleteObject(hBlendMaskBitmap
);
396 DeleteObject(hBlendColorBrush
);
399 /*************************************************************************
400 * IMAGELIST_InternalDrawOverlay [Internal]
402 * Draws the overlay image
405 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
406 * cx [I] the width of the image to display
407 * cy............[I] the height of the image to display
413 * This functions is used by ImageList_DrawIndirect, when it is
414 * required to draw the overlay
419 IMAGELIST_InternalDrawOverlay(IMAGELISTDRAWPARAMS
*pimldp
, INT cx
, INT cy
)
425 nOvlIdx
= (pimldp
->fStyle
& ILD_OVERLAYMASK
) >> 8;
426 if ((nOvlIdx
>= 1) && (nOvlIdx
<= MAX_OVERLAYIMAGE
))
428 nOvlIdx
= pimldp
->himl
->nOvlIdx
[nOvlIdx
- 1];
429 if ((nOvlIdx
>= 0) && (nOvlIdx
<= pimldp
->himl
->cCurImage
))
431 hImageDC
= CreateCompatibleDC(0);
432 if (pimldp
->himl
->hbmMask
)
434 hOldBitmap
= (HBITMAP
) SelectObject (hImageDC
,
435 pimldp
->himl
->hbmMask
);
437 BitBlt (pimldp
->hdcDst
,
438 pimldp
->x
, pimldp
->y
, cx
, cy
,
439 hImageDC
, pimldp
->himl
->cx
* nOvlIdx
, 0,
442 SelectObject(hImageDC
, hOldBitmap
);
444 hOldBitmap
= (HBITMAP
) SelectObject (hImageDC
,
445 pimldp
->himl
->hbmImage
);
447 BitBlt (pimldp
->hdcDst
,
448 pimldp
->x
, pimldp
->y
, cx
, cy
,
450 pimldp
->himl
->cx
* nOvlIdx
, 0,
453 SelectObject(hImageDC
, hOldBitmap
);
463 /*************************************************************************
464 * ImageList_Add [COMCTL32.40]
466 * Add an image or images to an image list.
469 * himl [I] handle to image list
470 * hbmImage [I] handle to image bitmap
471 * hbmMask [I] handle to mask bitmap
474 * Success: Index of the first new image.
479 ImageList_Add (HIMAGELIST himl
, HBITMAP hbmImage
, HBITMAP hbmMask
)
481 HDC hdcImage
, hdcBitmap
;
482 INT nFirstIndex
, nImageCount
;
485 HBITMAP hOldBitmapImage
, hOldBitmap
;
487 TRACE("himl=%p hbmimage=%x hbmmask=%x\n", himl
, hbmImage
, hbmMask
);
488 if (!himl
|| !hbmImage
)
491 GetObjectA (hbmImage
, sizeof(BITMAP
), (LPVOID
)&bmp
);
492 nImageCount
= bmp
.bmWidth
/ himl
->cx
;
494 IMAGELIST_InternalExpandBitmaps (himl
, nImageCount
, bmp
.bmWidth
, bmp
.bmHeight
);
496 nStartX
= himl
->cCurImage
* himl
->cx
;
498 hdcImage
= CreateCompatibleDC(0);
499 hdcBitmap
= CreateCompatibleDC(0);
501 hOldBitmapImage
= SelectObject(hdcImage
, himl
->hbmImage
);
502 hOldBitmap
= SelectObject(hdcBitmap
, hbmImage
);
504 /* Copy result to the imagelist
506 BitBlt (hdcImage
, nStartX
, 0, bmp
.bmWidth
, bmp
.bmHeight
,
507 hdcBitmap
, 0, 0, SRCCOPY
);
511 HDC hdcMask
, hdcTemp
, hOldBitmapMask
, hOldBitmapTemp
;
513 hdcMask
= CreateCompatibleDC (0);
514 hdcTemp
= CreateCompatibleDC(0);
515 hOldBitmapMask
= (HBITMAP
) SelectObject(hdcMask
, himl
->hbmMask
);
516 hOldBitmapTemp
= (HBITMAP
) SelectObject(hdcTemp
, hbmMask
);
519 nStartX
, 0, bmp
.bmWidth
, bmp
.bmHeight
,
524 SelectObject(hdcTemp
, hOldBitmapTemp
);
527 /* Remove the background from the image
530 nStartX
, 0, bmp
.bmWidth
, bmp
.bmHeight
,
533 0x220326); /* NOTSRCAND */
535 SelectObject(hdcMask
, hOldBitmapMask
);
539 SelectObject(hdcImage
, hOldBitmapImage
);
540 SelectObject(hdcBitmap
, hOldBitmap
);
544 nFirstIndex
= himl
->cCurImage
;
545 himl
->cCurImage
+= nImageCount
;
551 /*************************************************************************
552 * ImageList_AddIcon [COMCTL32.41]
554 * Adds an icon to an image list.
557 * himl [I] handle to image list
558 * hIcon [I] handle to icon
561 * Success: index of the new image
566 ImageList_AddIcon (HIMAGELIST himl
, HICON hIcon
)
568 return ImageList_ReplaceIcon (himl
, -1, hIcon
);
572 /*************************************************************************
573 * ImageList_AddMasked [COMCTL32.42]
575 * Adds an image or images to an image list and creates a mask from the
576 * specified bitmap using the mask color.
579 * himl [I] handle to image list.
580 * hBitmap [I] handle to bitmap
581 * clrMask [I] mask color.
584 * Success: Index of the first new image.
589 ImageList_AddMasked (HIMAGELIST himl
, HBITMAP hBitmap
, COLORREF clrMask
)
591 HDC hdcImage
, hdcMask
, hdcBitmap
;
592 INT nIndex
, nImageCount
, nMaskXOffset
=0;
594 HBITMAP hOldBitmap
, hOldBitmapMask
, hOldBitmapImage
;
595 HBITMAP hMaskBitmap
=0;
598 TRACE("himl=%p hbitmap=%x clrmask=%lx\n", himl
, hBitmap
, clrMask
);
602 if (!GetObjectA (hBitmap
, sizeof(BITMAP
), &bmp
))
605 nImageCount
= bmp
.bmWidth
/ himl
->cx
;
607 IMAGELIST_InternalExpandBitmaps (himl
, nImageCount
, bmp
.bmWidth
, bmp
.bmHeight
);
609 nIndex
= himl
->cCurImage
;
610 himl
->cCurImage
+= nImageCount
;
612 hdcMask
= CreateCompatibleDC (0);
613 hdcImage
= CreateCompatibleDC(0);
614 hdcBitmap
= CreateCompatibleDC(0);
617 hOldBitmapImage
= SelectObject(hdcImage
, himl
->hbmImage
);
618 hOldBitmap
= SelectObject(hdcBitmap
, hBitmap
);
621 hOldBitmapMask
= SelectObject(hdcMask
, himl
->hbmMask
);
622 nMaskXOffset
= nIndex
* himl
->cx
;
627 Create a temp Mask so we can remove the background of
628 the Image (Windows does this even if there is no mask)
630 hMaskBitmap
= CreateBitmap(bmp
.bmWidth
, bmp
.bmHeight
, 1, 1, NULL
);
631 hOldBitmapMask
= SelectObject(hdcMask
, hMaskBitmap
);
634 /* create monochrome image to the mask bitmap */
635 bkColor
= (clrMask
!= CLR_DEFAULT
) ? clrMask
:
636 GetPixel (hdcBitmap
, 0, 0);
637 SetBkColor (hdcBitmap
, bkColor
);
639 nMaskXOffset
, 0, bmp
.bmWidth
, bmp
.bmHeight
,
643 SetBkColor(hdcBitmap
, RGB(255,255,255));
644 /*Remove the background from the image
647 WINDOWS BUG ALERT!!!!!!
648 The statement below should not be done in common practice
649 but this is how ImageList_AddMasked works in Windows.
650 It overwrites the original bitmap passed, this was discovered
651 by using the same bitmap to iterate the different styles
652 on windows where it failed (BUT ImageList_Add is OK)
653 This is here in case some apps rely on this bug
656 0, 0, bmp
.bmWidth
, bmp
.bmHeight
,
659 0x220326); /* NOTSRCAND */
660 /* Copy result to the imagelist
663 nIndex
* himl
->cx
, 0, bmp
.bmWidth
, bmp
.bmHeight
,
669 SelectObject(hdcMask
,hOldBitmapMask
);
670 SelectObject(hdcImage
, hOldBitmapImage
);
671 SelectObject(hdcBitmap
, hOldBitmap
);
677 DeleteObject(hMaskBitmap
);
684 /*************************************************************************
685 * ImageList_BeginDrag [COMCTL32.43]
687 * Creates a temporary image list that contains one image. It will be used
691 * himlTrack [I] handle to the source image list
692 * iTrack [I] index of the drag image in the source image list
693 * dxHotspot [I] X position of the hot spot of the drag image
694 * dyHotspot [I] Y position of the hot spot of the drag image
702 ImageList_BeginDrag (HIMAGELIST himlTrack
, INT iTrack
,
703 INT dxHotspot
, INT dyHotspot
)
707 FIXME("partially implemented!\n");
709 if (himlTrack
== NULL
)
712 if (himlInternalDrag
)
713 ImageList_EndDrag ();
716 ImageList_Create (himlTrack
->cx
, himlTrack
->cy
,
717 himlTrack
->flags
, 1, 1);
718 if (himlInternalDrag
== NULL
) {
719 ERR("Error creating drag image list!\n");
723 nInternalDragHotspotX
= dxHotspot
;
724 nInternalDragHotspotY
= dyHotspot
;
726 hdcSrc
= CreateCompatibleDC (0);
727 hdcDst
= CreateCompatibleDC (0);
730 SelectObject (hdcSrc
, himlTrack
->hbmImage
);
731 SelectObject (hdcDst
, himlInternalDrag
->hbmImage
);
732 StretchBlt (hdcDst
, 0, 0, himlInternalDrag
->cx
, himlInternalDrag
->cy
, hdcSrc
,
733 iTrack
* himlTrack
->cx
, 0, himlTrack
->cx
, himlTrack
->cy
, SRCCOPY
);
736 SelectObject (hdcSrc
, himlTrack
->hbmMask
);
737 SelectObject (hdcDst
, himlInternalDrag
->hbmMask
);
738 StretchBlt (hdcDst
, 0, 0, himlInternalDrag
->cx
, himlInternalDrag
->cy
, hdcSrc
,
739 iTrack
* himlTrack
->cx
, 0, himlTrack
->cx
, himlTrack
->cy
, SRCCOPY
);
744 himlInternalDrag
->cCurImage
= 1;
750 /*************************************************************************
751 * ImageList_Copy [COMCTL32.44]
753 * Copies an image of the source image list to an image of the
754 * destination image list. Images can be copied or swapped.
757 * himlDst [I] handle to the destination image list
758 * iDst [I] destination image index.
759 * himlSrc [I] handle to the source image list
760 * iSrc [I] source image index
761 * uFlags [I] flags for the copy operation
768 * Copying from one image list to another is possible. The original
769 * implementation just copies or swaps within one image list.
770 * Could this feature become a bug??? ;-)
774 ImageList_Copy (HIMAGELIST himlDst
, INT iDst
, HIMAGELIST himlSrc
,
775 INT iSrc
, INT uFlags
)
779 TRACE("iDst=%d iSrc=%d\n", iDst
, iSrc
);
781 if ((himlSrc
== NULL
) || (himlDst
== NULL
))
783 if ((iDst
< 0) || (iDst
>= himlDst
->cCurImage
))
785 if ((iSrc
< 0) || (iSrc
>= himlSrc
->cCurImage
))
788 hdcSrc
= CreateCompatibleDC (0);
789 if (himlDst
== himlSrc
)
792 hdcDst
= CreateCompatibleDC (0);
794 if (uFlags
& ILCF_SWAP
) {
796 HBITMAP hbmTempImage
, hbmTempMask
;
798 /* create temporary bitmaps */
799 hbmTempImage
= CreateBitmap (himlSrc
->cx
, himlSrc
->cy
, 1,
800 himlSrc
->uBitsPixel
, NULL
);
801 hbmTempMask
= CreateBitmap (himlSrc
->cx
, himlSrc
->cy
, 1,
804 /* copy (and stretch) destination to temporary bitmaps.(save) */
806 SelectObject (hdcSrc
, himlDst
->hbmImage
);
807 SelectObject (hdcDst
, hbmTempImage
);
808 StretchBlt (hdcDst
, 0, 0, himlSrc
->cx
, himlSrc
->cy
,
809 hdcSrc
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
812 SelectObject (hdcSrc
, himlDst
->hbmMask
);
813 SelectObject (hdcDst
, hbmTempMask
);
814 StretchBlt (hdcDst
, 0, 0, himlSrc
->cx
, himlSrc
->cy
,
815 hdcSrc
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
818 /* copy (and stretch) source to destination */
820 SelectObject (hdcSrc
, himlSrc
->hbmImage
);
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
,
826 SelectObject (hdcSrc
, himlSrc
->hbmMask
);
827 SelectObject (hdcDst
, himlDst
->hbmMask
);
828 StretchBlt (hdcDst
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
829 hdcSrc
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
832 /* copy (without stretching) temporary bitmaps to source (restore) */
834 SelectObject (hdcSrc
, hbmTempImage
);
835 SelectObject (hdcDst
, himlSrc
->hbmImage
);
836 BitBlt (hdcDst
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
837 hdcSrc
, 0, 0, SRCCOPY
);
839 SelectObject (hdcSrc
, hbmTempMask
);
840 SelectObject (hdcDst
, himlSrc
->hbmMask
);
841 BitBlt (hdcDst
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
842 hdcSrc
, 0, 0, SRCCOPY
);
844 /* delete temporary bitmaps */
845 DeleteObject (hbmTempMask
);
846 DeleteObject (hbmTempImage
);
850 SelectObject (hdcSrc
, himlSrc
->hbmImage
);
851 if (himlSrc
== himlDst
)
854 SelectObject (hdcDst
, himlDst
->hbmImage
);
855 StretchBlt (hdcDst
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
856 hdcSrc
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
860 SelectObject (hdcSrc
, himlSrc
->hbmMask
);
861 if (himlSrc
== himlDst
)
864 SelectObject (hdcDst
, himlDst
->hbmMask
);
865 StretchBlt (hdcDst
, iDst
* himlDst
->cx
, 0, himlDst
->cx
, himlDst
->cy
,
866 hdcSrc
, iSrc
* himlSrc
->cx
, 0, himlSrc
->cx
, himlSrc
->cy
,
871 if (himlSrc
!= himlDst
)
878 /*************************************************************************
879 * ImageList_Create [COMCTL32.45] Creates a new image list.
882 * cx [I] image height
884 * flags [I] creation flags
885 * cInitial [I] initial number of images in the image list
886 * cGrow [I] number of images by which image list grows
889 * Success: Handle to the created image list
894 ImageList_Create (INT cx
, INT cy
, UINT flags
,
895 INT cInitial
, INT cGrow
)
901 static WORD aBitBlend25
[] =
902 {0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00};
904 static WORD aBitBlend50
[] =
905 {0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA};
907 TRACE("(%d %d 0x%x %d %d)\n", cx
, cy
, flags
, cInitial
, cGrow
);
909 himl
= (HIMAGELIST
)COMCTL32_Alloc (sizeof(struct _IMAGELIST
));
916 himl
->cMaxImage
= cInitial
+ cGrow
;
917 himl
->cInitial
= cInitial
;
920 himl
->clrFg
= CLR_DEFAULT
;
921 himl
->clrBk
= CLR_NONE
;
923 /* initialize overlay mask indices */
924 for (nCount
= 0; nCount
< MAX_OVERLAYIMAGE
; nCount
++)
925 himl
->nOvlIdx
[nCount
] = -1;
927 hdc
= CreateCompatibleDC (0);
928 himl
->uBitsPixel
= (UINT
)GetDeviceCaps (hdc
, BITSPIXEL
);
931 TRACE("Image: %d Bits per Pixel\n", himl
->uBitsPixel
);
933 if (himl
->cMaxImage
> 0) {
935 CreateBitmap (himl
->cx
* himl
->cMaxImage
, himl
->cy
,
936 1, himl
->uBitsPixel
, NULL
);
937 if (himl
->hbmImage
== 0) {
938 ERR("Error creating image bitmap!\n");
945 if ( (himl
->cMaxImage
> 0) && (himl
->flags
& ILC_MASK
)) {
946 himl
->hbmMask
= CreateBitmap (himl
->cx
* himl
->cMaxImage
, himl
->cy
,
948 if (himl
->hbmMask
== 0) {
949 ERR("Error creating mask bitmap!\n");
951 DeleteObject (himl
->hbmImage
);
958 /* create blending brushes */
959 hbmTemp
= CreateBitmap (8, 8, 1, 1, &aBitBlend25
);
960 himl
->hbrBlend25
= CreatePatternBrush (hbmTemp
);
961 DeleteObject (hbmTemp
);
963 hbmTemp
= CreateBitmap (8, 8, 1, 1, &aBitBlend50
);
964 himl
->hbrBlend50
= CreatePatternBrush (hbmTemp
);
965 DeleteObject (hbmTemp
);
967 TRACE("created imagelist %p\n", himl
);
972 /*************************************************************************
973 * ImageList_Destroy [COMCTL32.46]
975 * Destroys an image list.
978 * himl [I] handle to image list
986 ImageList_Destroy (HIMAGELIST himl
)
991 /* delete image bitmaps */
993 DeleteObject (himl
->hbmImage
);
995 DeleteObject (himl
->hbmMask
);
997 /* delete blending brushes */
998 if (himl
->hbrBlend25
)
999 DeleteObject (himl
->hbrBlend25
);
1000 if (himl
->hbrBlend50
)
1001 DeleteObject (himl
->hbrBlend50
);
1003 COMCTL32_Free (himl
);
1009 /*************************************************************************
1010 * ImageList_DragEnter [COMCTL32.47]
1012 * Locks window update and displays the drag image at the given position.
1015 * hwndLock [I] handle of the window that owns the drag image.
1016 * x [I] X position of the drag image.
1017 * y [I] Y position of the drag image.
1024 * The position of the drag image is relative to the window, not
1029 ImageList_DragEnter (HWND hwndLock
, INT x
, INT y
)
1031 if (himlInternalDrag
== NULL
)
1035 hwndInternalDrag
= hwndLock
;
1037 hwndInternalDrag
= GetDesktopWindow ();
1042 hdcBackBuffer
= CreateCompatibleDC (0);
1043 hbmBackBuffer
= CreateCompatibleBitmap (hdcBackBuffer
,
1044 himlInternalDrag
->cx
, himlInternalDrag
->cy
);
1046 ImageList_DragShowNolock (TRUE
);
1052 /*************************************************************************
1053 * ImageList_DragLeave [COMCTL32.48]
1055 * Unlocks window update and hides the drag image.
1058 * hwndLock [I] handle of the window that owns the drag image.
1066 ImageList_DragLeave (HWND hwndLock
)
1069 hwndInternalDrag
= hwndLock
;
1071 hwndInternalDrag
= GetDesktopWindow ();
1073 ImageList_DragShowNolock (FALSE
);
1075 DeleteDC (hdcBackBuffer
);
1076 DeleteObject (hbmBackBuffer
);
1082 /*************************************************************************
1083 * ImageList_DragMove [COMCTL32.49]
1085 * Moves the drag image.
1088 * x [I] X position of the drag image.
1089 * y [I] Y position of the drag image.
1096 * The position of the drag image is relative to the window, not
1101 ImageList_DragMove (INT x
, INT y
)
1103 ImageList_DragShowNolock (FALSE
);
1108 ImageList_DragShowNolock (TRUE
);
1114 /*************************************************************************
1115 * ImageList_DragShowNolock [COMCTL32.50]
1117 * Shows or hides the drag image.
1120 * bShow [I] TRUE shows the drag image, FALSE hides it.
1131 ImageList_DragShowNolock (BOOL bShow
)
1135 FIXME("semi-stub!\n");
1136 TRACE("bShow=0x%X!\n", bShow
);
1138 hdcDrag
= GetDCEx (hwndInternalDrag
, 0,
1139 DCX_WINDOW
| DCX_CACHE
| DCX_LOCKWINDOWUPDATE
);
1142 /* show drag image */
1144 /* save background */
1146 /* draw drag image */
1150 /* hide drag image */
1152 /* restore background */
1156 ReleaseDC (hwndInternalDrag
, hdcDrag
);
1162 /*************************************************************************
1163 * ImageList_Draw [COMCTL32.51] Draws an image.
1166 * himl [I] handle to image list
1168 * hdc [I] handle to device context
1171 * fStyle [I] drawing flags
1178 * Calls ImageList_DrawIndirect.
1181 * ImageList_DrawIndirect.
1185 ImageList_Draw (HIMAGELIST himl
, INT i
, HDC hdc
,
1186 INT x
, INT y
, UINT fStyle
)
1188 IMAGELISTDRAWPARAMS imldp
;
1190 imldp
.cbSize
= sizeof(IMAGELISTDRAWPARAMS
);
1200 imldp
.rgbBk
= CLR_DEFAULT
;
1201 imldp
.rgbFg
= CLR_DEFAULT
;
1202 imldp
.fStyle
= fStyle
;
1205 return ImageList_DrawIndirect (&imldp
);
1209 /*************************************************************************
1210 * ImageList_DrawEx [COMCTL32.52]
1212 * Draws an image and allows to use extended drawing features.
1215 * himl [I] handle to image list
1217 * hdc [I] handle to device context
1220 * xOffs [I] X offset
1221 * yOffs [I] Y offset
1222 * rgbBk [I] background color
1223 * rgbFg [I] foreground color
1224 * fStyle [I] drawing flags
1231 * Calls ImageList_DrawIndirect.
1234 * ImageList_DrawIndirect.
1238 ImageList_DrawEx (HIMAGELIST himl
, INT i
, HDC hdc
, INT x
, INT y
,
1239 INT dx
, INT dy
, COLORREF rgbBk
, COLORREF rgbFg
,
1242 IMAGELISTDRAWPARAMS imldp
;
1244 imldp
.cbSize
= sizeof(IMAGELISTDRAWPARAMS
);
1254 imldp
.rgbBk
= rgbBk
;
1255 imldp
.rgbFg
= rgbFg
;
1256 imldp
.fStyle
= fStyle
;
1259 return ImageList_DrawIndirect (&imldp
);
1263 /*************************************************************************
1264 * ImageList_DrawIndirect [COMCTL32.53]
1266 * Draws an image using ...
1269 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
1277 ImageList_DrawIndirect (IMAGELISTDRAWPARAMS
*pimldp
)
1281 Do some Error Checking
1285 if (pimldp
->cbSize
< sizeof(IMAGELISTDRAWPARAMS
))
1287 if (pimldp
->himl
== NULL
)
1289 if ((pimldp
->i
< 0) || (pimldp
->i
>= pimldp
->himl
->cCurImage
)) {
1290 ERR("%d not within range (max %d)\n",pimldp
->i
,pimldp
->himl
->cCurImage
-1);
1294 Get the Height and Width to display
1296 cx
= (pimldp
->cx
== 0) ? pimldp
->himl
->cx
: pimldp
->cx
;
1297 cy
= (pimldp
->cy
== 0) ? pimldp
->himl
->cy
: pimldp
->cy
;
1301 if(pimldp
->himl
->hbmMask
!= 0)
1303 IMAGELIST_InternalDrawMask(pimldp
, cx
, cy
);
1307 IMAGELIST_InternalDraw(pimldp
, cx
, cy
);
1310 Apply the blend if needed to the Image
1312 if((pimldp
->fStyle
& ILD_BLEND50
)
1313 || (pimldp
->fStyle
& ILD_BLEND25
))
1315 IMAGELIST_InternalDrawBlend(pimldp
, cx
, cy
);
1318 Apply the Overlay if needed
1320 if (pimldp
->fStyle
& ILD_OVERLAYMASK
)
1322 IMAGELIST_InternalDrawOverlay(pimldp
, cx
, cy
);
1329 /*************************************************************************
1330 * ImageList_Duplicate [COMCTL32.54] Duplicates an image list.
1333 * himlSrc [I] source image list handle
1336 * Success: Handle of duplicated image list.
1341 ImageList_Duplicate (HIMAGELIST himlSrc
)
1346 if (himlSrc
== NULL
) {
1347 ERR("Invalid image list handle!\n");
1351 himlDst
= ImageList_Create (himlSrc
->cx
, himlSrc
->cy
, himlSrc
->flags
,
1352 himlSrc
->cInitial
, himlSrc
->cGrow
);
1356 hdcSrc
= CreateCompatibleDC (0);
1357 hdcDst
= CreateCompatibleDC (0);
1358 SelectObject (hdcSrc
, himlSrc
->hbmImage
);
1359 SelectObject (hdcDst
, himlDst
->hbmImage
);
1360 BitBlt (hdcDst
, 0, 0, himlSrc
->cCurImage
* himlSrc
->cx
, himlSrc
->cy
,
1361 hdcSrc
, 0, 0, SRCCOPY
);
1363 if (himlDst
->hbmMask
)
1365 SelectObject (hdcSrc
, himlSrc
->hbmMask
);
1366 SelectObject (hdcDst
, himlDst
->hbmMask
);
1367 BitBlt (hdcDst
, 0, 0, himlSrc
->cCurImage
* himlSrc
->cx
,
1368 himlSrc
->cy
, hdcSrc
, 0, 0, SRCCOPY
);
1374 himlDst
->cCurImage
= himlSrc
->cCurImage
;
1375 himlDst
->cMaxImage
= himlSrc
->cMaxImage
;
1381 /*************************************************************************
1382 * ImageList_EndDrag [COMCTL32.55] Finishes a drag operation.
1384 * Finishes a drag operation.
1398 ImageList_EndDrag (void)
1400 FIXME("semi-stub!\n");
1402 if (himlInternalDrag
)
1405 ImageList_Destroy (himlInternalDrag
);
1406 himlInternalDrag
= NULL
;
1408 nInternalDragHotspotX
= 0;
1409 nInternalDragHotspotY
= 0;
1417 /*************************************************************************
1418 * ImageList_GetBkColor [COMCTL32.56]
1420 * Returns the background color of an image list.
1423 * himl [I] Image list handle.
1426 * Success: background color
1431 ImageList_GetBkColor (HIMAGELIST himl
)
1440 /*************************************************************************
1441 * ImageList_GetDragImage [COMCTL32.57]
1443 * Returns the handle to the internal drag image list.
1446 * ppt [O] Pointer to the drag position. Can be NULL.
1447 * pptHotspot [O] Pointer to the position of the hot spot. Can be NULL.
1450 * Success: Handle of the drag image list.
1458 ImageList_GetDragImage (POINT
*ppt
, POINT
*pptHotspot
)
1460 FIXME("semi-stub!\n");
1462 if (himlInternalDrag
)
1463 return (himlInternalDrag
);
1469 /*************************************************************************
1470 * ImageList_GetIcon [COMCTL32.59]
1472 * Creates an icon from a masked image of an image list.
1475 * himl [I] handle to image list
1477 * flags [I] drawing style flags
1480 * Success: icon handle
1485 ImageList_GetIcon (HIMAGELIST himl
, INT i
, UINT fStyle
)
1489 HBITMAP hOldSrcBitmap
,hOldDstBitmap
;
1492 if ((himl
== NULL
) || (i
< 0) || (i
>= himl
->cCurImage
)) {
1493 FIXME("(%p,%d,%x), params out of range!\n",himl
,i
,fStyle
);
1497 hdcSrc
= CreateCompatibleDC(0);
1498 hdcDst
= CreateCompatibleDC(0);
1501 ii
.hbmMask
= CreateCompatibleBitmap (hdcDst
, himl
->cx
, himl
->cy
);
1504 hOldDstBitmap
= (HBITMAP
)SelectObject (hdcDst
, ii
.hbmMask
);
1505 if (himl
->hbmMask
) {
1506 SelectObject (hdcSrc
, himl
->hbmMask
);
1507 BitBlt (hdcDst
, 0, 0, himl
->cx
, himl
->cy
,
1508 hdcSrc
, i
* himl
->cx
, 0, SRCCOPY
);
1511 PatBlt (hdcDst
, 0, 0, himl
->cx
, himl
->cy
, BLACKNESS
);
1514 hOldSrcBitmap
= (HBITMAP
)SelectObject (hdcSrc
, himl
->hbmImage
);
1515 ii
.hbmColor
= CreateCompatibleBitmap (hdcSrc
, himl
->cx
, himl
->cy
);
1516 SelectObject (hdcDst
, ii
.hbmColor
);
1517 BitBlt (hdcDst
, 0, 0, himl
->cx
, himl
->cy
,
1518 hdcSrc
, i
* himl
->cx
, 0, SRCCOPY
);
1521 * CreateIconIndirect requires us to deselect the bitmaps from
1522 * the DCs before calling
1524 SelectObject(hdcSrc
, hOldSrcBitmap
);
1525 SelectObject(hdcDst
, hOldDstBitmap
);
1527 hIcon
= CreateIconIndirect (&ii
);
1531 DeleteObject (ii
.hbmMask
);
1532 DeleteObject (ii
.hbmColor
);
1538 /*************************************************************************
1539 * ImageList_GetIconSize [COMCTL32.60]
1541 * Retrieves the size of an image in an image list.
1544 * himl [I] handle to image list
1545 * cx [O] pointer to the image width.
1546 * cy [O] pointer to the image height.
1553 * All images in an image list have the same size.
1557 ImageList_GetIconSize (HIMAGELIST himl
, INT
*cx
, INT
*cy
)
1561 if ((himl
->cx
<= 0) || (himl
->cy
<= 0))
1573 /*************************************************************************
1574 * ImageList_GetImageCount [COMCTL32.61]
1576 * Returns the number of images in an image list.
1579 * himl [I] handle to image list
1582 * Success: Number of images.
1587 ImageList_GetImageCount (HIMAGELIST himl
)
1592 return himl
->cCurImage
;
1596 /*************************************************************************
1597 * ImageList_GetImageInfo [COMCTL32.62]
1599 * Returns information about an image in an image list.
1602 * himl [I] handle to image list
1604 * pImageInfo [O] pointer to the image information
1612 ImageList_GetImageInfo (HIMAGELIST himl
, INT i
, IMAGEINFO
*pImageInfo
)
1614 if ((himl
== NULL
) || (pImageInfo
== NULL
))
1616 if ((i
< 0) || (i
>= himl
->cCurImage
))
1619 pImageInfo
->hbmImage
= himl
->hbmImage
;
1620 pImageInfo
->hbmMask
= himl
->hbmMask
;
1622 pImageInfo
->rcImage
.top
= 0;
1623 pImageInfo
->rcImage
.bottom
= himl
->cy
;
1624 pImageInfo
->rcImage
.left
= i
* himl
->cx
;
1625 pImageInfo
->rcImage
.right
= (i
+1) * himl
->cx
;
1631 /*************************************************************************
1632 * ImageList_GetImageRect [COMCTL32.63]
1634 * Retrieves the rectangle of the specified image in an image list.
1637 * himl [I] handle to image list
1639 * lpRect [O] pointer to the image rectangle
1646 * This is an UNDOCUMENTED function!!!
1650 ImageList_GetImageRect (HIMAGELIST himl
, INT i
, LPRECT lpRect
)
1652 if ((himl
== NULL
) || (lpRect
== NULL
))
1654 if ((i
< 0) || (i
>= himl
->cCurImage
))
1657 lpRect
->left
= i
* himl
->cx
;
1659 lpRect
->right
= lpRect
->left
+ himl
->cx
;
1660 lpRect
->bottom
= himl
->cy
;
1666 /*************************************************************************
1667 * ImageList_LoadImage [COMCTL32.64]
1668 * ImageList_LoadImageA [COMCTL32.65]
1670 * Creates an image list from a bitmap, icon or cursor.
1673 * hi [I] instance handle
1674 * lpbmp [I] name or id of the image
1675 * cx [I] width of each image
1676 * cGrow [I] number of images to expand
1677 * clrMask [I] mask color
1678 * uType [I] type of image to load
1679 * uFlags [I] loading flags
1682 * Success: handle to the loaded image list
1690 ImageList_LoadImageA (HINSTANCE hi
, LPCSTR lpbmp
, INT cx
, INT cGrow
,
1691 COLORREF clrMask
, UINT uType
, UINT uFlags
)
1693 HIMAGELIST himl
= NULL
;
1697 handle
= LoadImageA (hi
, lpbmp
, uType
, 0, 0, uFlags
);
1699 ERR("Error loading image!\n");
1703 if (uType
== IMAGE_BITMAP
) {
1705 GetObjectA (handle
, sizeof(BITMAP
), &bmp
);
1707 /* To match windows behavior, if cx is set to zero and
1708 the flag DI_DEFAULTSIZE is specified, cx becomes the
1709 system metric value for icons. If the flag is not specified
1710 the function sets the size to the height of the bitmap */
1713 if (uFlags
& DI_DEFAULTSIZE
)
1714 cx
= GetSystemMetrics (SM_CXICON
);
1719 nImageCount
= bmp
.bmWidth
/ cx
;
1721 himl
= ImageList_Create (cx
, bmp
.bmHeight
, ILC_MASK
| ILC_COLOR
,
1722 nImageCount
, cGrow
);
1723 ImageList_AddMasked (himl
, (HBITMAP
)handle
, clrMask
);
1725 else if ((uType
== IMAGE_ICON
) || (uType
== IMAGE_CURSOR
)) {
1729 GetIconInfo (handle
, &ii
);
1730 GetObjectA (ii
.hbmColor
, sizeof(BITMAP
), (LPVOID
)&bmp
);
1731 himl
= ImageList_Create (bmp
.bmWidth
, bmp
.bmHeight
,
1732 ILC_MASK
| ILC_COLOR
, 1, cGrow
);
1733 ImageList_Add (himl
, ii
.hbmColor
, ii
.hbmMask
);
1734 DeleteObject (ii
.hbmColor
);
1735 DeleteObject (ii
.hbmMask
);
1738 DeleteObject (handle
);
1744 /*************************************************************************
1745 * ImageList_LoadImageW [COMCTL32.66]
1747 * Creates an image list from a bitmap, icon or cursor.
1750 * hi [I] instance handle
1751 * lpbmp [I] name or id of the image
1752 * cx [I] width of each image
1753 * cGrow [I] number of images to expand
1754 * clrMask [I] mask color
1755 * uType [I] type of image to load
1756 * uFlags [I] loading flags
1759 * Success: handle to the loaded image list
1767 ImageList_LoadImageW (HINSTANCE hi
, LPCWSTR lpbmp
, INT cx
, INT cGrow
,
1768 COLORREF clrMask
, UINT uType
, UINT uFlags
)
1770 HIMAGELIST himl
= NULL
;
1774 handle
= LoadImageW (hi
, lpbmp
, uType
, 0, 0, uFlags
);
1776 ERR("Error loading image!\n");
1780 if (uType
== IMAGE_BITMAP
) {
1782 GetObjectA (handle
, sizeof(BITMAP
), &bmp
);
1783 nImageCount
= bmp
.bmWidth
/ cx
;
1785 himl
= ImageList_Create (cx
, bmp
.bmHeight
, ILC_MASK
| ILC_COLOR
,
1786 nImageCount
, cGrow
);
1787 ImageList_AddMasked (himl
, (HBITMAP
)handle
, clrMask
);
1789 else if ((uType
== IMAGE_ICON
) || (uType
== IMAGE_CURSOR
)) {
1793 GetIconInfo (handle
, &ii
);
1794 GetObjectA (ii
.hbmMask
, sizeof(BITMAP
), (LPVOID
)&bmp
);
1795 himl
= ImageList_Create (bmp
.bmWidth
, bmp
.bmHeight
,
1796 ILC_MASK
| ILC_COLOR
, 1, cGrow
);
1797 ImageList_Add (himl
, ii
.hbmColor
, ii
.hbmMask
);
1798 DeleteObject (ii
.hbmColor
);
1799 DeleteObject (ii
.hbmMask
);
1802 DeleteObject (handle
);
1808 /*************************************************************************
1809 * ImageList_Merge [COMCTL32.67]
1811 * Creates a new image list that contains a merged image from the specified
1812 * images of both source image lists.
1815 * himl1 [I] handle to first image list
1816 * i1 [I] first image index
1817 * himl2 [I] handle to second image list
1818 * i2 [I] second image index
1819 * dx [I] X offset of the second image relative to the first.
1820 * dy [I] Y offset of the second image relative to the first.
1823 * Success: handle of the merged image list.
1828 ImageList_Merge (HIMAGELIST himl1
, INT i1
, HIMAGELIST himl2
, INT i2
,
1831 HIMAGELIST himlDst
= NULL
;
1832 HDC hdcSrcImage
, hdcDstImage
;
1834 INT xOff1
, yOff1
, xOff2
, yOff2
;
1837 if ((himl1
== NULL
) || (himl2
== NULL
))
1841 if ((i1
< 0) || (i1
>= himl1
->cCurImage
)) {
1842 ERR("Index 1 out of range! %d\n", i1
);
1846 if ((i2
< 0) || (i2
>= himl2
->cCurImage
)) {
1847 ERR("Index 2 out of range! %d\n", i2
);
1852 cxDst
= max (himl1
->cx
, dx
+ himl2
->cx
);
1857 cxDst
= max (himl2
->cx
, himl1
->cx
- dx
);
1862 cxDst
= max (himl1
->cx
, himl2
->cx
);
1868 cyDst
= max (himl1
->cy
, dy
+ himl2
->cy
);
1873 cyDst
= max (himl2
->cy
, himl1
->cy
- dy
);
1878 cyDst
= max (himl1
->cy
, himl2
->cy
);
1883 himlDst
= ImageList_Create (cxDst
, cyDst
, ILC_MASK
| ILC_COLOR
, 1, 1);
1886 hdcSrcImage
= CreateCompatibleDC (0);
1887 hdcDstImage
= CreateCompatibleDC (0);
1888 nX1
= i1
* himl1
->cx
;
1889 nX2
= i2
* himl2
->cx
;
1892 SelectObject (hdcSrcImage
, himl1
->hbmImage
);
1893 SelectObject (hdcDstImage
, himlDst
->hbmImage
);
1894 BitBlt (hdcDstImage
, 0, 0, cxDst
, cyDst
,
1895 hdcSrcImage
, 0, 0, BLACKNESS
);
1896 BitBlt (hdcDstImage
, xOff1
, yOff1
, himl1
->cx
, himl1
->cy
,
1897 hdcSrcImage
, nX1
, 0, SRCCOPY
);
1899 SelectObject (hdcSrcImage
, himl2
->hbmMask
);
1900 BitBlt (hdcDstImage
, xOff2
, yOff2
, himl2
->cx
, himl2
->cy
,
1901 hdcSrcImage
, nX2
, 0, SRCAND
);
1903 SelectObject (hdcSrcImage
, himl2
->hbmImage
);
1904 BitBlt (hdcDstImage
, xOff2
, yOff2
, himl2
->cx
, himl2
->cy
,
1905 hdcSrcImage
, nX2
, 0, SRCPAINT
);
1908 SelectObject (hdcSrcImage
, himl1
->hbmMask
);
1909 SelectObject (hdcDstImage
, himlDst
->hbmMask
);
1910 BitBlt (hdcDstImage
, 0, 0, cxDst
, cyDst
,
1911 hdcSrcImage
, 0, 0, WHITENESS
);
1912 BitBlt (hdcDstImage
, xOff1
, yOff1
, himl1
->cx
, himl1
->cy
,
1913 hdcSrcImage
, nX1
, 0, SRCCOPY
);
1915 SelectObject (hdcSrcImage
, himl2
->hbmMask
);
1916 BitBlt (hdcDstImage
, xOff2
, yOff2
, himl2
->cx
, himl2
->cy
,
1917 hdcSrcImage
, nX2
, 0, SRCAND
);
1919 DeleteDC (hdcSrcImage
);
1920 DeleteDC (hdcDstImage
);
1927 /* helper for _read_bitmap currently unused */
1929 static int may_use_dibsection(HDC hdc
) {
1930 int bitspixel
= GetDeviceCaps(hdc
,BITSPIXEL
)*GetDeviceCaps(hdc
,PLANES
);
1935 return GetDeviceCaps(hdc
,CAPS1
) & C1_DIBENGINE
;
1939 /* helper for ImageList_Read, see comments below */
1940 static HBITMAP
_read_bitmap(LPSTREAM pstm
,int ilcFlag
,int cx
,int cy
) {
1942 BITMAPFILEHEADER bmfh
;
1943 BITMAPINFOHEADER bmih
;
1944 int bitsperpixel
,palspace
,longsperline
,width
,height
;
1945 LPBITMAPINFOHEADER bmihc
= NULL
;
1947 HBITMAP hbitmap
= 0;
1948 LPBYTE bits
= NULL
,nbits
= NULL
;
1949 int nbytesperline
,bytesperline
;
1951 if (!SUCCEEDED(IStream_Read ( pstm
, &bmfh
, sizeof(bmfh
), NULL
)) ||
1952 (bmfh
.bfType
!= (('M'<<8)|'B')) ||
1953 !SUCCEEDED(IStream_Read ( pstm
, &bmih
, sizeof(bmih
), NULL
)) ||
1954 (bmih
.biSize
!= sizeof(bmih
))
1958 bitsperpixel
= bmih
.biPlanes
* bmih
.biBitCount
;
1959 if (bitsperpixel
<=8)
1960 palspace
= (1<<bitsperpixel
)*sizeof(RGBQUAD
);
1963 width
= bmih
.biWidth
;
1964 height
= bmih
.biHeight
;
1965 bmihc
= (LPBITMAPINFOHEADER
)LocalAlloc(LMEM_ZEROINIT
,sizeof(bmih
)+palspace
);
1966 memcpy(bmihc
,&bmih
,sizeof(bmih
));
1967 longsperline
= ((width
*bitsperpixel
+31)&~0x1f)>>5;
1968 bmihc
->biSizeImage
= (longsperline
*height
)<<2;
1970 /* read the palette right after the end of the bitmapinfoheader */
1972 if (!SUCCEEDED(IStream_Read ( pstm
, bmihc
+1, palspace
, NULL
)))
1976 #if 0 /* Magic for NxM -> 1x(N*M) not implemented for DIB Sections */
1977 if ((bitsperpixel
>1) &&
1978 ((ilcFlag
!=ILC_COLORDDB
) && (!ilcFlag
|| may_use_dibsection(xdc
)))
1980 hbitmap
= CreateDIBSection(xdc
,(BITMAPINFO
*)bmihc
,0,(LPVOID
*)&bits
,0,0);
1983 if (!SUCCEEDED(IStream_Read( pstm
, bits
, bmihc
->biSizeImage
, NULL
)))
1989 int i
,nwidth
,nheight
;
1991 nwidth
= width
*(height
/cy
);
1994 if (bitsperpixel
==1)
1995 hbitmap
= CreateBitmap(nwidth
,nheight
,1,1,NULL
);
1997 hbitmap
= CreateCompatibleBitmap(xdc
,nwidth
,nheight
);
1999 /* Might be a bit excessive memory use here */
2000 bits
= (LPBYTE
)LocalAlloc(LMEM_ZEROINIT
,bmihc
->biSizeImage
);
2001 nbits
= (LPBYTE
)LocalAlloc(LMEM_ZEROINIT
,bmihc
->biSizeImage
);
2002 if (!SUCCEEDED(IStream_Read ( pstm
, bits
, bmihc
->biSizeImage
, NULL
)))
2005 /* Copy the NxM bitmap into a 1x(N*M) bitmap we need, linewise */
2006 /* Do not forget that windows bitmaps are bottom->top */
2007 bytesperline
= longsperline
*4;
2008 nbytesperline
= (height
/cy
)*bytesperline
;
2009 for (i
=0;i
<height
;i
++) {
2011 nbits
+((height
-1-i
)%cy
)*nbytesperline
+(i
/cy
)*bytesperline
,
2012 bits
+bytesperline
*(height
-1-i
),
2016 bmihc
->biWidth
= nwidth
;
2017 bmihc
->biHeight
= nheight
;
2018 if (!SetDIBits(xdc
,hbitmap
,0,nheight
,nbits
,(BITMAPINFO
*)bmihc
,0))
2020 LocalFree((HLOCAL
)nbits
);
2021 LocalFree((HLOCAL
)bits
);
2025 if (xdc
) ReleaseDC(0,xdc
);
2026 if (bmihc
) LocalFree((HLOCAL
)bmihc
);
2029 DeleteObject(hbitmap
);
2036 /*************************************************************************
2037 * ImageList_Read [COMCTL32.68]
2039 * Reads an image list from a stream.
2042 * pstm [I] pointer to a stream
2045 * Success: handle to image list
2048 * The format is like this:
2049 * ILHEAD ilheadstruct;
2051 * for the color image part:
2052 * BITMAPFILEHEADER bmfh;
2053 * BITMAPINFOHEADER bmih;
2054 * only if it has a palette:
2055 * RGBQUAD rgbs[nr_of_paletted_colors];
2057 * BYTE colorbits[imagesize];
2059 * the following only if the ILC_MASK bit is set in ILHEAD.ilFlags:
2060 * BITMAPFILEHEADER bmfh_mask;
2061 * BITMAPINFOHEADER bmih_mask;
2062 * only if it has a palette (it usually does not):
2063 * RGBQUAD rgbs[nr_of_paletted_colors];
2065 * BYTE maskbits[imagesize];
2067 * CAVEAT: Those images are within a NxM bitmap, not the 1xN we expect.
2068 * _read_bitmap needs to convert them.
2070 HIMAGELIST WINAPI
ImageList_Read (LPSTREAM pstm
)
2074 HBITMAP hbmColor
=0,hbmMask
=0;
2077 if (!SUCCEEDED(IStream_Read (pstm
, &ilHead
, sizeof(ILHEAD
), NULL
)))
2079 if (ilHead
.usMagic
!= (('L' << 8) | 'I'))
2081 if (ilHead
.usVersion
!= 0x101) /* probably version? */
2085 FIXME(" ilHead.cCurImage = %d\n",ilHead
.cCurImage
);
2086 FIXME(" ilHead.cMaxImage = %d\n",ilHead
.cMaxImage
);
2087 FIXME(" ilHead.cGrow = %d\n",ilHead
.cGrow
);
2088 FIXME(" ilHead.cx = %d\n",ilHead
.cx
);
2089 FIXME(" ilHead.cy = %d\n",ilHead
.cy
);
2090 FIXME(" ilHead.flags = %x\n",ilHead
.flags
);
2091 FIXME(" ilHead.ovls[0] = %d\n",ilHead
.ovls
[0]);
2092 FIXME(" ilHead.ovls[1] = %d\n",ilHead
.ovls
[1]);
2093 FIXME(" ilHead.ovls[2] = %d\n",ilHead
.ovls
[2]);
2094 FIXME(" ilHead.ovls[3] = %d\n",ilHead
.ovls
[3]);
2097 hbmColor
= _read_bitmap(pstm
,ilHead
.flags
& ~ILC_MASK
,ilHead
.cx
,ilHead
.cy
);
2100 if (ilHead
.flags
& ILC_MASK
) {
2101 hbmMask
= _read_bitmap(pstm
,0,ilHead
.cx
,ilHead
.cy
);
2103 DeleteObject(hbmColor
);
2108 himl
= ImageList_Create (
2116 DeleteObject(hbmColor
);
2117 DeleteObject(hbmMask
);
2120 himl
->hbmImage
= hbmColor
;
2121 himl
->hbmMask
= hbmMask
;
2122 himl
->cCurImage
= ilHead
.cCurImage
;
2123 himl
->cMaxImage
= ilHead
.cMaxImage
;
2125 ImageList_SetBkColor(himl
,ilHead
.bkcolor
);
2127 ImageList_SetOverlayImage(himl
,ilHead
.ovls
[i
],i
+1);
2132 /*************************************************************************
2133 * ImageList_Remove [COMCTL32.69] Removes an image from an image list
2136 * himl [I] image list handle
2145 ImageList_Remove (HIMAGELIST himl
, INT i
)
2147 HBITMAP hbmNewImage
, hbmNewMask
;
2152 ERR("Invalid image list handle!\n");
2156 if ((i
< -1) || (i
>= himl
->cCurImage
)) {
2157 ERR("index out of range! %d\n", i
);
2161 if (himl
->cCurImage
== 0) {
2162 ERR("image list is already empty!\n");
2168 TRACE("remove all!\n");
2170 himl
->cMaxImage
= himl
->cInitial
+ himl
->cGrow
;
2171 himl
->cCurImage
= 0;
2172 for (nCount
= 0; nCount
< MAX_OVERLAYIMAGE
; nCount
++)
2173 himl
->nOvlIdx
[nCount
] = -1;
2175 DeleteObject (himl
->hbmImage
);
2177 CreateBitmap (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
2178 1, himl
->uBitsPixel
, NULL
);
2180 if (himl
->hbmMask
) {
2181 DeleteObject (himl
->hbmMask
);
2183 CreateBitmap (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
2188 /* delete one image */
2189 TRACE("Remove single image! %d\n", i
);
2191 /* create new bitmap(s) */
2192 cxNew
= (himl
->cCurImage
+ himl
->cGrow
- 1) * himl
->cx
;
2194 TRACE(" - Number of images: %d / %d (Old/New)\n",
2195 himl
->cCurImage
, himl
->cCurImage
- 1);
2196 TRACE(" - Max. number of images: %d / %d (Old/New)\n",
2197 himl
->cMaxImage
, himl
->cCurImage
+ himl
->cGrow
- 1);
2200 CreateBitmap (cxNew
, himl
->cy
, 1, himl
->uBitsPixel
, NULL
);
2203 hbmNewMask
= CreateBitmap (cxNew
, himl
->cy
, 1, 1, NULL
);
2205 hbmNewMask
= 0; /* Just to keep compiler happy! */
2207 hdcSrc
= CreateCompatibleDC (0);
2208 hdcDst
= CreateCompatibleDC (0);
2210 /* copy all images and masks prior to the "removed" image */
2212 TRACE("Pre image copy: Copy %d images\n", i
);
2214 SelectObject (hdcSrc
, himl
->hbmImage
);
2215 SelectObject (hdcDst
, hbmNewImage
);
2216 BitBlt (hdcDst
, 0, 0, i
* himl
->cx
, himl
->cy
,
2217 hdcSrc
, 0, 0, SRCCOPY
);
2219 if (himl
->hbmMask
) {
2220 SelectObject (hdcSrc
, himl
->hbmMask
);
2221 SelectObject (hdcDst
, hbmNewMask
);
2222 BitBlt (hdcDst
, 0, 0, i
* himl
->cx
, himl
->cy
,
2223 hdcSrc
, 0, 0, SRCCOPY
);
2227 /* copy all images and masks behind the removed image */
2228 if (i
< himl
->cCurImage
- 1) {
2229 TRACE("Post image copy!\n");
2230 SelectObject (hdcSrc
, himl
->hbmImage
);
2231 SelectObject (hdcDst
, hbmNewImage
);
2232 BitBlt (hdcDst
, i
* himl
->cx
, 0, (himl
->cCurImage
- i
- 1) * himl
->cx
,
2233 himl
->cy
, hdcSrc
, (i
+ 1) * himl
->cx
, 0, SRCCOPY
);
2235 if (himl
->hbmMask
) {
2236 SelectObject (hdcSrc
, himl
->hbmMask
);
2237 SelectObject (hdcDst
, hbmNewMask
);
2238 BitBlt (hdcDst
, i
* himl
->cx
, 0,
2239 (himl
->cCurImage
- i
- 1) * himl
->cx
,
2240 himl
->cy
, hdcSrc
, (i
+ 1) * himl
->cx
, 0, SRCCOPY
);
2247 /* delete old images and insert new ones */
2248 DeleteObject (himl
->hbmImage
);
2249 himl
->hbmImage
= hbmNewImage
;
2250 if (himl
->hbmMask
) {
2251 DeleteObject (himl
->hbmMask
);
2252 himl
->hbmMask
= hbmNewMask
;
2256 himl
->cMaxImage
= himl
->cCurImage
+ himl
->cGrow
;
2263 /*************************************************************************
2264 * ImageList_Replace [COMCTL32.70]
2266 * Replaces an image in an image list with a new image.
2269 * himl [I] handle to image list
2271 * hbmImage [I] handle to image bitmap
2272 * hbmMask [I] handle to mask bitmap. Can be NULL.
2280 ImageList_Replace (HIMAGELIST himl
, INT i
, HBITMAP hbmImage
,
2283 HDC hdcImageList
, hdcImage
;
2287 ERR("Invalid image list handle!\n");
2291 if ((i
>= himl
->cMaxImage
) || (i
< 0)) {
2292 ERR("Invalid image index!\n");
2296 hdcImageList
= CreateCompatibleDC (0);
2297 hdcImage
= CreateCompatibleDC (0);
2298 GetObjectA (hbmImage
, sizeof(BITMAP
), (LPVOID
)&bmp
);
2301 SelectObject (hdcImageList
, himl
->hbmImage
);
2302 SelectObject (hdcImage
, hbmImage
);
2304 StretchBlt (hdcImageList
, i
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
2305 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
2310 SelectObject (hdcImageList
, himl
->hbmMask
);
2311 SelectObject (hdcImage
, hbmMask
);
2313 StretchBlt (hdcImageList
, i
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
2314 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
2317 /* Remove the background from the image
2319 SelectObject (hdcImageList
, himl
->hbmImage
);
2320 StretchBlt (hdcImageList
,
2321 i
*himl
->cx
, 0, himl
->cx
, himl
->cy
,
2323 0, 0, bmp
.bmWidth
, bmp
.bmHeight
,
2324 0x220326); /* NOTSRCAND */
2327 DeleteDC (hdcImage
);
2328 DeleteDC (hdcImageList
);
2334 /*************************************************************************
2335 * ImageList_ReplaceIcon [COMCTL32.75]
2337 * Replaces an image in an image list using an icon.
2340 * himl [I] handle to image list
2342 * hIcon [I] handle to icon
2345 * Success: index of the replaced image
2350 ImageList_ReplaceIcon (HIMAGELIST himl
, INT i
, HICON hIcon
)
2352 HDC hdcImageList
, hdcImage
;
2355 HBITMAP hbmOldSrc
, hbmOldDst
;
2359 TRACE("(0x%lx 0x%x 0x%x)\n", (DWORD
)himl
, i
, hIcon
);
2363 if ((i
>= himl
->cMaxImage
) || (i
< -1))
2366 hBestFitIcon
= CopyImage(
2369 LR_COPYFROMRESOURCE
);
2371 GetIconInfo (hBestFitIcon
, &ii
);
2372 if (ii
.hbmMask
== 0)
2374 if (ii
.hbmColor
== 0)
2376 GetObjectA (ii
.hbmMask
, sizeof(BITMAP
), (LPVOID
)&bmp
);
2379 if (himl
->cCurImage
+ 1 >= himl
->cMaxImage
)
2380 IMAGELIST_InternalExpandBitmaps (himl
, 1, 0, 0);
2382 nIndex
= himl
->cCurImage
;
2388 hdcImageList
= CreateCompatibleDC (0);
2389 TRACE("hdcImageList=0x%x!\n", hdcImageList
);
2390 if (hdcImageList
== 0)
2391 ERR("invalid hdcImageList!\n");
2393 hdcImage
= CreateCompatibleDC (0);
2394 TRACE("hdcImage=0x%x!\n", hdcImage
);
2396 ERR("invalid hdcImage!\n");
2398 hbmOldDst
= SelectObject (hdcImageList
, himl
->hbmImage
);
2399 SetTextColor( hdcImageList
, RGB(0,0,0));
2400 SetBkColor( hdcImageList
, RGB(255,255,255));
2401 hbmOldSrc
= SelectObject (hdcImage
, ii
.hbmColor
);
2402 StretchBlt (hdcImageList
, nIndex
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
2403 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
2405 if (himl
->hbmMask
) {
2406 SelectObject (hdcImageList
, himl
->hbmMask
);
2407 SelectObject (hdcImage
, ii
.hbmMask
);
2408 StretchBlt (hdcImageList
, nIndex
* himl
->cx
, 0, himl
->cx
, himl
->cy
,
2409 hdcImage
, 0, 0, bmp
.bmWidth
, bmp
.bmHeight
, SRCCOPY
);
2412 SelectObject (hdcImage
, hbmOldSrc
);
2413 SelectObject (hdcImageList
, hbmOldDst
);
2416 DestroyIcon(hBestFitIcon
);
2418 DeleteDC (hdcImageList
);
2420 DeleteDC (hdcImage
);
2422 DeleteObject (ii
.hbmColor
);
2424 DeleteObject (ii
.hbmMask
);
2430 /*************************************************************************
2431 * ImageList_SetBkColor [COMCTL32.76]
2433 * Sets the background color of an image list.
2436 * himl [I] handle to image list
2437 * clrBk [I] background color
2440 * Success: previous background color
2445 ImageList_SetBkColor (HIMAGELIST himl
, COLORREF clrBk
)
2452 clrOldBk
= himl
->clrBk
;
2453 himl
->clrBk
= clrBk
;
2458 /*************************************************************************
2459 * ImageList_SetDragCursorImage [COMCTL32.77]
2461 * Combines the specified image with the current drag image
2464 * himlDrag [I] handle to drag image list
2465 * iDrag [I] drag image index
2466 * dxHotspot [I] X position of the hot spot
2467 * dyHotspot [I] Y position of the hot spot
2478 ImageList_SetDragCursorImage (HIMAGELIST himlDrag
, INT iDrag
,
2479 INT dxHotspot
, INT dyHotspot
)
2481 HIMAGELIST himlTemp
;
2483 FIXME("semi-stub!\n");
2485 if (himlInternalDrag
== NULL
)
2488 TRACE(" dxH=%d dyH=%d nX=%d nY=%d\n",
2489 dxHotspot
, dyHotspot
, nInternalDragHotspotX
, nInternalDragHotspotY
);
2491 himlTemp
= ImageList_Merge (himlInternalDrag
, 0, himlDrag
, iDrag
,
2492 dxHotspot
, dyHotspot
);
2494 ImageList_Destroy (himlInternalDrag
);
2495 himlInternalDrag
= himlTemp
;
2497 nInternalDragHotspotX
= dxHotspot
;
2498 nInternalDragHotspotY
= dyHotspot
;
2504 /*************************************************************************
2505 * ImageList_SetFilter [COMCTL32.78]
2507 * Sets a filter (or does something completely different)!!???
2510 * himl [I] handle to image list
2516 * Failure: FALSE ???
2519 * This is an UNDOCUMENTED function!!!!
2524 ImageList_SetFilter (HIMAGELIST himl
, INT i
, DWORD dwFilter
)
2526 FIXME("(%p 0x%x 0x%lx):empty stub!\n",
2533 /*************************************************************************
2534 * ImageList_SetIconSize [COMCTL32.80]
2536 * Sets the image size of the bitmap and deletes all images.
2539 * himl [I] handle to image list
2540 * cx [I] image width
2541 * cy [I] image height
2549 ImageList_SetIconSize (HIMAGELIST himl
, INT cx
, INT cy
)
2556 /* remove all images */
2557 himl
->cMaxImage
= himl
->cInitial
+ himl
->cGrow
;
2558 himl
->cCurImage
= 0;
2562 /* initialize overlay mask indices */
2563 for (nCount
= 0; nCount
< MAX_OVERLAYIMAGE
; nCount
++)
2564 himl
->nOvlIdx
[nCount
] = -1;
2566 DeleteObject (himl
->hbmImage
);
2568 CreateBitmap (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
2569 1, himl
->uBitsPixel
, NULL
);
2571 if (himl
->hbmMask
) {
2572 DeleteObject (himl
->hbmMask
);
2574 CreateBitmap (himl
->cMaxImage
* himl
->cx
, himl
->cy
,
2582 /*************************************************************************
2583 * ImageList_SetImageCount [COMCTL32.81]
2585 * Resizes an image list to the specified number of images.
2588 * himl [I] handle to image list
2589 * iImageCount [I] number of images in the image list
2597 ImageList_SetImageCount (HIMAGELIST himl
, INT iImageCount
)
2599 HDC hdcImageList
, hdcBitmap
;
2600 HBITMAP hbmNewBitmap
;
2601 INT nNewCount
, nCopyCount
;
2605 if (himl
->cCurImage
>= iImageCount
)
2607 if (himl
->cMaxImage
> iImageCount
)
2610 nNewCount
= iImageCount
+ himl
->cGrow
;
2611 nCopyCount
= min(himl
->cCurImage
, iImageCount
);
2613 hdcImageList
= CreateCompatibleDC (0);
2614 hdcBitmap
= CreateCompatibleDC (0);
2616 hbmNewBitmap
= CreateBitmap (nNewCount
* himl
->cx
, himl
->cy
,
2617 1, himl
->uBitsPixel
, NULL
);
2618 if (hbmNewBitmap
!= 0)
2620 SelectObject (hdcImageList
, himl
->hbmImage
);
2621 SelectObject (hdcBitmap
, hbmNewBitmap
);
2624 BitBlt (hdcBitmap
, 0, 0, nCopyCount
* himl
->cx
, himl
->cy
,
2625 hdcImageList
, 0, 0, SRCCOPY
);
2627 /* delete 'empty' image space */
2628 SetBkColor (hdcBitmap
, RGB(255, 255, 255));
2629 SetTextColor (hdcBitmap
, RGB(0, 0, 0));
2630 PatBlt (hdcBitmap
, nCopyCount
* himl
->cx
, 0,
2631 (nNewCount
- nCopyCount
) * himl
->cx
, himl
->cy
, BLACKNESS
);
2633 DeleteObject (himl
->hbmImage
);
2634 himl
->hbmImage
= hbmNewBitmap
;
2637 ERR("Could not create new image bitmap !\n");
2641 hbmNewBitmap
= CreateBitmap (nNewCount
* himl
->cx
, himl
->cy
,
2643 if (hbmNewBitmap
!= 0)
2645 SelectObject (hdcImageList
, himl
->hbmMask
);
2646 SelectObject (hdcBitmap
, hbmNewBitmap
);
2649 BitBlt (hdcBitmap
, 0, 0, nCopyCount
* himl
->cx
, himl
->cy
,
2650 hdcImageList
, 0, 0, SRCCOPY
);
2652 /* delete 'empty' image space */
2653 SetBkColor (hdcBitmap
, RGB(255, 255, 255));
2654 SetTextColor (hdcBitmap
, RGB(0, 0, 0));
2655 PatBlt (hdcBitmap
, nCopyCount
* himl
->cx
, 0,
2656 (nNewCount
- nCopyCount
) * himl
->cx
, himl
->cy
, BLACKNESS
);
2658 DeleteObject (himl
->hbmMask
);
2659 himl
->hbmMask
= hbmNewBitmap
;
2662 ERR("Could not create new mask bitmap!\n");
2665 DeleteDC (hdcImageList
);
2666 DeleteDC (hdcBitmap
);
2668 /* Update max image count and current image count */
2669 himl
->cMaxImage
= nNewCount
;
2670 if (himl
->cCurImage
> nCopyCount
)
2671 himl
->cCurImage
= nCopyCount
;
2677 /*************************************************************************
2678 * ImageList_SetOverlayImage [COMCTL32.82]
2680 * Assigns an overlay mask index to an existing image in an image list.
2683 * himl [I] handle to image list
2684 * iImage [I] image index
2685 * iOverlay [I] overlay mask index
2693 ImageList_SetOverlayImage (HIMAGELIST himl
, INT iImage
, INT iOverlay
)
2697 if ((iOverlay
< 1) || (iOverlay
> MAX_OVERLAYIMAGE
))
2699 if ((iImage
!=-1) && ((iImage
< 0) || (iImage
> himl
->cCurImage
)))
2701 himl
->nOvlIdx
[iOverlay
- 1] = iImage
;
2706 /*************************************************************************
2707 * ImageList_Write [COMCTL32.83]
2709 * Writes an image list to a stream.
2712 * himl [I] handle to image list
2713 * pstm [O] Pointer to a stream.
2720 * This function can not be implemented yet, because
2721 * IStream32::Write is not implemented.
2728 ImageList_Write (HIMAGELIST himl
, LPSTREAM pstm
)
2733 FIXME("empty stub!\n");