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