ReactOS 0.4.16-dev-976-g18fc5a1
imagelist.c
Go to the documentation of this file.
1/*
2 * ImageList implementation
3 *
4 * Copyright 1998 Eric Kohl
5 * Copyright 2000 Jason Mawdsley
6 * Copyright 2001, 2004 Michael Stefaniuc
7 * Copyright 2001 Charles Loep for CodeWeavers
8 * Copyright 2002 Dimitrie O. Paun
9 * Copyright 2009 Owen Rudge for CodeWeavers
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 *
25 * TODO:
26 * - Add support for ILD_PRESERVEALPHA, ILD_SCALE, ILD_DPISCALE
27 * - Add support for ILS_GLOW, ILS_SHADOW
28 * - Thread-safe locking
29 */
30
31#include <stdarg.h>
32#include <stdlib.h>
33#include <string.h>
34
35#define COBJMACROS
36
37#include "winerror.h"
38#include "windef.h"
39#include "winbase.h"
40#include "objbase.h"
41#include "wingdi.h"
42#include "winuser.h"
43#include "commctrl.h"
44#include "comctl32.h"
45#include "commoncontrols.h"
46#include "wine/debug.h"
47#include "wine/exception.h"
48#include "wine/heap.h"
49
51
52#define MAX_OVERLAYIMAGE 15
53
54#ifdef __REACTOS__
55//The big bad reactos image list hack!
56BOOL is_valid2(HIMAGELIST himl);
57INT WINAPI Internal_ReplaceIcon (HIMAGELIST himl, INT nIndex, HICON hIcon);
58BOOL WINAPI Internal_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp);
59COLORREF WINAPI Internal_SetBkColor (HIMAGELIST himl, COLORREF clrBk);
60BOOL WINAPI Internal_SetOverlayImage (HIMAGELIST himl, INT iImage, INT iOverlay);
61
62#define ImageList_Add Internal_Add
63#define ImageList_ReplaceIcon Internal_ReplaceIcon
64#define ImageList_SetOverlayImage Internal_SetOverlayImage
65#define ImageList_Replace Internal_Replace
66#define ImageList_AddMasked Internal_AddMasked
67#define ImageList_Remove Internal_Remove
68#define ImageList_GetIcon Internal_GetIcon
69#define ImageList_GetImageInfo Internal_GetImageInfo
70#define ImageList_Copy Internal_Copy
71#define ImageList_Merge Internal_Merge
72#define ImageList_Duplicate Internal_Duplicate
73#define ImageList_GetIconSize Internal_GetIconSize
74#define ImageList_SetIconSize Internal_SetIconSize
75#define ImageList_GetImageCount Internal_GetImageCount
76#define ImageList_SetImageCount Internal_SetImageCount
77#define ImageList_SetBkColor Internal_SetBkColor
78#define ImageList_GetBkColor Internal_GetBkColor
79#define ImageList_BeginDrag Internal_BeginDrag
80#define ImageList_DrawIndirect Internal_DrawIndirect
81#endif
82
84{
85 IImageList2 IImageList2_iface; /* 00: IImageList vtable */
86 INT cCurImage; /* 04: ImageCount */
87 INT cMaxImage; /* 08: maximages */
88 INT cGrow; /* 0C: cGrow */
89 INT cx; /* 10: cx */
90 INT cy; /* 14: cy */
92 UINT flags; /* 1C: flags */
93 COLORREF clrFg; /* 20: foreground color */
94 COLORREF clrBk; /* 24: background color */
95
96
97 HBITMAP hbmImage; /* 28: images Bitmap */
98 HBITMAP hbmMask; /* 2C: masks Bitmap */
99 HDC hdcImage; /* 30: images MemDC */
100 HDC hdcMask; /* 34: masks MemDC */
101 INT nOvlIdx[MAX_OVERLAYIMAGE]; /* 38: overlay images index */
102
103 /* not yet found out */
104 #ifdef __REACTOS__
105 ULONG usMagic;
106 #endif
113
114 LONG ref; /* reference count */
115#ifdef __REACTOS__
116 USHORT usVersion; /* hack for IL from stream. Keep version here */
117#endif
118};
119
120#define IMAGELIST_MAGIC 0x53414D58
121#ifdef __REACTOS__
122#define IMAGELIST_MAGIC_DESTROYED 0x44454144
123#define IMAGELIST_VERSION 0x101
124
125#define WinVerMajor() LOBYTE(GetVersion())
126
127#include <comctl32_undoc.h>
128#define ILC_PUBLICFLAGS ( 0xFFFFFFFF ) /* Allow all flags for now */
129#define ILC_COLORMASK 0xFE
130#endif /* __REACTOS__ */
131
132/* Header used by ImageList_Read() and ImageList_Write() */
133#include "pshpack2.h"
134typedef struct _ILHEAD
135{
147#include "poppack.h"
148
149/* internal image list data used for Drag & Drop operations */
150typedef struct
151{
155 /* position of the drag image relative to the window */
158 /* offset of the hotspot relative to the origin of the image */
161 /* is the drag image visible */
163 /* saved background */
166
167static INTERNALDRAG InternalDrag = { 0, 0, 0, 0, 0, 0, 0, FALSE, 0 };
168
170{
171 return CONTAINING_RECORD(iface, struct _IMAGELIST, IImageList2_iface);
172}
173
175static HRESULT ImageListImpl_CreateInstance(const IUnknown *pUnkOuter, REFIID iid, void** ppv);
177
178/*
179 * An imagelist with N images is tiled like this:
180 *
181 * N/4 ->
182 *
183 * 4 048C..
184 * 159D..
185 * | 26AE.N
186 * V 37BF.
187 */
188
189#define TILE_COUNT 4
190
192{
193 return ((count + TILE_COUNT - 1)/TILE_COUNT);
194}
195
197{
198 pt->x = (index%TILE_COUNT) * himl->cx;
199 pt->y = (index/TILE_COUNT) * himl->cy;
200}
201
203{
204 sz->cx = himl->cx * TILE_COUNT;
205 sz->cy = imagelist_height( count ) * himl->cy;
206}
207
208static inline int get_dib_stride( int width, int bpp )
209{
210 return ((width * bpp + 31) >> 3) & ~3;
211}
212
213static inline int get_dib_image_size( const BITMAPINFO *info )
214{
215 return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount )
216 * abs( info->bmiHeader.biHeight );
217}
218
219/*
220 * imagelist_copy_images()
221 *
222 * Copies a block of count images from offset src in the list to offset dest.
223 * Images are copied a row at at time. Assumes hdcSrc and hdcDest are different.
224 */
225static inline void imagelist_copy_images( HIMAGELIST himl, HDC hdcSrc, HDC hdcDest,
227{
228 POINT ptSrc, ptDest;
229 SIZE sz;
230 UINT i;
231
232 for ( i=0; i<TILE_COUNT; i++ )
233 {
236 sz.cx = himl->cx;
237 sz.cy = himl->cy * imagelist_height( count - i );
238
239 BitBlt( hdcDest, ptDest.x, ptDest.y, sz.cx, sz.cy,
240 hdcSrc, ptSrc.x, ptSrc.y, SRCCOPY );
241 }
242}
243
244static void add_dib_bits( HIMAGELIST himl, int pos, int count, int width, int height,
245 BITMAPINFO *info, BITMAPINFO *mask_info, DWORD *bits, BYTE *mask_bits )
246{
247 int i, j, n;
248 POINT pt;
249 int stride = info->bmiHeader.biWidth;
250 int mask_stride = (info->bmiHeader.biWidth + 31) / 32 * 4;
251
252 for (n = 0; n < count; n++)
253 {
254 BOOL has_alpha = FALSE;
255
257
258 /* check if bitmap has an alpha channel */
259 for (i = 0; i < height && !has_alpha; i++)
260 for (j = n * width; j < (n + 1) * width; j++)
261 if ((has_alpha = ((bits[i * stride + j] & 0xff000000) != 0))) break;
262
263 if (!has_alpha) /* generate alpha channel from the mask */
264 {
265 for (i = 0; i < height; i++)
266 for (j = n * width; j < (n + 1) * width; j++)
267 if (!mask_info || !((mask_bits[i * mask_stride + j / 8] << (j % 8)) & 0x80))
268 bits[i * stride + j] |= 0xff000000;
269 else
270 bits[i * stride + j] = 0;
271 }
272 else
273 {
274 himl->has_alpha[pos + n] = 1;
275
276 if (mask_info && himl->hbmMask) /* generate the mask from the alpha channel */
277 {
278 for (i = 0; i < height; i++)
279 for (j = n * width; j < (n + 1) * width; j++)
280 if ((bits[i * stride + j] >> 24) > 25) /* more than 10% alpha */
281 mask_bits[i * mask_stride + j / 8] &= ~(0x80 >> (j % 8));
282 else
283 mask_bits[i * mask_stride + j / 8] |= 0x80 >> (j % 8);
284 }
285 }
288 if (mask_info)
290 n * width, 0, width, height, mask_bits, mask_info, DIB_RGB_COLORS, SRCCOPY );
291 }
292}
293
294/* add images with an alpha channel when the image list is 32 bpp */
296 int width, int height, HBITMAP hbmImage, HBITMAP hbmMask )
297{
298 BOOL ret = FALSE;
299 BITMAP bm;
300 BITMAPINFO *info, *mask_info = NULL;
301 DWORD *bits = NULL;
302 BYTE *mask_bits = NULL;
303 DWORD mask_width;
304
305 if (!GetObjectW( hbmImage, sizeof(bm), &bm )) return FALSE;
306
307 /* if either the imagelist or the source bitmap don't have an alpha channel, bail out now */
308 if (!himl->has_alpha) return FALSE;
309 if (bm.bmBitsPixel != 32) return FALSE;
310
311 SelectObject( hdc, hbmImage );
312 mask_width = (bm.bmWidth + 31) / 32 * 4;
313
314 if (!(info = heap_alloc( FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) goto done;
315 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
316 info->bmiHeader.biWidth = bm.bmWidth;
317 info->bmiHeader.biHeight = -height;
318 info->bmiHeader.biPlanes = 1;
319 info->bmiHeader.biBitCount = 32;
320 info->bmiHeader.biCompression = BI_RGB;
321 info->bmiHeader.biSizeImage = bm.bmWidth * height * 4;
322 info->bmiHeader.biXPelsPerMeter = 0;
323 info->bmiHeader.biYPelsPerMeter = 0;
324 info->bmiHeader.biClrUsed = 0;
325 info->bmiHeader.biClrImportant = 0;
326 if (!(bits = heap_alloc( info->bmiHeader.biSizeImage ))) goto done;
327 if (!GetDIBits( hdc, hbmImage, 0, height, bits, info, DIB_RGB_COLORS )) goto done;
328
329 if (hbmMask)
330 {
331 if (!(mask_info = heap_alloc( FIELD_OFFSET( BITMAPINFO, bmiColors[2] ))))
332 goto done;
333 mask_info->bmiHeader = info->bmiHeader;
334 mask_info->bmiHeader.biBitCount = 1;
335 mask_info->bmiHeader.biSizeImage = mask_width * height;
336 if (!(mask_bits = heap_alloc_zero( mask_info->bmiHeader.biSizeImage )))
337 goto done;
338 if (!GetDIBits( hdc, hbmMask, 0, height, mask_bits, mask_info, DIB_RGB_COLORS )) goto done;
339 }
340
341 add_dib_bits( himl, pos, count, width, height, info, mask_info, bits, mask_bits );
342 ret = TRUE;
343
344done:
345 heap_free( info );
346 heap_free( mask_info );
347 heap_free( bits );
348 heap_free( mask_bits );
349 return ret;
350}
351
354
355/*************************************************************************
356 * IMAGELIST_InternalExpandBitmaps [Internal]
357 *
358 * Expands the bitmaps of an image list by the given number of images.
359 *
360 * PARAMS
361 * himl [I] handle to image list
362 * nImageCount [I] number of images to add
363 *
364 * RETURNS
365 * nothing
366 *
367 * NOTES
368 * This function CANNOT be used to reduce the number of images.
369 */
370static void
372{
374 HBITMAP hbmNewBitmap, hbmNull;
375 INT nNewCount;
376 SIZE sz;
377
378 TRACE("%p has allocated %d, max %d, grow %d images\n", himl, himl->cCurImage, himl->cMaxImage, himl->cGrow);
379
380 if (himl->cCurImage + nImageCount < himl->cMaxImage)
381 return;
382
383 nNewCount = himl->cMaxImage + max(nImageCount, himl->cGrow) + 1;
384
385 imagelist_get_bitmap_size(himl, nNewCount, &sz);
386
387 TRACE("Create expanded bitmaps : himl=%p x=%d y=%d count=%d\n", himl, sz.cx, sz.cy, nNewCount);
389
390 hbmNewBitmap = ImageList_CreateImage(hdcBitmap, himl, nNewCount);
391
392 if (hbmNewBitmap == 0)
393 ERR("creating new image bitmap (x=%d y=%d)!\n", sz.cx, sz.cy);
394
395 if (himl->cCurImage)
396 {
397 hbmNull = SelectObject (hdcBitmap, hbmNewBitmap);
398 BitBlt (hdcBitmap, 0, 0, sz.cx, sz.cy,
399 himl->hdcImage, 0, 0, SRCCOPY);
400 SelectObject (hdcBitmap, hbmNull);
401 }
402 SelectObject (himl->hdcImage, hbmNewBitmap);
404 himl->hbmImage = hbmNewBitmap;
405
406 if (himl->flags & ILC_MASK)
407 {
408 hbmNewBitmap = CreateBitmap (sz.cx, sz.cy, 1, 1, NULL);
409
410 if (hbmNewBitmap == 0)
411 ERR("creating new mask bitmap!\n");
412
413 if(himl->cCurImage)
414 {
415 hbmNull = SelectObject (hdcBitmap, hbmNewBitmap);
416 BitBlt (hdcBitmap, 0, 0, sz.cx, sz.cy,
417 himl->hdcMask, 0, 0, SRCCOPY);
418 SelectObject (hdcBitmap, hbmNull);
419 }
420 SelectObject (himl->hdcMask, hbmNewBitmap);
422 himl->hbmMask = hbmNewBitmap;
423 }
424
425 if (himl->has_alpha)
426 {
427 char *new_alpha = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, himl->has_alpha, nNewCount );
428 if (new_alpha) himl->has_alpha = new_alpha;
429 else
430 {
433 }
434 }
435
436 himl->cMaxImage = nNewCount;
437
439}
440
441
442/*************************************************************************
443 * ImageList_Add [COMCTL32.@]
444 *
445 * Add an image or images to an image list.
446 *
447 * PARAMS
448 * himl [I] handle to image list
449 * hbmImage [I] handle to image bitmap
450 * hbmMask [I] handle to mask bitmap
451 *
452 * RETURNS
453 * Success: Index of the first new image.
454 * Failure: -1
455 */
456
459{
460 HDC hdcBitmap, hdcTemp = 0;
461 INT nFirstIndex, nImageCount, i;
462 BITMAP bmp;
463 POINT pt;
464
465 TRACE("himl=%p hbmimage=%p hbmmask=%p\n", himl, hbmImage, hbmMask);
466 if (!is_valid(himl))
467 return -1;
468
469 if (!GetObjectW(hbmImage, sizeof(BITMAP), &bmp))
470 return -1;
471
472 TRACE("himl %p, cCurImage %d, cMaxImage %d, cGrow %d, cx %d, cy %d\n",
474
475 nImageCount = bmp.bmWidth / himl->cx;
476
477 TRACE("%p has %d images (%d x %d) bpp %d\n", hbmImage, nImageCount, bmp.bmWidth, bmp.bmHeight,
478 bmp.bmBitsPixel);
479
481
483
484 SelectObject(hdcBitmap, hbmImage);
485
486 if (add_with_alpha( himl, hdcBitmap, himl->cCurImage, nImageCount,
487 himl->cx, min( himl->cy, bmp.bmHeight), hbmImage, hbmMask ))
488 goto done;
489
490 if (himl->hbmMask)
491 {
492 hdcTemp = CreateCompatibleDC(0);
493 SelectObject(hdcTemp, hbmMask);
494 }
495
496 if (himl->uBitsPixel <= 8 && bmp.bmBitsPixel <= 8 &&
498 {
499 RGBQUAD colors[256];
500 UINT num = GetDIBColorTable( hdcBitmap, 0, 1 << bmp.bmBitsPixel, colors );
501 if (num) ImageList_SetColorTable( himl, 0, num, colors );
502 }
503
504 for (i=0; i<nImageCount; i++)
505 {
507
508 /* Copy result to the imagelist
509 */
510 BitBlt( himl->hdcImage, pt.x, pt.y, himl->cx, bmp.bmHeight,
511 hdcBitmap, i*himl->cx, 0, SRCCOPY );
512
513 if (!himl->hbmMask)
514 continue;
515
516 BitBlt( himl->hdcMask, pt.x, pt.y, himl->cx, bmp.bmHeight,
517 hdcTemp, i*himl->cx, 0, SRCCOPY );
518
519 /* Remove the background from the image
520 */
521 BitBlt( himl->hdcImage, pt.x, pt.y, himl->cx, bmp.bmHeight,
522 himl->hdcMask, pt.x, pt.y, 0x220326 ); /* NOTSRCAND */
523 }
524 if (hdcTemp) DeleteDC(hdcTemp);
525
526done:
528
529 nFirstIndex = himl->cCurImage;
530 himl->cCurImage += nImageCount;
531
532 return nFirstIndex;
533}
534
535
536/*************************************************************************
537 * ImageList_AddIcon [COMCTL32.@]
538 *
539 * Adds an icon to an image list.
540 *
541 * PARAMS
542 * himl [I] handle to image list
543 * hIcon [I] handle to icon
544 *
545 * RETURNS
546 * Success: index of the new image
547 * Failure: -1
548 */
549#undef ImageList_AddIcon
551{
552 return ImageList_ReplaceIcon (himl, -1, hIcon);
553}
554
555
556/*************************************************************************
557 * ImageList_AddMasked [COMCTL32.@]
558 *
559 * Adds an image or images to an image list and creates a mask from the
560 * specified bitmap using the mask color.
561 *
562 * PARAMS
563 * himl [I] handle to image list.
564 * hBitmap [I] handle to bitmap
565 * clrMask [I] mask color.
566 *
567 * RETURNS
568 * Success: Index of the first new image.
569 * Failure: -1
570 */
571
574{
575 HDC hdcMask, hdcBitmap;
576 INT ret;
577 BITMAP bmp;
578 HBITMAP hMaskBitmap;
579 COLORREF bkColor;
580
581 TRACE("himl=%p hbitmap=%p clrmask=%x\n", himl, hBitmap, clrMask);
582 if (!is_valid(himl))
583 return -1;
584
585 if (!GetObjectW(hBitmap, sizeof(BITMAP), &bmp))
586 return -1;
587
590
591 /* Create a temp Mask so we can remove the background of the Image */
592 hdcMask = CreateCompatibleDC(0);
593 hMaskBitmap = CreateBitmap(bmp.bmWidth, bmp.bmHeight, 1, 1, NULL);
594 SelectObject(hdcMask, hMaskBitmap);
595
596 /* create monochrome image to the mask bitmap */
597 bkColor = (clrMask != CLR_DEFAULT) ? clrMask : GetPixel (hdcBitmap, 0, 0);
598 SetBkColor (hdcBitmap, bkColor);
599 BitBlt (hdcMask, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcBitmap, 0, 0, SRCCOPY);
600
601 /*
602 * Remove the background from the image
603 *
604 * WINDOWS BUG ALERT!!!!!!
605 * The statement below should not be done in common practice
606 * but this is how ImageList_AddMasked works in Windows.
607 * It overwrites the original bitmap passed, this was discovered
608 * by using the same bitmap to iterate the different styles
609 * on windows where it failed (BUT ImageList_Add is OK)
610 * This is here in case some apps rely on this bug
611 *
612 * Blt mode 0x220326 is NOTSRCAND
613 */
614 if (bmp.bmBitsPixel > 8) /* NOTSRCAND can't work with palettes */
615 {
616 SetBkColor(hdcBitmap, RGB(255,255,255));
617 BitBlt(hdcBitmap, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcMask, 0, 0, 0x220326);
618 }
619
621 DeleteDC(hdcMask);
622
623 ret = ImageList_Add( himl, hBitmap, hMaskBitmap );
624
625 DeleteObject(hMaskBitmap);
626 return ret;
627}
628
629
630/*************************************************************************
631 * ImageList_BeginDrag [COMCTL32.@]
632 *
633 * Creates a temporary image list that contains one image. It will be used
634 * as a drag image.
635 *
636 * PARAMS
637 * himlTrack [I] handle to the source image list
638 * iTrack [I] index of the drag image in the source image list
639 * dxHotspot [I] X position of the hot spot of the drag image
640 * dyHotspot [I] Y position of the hot spot of the drag image
641 *
642 * RETURNS
643 * Success: TRUE
644 * Failure: FALSE
645 */
646
649 INT dxHotspot, INT dyHotspot)
650{
651 INT cx, cy;
652 POINT src, dst;
653
654 TRACE("(himlTrack=%p iTrack=%d dx=%d dy=%d)\n", himlTrack, iTrack,
655 dxHotspot, dyHotspot);
656
657 if (!is_valid(himlTrack))
658 return FALSE;
659
660 if (iTrack >= himlTrack->cCurImage)
661 return FALSE;
662
663 if (InternalDrag.himl)
664 return FALSE;
665
666 cx = himlTrack->cx;
667 cy = himlTrack->cy;
668
670 if (InternalDrag.himl == NULL) {
671 WARN("Error creating drag image list!\n");
672 return FALSE;
673 }
674
675 InternalDrag.dxHotspot = dxHotspot;
676 InternalDrag.dyHotspot = dyHotspot;
677
678 /* copy image */
680 imagelist_point_from_index(himlTrack, iTrack, &src);
681 BitBlt(InternalDrag.himl->hdcImage, dst.x, dst.y, cx, cy, himlTrack->hdcImage, src.x, src.y,
682 SRCCOPY);
683 BitBlt(InternalDrag.himl->hdcMask, dst.x, dst.y, cx, cy, himlTrack->hdcMask, src.x, src.y,
684 SRCCOPY);
685
687
688 return TRUE;
689}
690
691
692/*************************************************************************
693 * ImageList_Copy [COMCTL32.@]
694 *
695 * Copies an image of the source image list to an image of the
696 * destination image list. Images can be copied or swapped.
697 *
698 * PARAMS
699 * himlDst [I] handle to the destination image list
700 * iDst [I] destination image index.
701 * himlSrc [I] handle to the source image list
702 * iSrc [I] source image index
703 * uFlags [I] flags for the copy operation
704 *
705 * RETURNS
706 * Success: TRUE
707 * Failure: FALSE
708 *
709 * NOTES
710 * Copying from one image list to another is possible. The original
711 * implementation just copies or swaps within one image list.
712 * Could this feature become a bug??? ;-)
713 */
714
716ImageList_Copy (HIMAGELIST himlDst, INT iDst, HIMAGELIST himlSrc,
717 INT iSrc, UINT uFlags)
718{
719 POINT ptSrc, ptDst;
720
721 TRACE("himlDst=%p iDst=%d himlSrc=%p iSrc=%d\n", himlDst, iDst, himlSrc, iSrc);
722
723 if (!is_valid(himlSrc) || !is_valid(himlDst))
724 return FALSE;
725 if ((iDst < 0) || (iDst >= himlDst->cCurImage))
726 return FALSE;
727 if ((iSrc < 0) || (iSrc >= himlSrc->cCurImage))
728 return FALSE;
729
730 imagelist_point_from_index( himlDst, iDst, &ptDst );
731 imagelist_point_from_index( himlSrc, iSrc, &ptSrc );
732
733 if (uFlags & ILCF_SWAP) {
734 /* swap */
735 HDC hdcBmp;
736 HBITMAP hbmTempImage, hbmTempMask;
737
738 hdcBmp = CreateCompatibleDC (0);
739
740 /* create temporary bitmaps */
741 hbmTempImage = CreateBitmap (himlSrc->cx, himlSrc->cy, 1,
742 himlSrc->uBitsPixel, NULL);
743 hbmTempMask = CreateBitmap (himlSrc->cx, himlSrc->cy, 1,
744 1, NULL);
745
746 /* copy (and stretch) destination to temporary bitmaps.(save) */
747 /* image */
748 SelectObject (hdcBmp, hbmTempImage);
749 StretchBlt (hdcBmp, 0, 0, himlSrc->cx, himlSrc->cy,
750 himlDst->hdcImage, ptDst.x, ptDst.y, himlDst->cx, himlDst->cy,
751 SRCCOPY);
752 /* mask */
753 SelectObject (hdcBmp, hbmTempMask);
754 StretchBlt (hdcBmp, 0, 0, himlSrc->cx, himlSrc->cy,
755 himlDst->hdcMask, ptDst.x, ptDst.y, himlDst->cx, himlDst->cy,
756 SRCCOPY);
757
758 /* copy (and stretch) source to destination */
759 /* image */
760 StretchBlt (himlDst->hdcImage, ptDst.x, ptDst.y, himlDst->cx, himlDst->cy,
761 himlSrc->hdcImage, ptSrc.x, ptSrc.y, himlSrc->cx, himlSrc->cy,
762 SRCCOPY);
763 /* mask */
764 StretchBlt (himlDst->hdcMask, ptDst.x, ptDst.y, himlDst->cx, himlDst->cy,
765 himlSrc->hdcMask, ptSrc.x, ptSrc.y, himlSrc->cx, himlSrc->cy,
766 SRCCOPY);
767
768 /* copy (without stretching) temporary bitmaps to source (restore) */
769 /* mask */
770 BitBlt (himlSrc->hdcMask, ptSrc.x, ptSrc.y, himlSrc->cx, himlSrc->cy,
771 hdcBmp, 0, 0, SRCCOPY);
772
773 /* image */
774 BitBlt (himlSrc->hdcImage, ptSrc.x, ptSrc.y, himlSrc->cx, himlSrc->cy,
775 hdcBmp, 0, 0, SRCCOPY);
776 /* delete temporary bitmaps */
777 DeleteObject (hbmTempMask);
778 DeleteObject (hbmTempImage);
779 DeleteDC(hdcBmp);
780 }
781 else {
782 /* copy image */
783 StretchBlt (himlDst->hdcImage, ptDst.x, ptDst.y, himlDst->cx, himlDst->cy,
784 himlSrc->hdcImage, ptSrc.x, ptSrc.y, himlSrc->cx, himlSrc->cy,
785 SRCCOPY);
786
787 /* copy mask */
788 StretchBlt (himlDst->hdcMask, ptDst.x, ptDst.y, himlDst->cx, himlDst->cy,
789 himlSrc->hdcMask, ptSrc.x, ptSrc.y, himlSrc->cx, himlSrc->cy,
790 SRCCOPY);
791 }
792
793 return TRUE;
794}
795
796
797/*************************************************************************
798 * ImageList_Create [COMCTL32.@]
799 *
800 * Creates a new image list.
801 *
802 * PARAMS
803 * cx [I] image height
804 * cy [I] image width
805 * flags [I] creation flags
806 * cInitial [I] initial number of images in the image list
807 * cGrow [I] number of images by which image list grows
808 *
809 * RETURNS
810 * Success: Handle to the created image list
811 * Failure: NULL
812 */
815 INT cInitial, INT cGrow)
816{
818 INT nCount;
819 HBITMAP hbmTemp;
820 UINT ilc = (flags & 0xFE);
821 static const WORD aBitBlend25[] =
822 {0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00};
823
824 static const WORD aBitBlend50[] =
825 {0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA};
826
827 TRACE("(%d %d 0x%x %d %d)\n", cx, cy, flags, cInitial, cGrow);
828
829 if (cx < 0 || cy < 0) return NULL;
830 if (!((flags&ILC_COLORDDB) == ILC_COLORDDB) && (cx == 0 || cy == 0)) return NULL;
831
832 /* Create the IImageList interface for the image list */
833 if (FAILED(ImageListImpl_CreateInstance(NULL, &IID_IImageList, (void **)&himl)))
834 return NULL;
835
836 cGrow = (WORD)((max( cGrow, 1 ) + 3) & ~3);
837
838 if (cGrow > 256)
839 {
840 /* Windows doesn't limit the size here, but X11 doesn't let us allocate such huge bitmaps */
841 WARN( "grow %d too large, limiting to 256\n", cGrow );
842 cGrow = 256;
843 }
844
845 himl->cx = cx;
846 himl->cy = cy;
847 himl->flags = flags;
848 himl->cMaxImage = cInitial + 1;
849 himl->cInitial = cInitial;
850 himl->cGrow = cGrow;
854#ifdef __REACTOS__
855 himl->usVersion = 0;
856#endif
857
858 /* initialize overlay mask indices */
859 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
860 himl->nOvlIdx[nCount] = -1;
861
862 /* Create Image & Mask DCs */
864 if (!himl->hdcImage)
865 goto cleanup;
866 if (himl->flags & ILC_MASK){
868 if (!himl->hdcMask)
869 goto cleanup;
870 }
871
872 /* Default to ILC_COLOR4 if none of the ILC_COLOR* flags are specified */
873 if (ilc == ILC_COLOR)
874 {
875 ilc = ILC_COLOR4;
877 }
878
879 if (ilc >= ILC_COLOR4 && ilc <= ILC_COLOR32)
880 himl->uBitsPixel = ilc;
881 else
883
884 if (himl->cMaxImage > 0) {
887 } else
888 himl->hbmImage = 0;
889
890 if ((himl->cMaxImage > 0) && (himl->flags & ILC_MASK)) {
891 SIZE sz;
892
894 himl->hbmMask = CreateBitmap (sz.cx, sz.cy, 1, 1, NULL);
895 if (himl->hbmMask == 0) {
896 ERR("Error creating mask bitmap!\n");
897 goto cleanup;
898 }
900 }
901 else
902 himl->hbmMask = 0;
903
904 if (ilc == ILC_COLOR32)
905 himl->has_alpha = heap_alloc_zero( himl->cMaxImage );
906 else
908
909 /* create blending brushes */
910 hbmTemp = CreateBitmap (8, 8, 1, 1, aBitBlend25);
912 DeleteObject (hbmTemp);
913
914 hbmTemp = CreateBitmap (8, 8, 1, 1, aBitBlend50);
916 DeleteObject (hbmTemp);
917
918 TRACE("created imagelist %p\n", himl);
919 return himl;
920
921cleanup:
923 return NULL;
924}
925
926
927/*************************************************************************
928 * ImageList_Destroy [COMCTL32.@]
929 *
930 * Destroys an image list.
931 *
932 * PARAMS
933 * himl [I] handle to image list
934 *
935 * RETURNS
936 * Success: TRUE
937 * Failure: FALSE
938 */
939
942{
943 if (!is_valid(himl))
944 return FALSE;
945
946#ifdef __REACTOS__
947 if ((himl->flags & ILC_SYSTEM) && WinVerMajor() >= 6)
948 return FALSE;
949#endif
950
951 IImageList_Release((IImageList *) himl);
952 return TRUE;
953}
954
955
956/*************************************************************************
957 * ImageList_DragEnter [COMCTL32.@]
958 *
959 * Locks window update and displays the drag image at the given position.
960 *
961 * PARAMS
962 * hwndLock [I] handle of the window that owns the drag image.
963 * x [I] X position of the drag image.
964 * y [I] Y position of the drag image.
965 *
966 * RETURNS
967 * Success: TRUE
968 * Failure: FALSE
969 *
970 * NOTES
971 * The position of the drag image is relative to the window, not
972 * the client area.
973 */
974
977{
978 TRACE("(hwnd=%p x=%d y=%d)\n", hwndLock, x, y);
979
981 return FALSE;
982
983 if (hwndLock)
984 InternalDrag.hwnd = hwndLock;
985 else
987
988 InternalDrag.x = x;
989 InternalDrag.y = y;
990
991 /* draw the drag image and save the background */
993}
994
995
996/*************************************************************************
997 * ImageList_DragLeave [COMCTL32.@]
998 *
999 * Unlocks window update and hides the drag image.
1000 *
1001 * PARAMS
1002 * hwndLock [I] handle of the window that owns the drag image.
1003 *
1004 * RETURNS
1005 * Success: TRUE
1006 * Failure: FALSE
1007 */
1008
1011{
1012 /* As we don't save drag info in the window this can lead to problems if
1013 an app does not supply the same window as DragEnter */
1014 /* if (hwndLock)
1015 InternalDrag.hwnd = hwndLock;
1016 else
1017 InternalDrag.hwnd = GetDesktopWindow (); */
1018 if(!hwndLock)
1019 hwndLock = GetDesktopWindow();
1020 if(InternalDrag.hwnd != hwndLock)
1021 FIXME("DragLeave hWnd != DragEnter hWnd\n");
1022
1024
1025 return TRUE;
1026}
1027
1028
1029/*************************************************************************
1030 * ImageList_InternalDragDraw [Internal]
1031 *
1032 * Draws the drag image.
1033 *
1034 * PARAMS
1035 * hdc [I] device context to draw into.
1036 * x [I] X position of the drag image.
1037 * y [I] Y position of the drag image.
1038 *
1039 * RETURNS
1040 * Success: TRUE
1041 * Failure: FALSE
1042 *
1043 * NOTES
1044 * The position of the drag image is relative to the window, not
1045 * the client area.
1046 *
1047 */
1048
1049static inline void
1051{
1052 IMAGELISTDRAWPARAMS imldp;
1053
1054 ZeroMemory (&imldp, sizeof(imldp));
1055 imldp.cbSize = sizeof(imldp);
1056 imldp.himl = InternalDrag.himl;
1057 imldp.i = 0;
1058 imldp.hdcDst = hdc;
1059 imldp.x = x;
1060 imldp.y = y;
1061 imldp.rgbBk = CLR_DEFAULT;
1062 imldp.rgbFg = CLR_DEFAULT;
1063 imldp.fStyle = ILD_NORMAL;
1064 imldp.fState = ILS_ALPHA;
1065 imldp.Frame = 192;
1066 ImageList_DrawIndirect (&imldp);
1067}
1068
1069/*************************************************************************
1070 * ImageList_DragMove [COMCTL32.@]
1071 *
1072 * Moves the drag image.
1073 *
1074 * PARAMS
1075 * x [I] X position of the drag image.
1076 * y [I] Y position of the drag image.
1077 *
1078 * RETURNS
1079 * Success: TRUE
1080 * Failure: FALSE
1081 *
1082 * NOTES
1083 * The position of the drag image is relative to the window, not
1084 * the client area.
1085 */
1086
1089{
1090 TRACE("(x=%d y=%d)\n", x, y);
1091
1093 return FALSE;
1094
1095 /* draw/update the drag image */
1096 if (InternalDrag.bShow) {
1097 HDC hdcDrag;
1098 HDC hdcOffScreen;
1099 HDC hdcBg;
1100 HBITMAP hbmOffScreen;
1101 INT origNewX, origNewY;
1102 INT origOldX, origOldY;
1103 INT origRegX, origRegY;
1104 INT sizeRegX, sizeRegY;
1105
1106
1107 /* calculate the update region */
1108 origNewX = x - InternalDrag.dxHotspot;
1109 origNewY = y - InternalDrag.dyHotspot;
1110 origOldX = InternalDrag.x - InternalDrag.dxHotspot;
1111 origOldY = InternalDrag.y - InternalDrag.dyHotspot;
1112 origRegX = min(origNewX, origOldX);
1113 origRegY = min(origNewY, origOldY);
1114 sizeRegX = InternalDrag.himl->cx + abs(x - InternalDrag.x);
1115 sizeRegY = InternalDrag.himl->cy + abs(y - InternalDrag.y);
1116
1117 hdcDrag = GetDCEx(InternalDrag.hwnd, 0,
1119 hdcOffScreen = CreateCompatibleDC(hdcDrag);
1120 hdcBg = CreateCompatibleDC(hdcDrag);
1121
1122 hbmOffScreen = CreateCompatibleBitmap(hdcDrag, sizeRegX, sizeRegY);
1123 SelectObject(hdcOffScreen, hbmOffScreen);
1125
1126 /* get the actual background of the update region */
1127 BitBlt(hdcOffScreen, 0, 0, sizeRegX, sizeRegY, hdcDrag,
1128 origRegX, origRegY, SRCCOPY);
1129 /* erase the old image */
1130 BitBlt(hdcOffScreen, origOldX - origRegX, origOldY - origRegY,
1131 InternalDrag.himl->cx, InternalDrag.himl->cy, hdcBg, 0, 0,
1132 SRCCOPY);
1133 /* save the background */
1134 BitBlt(hdcBg, 0, 0, InternalDrag.himl->cx, InternalDrag.himl->cy,
1135 hdcOffScreen, origNewX - origRegX, origNewY - origRegY, SRCCOPY);
1136 /* draw the image */
1137 ImageList_InternalDragDraw(hdcOffScreen, origNewX - origRegX,
1138 origNewY - origRegY);
1139 /* draw the update region to the screen */
1140 BitBlt(hdcDrag, origRegX, origRegY, sizeRegX, sizeRegY,
1141 hdcOffScreen, 0, 0, SRCCOPY);
1142
1143 DeleteDC(hdcBg);
1144 DeleteDC(hdcOffScreen);
1145 DeleteObject(hbmOffScreen);
1146 ReleaseDC(InternalDrag.hwnd, hdcDrag);
1147 }
1148
1149 /* update the image position */
1150 InternalDrag.x = x;
1151 InternalDrag.y = y;
1152
1153 return TRUE;
1154}
1155
1156
1157/*************************************************************************
1158 * ImageList_DragShowNolock [COMCTL32.@]
1159 *
1160 * Shows or hides the drag image.
1161 *
1162 * PARAMS
1163 * bShow [I] TRUE shows the drag image, FALSE hides it.
1164 *
1165 * RETURNS
1166 * Success: TRUE
1167 * Failure: FALSE
1168 */
1169
1172{
1173 HDC hdcDrag;
1174 HDC hdcBg;
1175 INT x, y;
1176
1178 return FALSE;
1179
1180 TRACE("bShow=0x%X!\n", bShow);
1181
1182 /* DragImage is already visible/hidden */
1183 if ((InternalDrag.bShow && bShow) || (!InternalDrag.bShow && !bShow)) {
1184 return FALSE;
1185 }
1186
1187 /* position of the origin of the DragImage */
1190
1191 hdcDrag = GetDCEx (InternalDrag.hwnd, 0,
1193 if (!hdcDrag) {
1194 return FALSE;
1195 }
1196
1197 hdcBg = CreateCompatibleDC(hdcDrag);
1198 if (!InternalDrag.hbmBg) {
1201 }
1203
1204 if (bShow) {
1205 /* save the background */
1206 BitBlt(hdcBg, 0, 0, InternalDrag.himl->cx, InternalDrag.himl->cy,
1207 hdcDrag, x, y, SRCCOPY);
1208 /* show the image */
1209 ImageList_InternalDragDraw(hdcDrag, x, y);
1210 } else {
1211 /* hide the image */
1213 hdcBg, 0, 0, SRCCOPY);
1214 }
1215
1217
1218 DeleteDC(hdcBg);
1219 ReleaseDC (InternalDrag.hwnd, hdcDrag);
1220 return TRUE;
1221}
1222
1223
1224/*************************************************************************
1225 * ImageList_Draw [COMCTL32.@]
1226 *
1227 * Draws an image.
1228 *
1229 * PARAMS
1230 * himl [I] handle to image list
1231 * i [I] image index
1232 * hdc [I] handle to device context
1233 * x [I] x position
1234 * y [I] y position
1235 * fStyle [I] drawing flags
1236 *
1237 * RETURNS
1238 * Success: TRUE
1239 * Failure: FALSE
1240 *
1241 * SEE
1242 * ImageList_DrawEx.
1243 */
1244
1247{
1248 return ImageList_DrawEx (himl, i, hdc, x, y, 0, 0,
1249 CLR_DEFAULT, CLR_DEFAULT, fStyle);
1250}
1251
1252
1253/*************************************************************************
1254 * ImageList_DrawEx [COMCTL32.@]
1255 *
1256 * Draws an image and allows using extended drawing features.
1257 *
1258 * PARAMS
1259 * himl [I] handle to image list
1260 * i [I] image index
1261 * hdc [I] handle to device context
1262 * x [I] X position
1263 * y [I] Y position
1264 * dx [I] X offset
1265 * dy [I] Y offset
1266 * rgbBk [I] background color
1267 * rgbFg [I] foreground color
1268 * fStyle [I] drawing flags
1269 *
1270 * RETURNS
1271 * Success: TRUE
1272 * Failure: FALSE
1273 *
1274 * NOTES
1275 * Calls ImageList_DrawIndirect.
1276 *
1277 * SEE
1278 * ImageList_DrawIndirect.
1279 */
1280
1283 INT dx, INT dy, COLORREF rgbBk, COLORREF rgbFg,
1284 UINT fStyle)
1285{
1286 IMAGELISTDRAWPARAMS imldp;
1287
1288 ZeroMemory (&imldp, sizeof(imldp));
1289 imldp.cbSize = sizeof(imldp);
1290 imldp.himl = himl;
1291 imldp.i = i;
1292 imldp.hdcDst = hdc;
1293 imldp.x = x;
1294 imldp.y = y;
1295 imldp.cx = dx;
1296 imldp.cy = dy;
1297 imldp.rgbBk = rgbBk;
1298 imldp.rgbFg = rgbFg;
1299 imldp.fStyle = fStyle;
1300
1301 return ImageList_DrawIndirect (&imldp);
1302}
1303
1304#ifdef __REACTOS__
1305static BOOL alpha_blend_image( HIMAGELIST himl, HDC srce_dc, HDC srce_dcMask, HDC dest_dc, int dest_x, int dest_y,
1306#else
1307static BOOL alpha_blend_image( HIMAGELIST himl, HDC dest_dc, int dest_x, int dest_y,
1308#endif
1309 int src_x, int src_y, int cx, int cy, BLENDFUNCTION func,
1310 UINT style, COLORREF blend_col )
1311{
1312 BOOL ret = FALSE;
1313 HDC hdc;
1314 HBITMAP bmp = 0, mask = 0;
1316 void *bits, *mask_bits;
1317 unsigned int *ptr;
1318 int i, j;
1319
1320 if (!(hdc = CreateCompatibleDC( 0 ))) return FALSE;
1321 if (!(info = heap_alloc( FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) goto done;
1322 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1323 info->bmiHeader.biWidth = cx;
1324 info->bmiHeader.biHeight = cy;
1325 info->bmiHeader.biPlanes = 1;
1326 info->bmiHeader.biBitCount = 32;
1327 info->bmiHeader.biCompression = BI_RGB;
1328 info->bmiHeader.biSizeImage = cx * cy * 4;
1329 info->bmiHeader.biXPelsPerMeter = 0;
1330 info->bmiHeader.biYPelsPerMeter = 0;
1331 info->bmiHeader.biClrUsed = 0;
1332 info->bmiHeader.biClrImportant = 0;
1333#ifdef __REACTOS__
1334 if (!(bmp = CreateDIBSection( srce_dc, info, DIB_RGB_COLORS, &bits, 0, 0 ))) goto done;
1335#else
1336 if (!(bmp = CreateDIBSection( himl->hdcImage, info, DIB_RGB_COLORS, &bits, 0, 0 ))) goto done;
1337#endif
1338 SelectObject( hdc, bmp );
1339#ifdef __REACTOS__
1340 if (!BitBlt(hdc, 0, 0, cx, cy, srce_dc, src_x, src_y, SRCCOPY))
1341 {
1342 TRACE("BitBlt failed\n");
1343 goto done;
1344 }
1345#else
1346 BitBlt( hdc, 0, 0, cx, cy, himl->hdcImage, src_x, src_y, SRCCOPY );
1347#endif
1348
1349 if (blend_col != CLR_NONE)
1350 {
1351 BYTE r = GetRValue( blend_col );
1352 BYTE g = GetGValue( blend_col );
1353 BYTE b = GetBValue( blend_col );
1354
1355 if (style & ILD_BLEND25)
1356 {
1357 for (i = 0, ptr = bits; i < cx * cy; i++, ptr++)
1358 *ptr = ((*ptr & 0xff000000) |
1359 ((((*ptr & 0x00ff0000) * 3 + (r << 16)) / 4) & 0x00ff0000) |
1360 ((((*ptr & 0x0000ff00) * 3 + (g << 8)) / 4) & 0x0000ff00) |
1361 ((((*ptr & 0x000000ff) * 3 + (b << 0)) / 4) & 0x000000ff));
1362 }
1363 else if (style & ILD_BLEND50)
1364 {
1365 for (i = 0, ptr = bits; i < cx * cy; i++, ptr++)
1366 *ptr = ((*ptr & 0xff000000) |
1367 ((((*ptr & 0x00ff0000) + (r << 16)) / 2) & 0x00ff0000) |
1368 ((((*ptr & 0x0000ff00) + (g << 8)) / 2) & 0x0000ff00) |
1369 ((((*ptr & 0x000000ff) + (b << 0)) / 2) & 0x000000ff));
1370 }
1371 }
1372
1373 if (himl->has_alpha) /* we already have an alpha channel in this case */
1374 {
1375 /* pre-multiply by the alpha channel */
1376 for (i = 0, ptr = bits; i < cx * cy; i++, ptr++)
1377 {
1378 DWORD alpha = *ptr >> 24;
1379 *ptr = ((*ptr & 0xff000000) |
1380 (((*ptr & 0x00ff0000) * alpha / 255) & 0x00ff0000) |
1381 (((*ptr & 0x0000ff00) * alpha / 255) & 0x0000ff00) |
1382 (((*ptr & 0x000000ff) * alpha / 255)));
1383 }
1384 }
1385 else if (himl->hbmMask)
1386 {
1387 unsigned int width_bytes = (cx + 31) / 32 * 4;
1388 /* generate alpha channel from the mask */
1389 info->bmiHeader.biBitCount = 1;
1390 info->bmiHeader.biSizeImage = width_bytes * cy;
1391 info->bmiColors[0].rgbRed = 0;
1392 info->bmiColors[0].rgbGreen = 0;
1393 info->bmiColors[0].rgbBlue = 0;
1394 info->bmiColors[0].rgbReserved = 0;
1395 info->bmiColors[1].rgbRed = 0xff;
1396 info->bmiColors[1].rgbGreen = 0xff;
1397 info->bmiColors[1].rgbBlue = 0xff;
1398 info->bmiColors[1].rgbReserved = 0;
1399 if (!(mask = CreateDIBSection( srce_dcMask, info, DIB_RGB_COLORS, &mask_bits, 0, 0)))
1400 {
1401 TRACE("CreateDIBSection failed %i\n", GetLastError());
1402 goto done;
1403 }
1404 if (SelectObject(hdc, mask) == NULL)
1405 {
1406 TRACE("SelectObject failed %i\n", GetLastError());
1408 goto done;
1409 }
1410 if (!BitBlt( hdc, 0, 0, cx, cy, srce_dcMask, src_x, src_y, SRCCOPY))
1411 {
1412 TRACE("BitBlt failed %i\n", GetLastError());
1414 goto done;
1415 }
1416 if (SelectObject( hdc, bmp) == NULL)
1417 {
1418 TRACE("SelectObject failed %i\n", GetLastError());
1419 goto done;
1420 }
1421 for (i = 0, ptr = bits; i < cy; i++)
1422 for (j = 0; j < cx; j++, ptr++)
1423 if ((((BYTE *)mask_bits)[i * width_bytes + j / 8] << (j % 8)) & 0x80) *ptr = 0;
1424 else *ptr |= 0xff000000;
1425 }
1426
1427 ret = GdiAlphaBlend( dest_dc, dest_x, dest_y, cx, cy, hdc, 0, 0, cx, cy, func );
1428
1429done:
1430 DeleteDC( hdc );
1431 if (bmp) DeleteObject( bmp );
1432 if (mask) DeleteObject( mask );
1433 heap_free( info );
1434 return ret;
1435}
1436
1437#ifdef __REACTOS__
1438BOOL saturate_image(HIMAGELIST himl, HDC dest_dc, int dest_x, int dest_y,
1439 int src_x, int src_y, int cx, int cy, COLORREF rgbFg,
1440 HDC *hdcImageListDC, HDC *hdcMaskListDC)
1441{
1442 HDC hdc = NULL, hdcMask = NULL;
1443 HBITMAP bmp = 0, bmpMask = 0;
1445
1446 unsigned int *ptr;
1447 void *bits;
1448 int i;
1449
1450 /* create a dc and its device independent bitmap for doing the work,
1451 shamelessly copied from the alpha-blending function above */
1452 if (!(hdc = CreateCompatibleDC( 0 ))) return FALSE;
1453 if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) goto done;
1454 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1455 info->bmiHeader.biWidth = cx;
1456 info->bmiHeader.biHeight = cy;
1457 info->bmiHeader.biPlanes = 1;
1458 info->bmiHeader.biBitCount = 32;
1459 info->bmiHeader.biCompression = BI_RGB;
1460 info->bmiHeader.biSizeImage = cx * cy * 4;
1461 info->bmiHeader.biXPelsPerMeter = 0;
1462 info->bmiHeader.biYPelsPerMeter = 0;
1463 info->bmiHeader.biClrUsed = 0;
1464 info->bmiHeader.biClrImportant = 0;
1465 if (!(bmp = CreateDIBSection(himl->hdcImage, info, DIB_RGB_COLORS, &bits, 0, 0 ))) goto done;
1466
1467 /* bind both surfaces */
1468 if (SelectObject(hdc, bmp) == NULL)
1469 {
1470 TRACE("SelectObject failed\n");
1471 goto done;
1472 }
1473
1474 /* copy into our dc the section that covers just the icon we we're asked for */
1475 if (!BitBlt(hdc, 0, 0, cx, cy, himl->hdcImage, src_x, src_y, SRCCOPY))
1476 {
1477 TRACE("BitBlt failed!\n");
1478 goto done;
1479 }
1480
1481 /* loop every pixel of the bitmap */
1482 for (i = 0, ptr = bits; i < cx * cy; i++, ptr++)
1483 {
1484 COLORREF orig_color = *ptr;
1485
1486 /* calculate the effective luminance using the constants from here, adapted to the human eye:
1487 <http://bobpowell.net/grayscale.aspx> */
1488 float mixed_color = (GetRValue(orig_color) * .30 +
1489 GetGValue(orig_color) * .59 +
1490 GetBValue(orig_color) * .11);
1491
1492 *ptr = RGBA(mixed_color, mixed_color, mixed_color, GetAValue(orig_color));
1493 }
1494
1495 if (himl->hdcMask)
1496 {
1497 hdcMask = CreateCompatibleDC(NULL);
1498 bmpMask = CreateCompatibleBitmap(hdcMask, cx, cy);
1499
1500 SelectObject(hdcMask, bmpMask);
1501
1502 if (!BitBlt(hdcMask, 0, 0, cx, cy, himl->hdcMask, src_x, src_y, SRCCOPY))
1503 {
1504 ERR("BitBlt failed %i\n", GetLastError());
1505 DeleteDC(hdcMask);
1506 hdcMask = NULL;
1507 goto done;
1508 }
1509 TRACE("mask ok\n");
1510 }
1511
1512done:
1513
1514 if (bmp)
1516 if (bmpMask)
1517 DeleteObject(bmpMask);
1518
1519 if (info)
1521
1522 /* return the handle to our desaturated dc, that will substitute its original counterpart in the next calls */
1523 *hdcMaskListDC = hdcMask;
1524 *hdcImageListDC = hdc;
1525 return (hdc != NULL);
1526}
1527#endif /* __REACTOS__ */
1528
1529/*************************************************************************
1530 * ImageList_DrawIndirect [COMCTL32.@]
1531 *
1532 * Draws an image using various parameters specified in pimldp.
1533 *
1534 * PARAMS
1535 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
1536 *
1537 * RETURNS
1538 * Success: TRUE
1539 * Failure: FALSE
1540 */
1541
1544{
1545 INT cx, cy, nOvlIdx;
1546 DWORD fState, dwRop;
1547 UINT fStyle;
1548 COLORREF oldImageBk, oldImageFg;
1549 HDC hImageDC, hImageListDC, hMaskListDC;
1550 HBITMAP hImageBmp, hOldImageBmp, hBlendMaskBmp;
1551 BOOL bIsTransparent, bBlend, bResult = FALSE, bMask;
1553 HBRUSH hOldBrush;
1554 POINT pt;
1555 BOOL has_alpha;
1556#ifdef __REACTOS__
1557 HDC hdcSaturated = NULL, hdcSaturatedMask = NULL;
1558#endif
1559
1560 if (!pimldp || !(himl = pimldp->himl)) return FALSE;
1561 if (!is_valid(himl)) return FALSE;
1562 if ((pimldp->i < 0) || (pimldp->i >= himl->cCurImage)) return FALSE;
1563
1564 imagelist_point_from_index( himl, pimldp->i, &pt );
1565 pt.x += pimldp->xBitmap;
1566 pt.y += pimldp->yBitmap;
1567
1568 fState = pimldp->cbSize < sizeof(IMAGELISTDRAWPARAMS) ? ILS_NORMAL : pimldp->fState;
1569 fStyle = pimldp->fStyle & ~ILD_OVERLAYMASK;
1570 cx = (pimldp->cx == 0) ? himl->cx : pimldp->cx;
1571 cy = (pimldp->cy == 0) ? himl->cy : pimldp->cy;
1572
1573 bIsTransparent = (fStyle & ILD_TRANSPARENT);
1574 if( pimldp->rgbBk == CLR_NONE )
1575 bIsTransparent = TRUE;
1576 if( ( pimldp->rgbBk == CLR_DEFAULT ) && ( himl->clrBk == CLR_NONE ) )
1577 bIsTransparent = TRUE;
1578 bMask = (himl->flags & ILC_MASK) && (fStyle & ILD_MASK) ;
1579 bBlend = (fStyle & (ILD_BLEND25 | ILD_BLEND50) ) && !bMask;
1580
1581 TRACE("himl(%p) hbmMask(%p) iImage(%d) x(%d) y(%d) cx(%d) cy(%d)\n",
1582 himl, himl->hbmMask, pimldp->i, pimldp->x, pimldp->y, cx, cy);
1583
1584 /* we will use these DCs to access the images and masks in the ImageList */
1585 hImageListDC = himl->hdcImage;
1586 hMaskListDC = himl->hdcMask;
1587
1588 /* these will accumulate the image and mask for the image we're drawing */
1589 hImageDC = CreateCompatibleDC( pimldp->hdcDst );
1590 hImageBmp = CreateCompatibleBitmap( pimldp->hdcDst, cx, cy );
1591 hBlendMaskBmp = bBlend ? CreateBitmap(cx, cy, 1, 1, NULL) : 0;
1592
1593 /* Create a compatible DC. */
1594 if (!hImageListDC || !hImageDC || !hImageBmp ||
1595 (bBlend && !hBlendMaskBmp) || (himl->hbmMask && !hMaskListDC))
1596 goto cleanup;
1597
1598 hOldImageBmp = SelectObject(hImageDC, hImageBmp);
1599
1600 /*
1601 * To obtain a transparent look, background color should be set
1602 * to white and foreground color to black when blitting the
1603 * monochrome mask.
1604 */
1605 oldImageFg = SetTextColor( hImageDC, RGB( 0, 0, 0 ) );
1606 oldImageBk = SetBkColor( hImageDC, RGB( 0xff, 0xff, 0xff ) );
1607
1608#ifdef __REACTOS__
1609 /*
1610 * If the ILS_SATURATE bit is enabled we should multiply the
1611 * RGB colors of the original image by the contents of rgbFg.
1612 */
1613 if (fState & ILS_SATURATE)
1614 {
1615 if (saturate_image(himl, pimldp->hdcDst, pimldp->x, pimldp->y,
1616 pt.x, pt.y, cx, cy, pimldp->rgbFg,
1617 &hdcSaturated, &hdcSaturatedMask))
1618 {
1619 hImageListDC = hdcSaturated;
1620 hMaskListDC = hdcSaturatedMask;
1621 /* shitty way of getting subroutines to blit at the right place (top left corner),
1622 as our modified imagelist only contains a single image for performance reasons */
1623 pt.x = 0;
1624 pt.y = 0;
1625 }
1626 }
1627#endif
1628
1629 has_alpha = (himl->has_alpha && himl->has_alpha[pimldp->i]);
1630 if (!bMask && (has_alpha || (fState & ILS_ALPHA)))
1631 {
1632 COLORREF colour, blend_col = CLR_NONE;
1634
1635 if (bBlend)
1636 {
1637 blend_col = pimldp->rgbFg;
1638 if (blend_col == CLR_DEFAULT) blend_col = GetSysColor( COLOR_HIGHLIGHT );
1639 else if (blend_col == CLR_NONE) blend_col = GetTextColor( pimldp->hdcDst );
1640 }
1641
1642 func.BlendOp = AC_SRC_OVER;
1643 func.BlendFlags = 0;
1644 func.SourceConstantAlpha = (fState & ILS_ALPHA) ? pimldp->Frame : 255;
1645 func.AlphaFormat = AC_SRC_ALPHA;
1646
1647 if (bIsTransparent)
1648 {
1649#ifdef __REACTOS__
1650 bResult = alpha_blend_image( himl, hImageListDC, hMaskListDC, pimldp->hdcDst, pimldp->x, pimldp->y,
1651#else
1652 bResult = alpha_blend_image( himl, pimldp->hdcDst, pimldp->x, pimldp->y,
1653#endif
1654 pt.x, pt.y, cx, cy, func, fStyle, blend_col );
1655 goto end;
1656 }
1657 colour = pimldp->rgbBk;
1658 if (colour == CLR_DEFAULT) colour = himl->clrBk;
1659 if (colour == CLR_NONE) colour = GetBkColor( pimldp->hdcDst );
1660
1661 hOldBrush = SelectObject (hImageDC, CreateSolidBrush (colour));
1662 PatBlt( hImageDC, 0, 0, cx, cy, PATCOPY );
1663#ifdef __REACTOS__
1664 alpha_blend_image( himl, hImageListDC, hMaskListDC, hImageDC, 0, 0, pt.x, pt.y, cx, cy, func, fStyle, blend_col );
1665#else
1666 alpha_blend_image( himl, hImageDC, 0, 0, pt.x, pt.y, cx, cy, func, fStyle, blend_col );
1667#endif
1668 DeleteObject (SelectObject (hImageDC, hOldBrush));
1669 bResult = BitBlt( pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy, hImageDC, 0, 0, SRCCOPY );
1670 goto end;
1671 }
1672
1673 /*
1674 * Draw the initial image
1675 */
1676 if( bMask ) {
1677 if (himl->hbmMask) {
1678 hOldBrush = SelectObject (hImageDC, CreateSolidBrush (GetTextColor(pimldp->hdcDst)));
1679 PatBlt( hImageDC, 0, 0, cx, cy, PATCOPY );
1680 BitBlt(hImageDC, 0, 0, cx, cy, hMaskListDC, pt.x, pt.y, SRCPAINT);
1681 DeleteObject (SelectObject (hImageDC, hOldBrush));
1682 if( bIsTransparent )
1683 {
1684 BitBlt ( pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy, hImageDC, 0, 0, SRCAND);
1685 bResult = TRUE;
1686 goto end;
1687 }
1688 } else {
1689 hOldBrush = SelectObject (hImageDC, GetStockObject(BLACK_BRUSH));
1690 PatBlt( hImageDC, 0, 0, cx, cy, PATCOPY);
1691 SelectObject(hImageDC, hOldBrush);
1692 }
1693 } else {
1694 /* blend the image with the needed solid background */
1695 COLORREF colour = RGB(0,0,0);
1696
1697 if( !bIsTransparent )
1698 {
1699 colour = pimldp->rgbBk;
1700 if( colour == CLR_DEFAULT )
1701 colour = himl->clrBk;
1702 if( colour == CLR_NONE )
1703 colour = GetBkColor(pimldp->hdcDst);
1704 }
1705
1706 hOldBrush = SelectObject (hImageDC, CreateSolidBrush (colour));
1707 PatBlt( hImageDC, 0, 0, cx, cy, PATCOPY );
1708 if (himl->hbmMask)
1709 {
1710 BitBlt( hImageDC, 0, 0, cx, cy, hMaskListDC, pt.x, pt.y, SRCAND );
1711 BitBlt( hImageDC, 0, 0, cx, cy, hImageListDC, pt.x, pt.y, SRCPAINT );
1712 }
1713 else
1714 BitBlt( hImageDC, 0, 0, cx, cy, hImageListDC, pt.x, pt.y, SRCCOPY);
1715 DeleteObject (SelectObject (hImageDC, hOldBrush));
1716 }
1717
1718 /* Time for blending, if required */
1719 if (bBlend) {
1720 HBRUSH hBlendBrush;
1721 COLORREF clrBlend = pimldp->rgbFg;
1722 HDC hBlendMaskDC = hImageListDC;
1723 HBITMAP hOldBitmap;
1724
1725 /* Create the blend Mask */
1726 hOldBitmap = SelectObject(hBlendMaskDC, hBlendMaskBmp);
1727 hBlendBrush = fStyle & ILD_BLEND50 ? himl->hbrBlend50 : himl->hbrBlend25;
1728 hOldBrush = SelectObject(hBlendMaskDC, hBlendBrush);
1729 PatBlt(hBlendMaskDC, 0, 0, cx, cy, PATCOPY);
1730 SelectObject(hBlendMaskDC, hOldBrush);
1731
1732 /* Modify the blend mask if an Image Mask exist */
1733 if(himl->hbmMask) {
1734 BitBlt(hBlendMaskDC, 0, 0, cx, cy, hMaskListDC, pt.x, pt.y, 0x220326); /* NOTSRCAND */
1735 BitBlt(hBlendMaskDC, 0, 0, cx, cy, hBlendMaskDC, 0, 0, NOTSRCCOPY);
1736 }
1737
1738 /* now apply blend to the current image given the BlendMask */
1739 if (clrBlend == CLR_DEFAULT) clrBlend = GetSysColor (COLOR_HIGHLIGHT);
1740 else if (clrBlend == CLR_NONE) clrBlend = GetTextColor (pimldp->hdcDst);
1741 hOldBrush = SelectObject (hImageDC, CreateSolidBrush(clrBlend));
1742 BitBlt (hImageDC, 0, 0, cx, cy, hBlendMaskDC, 0, 0, 0xB8074A); /* PSDPxax */
1743 DeleteObject(SelectObject(hImageDC, hOldBrush));
1744 SelectObject(hBlendMaskDC, hOldBitmap);
1745 }
1746
1747 /* Now do the overlay image, if any */
1748 nOvlIdx = (pimldp->fStyle & ILD_OVERLAYMASK) >> 8;
1749 if ( (nOvlIdx >= 1) && (nOvlIdx <= MAX_OVERLAYIMAGE)) {
1750 nOvlIdx = himl->nOvlIdx[nOvlIdx - 1];
1751 if ((nOvlIdx >= 0) && (nOvlIdx < himl->cCurImage)) {
1752 POINT ptOvl;
1753 imagelist_point_from_index( himl, nOvlIdx, &ptOvl );
1754 ptOvl.x += pimldp->xBitmap;
1755 if (himl->hbmMask && !(fStyle & ILD_IMAGE))
1756 BitBlt (hImageDC, 0, 0, cx, cy, hMaskListDC, ptOvl.x, ptOvl.y, SRCAND);
1757 BitBlt (hImageDC, 0, 0, cx, cy, hImageListDC, ptOvl.x, ptOvl.y, SRCPAINT);
1758 }
1759 }
1760
1761#ifndef __REACTOS__
1762 if (fState & ILS_SATURATE) FIXME("ILS_SATURATE: unimplemented!\n");
1763#endif
1764 if (fState & ILS_GLOW) FIXME("ILS_GLOW: unimplemented!\n");
1765 if (fState & ILS_SHADOW) FIXME("ILS_SHADOW: unimplemented!\n");
1766
1767 if (fStyle & ILD_PRESERVEALPHA) FIXME("ILD_PRESERVEALPHA: unimplemented!\n");
1768 if (fStyle & ILD_SCALE) FIXME("ILD_SCALE: unimplemented!\n");
1769 if (fStyle & ILD_DPISCALE) FIXME("ILD_DPISCALE: unimplemented!\n");
1770
1771 /* now copy the image to the screen */
1772 dwRop = SRCCOPY;
1773 if (himl->hbmMask && bIsTransparent ) {
1774 COLORREF oldDstFg = SetTextColor(pimldp->hdcDst, RGB( 0, 0, 0 ) );
1775 COLORREF oldDstBk = SetBkColor(pimldp->hdcDst, RGB( 0xff, 0xff, 0xff ));
1776 BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy, hMaskListDC, pt.x, pt.y, SRCAND);
1777 SetBkColor(pimldp->hdcDst, oldDstBk);
1778 SetTextColor(pimldp->hdcDst, oldDstFg);
1779 dwRop = SRCPAINT;
1780 }
1781 if (fStyle & ILD_ROP) dwRop = pimldp->dwRop;
1782 BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy, hImageDC, 0, 0, dwRop);
1783
1784 bResult = TRUE;
1785end:
1786 /* cleanup the mess */
1787 SetBkColor(hImageDC, oldImageBk);
1788 SetTextColor(hImageDC, oldImageFg);
1789 SelectObject(hImageDC, hOldImageBmp);
1790cleanup:
1791#ifdef __REACTOS__
1792 if (hdcSaturated)
1793 DeleteDC(hdcSaturated);
1794 if (hdcSaturatedMask)
1795 DeleteDC(hdcSaturatedMask);
1796#endif
1797 DeleteObject(hBlendMaskBmp);
1798 DeleteObject(hImageBmp);
1799 DeleteDC(hImageDC);
1800
1801 return bResult;
1802}
1803
1804
1805/*************************************************************************
1806 * ImageList_Duplicate [COMCTL32.@]
1807 *
1808 * Duplicates an image list.
1809 *
1810 * PARAMS
1811 * himlSrc [I] source image list handle
1812 *
1813 * RETURNS
1814 * Success: Handle of duplicated image list.
1815 * Failure: NULL
1816 */
1817
1820{
1821 HIMAGELIST himlDst;
1822
1823 if (!is_valid(himlSrc)) {
1824 ERR("Invalid image list handle!\n");
1825 return NULL;
1826 }
1827
1828 himlDst = ImageList_Create (himlSrc->cx, himlSrc->cy, himlSrc->flags,
1829 himlSrc->cCurImage, himlSrc->cGrow);
1830
1831 if (himlDst)
1832 {
1833 SIZE sz;
1834
1835 imagelist_get_bitmap_size(himlSrc, himlSrc->cCurImage, &sz);
1836 BitBlt (himlDst->hdcImage, 0, 0, sz.cx, sz.cy,
1837 himlSrc->hdcImage, 0, 0, SRCCOPY);
1838
1839 if (himlDst->hbmMask)
1840 BitBlt (himlDst->hdcMask, 0, 0, sz.cx, sz.cy,
1841 himlSrc->hdcMask, 0, 0, SRCCOPY);
1842
1843 himlDst->cCurImage = himlSrc->cCurImage;
1844 if (himlSrc->has_alpha && himlDst->has_alpha)
1845 memcpy( himlDst->has_alpha, himlSrc->has_alpha, himlDst->cCurImage );
1846 }
1847 return himlDst;
1848}
1849
1850
1851/*************************************************************************
1852 * ImageList_EndDrag [COMCTL32.@]
1853 *
1854 * Finishes a drag operation.
1855 *
1856 * PARAMS
1857 * no Parameters
1858 *
1859 * RETURNS
1860 * Success: TRUE
1861 * Failure: FALSE
1862 */
1863
1866{
1867 /* cleanup the InternalDrag struct */
1868 InternalDrag.hwnd = 0;
1873 InternalDrag.x= 0;
1874 InternalDrag.y= 0;
1879 InternalDrag.hbmBg = 0;
1880}
1881
1882
1883/*************************************************************************
1884 * ImageList_GetBkColor [COMCTL32.@]
1885 *
1886 * Returns the background color of an image list.
1887 *
1888 * PARAMS
1889 * himl [I] Image list handle.
1890 *
1891 * RETURNS
1892 * Success: background color
1893 * Failure: CLR_NONE
1894 */
1895
1898{
1899 return himl ? himl->clrBk : CLR_NONE;
1900}
1901
1902
1903/*************************************************************************
1904 * ImageList_GetDragImage [COMCTL32.@]
1905 *
1906 * Returns the handle to the internal drag image list.
1907 *
1908 * PARAMS
1909 * ppt [O] Pointer to the drag position. Can be NULL.
1910 * pptHotspot [O] Pointer to the position of the hot spot. Can be NULL.
1911 *
1912 * RETURNS
1913 * Success: Handle of the drag image list.
1914 * Failure: NULL.
1915 */
1916
1919{
1920 if (is_valid(InternalDrag.himl)) {
1921 if (ppt) {
1922 ppt->x = InternalDrag.x;
1923 ppt->y = InternalDrag.y;
1924 }
1925 if (pptHotspot) {
1928 }
1929 return (InternalDrag.himl);
1930 }
1931
1932 return NULL;
1933}
1934
1935
1936/*************************************************************************
1937 * ImageList_GetFlags [COMCTL32.@]
1938 *
1939 * Gets the flags of the specified image list.
1940 *
1941 * PARAMS
1942 * himl [I] Handle to image list
1943 *
1944 * RETURNS
1945 * Image list flags.
1946 *
1947 * BUGS
1948 * Stub.
1949 */
1950
1953{
1954 TRACE("%p\n", himl);
1955#ifdef __REACTOS__
1956 if(!is_valid2(himl))
1957 return 0;
1958 return himl->flags & ILC_PUBLICFLAGS;
1959#else
1960 return is_valid(himl) ? himl->flags : 0;
1961#endif
1962}
1963
1964
1965/*************************************************************************
1966 * ImageList_GetIcon [COMCTL32.@]
1967 *
1968 * Creates an icon from a masked image of an image list.
1969 *
1970 * PARAMS
1971 * himl [I] handle to image list
1972 * i [I] image index
1973 * flags [I] drawing style flags
1974 *
1975 * RETURNS
1976 * Success: icon handle
1977 * Failure: NULL
1978 */
1979
1982{
1983 ICONINFO ii;
1984 HICON hIcon;
1985 HBITMAP hOldDstBitmap;
1986 HDC hdcDst;
1987 POINT pt;
1988
1989 TRACE("%p %d %d\n", himl, i, fStyle);
1990 if (!is_valid(himl) || (i < 0) || (i >= himl->cCurImage)) return NULL;
1991
1992 ii.fIcon = TRUE;
1993 ii.xHotspot = 0;
1994 ii.yHotspot = 0;
1995
1996 /* create colour bitmap */
1997 hdcDst = GetDC(0);
1999 ReleaseDC(0, hdcDst);
2000
2002
2004
2005 /* draw mask*/
2006 ii.hbmMask = CreateBitmap (himl->cx, himl->cy, 1, 1, NULL);
2007 hOldDstBitmap = SelectObject (hdcDst, ii.hbmMask);
2008 if (himl->hbmMask) {
2009 BitBlt (hdcDst, 0, 0, himl->cx, himl->cy,
2010 himl->hdcMask, pt.x, pt.y, SRCCOPY);
2011 }
2012 else
2013 PatBlt (hdcDst, 0, 0, himl->cx, himl->cy, BLACKNESS);
2014
2015 /* draw image*/
2017 BitBlt (hdcDst, 0, 0, himl->cx, himl->cy,
2018 himl->hdcImage, pt.x, pt.y, SRCCOPY);
2019
2020 /*
2021 * CreateIconIndirect requires us to deselect the bitmaps from
2022 * the DCs before calling
2023 */
2024 SelectObject(hdcDst, hOldDstBitmap);
2025
2026 hIcon = CreateIconIndirect (&ii);
2027
2028 DeleteObject (ii.hbmMask);
2030 DeleteDC (hdcDst);
2031
2032 return hIcon;
2033}
2034
2035
2036/*************************************************************************
2037 * ImageList_GetIconSize [COMCTL32.@]
2038 *
2039 * Retrieves the size of an image in an image list.
2040 *
2041 * PARAMS
2042 * himl [I] handle to image list
2043 * cx [O] pointer to the image width.
2044 * cy [O] pointer to the image height.
2045 *
2046 * RETURNS
2047 * Success: TRUE
2048 * Failure: FALSE
2049 *
2050 * NOTES
2051 * All images in an image list have the same size.
2052 */
2053
2056{
2057 if (!is_valid(himl) || !cx || !cy)
2058 return FALSE;
2059
2060 *cx = himl->cx;
2061 *cy = himl->cy;
2062
2063 return TRUE;
2064}
2065
2066
2067/*************************************************************************
2068 * ImageList_GetImageCount [COMCTL32.@]
2069 *
2070 * Returns the number of images in an image list.
2071 *
2072 * PARAMS
2073 * himl [I] handle to image list
2074 *
2075 * RETURNS
2076 * Success: Number of images.
2077 * Failure: 0
2078 */
2079
2080INT WINAPI
2082{
2083 if (!is_valid(himl))
2084 return 0;
2085
2086 return himl->cCurImage;
2087}
2088
2089
2090/*************************************************************************
2091 * ImageList_GetImageInfo [COMCTL32.@]
2092 *
2093 * Returns information about an image in an image list.
2094 *
2095 * PARAMS
2096 * himl [I] handle to image list
2097 * i [I] image index
2098 * pImageInfo [O] pointer to the image information
2099 *
2100 * RETURNS
2101 * Success: TRUE
2102 * Failure: FALSE
2103 */
2104
2107{
2108 POINT pt;
2109
2110 if (!is_valid(himl) || (pImageInfo == NULL))
2111 return FALSE;
2112 if ((i < 0) || (i >= himl->cCurImage))
2113 return FALSE;
2114
2117
2119 pImageInfo->rcImage.top = pt.y;
2122 pImageInfo->rcImage.right = pt.x + himl->cx;
2123
2124 return TRUE;
2125}
2126
2127
2128/*************************************************************************
2129 * ImageList_GetImageRect [COMCTL32.@]
2130 *
2131 * Retrieves the rectangle of the specified image in an image list.
2132 *
2133 * PARAMS
2134 * himl [I] handle to image list
2135 * i [I] image index
2136 * lpRect [O] pointer to the image rectangle
2137 *
2138 * RETURNS
2139 * Success: TRUE
2140 * Failure: FALSE
2141 *
2142 * NOTES
2143 * This is an UNDOCUMENTED function!!!
2144 */
2145
2148{
2149#ifdef __REACTOS__
2150 IMAGEINFO ImageInfo;
2151 if (!ImageList_GetImageInfo(himl, i, &ImageInfo))
2152 return FALSE;
2153 *lpRect = ImageInfo.rcImage;
2154#else
2155 POINT pt;
2156
2157 if (!is_valid(himl) || (lpRect == NULL))
2158 return FALSE;
2159 if ((i < 0) || (i >= himl->cCurImage))
2160 return FALSE;
2161
2163 lpRect->left = pt.x;
2164 lpRect->top = pt.y;
2165 lpRect->right = pt.x + himl->cx;
2166 lpRect->bottom = pt.y + himl->cy;
2167#endif
2168 return TRUE;
2169}
2170
2171
2172/*************************************************************************
2173 * ImageList_LoadImage [COMCTL32.@]
2174 * ImageList_LoadImageA [COMCTL32.@]
2175 *
2176 * Creates an image list from a bitmap, icon or cursor.
2177 *
2178 * See ImageList_LoadImageW.
2179 */
2180
2183 COLORREF clrMask, UINT uType, UINT uFlags)
2184{
2186 LPWSTR lpbmpW;
2187 DWORD len;
2188
2189 if (IS_INTRESOURCE(lpbmp))
2190 return ImageList_LoadImageW(hi, (LPCWSTR)lpbmp, cx, cGrow, clrMask,
2191 uType, uFlags);
2192
2193 len = MultiByteToWideChar(CP_ACP, 0, lpbmp, -1, NULL, 0);
2194 lpbmpW = heap_alloc(len * sizeof(WCHAR));
2195 MultiByteToWideChar(CP_ACP, 0, lpbmp, -1, lpbmpW, len);
2196
2197 himl = ImageList_LoadImageW(hi, lpbmpW, cx, cGrow, clrMask, uType, uFlags);
2198 heap_free (lpbmpW);
2199 return himl;
2200}
2201
2202
2203/*************************************************************************
2204 * ImageList_LoadImageW [COMCTL32.@]
2205 *
2206 * Creates an image list from a bitmap, icon or cursor.
2207 *
2208 * PARAMS
2209 * hi [I] instance handle
2210 * lpbmp [I] name or id of the image
2211 * cx [I] width of each image
2212 * cGrow [I] number of images to expand
2213 * clrMask [I] mask color
2214 * uType [I] type of image to load
2215 * uFlags [I] loading flags
2216 *
2217 * RETURNS
2218 * Success: handle to the loaded image list
2219 * Failure: NULL
2220 *
2221 * SEE
2222 * LoadImage ()
2223 */
2224
2227 COLORREF clrMask, UINT uType, UINT uFlags)
2228{
2230 HANDLE handle;
2231 INT nImageCount;
2232
2233 handle = LoadImageW (hi, lpbmp, uType, 0, 0, uFlags);
2234 if (!handle) {
2235 WARN("Couldn't load image\n");
2236 return NULL;
2237 }
2238
2239 if (uType == IMAGE_BITMAP) {
2241 UINT color;
2242
2243 if (GetObjectW (handle, sizeof(dib), &dib) == sizeof(BITMAP)) color = ILC_COLOR;
2244 else color = dib.dsBm.bmBitsPixel;
2245
2246 /* To match windows behavior, if cx is set to zero and
2247 the flag DI_DEFAULTSIZE is specified, cx becomes the
2248 system metric value for icons. If the flag is not specified
2249 the function sets the size to the height of the bitmap */
2250 if (cx == 0)
2251 {
2252 if (uFlags & DI_DEFAULTSIZE)
2254 else
2255 cx = dib.dsBm.bmHeight;
2256 }
2257
2258 nImageCount = dib.dsBm.bmWidth / cx;
2259
2260 if (clrMask != CLR_NONE) color |= ILC_MASK;
2261 himl = ImageList_Create (cx, dib.dsBm.bmHeight, color, nImageCount, cGrow);
2262 if (!himl) {
2264 return NULL;
2265 }
2266#ifdef __REACTOS__
2267 if (clrMask == CLR_NONE)
2268 nImageCount = ImageList_Add(himl, handle, NULL);
2269 else
2270 nImageCount = ImageList_AddMasked(himl, handle, clrMask);
2271
2272 if (nImageCount < 0)
2273 {
2275 himl = NULL;
2276 }
2277#else
2278 ImageList_AddMasked (himl, handle, clrMask);
2279#endif
2280 }
2281 else if ((uType == IMAGE_ICON) || (uType == IMAGE_CURSOR)) {
2282 ICONINFO ii;
2283 BITMAP bmp;
2284
2285 GetIconInfo (handle, &ii);
2286 GetObjectW (ii.hbmColor, sizeof(BITMAP), &bmp);
2287 himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight,
2288 ILC_MASK | ILC_COLOR, 1, cGrow);
2289 if (!himl) {
2291 DeleteObject (ii.hbmMask);
2293 return NULL;
2294 }
2297 DeleteObject (ii.hbmMask);
2298 }
2299
2301
2302 return himl;
2303}
2304
2305
2306/*************************************************************************
2307 * ImageList_Merge [COMCTL32.@]
2308 *
2309 * Create an image list containing a merged image from two image lists.
2310 *
2311 * PARAMS
2312 * himl1 [I] handle to first image list
2313 * i1 [I] first image index
2314 * himl2 [I] handle to second image list
2315 * i2 [I] second image index
2316 * dx [I] X offset of the second image relative to the first.
2317 * dy [I] Y offset of the second image relative to the first.
2318 *
2319 * RETURNS
2320 * Success: The newly created image list. It contains a single image
2321 * consisting of the second image merged with the first.
2322 * Failure: NULL, if either himl1 or himl2 is invalid.
2323 *
2324 * NOTES
2325 * - The returned image list should be deleted by the caller using
2326 * ImageList_Destroy() when it is no longer required.
2327 * - If either i1 or i2 is not a valid image index, they will be treated
2328 * as blank images.
2329 */
2332 INT dx, INT dy)
2333{
2334 HIMAGELIST himlDst = NULL;
2335 INT cxDst, cyDst;
2336 INT xOff1, yOff1, xOff2, yOff2;
2337 POINT pt1, pt2;
2338 INT newFlags;
2339
2340 TRACE("(himl1=%p i1=%d himl2=%p i2=%d dx=%d dy=%d)\n", himl1, i1, himl2,
2341 i2, dx, dy);
2342
2343 if (!is_valid(himl1) || !is_valid(himl2))
2344 return NULL;
2345
2346 if (dx > 0) {
2347 cxDst = max (himl1->cx, dx + himl2->cx);
2348 xOff1 = 0;
2349 xOff2 = dx;
2350 }
2351 else if (dx < 0) {
2352 cxDst = max (himl2->cx, himl1->cx - dx);
2353 xOff1 = -dx;
2354 xOff2 = 0;
2355 }
2356 else {
2357 cxDst = max (himl1->cx, himl2->cx);
2358 xOff1 = 0;
2359 xOff2 = 0;
2360 }
2361
2362 if (dy > 0) {
2363 cyDst = max (himl1->cy, dy + himl2->cy);
2364 yOff1 = 0;
2365 yOff2 = dy;
2366 }
2367 else if (dy < 0) {
2368 cyDst = max (himl2->cy, himl1->cy - dy);
2369 yOff1 = -dy;
2370 yOff2 = 0;
2371 }
2372 else {
2373 cyDst = max (himl1->cy, himl2->cy);
2374 yOff1 = 0;
2375 yOff2 = 0;
2376 }
2377
2378 newFlags = (himl1->flags > himl2->flags ? himl1->flags : himl2->flags) & ILC_COLORDDB;
2379 if (newFlags == ILC_COLORDDB && (himl1->flags & ILC_COLORDDB) == ILC_COLOR16)
2380 newFlags = ILC_COLOR16; /* this is what native (at least v5) does, don't know why */
2381 himlDst = ImageList_Create (cxDst, cyDst, ILC_MASK | newFlags, 1, 1);
2382
2383 if (himlDst)
2384 {
2385 imagelist_point_from_index( himl1, i1, &pt1 );
2386 imagelist_point_from_index( himl2, i2, &pt2 );
2387
2388 /* copy image */
2389 BitBlt (himlDst->hdcImage, 0, 0, cxDst, cyDst, himl1->hdcImage, 0, 0, BLACKNESS);
2390 if (i1 >= 0 && i1 < himl1->cCurImage)
2391 BitBlt (himlDst->hdcImage, xOff1, yOff1, himl1->cx, himl1->cy, himl1->hdcImage, pt1.x, pt1.y, SRCCOPY);
2392 if (i2 >= 0 && i2 < himl2->cCurImage)
2393 {
2394 if (himl2->flags & ILC_MASK)
2395 {
2396 BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcMask , pt2.x, pt2.y, SRCAND);
2397 BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcImage, pt2.x, pt2.y, SRCPAINT);
2398 }
2399 else
2400 BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcImage, pt2.x, pt2.y, SRCCOPY);
2401 }
2402
2403 /* copy mask */
2404 BitBlt (himlDst->hdcMask, 0, 0, cxDst, cyDst, himl1->hdcMask, 0, 0, WHITENESS);
2405 if (i1 >= 0 && i1 < himl1->cCurImage)
2406 BitBlt (himlDst->hdcMask, xOff1, yOff1, himl1->cx, himl1->cy, himl1->hdcMask, pt1.x, pt1.y, SRCCOPY);
2407 if (i2 >= 0 && i2 < himl2->cCurImage)
2408 BitBlt (himlDst->hdcMask, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcMask, pt2.x, pt2.y, SRCAND);
2409
2410 himlDst->cCurImage = 1;
2411 }
2412
2413 return himlDst;
2414}
2415
2416
2417/* helper for ImageList_Read, see comments below */
2418static void *read_bitmap(IStream *pstm, BITMAPINFO *bmi)
2419{
2420 BITMAPFILEHEADER bmfh;
2421 int bitsperpixel, palspace;
2422 void *bits;
2423
2424 if (FAILED(IStream_Read ( pstm, &bmfh, sizeof(bmfh), NULL)))
2425 return NULL;
2426
2427 if (bmfh.bfType != (('M'<<8)|'B'))
2428 return NULL;
2429
2430 if (FAILED(IStream_Read ( pstm, &bmi->bmiHeader, sizeof(bmi->bmiHeader), NULL)))
2431 return NULL;
2432
2433 if ((bmi->bmiHeader.biSize != sizeof(bmi->bmiHeader)))
2434 return NULL;
2435
2436 TRACE("width %u, height %u, planes %u, bpp %u\n",
2439
2440 bitsperpixel = bmi->bmiHeader.biPlanes * bmi->bmiHeader.biBitCount;
2441 if (bitsperpixel<=8)
2442 palspace = (1<<bitsperpixel)*sizeof(RGBQUAD);
2443 else
2444 palspace = 0;
2445
2447
2448 /* read the palette right after the end of the bitmapinfoheader */
2449 if (palspace && FAILED(IStream_Read(pstm, bmi->bmiColors, palspace, NULL)))
2450 return NULL;
2451
2452 bits = heap_alloc_zero(bmi->bmiHeader.biSizeImage);
2453 if (!bits) return NULL;
2454
2455 if (FAILED(IStream_Read(pstm, bits, bmi->bmiHeader.biSizeImage, NULL)))
2456 {
2457 heap_free(bits);
2458 return NULL;
2459 }
2460 return bits;
2461}
2462
2463/*************************************************************************
2464 * ImageList_Read [COMCTL32.@]
2465 *
2466 * Reads an image list from a stream.
2467 *
2468 * PARAMS
2469 * pstm [I] pointer to a stream
2470 *
2471 * RETURNS
2472 * Success: handle to image list
2473 * Failure: NULL
2474 *
2475 * The format is like this:
2476 * ILHEAD ilheadstruct;
2477 *
2478 * for the color image part:
2479 * BITMAPFILEHEADER bmfh;
2480 * BITMAPINFOHEADER bmih;
2481 * only if it has a palette:
2482 * RGBQUAD rgbs[nr_of_paletted_colors];
2483 *
2484 * BYTE colorbits[imagesize];
2485 *
2486 * the following only if the ILC_MASK bit is set in ILHEAD.ilFlags:
2487 * BITMAPFILEHEADER bmfh_mask;
2488 * BITMAPINFOHEADER bmih_mask;
2489 * only if it has a palette (it usually does not):
2490 * RGBQUAD rgbs[nr_of_paletted_colors];
2491 *
2492 * BYTE maskbits[imagesize];
2493 */
2495{
2496 char image_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
2497 char mask_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
2498 BITMAPINFO *image_info = (BITMAPINFO *)image_buf;
2499 BITMAPINFO *mask_info = (BITMAPINFO *)mask_buf;
2500 void *image_bits, *mask_bits = NULL;
2501 ILHEAD ilHead;
2503 unsigned int i;
2504
2505 TRACE("%p\n", pstm);
2506
2507 if (FAILED(IStream_Read (pstm, &ilHead, sizeof(ILHEAD), NULL)))
2508 return NULL;
2509 if (ilHead.usMagic != (('L' << 8) | 'I'))
2510 return NULL;
2511#ifdef __REACTOS__
2512 if (ilHead.usVersion != IMAGELIST_VERSION &&
2513 ilHead.usVersion != 0x600 && /* XP/2003 version */
2514 ilHead.usVersion != 0x620) /* Vista/7 version */
2515#else
2516 if (ilHead.usVersion != 0x101) /* probably version? */
2517#endif
2518 return NULL;
2519
2520 TRACE("cx %u, cy %u, flags 0x%04x, cCurImage %u, cMaxImage %u\n",
2521 ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
2522
2523 himl = ImageList_Create(ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cMaxImage, ilHead.cGrow);
2524 if (!himl)
2525 return NULL;
2526
2527#ifdef __REACTOS__
2528 /* keep version from stream */
2529 himl->usVersion = ilHead.usVersion;
2530#endif
2531
2532 if (!(image_bits = read_bitmap(pstm, image_info)))
2533 {
2534 WARN("failed to read bitmap from stream\n");
2535 return NULL;
2536 }
2537 if (ilHead.flags & ILC_MASK)
2538 {
2539 if (!(mask_bits = read_bitmap(pstm, mask_info)))
2540 {
2541 WARN("failed to read mask bitmap from stream\n");
2542 return NULL;
2543 }
2544 }
2545 else mask_info = NULL;
2546
2547 if (himl->has_alpha && image_info->bmiHeader.biBitCount == 32)
2548 {
2549 DWORD *ptr = image_bits;
2550 BYTE *mask_ptr = mask_bits;
2551#ifdef __REACTOS__
2552 int stride = himl->cy * (ilHead.usVersion != IMAGELIST_VERSION ? himl->cx : image_info->bmiHeader.biWidth);
2553 int image_step = ilHead.usVersion != IMAGELIST_VERSION ? 1 : TILE_COUNT;
2554 int mask_step = ilHead.usVersion != IMAGELIST_VERSION ? 4 : 8;
2555#else
2556 int stride = himl->cy * image_info->bmiHeader.biWidth;
2557#endif
2558 if (image_info->bmiHeader.biHeight > 0) /* bottom-up */
2559 {
2560 ptr += image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride;
2561#ifdef __REACTOS__
2562 mask_ptr += (image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride) / mask_step;
2563#else
2564 mask_ptr += (image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride) / 8;
2565#endif
2566 stride = -stride;
2567 image_info->bmiHeader.biHeight = himl->cy;
2568 }
2569 else image_info->bmiHeader.biHeight = -himl->cy;
2570#ifdef __REACTOS__
2571 for (i = 0; i < ilHead.cCurImage; i += image_step)
2572 {
2573 add_dib_bits(himl, i, min(ilHead.cCurImage - i, image_step),
2574 himl->cx, himl->cy, image_info, mask_info, ptr, mask_ptr);
2575 ptr += stride;
2576 mask_ptr += stride / mask_step;
2577 }
2578#else
2579 for (i = 0; i < ilHead.cCurImage; i += TILE_COUNT)
2580 {
2581 add_dib_bits( himl, i, min( ilHead.cCurImage - i, TILE_COUNT ),
2582 himl->cx, himl->cy, image_info, mask_info, ptr, mask_ptr );
2583 ptr += stride;
2584 mask_ptr += stride / 8;
2585 }
2586#endif
2587 }
2588 else
2589 {
2590 StretchDIBits( himl->hdcImage, 0, 0, image_info->bmiHeader.biWidth, image_info->bmiHeader.biHeight,
2591 0, 0, image_info->bmiHeader.biWidth, image_info->bmiHeader.biHeight,
2592 image_bits, image_info, DIB_RGB_COLORS, SRCCOPY);
2593 if (mask_info)
2594 StretchDIBits( himl->hdcMask, 0, 0, mask_info->bmiHeader.biWidth, mask_info->bmiHeader.biHeight,
2595 0, 0, mask_info->bmiHeader.biWidth, mask_info->bmiHeader.biHeight,
2596 mask_bits, mask_info, DIB_RGB_COLORS, SRCCOPY);
2597 }
2598 heap_free( image_bits );
2599 heap_free( mask_bits );
2600
2601 himl->cCurImage = ilHead.cCurImage;
2602 himl->cMaxImage = ilHead.cMaxImage;
2603
2605 for (i=0;i<4;i++)
2607 return himl;
2608}
2609
2610
2611/*************************************************************************
2612 * ImageList_Remove [COMCTL32.@]
2613 *
2614 * Removes an image from an image list
2615 *
2616 * PARAMS
2617 * himl [I] image list handle
2618 * i [I] image index
2619 *
2620 * RETURNS
2621 * Success: TRUE
2622 * Failure: FALSE
2623 *
2624 * FIXME: as the image list storage test shows, native comctl32 simply shifts
2625 * images without creating a new bitmap.
2626 */
2629{
2630 HBITMAP hbmNewImage, hbmNewMask;
2631 HDC hdcBmp;
2632 SIZE sz;
2633
2634 TRACE("(himl=%p i=%d)\n", himl, i);
2635
2636 if (!is_valid(himl)) {
2637 ERR("Invalid image list handle!\n");
2638 return FALSE;
2639 }
2640
2641 if ((i < -1) || (i >= himl->cCurImage)) {
2642 TRACE("index out of range! %d\n", i);
2643 return FALSE;
2644 }
2645
2646 if (i == -1) {
2647 INT nCount;
2648
2649 /* remove all */
2650 if (himl->cCurImage == 0) {
2651 /* remove all on empty ImageList is allowed */
2652 TRACE("remove all on empty ImageList!\n");
2653 return TRUE;
2654 }
2655
2657 himl->cCurImage = 0;
2658 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
2659 himl->nOvlIdx[nCount] = -1;
2660
2661 if (himl->has_alpha)
2662 {
2664 himl->has_alpha = heap_alloc_zero( himl->cMaxImage );
2665 }
2666
2668 SelectObject (himl->hdcImage, hbmNewImage);
2670 himl->hbmImage = hbmNewImage;
2671
2672 if (himl->hbmMask) {
2673
2675 hbmNewMask = CreateBitmap (sz.cx, sz.cy, 1, 1, NULL);
2676 SelectObject (himl->hdcMask, hbmNewMask);
2678 himl->hbmMask = hbmNewMask;
2679 }
2680 }
2681 else {
2682 /* delete one image */
2683 TRACE("Remove single image! %d\n", i);
2684
2685 /* create new bitmap(s) */
2686 TRACE(" - Number of images: %d / %d (Old/New)\n",
2687 himl->cCurImage, himl->cCurImage - 1);
2688
2690
2692 if (himl->hbmMask)
2693 hbmNewMask = CreateBitmap (sz.cx, sz.cy, 1, 1, NULL);
2694 else
2695 hbmNewMask = 0; /* Just to keep compiler happy! */
2696
2697 hdcBmp = CreateCompatibleDC (0);
2698
2699 /* copy all images and masks prior to the "removed" image */
2700 if (i > 0) {
2701 TRACE("Pre image copy: Copy %d images\n", i);
2702
2703 SelectObject (hdcBmp, hbmNewImage);
2704 imagelist_copy_images( himl, himl->hdcImage, hdcBmp, 0, i, 0 );
2705
2706 if (himl->hbmMask) {
2707 SelectObject (hdcBmp, hbmNewMask);
2708 imagelist_copy_images( himl, himl->hdcMask, hdcBmp, 0, i, 0 );
2709 }
2710 }
2711
2712 /* copy all images and masks behind the removed image */
2713 if (i < himl->cCurImage - 1) {
2714 TRACE("Post image copy!\n");
2715
2716 SelectObject (hdcBmp, hbmNewImage);
2717 imagelist_copy_images( himl, himl->hdcImage, hdcBmp, i + 1,
2718 (himl->cCurImage - i), i );
2719
2720 if (himl->hbmMask) {
2721 SelectObject (hdcBmp, hbmNewMask);
2722 imagelist_copy_images( himl, himl->hdcMask, hdcBmp, i + 1,
2723 (himl->cCurImage - i), i );
2724 }
2725 }
2726
2727 DeleteDC (hdcBmp);
2728
2729 /* delete old images and insert new ones */
2730 SelectObject (himl->hdcImage, hbmNewImage);
2732 himl->hbmImage = hbmNewImage;
2733 if (himl->hbmMask) {
2734 SelectObject (himl->hdcMask, hbmNewMask);
2736 himl->hbmMask = hbmNewMask;
2737 }
2738
2739 himl->cCurImage--;
2740 }
2741
2742 return TRUE;
2743}
2744
2745
2746/*************************************************************************
2747 * ImageList_Replace [COMCTL32.@]
2748 *
2749 * Replaces an image in an image list with a new image.
2750 *
2751 * PARAMS
2752 * himl [I] handle to image list
2753 * i [I] image index
2754 * hbmImage [I] handle to image bitmap
2755 * hbmMask [I] handle to mask bitmap. Can be NULL.
2756 *
2757 * RETURNS
2758 * Success: TRUE
2759 * Failure: FALSE
2760 */
2761
2764 HBITMAP hbmMask)
2765{
2766 HDC hdcImage;
2767 BITMAP bmp;
2768 POINT pt;
2769
2770 TRACE("%p %d %p %p\n", himl, i, hbmImage, hbmMask);
2771
2772 if (!is_valid(himl)) {
2773 ERR("Invalid image list handle!\n");
2774 return FALSE;
2775 }
2776
2777 if ((i >= himl->cMaxImage) || (i < 0)) {
2778 ERR("Invalid image index!\n");
2779 return FALSE;
2780 }
2781
2782 if (!GetObjectW(hbmImage, sizeof(BITMAP), &bmp))
2783 return FALSE;
2784
2785 hdcImage = CreateCompatibleDC (0);
2786
2787 /* Replace Image */
2788 SelectObject (hdcImage, hbmImage);
2789
2790 if (add_with_alpha( himl, hdcImage, i, 1, bmp.bmWidth, bmp.bmHeight, hbmImage, hbmMask ))
2791 goto done;
2792
2794 StretchBlt (himl->hdcImage, pt.x, pt.y, himl->cx, himl->cy,
2795 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
2796
2797 if (himl->hbmMask)
2798 {
2799 HDC hdcTemp;
2800 HBITMAP hOldBitmapTemp;
2801
2802 hdcTemp = CreateCompatibleDC(0);
2803 hOldBitmapTemp = SelectObject(hdcTemp, hbmMask);
2804
2805 StretchBlt (himl->hdcMask, pt.x, pt.y, himl->cx, himl->cy,
2806 hdcTemp, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
2807 SelectObject(hdcTemp, hOldBitmapTemp);
2808 DeleteDC(hdcTemp);
2809
2810 /* Remove the background from the image
2811 */
2812 BitBlt (himl->hdcImage, pt.x, pt.y, bmp.bmWidth, bmp.bmHeight,
2813 himl->hdcMask, pt.x, pt.y, 0x220326); /* NOTSRCAND */
2814 }
2815
2816done:
2817 DeleteDC (hdcImage);
2818
2819 return TRUE;
2820}
2821
2822
2823/*************************************************************************
2824 * ImageList_ReplaceIcon [COMCTL32.@]
2825 *
2826 * Replaces an image in an image list using an icon.
2827 *
2828 * PARAMS
2829 * himl [I] handle to image list
2830 * i [I] image index
2831 * hIcon [I] handle to icon
2832 *
2833 * RETURNS
2834 * Success: index of the replaced image
2835 * Failure: -1
2836 */
2837
2838INT WINAPI
2840{
2841 HICON hBestFitIcon;
2842 ICONINFO ii;
2843 BITMAP bmp;
2844 BOOL ret;
2845 POINT pt;
2846
2847 TRACE("(%p %d %p)\n", himl, nIndex, hIcon);
2848
2849 if (!is_valid(himl)) {
2850 ERR("invalid image list\n");
2851 return -1;
2852 }
2853 if ((nIndex >= himl->cMaxImage) || (nIndex < -1)) {
2854 ERR("invalid image index %d / %d\n", nIndex, himl->cMaxImage);
2855 return -1;
2856 }
2857
2858 hBestFitIcon = CopyImage(
2860 himl->cx, himl->cy,
2862 /* the above will fail if the icon wasn't loaded from a resource, so try
2863 * again without LR_COPYFROMRESOURCE flag */
2864 if (!hBestFitIcon)
2865 hBestFitIcon = CopyImage(
2867 himl->cx, himl->cy,
2868 0);
2869 if (!hBestFitIcon)
2870 return -1;
2871
2872 if (nIndex == -1) {
2873 if (himl->cCurImage + 1 >= himl->cMaxImage)
2875
2876 nIndex = himl->cCurImage;
2877 himl->cCurImage++;
2878 }
2879
2880 if (himl->has_alpha && GetIconInfo (hBestFitIcon, &ii))
2881 {
2882 HDC hdcImage = CreateCompatibleDC( 0 );
2883 GetObjectW (ii.hbmMask, sizeof(BITMAP), &bmp);
2884
2885 if (!ii.hbmColor)
2886 {
2887 UINT height = bmp.bmHeight / 2;
2888 HDC hdcMask = CreateCompatibleDC( 0 );
2889 HBITMAP color = CreateBitmap( bmp.bmWidth, height, 1, 1, NULL );
2890 SelectObject( hdcImage, color );
2891 SelectObject( hdcMask, ii.hbmMask );
2892 BitBlt( hdcImage, 0, 0, bmp.bmWidth, height, hdcMask, 0, height, SRCCOPY );
2893 ret = add_with_alpha( himl, hdcImage, nIndex, 1, bmp.bmWidth, height, color, ii.hbmMask );
2894 DeleteDC( hdcMask );
2896 }
2897 else ret = add_with_alpha( himl, hdcImage, nIndex, 1, bmp.bmWidth, bmp.bmHeight,
2898 ii.hbmColor, ii.hbmMask );
2899
2900 DeleteDC( hdcImage );
2901 DeleteObject (ii.hbmMask);
2902 if (ii.hbmColor) DeleteObject (ii.hbmColor);
2903 if (ret) goto done;
2904 }
2905
2907
2908 if (himl->hbmMask)
2909 {
2910 DrawIconEx( himl->hdcImage, pt.x, pt.y, hBestFitIcon, himl->cx, himl->cy, 0, 0, DI_IMAGE );
2911 PatBlt( himl->hdcMask, pt.x, pt.y, himl->cx, himl->cy, WHITENESS );
2912 DrawIconEx( himl->hdcMask, pt.x, pt.y, hBestFitIcon, himl->cx, himl->cy, 0, 0, DI_MASK );
2913 }
2914 else
2915 {
2917 HBRUSH brush = CreateSolidBrush( GetNearestColor( himl->hdcImage, color ));
2918
2919 SelectObject( himl->hdcImage, brush );
2920 PatBlt( himl->hdcImage, pt.x, pt.y, himl->cx, himl->cy, PATCOPY );
2922 DeleteObject( brush );
2923 DrawIconEx( himl->hdcImage, pt.x, pt.y, hBestFitIcon, himl->cx, himl->cy, 0, 0, DI_NORMAL );
2924 }
2925
2926done:
2927 DestroyIcon(hBestFitIcon);
2928
2929 TRACE("Insert index = %d, himl->cCurImage = %d\n", nIndex, himl->cCurImage);
2930 return nIndex;
2931}
2932
2933
2934/*************************************************************************
2935 * ImageList_SetBkColor [COMCTL32.@]
2936 *
2937 * Sets the background color of an image list.
2938 *
2939 * PARAMS
2940 * himl [I] handle to image list
2941 * clrBk [I] background color
2942 *
2943 * RETURNS
2944 * Success: previous background color
2945 * Failure: CLR_NONE
2946 */
2947
2950{
2951 COLORREF clrOldBk;
2952
2953 if (!is_valid(himl))
2954 return CLR_NONE;
2955
2956 clrOldBk = himl->clrBk;
2957 himl->clrBk = clrBk;
2958 return clrOldBk;
2959}
2960
2961
2962/*************************************************************************
2963 * ImageList_SetDragCursorImage [COMCTL32.@]
2964 *
2965 * Combines the specified image with the current drag image
2966 *
2967 * PARAMS
2968 * himlDrag [I] handle to drag image list
2969 * iDrag [I] drag image index
2970 * dxHotspot [I] X position of the hot spot
2971 * dyHotspot [I] Y position of the hot spot
2972 *
2973 * RETURNS
2974 * Success: TRUE
2975 * Failure: FALSE
2976 *
2977 * NOTES
2978 * - The names dxHotspot, dyHotspot are misleading because they have nothing
2979 * to do with a hotspot but are only the offset of the origin of the new
2980 * image relative to the origin of the old image.
2981 *
2982 * - When this function is called and the drag image is visible, a
2983 * short flickering occurs but this matches the Win9x behavior. It is
2984 * possible to fix the flickering using code like in ImageList_DragMove.
2985 */
2986
2989 INT dxHotspot, INT dyHotspot)
2990{
2991 HIMAGELIST himlTemp;
2992 BOOL visible;
2993
2994 if (!is_valid(InternalDrag.himl) || !is_valid(himlDrag))
2995 return FALSE;
2996
2997 TRACE(" dxH=%d dyH=%d nX=%d nY=%d\n",
2998 dxHotspot, dyHotspot, InternalDrag.dxHotspot, InternalDrag.dyHotspot);
2999
3000 visible = InternalDrag.bShow;
3001
3002 himlTemp = ImageList_Merge (InternalDrag.himlNoCursor, 0, himlDrag, iDrag,
3003 dxHotspot, dyHotspot);
3004
3005 if (visible) {
3006 /* hide the drag image */
3008 }
3009 if ((InternalDrag.himl->cx != himlTemp->cx) ||
3010 (InternalDrag.himl->cy != himlTemp->cy)) {
3011 /* the size of the drag image changed, invalidate the buffer */
3013 InternalDrag.hbmBg = 0;
3014 }
3015
3018 InternalDrag.himl = himlTemp;
3019
3020 if (visible) {
3021 /* show the drag image */
3023 }
3024
3025 return TRUE;
3026}
3027
3028
3029/*************************************************************************
3030 * ImageList_SetFilter [COMCTL32.@]
3031 *
3032 * Sets a filter (or does something completely different)!!???
3033 * It removes 12 Bytes from the stack (3 Parameters).
3034 *
3035 * PARAMS
3036 * himl [I] SHOULD be a handle to image list
3037 * i [I] COULD be an index?
3038 * dwFilter [I] ???
3039 *
3040 * RETURNS
3041 * Success: TRUE ???
3042 * Failure: FALSE ???
3043 *
3044 * BUGS
3045 * This is an UNDOCUMENTED function!!!!
3046 * empty stub.
3047 */
3048
3051{
3052 FIXME("(%p 0x%x 0x%x):empty stub!\n", himl, i, dwFilter);
3053
3054 return FALSE;
3055}
3056
3057
3058/*************************************************************************
3059 * ImageList_SetFlags [COMCTL32.@]
3060 *
3061 * Sets the image list flags.
3062 *
3063 * PARAMS
3064 * himl [I] Handle to image list
3065 * flags [I] Flags to set
3066 *
3067 * RETURNS
3068 * Old flags?
3069 *
3070 * BUGS
3071 * Stub.
3072 */
3073
3074#ifdef __REACTOS__
3075static BOOL
3076ChangeColorDepth(HIMAGELIST himl)
3077{
3078 UINT ilc = himl->flags & ILC_COLORMASK;
3079 if (ilc >= ILC_COLOR4 && ilc <= ILC_COLOR32)
3080 himl->uBitsPixel = ilc;
3081 else
3083
3084 /* Create new himl->hbmImage for BPP changes (for SHELL32) */
3085 return ((IImageList*)himl)->lpVtbl->SetImageCount((IImageList*)himl, 0) == S_OK;
3086}
3087
3090{
3091 if (!is_valid(himl))
3092 return FALSE;
3093
3094 if (flags & ~ILC_PUBLICFLAGS)
3095 return FALSE;
3096
3097 if (((himl->flags ^ flags) & ILC_SYSTEM) && WinVerMajor() < 6)
3098 return FALSE; /* Can't change this flag */
3099
3100 if (himl->flags == flags && WinVerMajor() >= 6)
3101 return TRUE;
3102
3103 himl->flags = flags;
3104 return ChangeColorDepth(himl);
3105}
3106#else
3109{
3110 FIXME("(%p %08x):empty stub\n", himl, flags);
3111 return 0;
3112}
3113#endif /* __REACTOS__ */
3114
3115
3116/*************************************************************************
3117 * ImageList_SetIconSize [COMCTL32.@]
3118 *
3119 * Sets the image size of the bitmap and deletes all images.
3120 *
3121 * PARAMS
3122 * himl [I] handle to image list
3123 * cx [I] image width
3124 * cy [I] image height
3125 *
3126 * RETURNS
3127 * Success: TRUE
3128 * Failure: FALSE
3129 */
3130
3133{
3134 INT nCount;
3135 HBITMAP hbmNew;
3136
3137 if (!is_valid(himl))
3138 return FALSE;
3139
3140 /* remove all images */
3141 himl->cMaxImage = himl->cInitial + 1;
3142 himl->cCurImage = 0;
3143 himl->cx = cx;
3144 himl->cy = cy;
3145
3146 /* initialize overlay mask indices */
3147 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
3148 himl->nOvlIdx[nCount] = -1;
3149
3151 SelectObject (himl->hdcImage, hbmNew);
3153 himl->hbmImage = hbmNew;
3154
3155 if (himl->hbmMask) {
3156 SIZE sz;
3158 hbmNew = CreateBitmap (sz.cx, sz.cy, 1, 1, NULL);
3159 SelectObject (himl->hdcMask, hbmNew);
3161 himl->hbmMask = hbmNew;
3162 }
3163
3164 return TRUE;
3165}
3166
3167
3168/*************************************************************************
3169 * ImageList_SetImageCount [COMCTL32.@]
3170 *
3171 * Resizes an image list to the specified number of images.
3172 *
3173 * PARAMS
3174 * himl [I] handle to image list
3175 * iImageCount [I] number of images in the image list
3176 *
3177 * RETURNS
3178 * Success: TRUE
3179 * Failure: FALSE
3180 */
3181
3184{
3185 HDC hdcBitmap;
3186 HBITMAP hbmNewBitmap, hbmOld;
3187 INT nNewCount, nCopyCount;
3188
3189 TRACE("%p %d\n",himl,iImageCount);
3190
3191 if (!is_valid(himl))
3192 return FALSE;
3193
3194 nNewCount = iImageCount + 1;
3195 nCopyCount = min(himl->cCurImage, iImageCount);
3196
3198
3199 hbmNewBitmap = ImageList_CreateImage(hdcBitmap, himl, nNewCount);
3200
3201 if (hbmNewBitmap != 0)
3202 {
3203 hbmOld = SelectObject (hdcBitmap, hbmNewBitmap);
3204 imagelist_copy_images( himl, himl->hdcImage, hdcBitmap, 0, nCopyCount, 0 );
3205 SelectObject (hdcBitmap, hbmOld);
3206
3207 /* FIXME: delete 'empty' image space? */
3208
3209 SelectObject (himl->hdcImage, hbmNewBitmap);
3211 himl->hbmImage = hbmNewBitmap;
3212 }
3213 else
3214 ERR("Could not create new image bitmap!\n");
3215
3216 if (himl->hbmMask)
3217 {
3218 SIZE sz;
3219 imagelist_get_bitmap_size( himl, nNewCount, &sz );
3220 hbmNewBitmap = CreateBitmap (sz.cx, sz.cy, 1, 1, NULL);
3221 if (hbmNewBitmap != 0)
3222 {
3223 hbmOld = SelectObject (hdcBitmap, hbmNewBitmap);
3224 imagelist_copy_images( himl, himl->hdcMask, hdcBitmap, 0, nCopyCount, 0 );
3225 SelectObject (hdcBitmap, hbmOld);
3226
3227 /* FIXME: delete 'empty' image space? */
3228
3229 SelectObject (himl->hdcMask, hbmNewBitmap);
3231 himl->hbmMask = hbmNewBitmap;
3232 }
3233 else
3234 ERR("Could not create new mask bitmap!\n");
3235 }
3236
3238
3239 if (himl->has_alpha)
3240 {
3241 char *new_alpha = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, himl->has_alpha, nNewCount );
3242 if (new_alpha) himl->has_alpha = new_alpha;
3243 else
3244 {
3246 himl->has_alpha = NULL;
3247 }
3248 }
3249
3250 /* Update max image count and current image count */
3251 himl->cMaxImage = nNewCount;
3252 himl->cCurImage = iImageCount;
3253
3254 return TRUE;
3255}
3256
3257
3258/*************************************************************************
3259 * ImageList_SetOverlayImage [COMCTL32.@]
3260 *
3261 * Assigns an overlay mask index to an existing image in an image list.
3262 *
3263 * PARAMS
3264 * himl [I] handle to image list
3265 * iImage [I] image index
3266 * iOverlay [I] overlay mask index
3267 *
3268 * RETURNS
3269 * Success: TRUE
3270 * Failure: FALSE
3271 */
3272
3275{
3276 if (!is_valid(himl))
3277 return FALSE;
3278 if ((iOverlay < 1) || (iOverlay > MAX_OVERLAYIMAGE))
3279 return FALSE;
3280 if ((iImage!=-1) && ((iImage < 0) || (iImage > himl->cCurImage)))
3281 return FALSE;
3282 himl->nOvlIdx[iOverlay - 1] = iImage;
3283 return TRUE;
3284}
3285
3286
3287
3288/* helper for ImageList_Write - write bitmap to pstm
3289 * currently everything is written as 24 bit RGB, except masks
3290 */
3292{
3293 LPBITMAPFILEHEADER bmfh;
3294 LPBITMAPINFOHEADER bmih;
3295 LPBYTE data = NULL, lpBits;
3296 BITMAP bm;
3297 INT bitCount, sizeImage, offBits, totalSize;
3298 HDC xdc;
3299 BOOL result = FALSE;
3300
3301 if (!GetObjectW(hBitmap, sizeof(BITMAP), &bm))
3302 return FALSE;
3303
3304 bitCount = bm.bmBitsPixel;
3305 sizeImage = get_dib_stride(bm.bmWidth, bitCount) * bm.bmHeight;
3306
3307 totalSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
3308 if(bitCount <= 8)
3309 totalSize += (1 << bitCount) * sizeof(RGBQUAD);
3310 offBits = totalSize;
3311 totalSize += sizeImage;
3312
3313 data = heap_alloc_zero(totalSize);
3314 bmfh = (LPBITMAPFILEHEADER)data;
3315 bmih = (LPBITMAPINFOHEADER)(data + sizeof(BITMAPFILEHEADER));
3316 lpBits = data + offBits;
3317
3318 /* setup BITMAPFILEHEADER */
3319 bmfh->bfType = (('M' << 8) | 'B');
3320 bmfh->bfSize = offBits;
3321 bmfh->bfReserved1 = 0;
3322 bmfh->bfReserved2 = 0;
3323 bmfh->bfOffBits = offBits;
3324
3325 /* setup BITMAPINFOHEADER */
3326 bmih->biSize = sizeof(BITMAPINFOHEADER);
3327 bmih->biWidth = bm.bmWidth;
3328 bmih->biHeight = bm.bmHeight;
3329 bmih->biPlanes = 1;
3330 bmih->biBitCount = bitCount;
3331 bmih->biCompression = BI_RGB;
3332 bmih->biSizeImage = sizeImage;
3333 bmih->biXPelsPerMeter = 0;
3334 bmih->biYPelsPerMeter = 0;
3335 bmih->biClrUsed = 0;
3336 bmih->biClrImportant = 0;
3337
3338 xdc = GetDC(0);
3339 result = GetDIBits(xdc, hBitmap, 0, bm.bmHeight, lpBits, (BITMAPINFO *)bmih, DIB_RGB_COLORS) == bm.bmHeight;
3340 ReleaseDC(0, xdc);
3341 if (!result)
3342 goto failed;
3343
3344 TRACE("width %u, height %u, planes %u, bpp %u\n",
3345 bmih->biWidth, bmih->biHeight,
3346 bmih->biPlanes, bmih->biBitCount);
3347
3348 if(FAILED(IStream_Write(pstm, data, totalSize, NULL)))
3349 goto failed;
3350
3351 result = TRUE;
3352
3353failed:
3354 heap_free(data);
3355
3356 return result;
3357}
3358
3359
3360/*************************************************************************
3361 * ImageList_Write [COMCTL32.@]
3362 *
3363 * Writes an image list to a stream.
3364 *
3365 * PARAMS
3366 * himl [I] handle to image list
3367 * pstm [O] Pointer to a stream.
3368 *
3369 * RETURNS
3370 * Success: TRUE
3371 * Failure: FALSE
3372 *
3373 * BUGS
3374 * probably.
3375 */
3376
3378{
3379 ILHEAD ilHead;
3380 int i;
3381
3382 TRACE("%p %p\n", himl, pstm);
3383
3384 if (!is_valid(himl))
3385 return FALSE;
3386
3387 ilHead.usMagic = (('L' << 8) | 'I');
3388 ilHead.usVersion = 0x101;
3389 ilHead.cCurImage = himl->cCurImage;
3390 ilHead.cMaxImage = himl->cMaxImage;
3391 ilHead.cGrow = himl->cGrow;
3392 ilHead.cx = himl->cx;
3393 ilHead.cy = himl->cy;
3394 ilHead.bkcolor = himl->clrBk;
3395 ilHead.flags = himl->flags;
3396 for(i = 0; i < 4; i++) {
3397 ilHead.ovls[i] = himl->nOvlIdx[i];
3398 }
3399
3400 TRACE("cx %u, cy %u, flags 0x04%x, cCurImage %u, cMaxImage %u\n",
3401 ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
3402
3403 if(FAILED(IStream_Write(pstm, &ilHead, sizeof(ILHEAD), NULL)))
3404 return FALSE;
3405
3406 /* write the bitmap */
3407 if(!_write_bitmap(himl->hbmImage, pstm))
3408 return FALSE;
3409
3410 /* write the mask if we have one */
3411 if(himl->flags & ILC_MASK) {
3412 if(!_write_bitmap(himl->hbmMask, pstm))
3413 return FALSE;
3414 }
3415
3416 return TRUE;
3417}
3418
3419
3421{
3422 HBITMAP hbmNewBitmap;
3423 UINT ilc = (himl->flags & 0xFE);
3424 SIZE sz;
3425
3427
3428 if ((ilc >= ILC_COLOR4 && ilc <= ILC_COLOR32) || ilc == ILC_COLOR)
3429 {
3430 char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
3431 BITMAPINFO *bmi = (BITMAPINFO *)buffer;
3432
3433 TRACE("Creating DIBSection %d x %d, %d Bits per Pixel\n",
3434 sz.cx, sz.cy, himl->uBitsPixel);
3435
3436 memset( buffer, 0, sizeof(buffer) );
3437 bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3438 bmi->bmiHeader.biWidth = sz.cx;
3439 bmi->bmiHeader.biHeight = sz.cy;
3440 bmi->bmiHeader.biPlanes = 1;
3443
3444 if (himl->uBitsPixel <= ILC_COLOR8)
3445 {
3446 if (!himl->color_table_set)
3447 {
3448 /* retrieve the default color map */
3449 HBITMAP tmp = CreateBitmap( 1, 1, 1, 1, NULL );
3450 GetDIBits( hdc, tmp, 0, 0, NULL, bmi, DIB_RGB_COLORS );
3451 DeleteObject( tmp );
3452 if (ilc == ILC_COLOR4)
3453 {
3454 RGBQUAD tmp;
3455 tmp = bmi->bmiColors[7];
3456 bmi->bmiColors[7] = bmi->bmiColors[8];
3457 bmi->bmiColors[8] = tmp;
3458 }
3459 }
3460 else
3461 {
3463 }
3464 }
3465 hbmNewBitmap = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, 0, 0);
3466 }
3467 else /*if (ilc == ILC_COLORDDB)*/
3468 {
3469 TRACE("Creating Bitmap: %d Bits per Pixel\n", himl->uBitsPixel);
3470
3471 hbmNewBitmap = CreateBitmap (sz.cx, sz.cy, 1, himl->uBitsPixel, NULL);
3472 }
3473 TRACE("returning %p\n", hbmNewBitmap);
3474 return hbmNewBitmap;
3475}
3476
3477/*************************************************************************
3478 * ImageList_SetColorTable [COMCTL32.@]
3479 *
3480 * Sets the color table of an image list.
3481 *
3482 * PARAMS
3483 * himl [I] Handle to the image list.
3484 * uStartIndex [I] The first index to set.
3485 * cEntries [I] Number of entries to set.
3486 * prgb [I] New color information for color table for the image list.
3487 *
3488 * RETURNS
3489 * Success: Number of entries in the table that were set.
3490 * Failure: Zero.
3491 *
3492 * SEE
3493 * ImageList_Create(), SetDIBColorTable()
3494 */
3495
3498{
3499#ifdef __REACTOS__
3500 if(!is_valid2(himl))
3501 return 0;
3502#endif
3503 TRACE("(%p, %d, %d, %p)\n", himl, uStartIndex, cEntries, prgb);
3505 return SetDIBColorTable(himl->hdcImage, uStartIndex, cEntries, prgb);
3506}
3507
3508/*************************************************************************
3509 * ImageList_CoCreateInstance [COMCTL32.@]
3510 *
3511 * Creates a new imagelist instance and returns an interface pointer to it.
3512 *
3513 * PARAMS
3514 * rclsid [I] A reference to the CLSID (CLSID_ImageList).
3515 * punkOuter [I] Pointer to IUnknown interface for aggregation, if desired
3516 * riid [I] Identifier of the requested interface.
3517 * ppv [O] Returns the address of the pointer requested, or NULL.
3518 *
3519 * RETURNS
3520 * Success: S_OK.
3521 * Failure: Error value.
3522 */
3524ImageList_CoCreateInstance (REFCLSID rclsid, const IUnknown *punkOuter, REFIID riid, void **ppv)
3525{
3526 TRACE("(%s,%p,%s,%p)\n", debugstr_guid(rclsid), punkOuter, debugstr_guid(riid), ppv);
3527
3528 if (!IsEqualCLSID(&CLSID_ImageList, rclsid))
3529 return E_NOINTERFACE;
3530
3531 return ImageListImpl_CreateInstance(punkOuter, riid, ppv);
3532}
3533
3534
3535/*************************************************************************
3536 * IImageList implementation
3537 */
3538
3540 REFIID iid, void **ppv)
3541{
3542 HIMAGELIST imgl = impl_from_IImageList2(iface);
3543
3544 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
3545
3546 if (!ppv) return E_INVALIDARG;
3547
3548 if (IsEqualIID(&IID_IUnknown, iid) ||
3549 IsEqualIID(&IID_IImageList, iid) ||
3550 IsEqualIID(&IID_IImageList2, iid))
3551 {
3552 *ppv = &imgl->IImageList2_iface;
3553 }
3554 else
3555 {
3556 *ppv = NULL;
3557 return E_NOINTERFACE;
3558 }
3559
3560 IImageList2_AddRef(iface);
3561 return S_OK;
3562}
3563
3565{
3566 HIMAGELIST imgl = impl_from_IImageList2(iface);
3568
3569 TRACE("(%p) refcount=%u\n", iface, ref);
3570 return ref;
3571}
3572
3574{
3577
3578 TRACE("(%p) refcount=%u\n", iface, ref);
3579
3580 if (ref == 0)
3581 {
3582 /* delete image bitmaps */
3583 if (This->hbmImage) DeleteObject (This->hbmImage);
3584 if (This->hbmMask) DeleteObject (This->hbmMask);
3585
3586 /* delete image & mask DCs */
3587 if (This->hdcImage) DeleteDC (This->hdcImage);
3588 if (This->hdcMask) DeleteDC (This->hdcMask);
3589
3590 /* delete blending brushes */
3591 if (This->hbrBlend25) DeleteObject (This->hbrBlend25);
3592 if (This->hbrBlend50) DeleteObject (This->hbrBlend50);
3593
3594#ifdef __REACTOS__
3595 This->usMagic = IMAGELIST_MAGIC_DESTROYED;
3596#endif
3597 This->IImageList2_iface.lpVtbl = NULL;
3598 heap_free(This->has_alpha);
3599 heap_free(This);
3600 }
3601
3602 return ref;
3603}
3604
3606 HBITMAP hbmMask, int *pi)
3607{
3608 HIMAGELIST imgl = impl_from_IImageList2(iface);
3609 int ret;
3610
3611 if (!pi)
3612 return E_FAIL;
3613
3614 ret = ImageList_Add(imgl, hbmImage, hbmMask);
3615
3616 if (ret == -1)
3617 return E_FAIL;
3618
3619 *pi = ret;
3620 return S_OK;
3621}
3622
3624 HICON hicon, int *pi)
3625{
3626 HIMAGELIST imgl = impl_from_IImageList2(iface);
3627 int ret;
3628
3629 if (!pi)
3630 return E_FAIL;
3631
3632 ret = ImageList_ReplaceIcon(imgl, i, hicon);
3633
3634 if (ret == -1)
3635 return E_FAIL;
3636
3637 *pi = ret;
3638 return S_OK;
3639}
3640
3642 int iImage, int iOverlay)
3643{
3644 HIMAGELIST imgl = impl_from_IImageList2(iface);
3645 return ImageList_SetOverlayImage(imgl, iImage, iOverlay) ? S_OK : E_FAIL;
3646}
3647
3649 HBITMAP hbmImage, HBITMAP hbmMask)
3650{
3651 HIMAGELIST imgl = impl_from_IImageList2(iface);
3652 return ImageList_Replace(imgl, i, hbmImage, hbmMask) ? S_OK : E_FAIL;
3653}
3654
3656 COLORREF crMask, int *pi)
3657{
3658 HIMAGELIST imgl = impl_from_IImageList2(iface);
3659 int ret;
3660
3661 if (!pi)
3662 return E_FAIL;
3663
3664 ret = ImageList_AddMasked(imgl, hbmImage, crMask);
3665
3666 if (ret == -1)
3667 return E_FAIL;
3668
3669 *pi = ret;
3670 return S_OK;
3671}
3672
3674 IMAGELISTDRAWPARAMS *pimldp)
3675{
3676 HIMAGELIST imgl = impl_from_IImageList2(iface);
3677 HIMAGELIST old_himl;
3678 int ret;
3679
3680 /* As far as I can tell, Windows simply ignores the contents of pimldp->himl
3681 so we shall simulate the same */
3682 old_himl = pimldp->himl;
3683 pimldp->himl = imgl;
3684
3685 ret = ImageList_DrawIndirect(pimldp);
3686
3687 pimldp->himl = old_himl;
3688 return ret ? S_OK : E_INVALIDARG;
3689}
3690
3692{
3693 HIMAGELIST imgl = impl_from_IImageList2(iface);
3694 return (ImageList_Remove(imgl, i) == 0) ? E_INVALIDARG : S_OK;
3695}
3696
3698 HICON *picon)
3699{
3700 HIMAGELIST imgl = impl_from_IImageList2(iface);
3701 HICON hIcon;
3702
3703 if (!picon)
3704 return E_FAIL;
3705
3706 hIcon = ImageList_GetIcon(imgl, i, flags);
3707
3708 if (hIcon == NULL)
3709 return E_FAIL;
3710
3711 *picon = hIcon;
3712 return S_OK;
3713}
3714
3717{
3718 HIMAGELIST imgl = impl_from_IImageList2(iface);
3719 return ImageList_GetImageInfo(imgl, i, pImageInfo) ? S_OK : E_FAIL;
3720}
3721
3722static HRESULT WINAPI ImageListImpl_Copy(IImageList2 *iface, int dst_index,
3723 IUnknown *unk_src, int src_index, UINT flags)
3724{
3725 HIMAGELIST imgl = impl_from_IImageList2(iface);
3726 IImageList *src = NULL;
3727 HRESULT ret;
3728
3729 if (!unk_src)
3730 return E_FAIL;
3731
3732#ifdef __REACTOS__
3733 /* Make sure that the second image list uses the same implementation with the first */
3734 if (!is_valid2((HIMAGELIST)unk_src))
3735 return E_FAIL;
3736#endif
3737
3738 /* TODO: Add test for IID_ImageList2 too */
3739 if (FAILED(IUnknown_QueryInterface(unk_src, &IID_IImageList,
3740 (void **) &src)))
3741 return E_FAIL;
3742
3743 if (ImageList_Copy(imgl, dst_index, (HIMAGELIST) src, src_index, flags))
3744 ret = S_OK;
3745 else
3746 ret = E_FAIL;
3747
3748 IImageList_Release(src);
3749 return ret;
3750}
3751
3753 IUnknown *punk2, int i2, int dx, int dy, REFIID riid, void **ppv)
3754{
3755 HIMAGELIST imgl = impl_from_IImageList2(iface);
3756 IImageList *iml2 = NULL;
3757 HIMAGELIST merged;
3758 HRESULT ret = E_FAIL;
3759
3760 TRACE("(%p)->(%d %p %d %d %d %s %p)\n", iface, i1, punk2, i2, dx, dy, debugstr_guid(riid), ppv);
3761
3762#ifdef __REACTOS__
3763 /* Make sure that the second image list uses the same implementation with the first */
3764 if (!is_valid2((HIMAGELIST)punk2))
3765 return E_FAIL;
3766#endif
3767
3768 /* TODO: Add test for IID_ImageList2 too */
3769 if (FAILED(IUnknown_QueryInterface(punk2, &IID_IImageList,
3770 (void **) &iml2)))
3771 return E_FAIL;
3772
3773 merged = ImageList_Merge(imgl, i1, (HIMAGELIST) iml2, i2, dx, dy);
3774
3775 /* Get the interface for the new image list */
3776 if (merged)
3777 {
3779 ImageList_Destroy(merged);
3780 }
3781
3782 IImageList_Release(iml2);
3783 return ret;
3784}
3785
3787{
3788 HIMAGELIST imgl = impl_from_IImageList2(iface);
3789 HIMAGELIST clone;
3790 HRESULT ret = E_FAIL;
3791
3792 TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
3793
3794 clone = ImageList_Duplicate(imgl);
3795
3796 /* Get the interface for the new image list */
3797 if (clone)
3798 {
3800 ImageList_Destroy(clone);
3801 }
3802
3803 return ret;
3804}
3805
3807 RECT *prc)
3808{
3809 HIMAGELIST imgl = impl_from_IImageList2(iface);
3811
3812 if (!prc)
3813 return E_FAIL;
3814
3815 if (!ImageList_GetImageInfo(imgl, i, &info))
3816 return E_FAIL;
3817
3818 *prc = info.rcImage;
3819
3820 return S_OK;
3821}
3822
3824 int *cy)
3825{
3826 HIMAGELIST imgl = impl_from_IImageList2(iface);
3827 return ImageList_GetIconSize(imgl, cx, cy) ? S_OK : E_INVALIDARG;
3828}
3829
3831 int cy)
3832{
3833 HIMAGELIST imgl = impl_from_IImageList2(iface);
3834 return ImageList_SetIconSize(imgl, cx, cy) ? S_OK : E_FAIL;
3835}
3836
3838{
3839 HIMAGELIST imgl = impl_from_IImageList2(iface);
3840 *pi = ImageList_GetImageCount(imgl);
3841 return S_OK;
3842}
3843
3845{
3846 HIMAGELIST imgl = impl_from_IImageList2(iface);
3847 return ImageList_SetImageCount(imgl, count) ? S_OK : E_FAIL;
3848}
3849
3851 COLORREF *pclr)
3852{
3853 HIMAGELIST imgl = impl_from_IImageList2(iface);
3854 *pclr = ImageList_SetBkColor(imgl, clrBk);
3855 return S_OK;
3856}
3857
3859{
3860 HIMAGELIST imgl = impl_from_IImageList2(iface);
3861 *pclr = ImageList_GetBkColor(imgl);
3862 return S_OK;
3863}
3864
3866 int dxHotspot, int dyHotspot)
3867{
3868 HIMAGELIST imgl = impl_from_IImageList2(iface);
3869 return ImageList_BeginDrag(imgl, iTrack, dxHotspot, dyHotspot) ? S_OK : E_FAIL;
3870}
3871
3873{
3875 return S_OK;
3876}
3877
3879 int x, int y)
3880{
3881 return ImageList_DragEnter(hwndLock, x, y) ? S_OK : E_FAIL;
3882}
3883
3885{
3886 return ImageList_DragLeave(hwndLock) ? S_OK : E_FAIL;
3887}
3888
3890{
3891 return ImageList_DragMove(x, y) ? S_OK : E_FAIL;
3892}
3893
3895 IUnknown *punk, int iDrag, int dxHotspot, int dyHotspot)
3896{
3897 IImageList *iml2 = NULL;
3898 BOOL ret;
3899
3900 if (!punk)
3901 return E_FAIL;
3902
3903 /* TODO: Add test for IID_ImageList2 too */
3904 if (FAILED(IUnknown_QueryInterface(punk, &IID_IImageList,
3905 (void **) &iml2)))
3906 return E_FAIL;
3907
3908 ret = ImageList_SetDragCursorImage((HIMAGELIST) iml2, iDrag, dxHotspot,
3909 dyHotspot);
3910
3911 IImageList_Release(iml2);
3912
3913 return ret ? S_OK : E_FAIL;
3914}
3915
3917{
3918 return ImageList_DragShowNolock(fShow) ? S_OK : E_FAIL;
3919}
3920
3923{
3924 HRESULT ret = E_FAIL;
3925 HIMAGELIST hNew;
3926
3927 if (!ppv)
3928 return E_FAIL;
3929
3931
3932 /* Get the interface for the new image list */
3933 if (hNew)
3934 {
3935 IImageList *idrag = (IImageList*)hNew;
3936
3938 IImageList_Release(idrag);
3939 }
3940
3941 return ret;
3942}
3943
3945 DWORD *dwFlags)
3946{
3947 FIXME("STUB: %p %d %p\n", iface, i, dwFlags);
3948 return E_NOTIMPL;
3949}
3950
3952 int *piIndex)
3953{
3955 int i;
3956
3957 if ((iOverlay < 0) || (iOverlay > This->cCurImage))
3958 return E_FAIL;
3959
3960 for (i = 0; i < MAX_OVERLAYIMAGE; i++)
3961 {
3962 if (This->nOvlIdx[i] == iOverlay)
3963 {
3964 *piIndex = i + 1;
3965 return S_OK;
3966 }
3967 }
3968
3969 return E_FAIL;
3970}
3971
3973{
3974 FIXME("(%p)->(%d %d): stub\n", iface, cx, cy);
3975 return E_NOTIMPL;
3976}
3977
3979{
3980 FIXME("(%p)->(%d %x %p %p): stub\n", iface, image, flags, cx, cy);
3981 return E_NOTIMPL;
3982}
3983
3985{
3986 FIXME("(%p)->(%d %d %d): stub\n", iface, image, cx, cy);
3987 return E_NOTIMPL;
3988}
3989
3991{
3992 FIXME("(%p)->(%p): stub\n", iface, callback);
3993 return E_NOTIMPL;
3994}
3995
3997{
3998 FIXME("(%p)->(%s %p): stub\n", iface, debugstr_guid(riid), ppv);
3999 return E_NOTIMPL;
4000}
4001
4003{
4004 FIXME("(%p)->(%d %x): stub\n", iface, image, flags);
4005 return E_NOTIMPL;
4006}
4007
4008static HRESULT WINAPI ImageListImpl_DiscardImages(IImageList2 *iface, INT first_image, INT last_image, DWORD flags)
4009{
4010 FIXME("(%p)->(%d %d %x): stub\n", iface, first_image, last_image, flags);
4011 return E_NOTIMPL;
4012}
4013
4015{
4016 FIXME("(%p)->(%p): stub\n", iface, params);
4017 return E_NOTIMPL;
4018}
4019
4020static HRESULT WINAPI ImageListImpl_GetStatistics(IImageList2 *iface, IMAGELISTSTATS *stats)
4021{
4022 FIXME("(%p)->(%p): stub\n", iface, stats);
4023 return E_NOTIMPL;
4024}
4025
4027{
4028 FIXME("(%p)->(%d %d %d %d %d): stub\n", iface, cx, cy, flags, initial, grow);
4029 return E_NOTIMPL;
4030}
4031
4033{
4034 FIXME("(%p)->(%d %p %p %p %x): stub\n", iface, i, image, mask, unk, flags);
4035 return E_NOTIMPL;
4036}
4037
4039 IUnknown *unk, DWORD flags)
4040{
4041 FIXME("(%p)->(%d %p %d %p %x): stub\n", iface, i, imagelist, src, unk, flags);
4042 return E_NOTIMPL;
4043}
4044
4045static const IImageList2Vtbl ImageListImpl_Vtbl = {
4090};
4091
4093{
4094 BOOL valid;
4095 __TRY
4096 {
4097 #ifdef __REACTOS__
4098 valid = himl && himl->usMagic == IMAGELIST_MAGIC;
4099 if (!valid && himl && himl->usMagic == IMAGELIST_MAGIC_DESTROYED)
4100 {
4101 ERR("Imagelist no longer valid: 0x%p\n", himl);
4102 }
4103 #else
4105 #endif
4106
4107 }
4109 {
4110 valid = FALSE;
4111 }
4112 __ENDTRY
4113 return valid;
4114}
4115
4116/*************************************************************************
4117 * HIMAGELIST_QueryInterface [COMCTL32.@]
4118 *
4119 * Returns a pointer to an IImageList or IImageList2 object for the given
4120 * HIMAGELIST.
4121 *
4122 * PARAMS
4123 * himl [I] Image list handle.
4124 * riid [I] Identifier of the requested interface.
4125 * ppv [O] Returns the address of the pointer requested, or NULL.
4126 *
4127 * RETURNS
4128 * Success: S_OK.
4129 * Failure: Error value.
4130 */
4133{
4134 TRACE("(%p,%s,%p)\n", himl, debugstr_guid(riid), ppv);
4135 return IImageList2_QueryInterface((IImageList2 *) himl, riid, ppv);
4136}
4137
4138static HRESULT ImageListImpl_CreateInstance(const IUnknown *pUnkOuter, REFIID iid, void** ppv)
4139{
4141 HRESULT ret;
4142
4143 TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);
4144
4145 *ppv = NULL;
4146
4147 if (pUnkOuter) return CLASS_E_NOAGGREGATION;
4148
4149 This = heap_alloc_zero(sizeof(struct _IMAGELIST));
4150 if (!This) return E_OUTOFMEMORY;
4151
4152 This->IImageList2_iface.lpVtbl = &ImageListImpl_Vtbl;
4153#ifdef __REACTOS__
4154 This->usMagic = IMAGELIST_MAGIC;
4155#endif
4156 This->ref = 1;
4157
4158 ret = IImageList2_QueryInterface(&This->IImageList2_iface, iid, ppv);
4159 IImageList2_Release(&This->IImageList2_iface);
4160
4161 return ret;
4162}
4163
4164
4165
4166#ifdef __REACTOS__
4167//The big bad reactos image list hack!
4168#undef ImageList_Add
4169#undef ImageList_ReplaceIcon
4170#undef ImageList_SetOverlayImage
4171#undef ImageList_Replace
4172#undef ImageList_AddMasked
4173#undef ImageList_Remove
4174#undef ImageList_GetIcon
4175#undef ImageList_GetImageInfo
4176#undef ImageList_Copy
4177#undef ImageList_Merge
4178#undef ImageList_Duplicate
4179#undef ImageList_GetIconSize
4180#undef ImageList_SetIconSize
4181#undef ImageList_GetImageCount
4182#undef ImageList_SetImageCount
4183#undef ImageList_SetBkColor
4184#undef ImageList_GetBkColor
4185#undef ImageList_BeginDrag
4186#undef ImageList_DrawIndirect
4187
4188static inline IImageList2* IImageList2_from_impl(HIMAGELIST himl)
4189{
4190 if (is_valid(himl))
4191 {
4192 return &himl->IImageList2_iface;
4193 }
4194 return NULL;
4195}
4196
4197BOOL is_valid2(HIMAGELIST himl)
4198{
4199 BOOL valid;
4200 __TRY
4201 {
4202 valid = himl &&
4204 himl->usMagic == IMAGELIST_MAGIC;
4205 if (!valid && himl &&
4206 himl->usMagic == IMAGELIST_MAGIC_DESTROYED)
4207 {
4208 ERR("Imagelist no longer valid: 0x%p\n", himl);
4209 }
4210 }
4212 {
4213 valid = FALSE;
4214 }
4215 __ENDTRY
4216 return valid;
4217}
4218
4219INT WINAPI
4220ImageList_Add (HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask)
4221{
4222 int res;
4223 HRESULT hr;
4224 IImageList2* piml = IImageList2_from_impl(himl);
4225 if (!piml)
4226 return -1;
4227
4228 hr = piml->lpVtbl->Add(piml, hbmImage, hbmMask, &res);
4229 if (FAILED(hr))
4230 return -1;
4231
4232 return res;
4233}
4234
4235INT WINAPI
4237{
4238 int res;
4239 HRESULT hr;
4240 IImageList2* piml = IImageList2_from_impl(himl);
4241 if (!piml)
4242 return -1;
4243
4244 hr = piml->lpVtbl->ReplaceIcon(piml, nIndex, hIcon, &res);
4245 if (FAILED(hr))
4246 return -1;
4247
4248 return res;
4249}
4250
4253{
4254 IImageList2* piml = IImageList2_from_impl(himl);
4255 if (!piml)
4256 return FALSE;
4257
4258 return (piml->lpVtbl->SetOverlayImage(piml, iImage, iOverlay) == S_OK) ? TRUE : FALSE;
4259}
4260
4263 HBITMAP hbmMask)
4264{
4265 IImageList2* piml = IImageList2_from_impl(himl);
4266 if (!piml)
4267 return FALSE;
4268
4269 return (piml->lpVtbl->Replace(piml, i, hbmImage, hbmMask) == S_OK) ? TRUE : FALSE;
4270}
4271
4272INT WINAPI
4274{
4275 int res;
4276 IImageList2* piml = IImageList2_from_impl(himl);
4277 HRESULT hr;
4278 if (!piml)
4279 return -1;
4280
4281 hr = piml->lpVtbl->AddMasked(piml, hBitmap, clrMask, &res);
4282 if (FAILED(hr))
4283 return -1;
4284
4285 return res;
4286}
4287
4290{
4291 IImageList2* piml = IImageList2_from_impl(himl);
4292 if (!piml)
4293 return FALSE;
4294
4295 return (piml->lpVtbl->Remove(piml, i) == S_OK) ? TRUE : FALSE;
4296}
4297
4300{
4301 HICON res;
4302 IImageList2* piml = IImageList2_from_impl(himl);
4303 HRESULT hr;
4304 if (!piml)
4305 return NULL;
4306
4307 hr = piml->lpVtbl->GetIcon(piml, i, fStyle, &res);
4308 if (FAILED(hr))
4309 return NULL;
4310
4311 return res;
4312}
4313
4316{
4317 IImageList2* piml = IImageList2_from_impl(himl);
4318 if (!piml)
4319 return FALSE;
4320
4321 return (piml->lpVtbl->GetImageInfo(piml, i, pImageInfo) == S_OK) ? TRUE : FALSE;
4322}
4323
4325ImageList_Copy (HIMAGELIST himlDst, INT iDst, HIMAGELIST himlSrc,
4326 INT iSrc, UINT uFlags)
4327{
4328 IImageList2 *pimlDst, *pimlSrc;
4329 pimlDst = IImageList2_from_impl(himlDst);
4330 pimlSrc = IImageList2_from_impl(himlSrc);
4331 if (!pimlDst || !pimlSrc)
4332 return FALSE;
4333
4334 return (pimlDst->lpVtbl->Copy(pimlDst, iDst, (IUnknown*)pimlSrc, iSrc, uFlags) == S_OK) ? TRUE : FALSE;
4335}
4336
4338ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2,
4339 INT dx, INT dy)
4340{
4341 HRESULT hr;
4342 IImageList2 *piml1, *piml2, *pimlMerged;
4343 piml1 = IImageList2_from_impl(himl1);
4344 piml2 = IImageList2_from_impl(himl2);
4345 if (!piml1 || !piml2)
4346 return NULL;
4347
4348 hr = piml1->lpVtbl->Merge(piml1, i1, (IUnknown*)piml2, i2, dx, dy, &IID_IImageList2, (void**)&pimlMerged);
4349 if (FAILED(hr))
4350 return NULL;
4351
4352 return (HIMAGELIST)pimlMerged;
4353}
4354
4357{
4358 HRESULT hr;
4359 IImageList2 *piml, *pimlCloned;
4360 piml = IImageList2_from_impl(himlSrc);
4361 if (!piml)
4362 return FALSE;
4363
4364 hr = piml->lpVtbl->Clone(piml, &IID_IImageList2, (void**)&pimlCloned);
4365 if (FAILED(hr))
4366 return NULL;
4367
4368 return (HIMAGELIST)pimlCloned;
4369}
4370
4373{
4374 IImageList2* piml = IImageList2_from_impl(himl);
4375 if (!piml)
4376 return FALSE;
4377
4378 return (piml->lpVtbl->GetIconSize(piml, cx, cy) == S_OK) ? TRUE : FALSE;
4379}
4380
4383{
4384 IImageList2* piml = IImageList2_from_impl(himl);
4385 if (!piml)
4386 return FALSE;
4387
4388 return (piml->lpVtbl->SetIconSize(piml, cx, cy) == S_OK) ? TRUE : FALSE;
4389}
4390
4391INT WINAPI
4393{
4394 int res;
4395 HRESULT hr;
4396 IImageList2* piml = IImageList2_from_impl(himl);
4397 if (!piml)
4398 return 0;
4399
4400 hr = piml->lpVtbl->GetImageCount(piml, &res);
4401 if (FAILED(hr))
4402 return 0;
4403
4404 return res;
4405}
4406
4409{
4410 IImageList2* piml = IImageList2_from_impl(himl);
4411 if (!piml)
4412 return FALSE;
4413
4414 return (piml->lpVtbl->SetImageCount(piml, iImageCount) == S_OK) ? TRUE : FALSE;
4415}
4416
4419{
4420 COLORREF res;
4421 HRESULT hr;
4422 IImageList2* piml = IImageList2_from_impl(himl);
4423 if (!piml)
4424 return CLR_NONE;
4425
4426 hr = piml->lpVtbl->SetBkColor(piml, clrBk, &res);
4427 if (FAILED(hr))
4428 return CLR_NONE;
4429
4430 return res;
4431}
4432
4435{
4436 COLORREF res;
4437 HRESULT hr;
4438 IImageList2* piml = IImageList2_from_impl(himl);
4439 if (!piml)
4440 return CLR_NONE;
4441
4442 hr = piml->lpVtbl->GetBkColor(piml, &res);
4443 if (FAILED(hr))
4444 return CLR_NONE;
4445
4446 return res;
4447}
4448
4450ImageList_BeginDrag (HIMAGELIST himlTrack, INT iTrack,
4451 INT dxHotspot, INT dyHotspot)
4452{
4453 IImageList2* piml = IImageList2_from_impl(himlTrack);
4454 if (!piml)
4455 return FALSE;
4456
4457 return (piml->lpVtbl->BeginDrag(piml, iTrack, dxHotspot, dyHotspot) == S_OK) ? TRUE : FALSE;
4458}
4459
4462{
4463 IImageList2* piml;
4464
4465 if (!pimldp)
4466 return FALSE;
4467
4468 piml = IImageList2_from_impl(pimldp->himl);
4469 if (!piml)
4470 return FALSE;
4471
4472 return (piml->lpVtbl->Draw(piml, pimldp) == S_OK) ? TRUE : FALSE;
4473}
4474
4475#endif
Arabic default style
Definition: afstyles.h:94
struct BITMAPINFOHEADER * LPBITMAPINFOHEADER
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
DWORD GetPixel(LPDIRECTDRAWSURFACE7 Surface, UINT x, UINT y)
Definition: blt.cpp:2
HIMAGELIST himl
#define ILC_SYSTEM
COMCTL32_SysColor comctl32_color
Definition: commctrl.c:82
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HBITMAP hBitmap
Definition: timezone.c:26
DWORD bpp
Definition: surface.c:185
UINT uFlags
Definition: api.c:59
static HRESULT WINAPI ImageListImpl_DragEnter(IImageList2 *iface, HWND hwndLock, int x, int y)
Definition: imagelist.c:3878
static HRESULT WINAPI ImageListImpl_DiscardImages(IImageList2 *iface, INT first_image, INT last_image, DWORD flags)
Definition: imagelist.c:4008
static BOOL _write_bitmap(HBITMAP hBitmap, IStream *pstm)
Definition: imagelist.c:3291
BOOL WINAPI ImageList_SetIconSize(HIMAGELIST himl, INT cx, INT cy)
Definition: imagelist.c:3132
BOOL WINAPI ImageList_SetFilter(HIMAGELIST himl, INT i, DWORD dwFilter)
Definition: imagelist.c:3050
BOOL WINAPI ImageList_Draw(HIMAGELIST himl, INT i, HDC hdc, INT x, INT y, UINT fStyle)
Definition: imagelist.c:1246
static HRESULT WINAPI ImageListImpl_Merge(IImageList2 *iface, int i1, IUnknown *punk2, int i2, int dx, int dy, REFIID riid, void **ppv)
Definition: imagelist.c:3752
struct _ILHEAD ILHEAD
HRESULT WINAPI HIMAGELIST_QueryInterface(HIMAGELIST himl, REFIID riid, void **ppv)
Definition: imagelist.c:4132
BOOL WINAPI ImageList_Remove(HIMAGELIST himl, INT i)
Definition: imagelist.c:2628
static BOOL is_valid(HIMAGELIST himl)
Definition: imagelist.c:4092
static void imagelist_copy_images(HIMAGELIST himl, HDC hdcSrc, HDC hdcDest, UINT src, UINT count, UINT dest)
Definition: imagelist.c:225
static HRESULT WINAPI ImageListImpl_GetOriginalSize(IImageList2 *iface, INT image, DWORD flags, INT *cx, INT *cy)
Definition: imagelist.c:3978
static HRESULT WINAPI ImageListImpl_SetImageCount(IImageList2 *iface, UINT count)
Definition: imagelist.c:3844
static int get_dib_stride(int width, int bpp)
Definition: imagelist.c:208
static HRESULT WINAPI ImageListImpl_GetImageRect(IImageList2 *iface, int i, RECT *prc)
Definition: imagelist.c:3806
COLORREF WINAPI ImageList_SetBkColor(HIMAGELIST himl, COLORREF clrBk)
Definition: imagelist.c:2949
static HRESULT WINAPI ImageListImpl_Resize(IImageList2 *iface, INT cx, INT cy)
Definition: imagelist.c:3972
static HRESULT WINAPI ImageListImpl_Copy(IImageList2 *iface, int dst_index, IUnknown *unk_src, int src_index, UINT flags)
Definition: imagelist.c:3722
INT WINAPI ImageList_Add(HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask)
Definition: imagelist.c:458
HIMAGELIST WINAPI ImageList_LoadImageA(HINSTANCE hi, LPCSTR lpbmp, INT cx, INT cGrow, COLORREF clrMask, UINT uType, UINT uFlags)
Definition: imagelist.c:2182
BOOL WINAPI ImageList_Replace(HIMAGELIST himl, INT i, HBITMAP hbmImage, HBITMAP hbmMask)
Definition: imagelist.c:2763
#define TILE_COUNT
Definition: imagelist.c:189
static HRESULT WINAPI ImageListImpl_AddMasked(IImageList2 *iface, HBITMAP hbmImage, COLORREF crMask, int *pi)
Definition: imagelist.c:3655
BOOL WINAPI ImageList_SetOverlayImage(HIMAGELIST himl, INT iImage, INT iOverlay)
Definition: imagelist.c:3274
HIMAGELIST WINAPI ImageList_Duplicate(HIMAGELIST himlSrc)
Definition: imagelist.c:1819
static HRESULT WINAPI ImageListImpl_SetOriginalSize(IImageList2 *iface, INT image, INT cx, INT cy)
Definition: imagelist.c:3984
static void imagelist_point_from_index(HIMAGELIST himl, UINT index, LPPOINT pt)
Definition: imagelist.c:196
INT WINAPI ImageList_ReplaceIcon(HIMAGELIST himl, INT nIndex, HICON hIcon)
Definition: imagelist.c:2839
static void IMAGELIST_InternalExpandBitmaps(HIMAGELIST himl, INT nImageCount)
Definition: imagelist.c:371
static HRESULT WINAPI ImageListImpl_ForceImagePresent(IImageList2 *iface, INT image, DWORD flags)
Definition: imagelist.c:4002
static void add_dib_bits(HIMAGELIST himl, int pos, int count, int width, int height, BITMAPINFO *info, BITMAPINFO *mask_info, DWORD *bits, BYTE *mask_bits)
Definition: imagelist.c:244
static HRESULT WINAPI ImageListImpl_GetDragImage(IImageList2 *iface, POINT *ppt, POINT *pptHotspot, REFIID riid, PVOID *ppv)
Definition: imagelist.c:3921
static HRESULT WINAPI ImageListImpl_EndDrag(IImageList2 *iface)
Definition: imagelist.c:3872
BOOL WINAPI ImageList_GetImageInfo(HIMAGELIST himl, INT i, IMAGEINFO *pImageInfo)
Definition: imagelist.c:2106
VOID WINAPI ImageList_EndDrag(void)
Definition: imagelist.c:1865
BOOL WINAPI ImageList_DragEnter(HWND hwndLock, INT x, INT y)
Definition: imagelist.c:976
#define IMAGELIST_MAGIC
Definition: imagelist.c:120
BOOL WINAPI ImageList_DragMove(INT x, INT y)
Definition: imagelist.c:1088
static HRESULT WINAPI ImageListImpl_GetIcon(IImageList2 *iface, int i, UINT flags, HICON *picon)
Definition: imagelist.c:3697
static HRESULT WINAPI ImageListImpl_Add(IImageList2 *iface, HBITMAP hbmImage, HBITMAP hbmMask, int *pi)
Definition: imagelist.c:3605
COLORREF WINAPI ImageList_GetBkColor(HIMAGELIST himl)
Definition: imagelist.c:1897
static HRESULT WINAPI ImageListImpl_ReplaceIcon(IImageList2 *iface, int i, HICON hicon, int *pi)
Definition: imagelist.c:3623
BOOL WINAPI ImageList_GetImageRect(HIMAGELIST himl, INT i, LPRECT lpRect)
Definition: imagelist.c:2147
BOOL WINAPI ImageList_DragLeave(HWND hwndLock)
Definition: imagelist.c:1010
static INTERNALDRAG InternalDrag
Definition: imagelist.c:167
static UINT imagelist_height(UINT count)
Definition: imagelist.c:191
static BOOL alpha_blend_image(HIMAGELIST himl, HDC dest_dc, int dest_x, int dest_y, int src_x, int src_y, int cx, int cy, BLENDFUNCTION func, UINT style, COLORREF blend_col)
Definition: imagelist.c:1307
HRESULT WINAPI ImageList_CoCreateInstance(REFCLSID rclsid, const IUnknown *punkOuter, REFIID riid, void **ppv)
Definition: imagelist.c:3524
static HRESULT WINAPI ImageListImpl_BeginDrag(IImageList2 *iface, int iTrack, int dxHotspot, int dyHotspot)
Definition: imagelist.c:3865
static HRESULT WINAPI ImageListImpl_DragLeave(IImageList2 *iface, HWND hwndLock)
Definition: imagelist.c:3884
static HRESULT WINAPI ImageListImpl_GetItemFlags(IImageList2 *iface, int i, DWORD *dwFlags)
Definition: imagelist.c:3944
BOOL WINAPI ImageList_DrawIndirect(IMAGELISTDRAWPARAMS *pimldp)
Definition: imagelist.c:1543
static void * read_bitmap(IStream *pstm, BITMAPINFO *bmi)
Definition: imagelist.c:2418
static HRESULT WINAPI ImageListImpl_SetBkColor(IImageList2 *iface, COLORREF clrBk, COLORREF *pclr)
Definition: imagelist.c:3850
static HRESULT WINAPI ImageListImpl_GetImageInfo(IImageList2 *iface, int i, IMAGEINFO *pImageInfo)
Definition: imagelist.c:3715
HIMAGELIST WINAPI ImageList_GetDragImage(POINT *ppt, POINT *pptHotspot)
Definition: imagelist.c:1918
static HRESULT WINAPI ImageListImpl_GetImageCount(IImageList2 *iface, int *pi)
Definition: imagelist.c:3837
static BOOL add_with_alpha(HIMAGELIST himl, HDC hdc, int pos, int count, int width, int height, HBITMAP hbmImage, HBITMAP hbmMask)
Definition: imagelist.c:295
static HRESULT WINAPI ImageListImpl_Replace2(IImageList2 *iface, INT i, HBITMAP image, HBITMAP mask, IUnknown *unk, DWORD flags)
Definition: imagelist.c:4032
DWORD WINAPI ImageList_SetFlags(HIMAGELIST himl, DWORD flags)
Definition: imagelist.c:3108
BOOL WINAPI ImageList_Destroy(HIMAGELIST himl)
Definition: imagelist.c:941
static HRESULT WINAPI ImageListImpl_DragShowNolock(IImageList2 *iface, BOOL fShow)
Definition: imagelist.c:3916
UINT WINAPI ImageList_SetColorTable(HIMAGELIST himl, UINT uStartIndex, UINT cEntries, const RGBQUAD *prgb)
Definition: imagelist.c:3497
static HRESULT WINAPI ImageListImpl_GetBkColor(IImageList2 *iface, COLORREF *pclr)
Definition: imagelist.c:3858
BOOL WINAPI ImageList_DrawEx(HIMAGELIST himl, INT i, HDC hdc, INT x, INT y, INT dx, INT dy, COLORREF rgbBk, COLORREF rgbFg, UINT fStyle)
Definition: imagelist.c:1282
static HRESULT WINAPI ImageListImpl_Draw(IImageList2 *iface, IMAGELISTDRAWPARAMS *pimldp)
Definition: imagelist.c:3673
static HRESULT WINAPI ImageListImpl_Replace(IImageList2 *iface, int i, HBITMAP hbmImage, HBITMAP hbmMask)
Definition: imagelist.c:3648
static void imagelist_get_bitmap_size(HIMAGELIST himl, UINT count, SIZE *sz)
Definition: imagelist.c:202
HIMAGELIST WINAPI ImageList_LoadImageW(HINSTANCE hi, LPCWSTR lpbmp, INT cx, INT cGrow, COLORREF clrMask, UINT uType, UINT uFlags)
Definition: imagelist.c:2226
static HBITMAP ImageList_CreateImage(HDC hdc, HIMAGELIST himl, UINT count)
Definition: imagelist.c:3420
HIMAGELIST WINAPI ImageList_Merge(HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2, INT dx, INT dy)
Definition: imagelist.c:2331
static HRESULT WINAPI ImageListImpl_DragMove(IImageList2 *iface, int x, int y)
Definition: imagelist.c:3889
static HRESULT WINAPI ImageListImpl_GetIconSize(IImageList2 *iface, int *cx, int *cy)
Definition: imagelist.c:3823
#define MAX_OVERLAYIMAGE
Definition: imagelist.c:52
HICON WINAPI ImageList_GetIcon(HIMAGELIST himl, INT i, UINT fStyle)
Definition: imagelist.c:1981
static HRESULT WINAPI ImageListImpl_GetStatistics(IImageList2 *iface, IMAGELISTSTATS *stats)
Definition: imagelist.c:4020
BOOL WINAPI ImageList_Write(HIMAGELIST himl, IStream *pstm)
Definition: imagelist.c:3377
static HRESULT WINAPI ImageListImpl_Clone(IImageList2 *iface, REFIID riid, void **ppv)
Definition: imagelist.c:3786
BOOL WINAPI ImageList_Copy(HIMAGELIST himlDst, INT iDst, HIMAGELIST himlSrc, INT iSrc, UINT uFlags)
Definition: imagelist.c:716
static HRESULT WINAPI ImageListImpl_SetOverlayImage(IImageList2 *iface, int iImage, int iOverlay)
Definition: imagelist.c:3641
static ULONG WINAPI ImageListImpl_Release(IImageList2 *iface)
Definition: imagelist.c:3573
static HRESULT WINAPI ImageListImpl_QueryInterface(IImageList2 *iface, REFIID iid, void **ppv)
Definition: imagelist.c:3539
static void ImageList_InternalDragDraw(HDC hdc, INT x, INT y)
Definition: imagelist.c:1050
static HRESULT WINAPI ImageListImpl_GetOverlayImage(IImageList2 *iface, int iOverlay, int *piIndex)
Definition: imagelist.c:3951
BOOL WINAPI ImageList_BeginDrag(HIMAGELIST himlTrack, INT iTrack, INT dxHotspot, INT dyHotspot)
Definition: imagelist.c:648
static HRESULT WINAPI ImageListImpl_Remove(IImageList2 *iface, int i)
Definition: imagelist.c:3691
INT WINAPI ImageList_GetImageCount(HIMAGELIST himl)
Definition: imagelist.c:2081
static HRESULT WINAPI ImageListImpl_Initialize(IImageList2 *iface, INT cx, INT cy, UINT flags, INT initial, INT grow)
Definition: imagelist.c:4026
static HRESULT WINAPI ImageListImpl_SetDragCursorImage(IImageList2 *iface, IUnknown *punk, int iDrag, int dxHotspot, int dyHotspot)
Definition: imagelist.c:3894
INT WINAPI ImageList_AddMasked(HIMAGELIST himl, HBITMAP hBitmap, COLORREF clrMask)
Definition: imagelist.c:573
HIMAGELIST WINAPI ImageList_Create(INT cx, INT cy, UINT flags, INT cInitial, INT cGrow)
Definition: imagelist.c:814
BOOL WINAPI ImageList_SetImageCount(HIMAGELIST himl, UINT iImageCount)
Definition: imagelist.c:3183
static HRESULT WINAPI ImageListImpl_GetCallback(IImageList2 *iface, REFIID riid, void **ppv)
Definition: imagelist.c:3996
static HRESULT WINAPI ImageListImpl_SetIconSize(IImageList2 *iface, int cx, int cy)
Definition: imagelist.c:3830
BOOL WINAPI ImageList_DragShowNolock(BOOL bShow)
Definition: imagelist.c:1171
static HRESULT WINAPI ImageListImpl_SetCallback(IImageList2 *iface, IUnknown *callback)
Definition: imagelist.c:3990
static HRESULT WINAPI ImageListImpl_ReplaceFromImageList(IImageList2 *iface, INT i, IImageList *imagelist, INT src, IUnknown *unk, DWORD flags)
Definition: imagelist.c:4038
static HRESULT WINAPI ImageListImpl_PreloadImages(IImageList2 *iface, IMAGELISTDRAWPARAMS *params)
Definition: imagelist.c:4014
BOOL WINAPI ImageList_GetIconSize(HIMAGELIST himl, INT *cx, INT *cy)
Definition: imagelist.c:2055
static HIMAGELIST impl_from_IImageList2(IImageList2 *iface)
Definition: imagelist.c:169
static int get_dib_image_size(const BITMAPINFO *info)
Definition: imagelist.c:213
static HRESULT ImageListImpl_CreateInstance(const IUnknown *pUnkOuter, REFIID iid, void **ppv)
Definition: imagelist.c:4138
static const IImageList2Vtbl ImageListImpl_Vtbl
Definition: imagelist.c:4045
DWORD WINAPI ImageList_GetFlags(HIMAGELIST himl)
Definition: imagelist.c:1952
BOOL WINAPI ImageList_SetDragCursorImage(HIMAGELIST himlDrag, INT iDrag, INT dxHotspot, INT dyHotspot)
Definition: imagelist.c:2988
HIMAGELIST WINAPI ImageList_Read(IStream *pstm)
Definition: imagelist.c:2494
static ULONG WINAPI ImageListImpl_AddRef(IImageList2 *iface)
Definition: imagelist.c:3564
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define __TRY
Definition: compat.h:80
#define HeapFree(x, y, z)
Definition: compat.h:735
#define __ENDTRY
Definition: compat.h:82
#define MultiByteToWideChar
Definition: compat.h:110
#define __EXCEPT_PAGE_FAULT
Definition: compat.h:81
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static void cleanup(void)
Definition: main.c:1335
#define pt(x, y)
Definition: drawing.c:79
static VOID BitBlt(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_reads_bytes_(Delta *Height) PUCHAR Buffer, _In_ ULONG BitsPerPixel, _In_ ULONG Delta)
Definition: common.c:57
#define BI_RGB
Definition: precomp.h:56
#define RGB(r, g, b)
Definition: precomp.h:71
#define GetBValue(quad)
Definition: precomp.h:75
#define GetGValue(quad)
Definition: precomp.h:74
ULONG RGBQUAD
Definition: precomp.h:59
#define GetRValue(quad)
Definition: precomp.h:73
#define abs(i)
Definition: fconv.c:206
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
BOOLEAN valid
pKey DeleteObject()
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLint GLint GLsizei width
Definition: gl.h:1546
GLenum func
Definition: glext.h:6028
GLdouble n
Definition: glext.h:7729
GLsizei stride
Definition: glext.h:5848
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLuint color
Definition: glext.h:6243
GLuint index
Definition: glext.h:6031
GLenum GLint GLuint mask
Definition: glext.h:6028
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLboolean GLboolean g
Definition: glext.h:6204
GLuint64EXT * result
Definition: glext.h:11304
GLuint GLuint num
Definition: glext.h:9618
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define bits
Definition: infblock.c:15
HRESULT ReplaceIcon([in] int i, [in] HICON hicon, [out] int *pi)
HRESULT GetImageInfo([in] int i, [out] IMAGEINFO *pImageInfo)
HRESULT GetBkColor([out] COLORREF *pclr)
HRESULT GetIcon([in] int i, [in] UINT flags, [out] HICON *picon)
HRESULT Draw([in] IMAGELISTDRAWPARAMS *pimldp)
HRESULT Add([in] HBITMAP hbmImage, [in] HBITMAP hbmMask, [out] int *pi)
HRESULT Replace([in] int i, [in] HBITMAP hbmImage, [in] HBITMAP hbmMask)
HRESULT SetImageCount([in] UINT uNewCount)
HRESULT GetIconSize([out] int *cx, [out] int *cy)
HRESULT SetIconSize([in] int cx, [in] int cy)
HRESULT Clone([in] REFIID riid, [out] PVOID *ppv)
HRESULT SetBkColor([in] COLORREF clrBk, [out] COLORREF *pclr)
HRESULT AddMasked([in] HBITMAP hbmImage, [in] COLORREF crMask, [out] int *pi)
HRESULT Merge([in] int i1, [in] IUnknown *punk2, [in] int i2, [in] int dx, [in] int dy, [out] REFIID riid, [out] PVOID *ppv)
HRESULT BeginDrag([in] int iTrack, [in] int dxHotspot, [in] int dyHotspot)
HRESULT GetImageCount([out] int *pi)
HRESULT Copy([in] int iDst, [in] IUnknown *punkSrc, [in] int iSrc, [in] UINT uFlags)
HRESULT Remove([in] int i)
HRESULT SetOverlayImage([in] int iImage, [in] int iOverlay)
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
GLint dy
Definition: linetemp.h:97
if(dx< 0)
Definition: linetemp.h:194
GLint dx
Definition: linetemp.h:97
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
#define WinVerMajor()
Definition: imagelist.c:14
#define ILC_COLORMASK
Definition: imagelist.c:16
BITMAP bmp
Definition: alphablend.c:62
BOOL WINAPI GdiAlphaBlend(HDC hdcDst, int xDst, int yDst, int widthDst, int heightDst, HDC hdcSrc, int xSrc, int ySrc, int widthSrc, int heightSrc, BLENDFUNCTION blendFunction)
#define AC_SRC_ALPHA
Definition: alphablend.c:9
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:88
static HICON
Definition: imagelist.c:80
static IPrintDialogCallback callback
Definition: printdlg.c:326
static char * dest
Definition: rtl.c:135
static const BYTE dib[]
Definition: ole2.c:201
static refpint_t pi[]
Definition: server.c:96
#define min(a, b)
Definition: monoChain.cc:55
HICON hIcon
Definition: msconfig.c:44
unsigned int UINT
Definition: ndis.h:50
_Out_ LPRECT prc
Definition: ntgdi.h:1658
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define ILC_COLOR4
Definition: commctrl.h:354
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
#define ILD_NORMAL
Definition: commctrl.h:417
#define ILD_OVERLAYMASK
Definition: commctrl.h:424
#define ILD_BLEND25
Definition: commctrl.h:422
#define ILC_COLORDDB
Definition: commctrl.h:353
#define ILS_SHADOW
Definition: commctrl.h:437
#define ILC_COLOR16
Definition: commctrl.h:356
#define ILC_COLOR8
Definition: commctrl.h:355
#define CLR_NONE
Definition: commctrl.h:319
_Out_opt_ int * cx
Definition: commctrl.h:585
_In_ int _Out_ IMAGEINFO * pImageInfo
Definition: commctrl.h:604
#define ILC_COLOR32
Definition: commctrl.h:358
#define ILD_DPISCALE
Definition: commctrl.h:428
#define ILS_ALPHA
Definition: commctrl.h:439
#define ILD_TRANSPARENT
Definition: commctrl.h:418
#define ILS_NORMAL
Definition: commctrl.h:435
#define ILS_SATURATE
Definition: commctrl.h:438
#define CLR_DEFAULT
Definition: commctrl.h:320
#define ILS_GLOW
Definition: commctrl.h:436
#define ImageList_AddIcon(himl, hicon)
Definition: commctrl.h:415
#define ILD_ROP
Definition: commctrl.h:421
#define ILC_MASK
Definition: commctrl.h:351
#define ILD_IMAGE
Definition: commctrl.h:420
#define ILD_SCALE
Definition: commctrl.h:427
#define ILD_MASK
Definition: commctrl.h:419
#define ILD_PRESERVEALPHA
Definition: commctrl.h:426
#define ILD_BLEND50
Definition: commctrl.h:423
_Out_opt_ POINT * pptHotspot
Definition: commctrl.h:554
#define ILCF_SWAP
Definition: commctrl.h:511
#define ILC_COLOR
Definition: commctrl.h:352
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
#define IsEqualCLSID(rclsid1, rclsid2)
Definition: guiddef.h:96
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
HDC hdcBitmap
Definition: solcreate.cpp:9
#define TRACE(s)
Definition: solgame.cpp:4
LONG biYPelsPerMeter
Definition: amvideo.idl:38
DWORD biCompression
Definition: amvideo.idl:35
DWORD biClrImportant
Definition: amvideo.idl:40
LONG biXPelsPerMeter
Definition: amvideo.idl:37
DWORD biSizeImage
Definition: amvideo.idl:36
COLORREF clrWindow
Definition: comctl32.h:182
HBITMAP hbmMask
HBITMAP hbmImage
HBITMAP hbmBg
Definition: imagelist.c:164
HIMAGELIST himlNoCursor
Definition: imagelist.c:154
HIMAGELIST himl
Definition: imagelist.c:153
Definition: bl.h:1331
DWORD yHotspot
Definition: winuser.h:3136
BOOL fIcon
Definition: winuser.h:3134
DWORD xHotspot
Definition: winuser.h:3135
HBITMAP hbmColor
Definition: winuser.h:3138
HBITMAP hbmMask
Definition: winuser.h:3137
WORD cCurImage
Definition: imagelist.c:138
WORD flags
Definition: imagelist.c:144
WORD cy
Definition: imagelist.c:142
SHORT ovls[4]
Definition: imagelist.c:145
WORD cMaxImage
Definition: imagelist.c:139
USHORT usMagic
Definition: imagelist.c:136
WORD cGrow
Definition: imagelist.c:140
COLORREF bkcolor
Definition: imagelist.c:143
USHORT usVersion
Definition: imagelist.c:137
WORD cx
Definition: imagelist.c:141
INT cGrow
Definition: imagelist.c:88
HBRUSH hbrBlend50
Definition: imagelist.c:108
HBITMAP hbmImage
Definition: imagelist.c:97
INT cMaxImage
Definition: imagelist.c:87
INT cCurImage
Definition: imagelist.c:86
COLORREF clrBk
Definition: imagelist.c:94
INT nOvlIdx[MAX_OVERLAYIMAGE]
Definition: imagelist.c:101
UINT uBitsPixel
Definition: imagelist.c:110
BOOL color_table_set
Definition: imagelist.c:112
IImageList2 IImageList2_iface
Definition: imagelist.c:85
HDC hdcImage
Definition: imagelist.c:99
COLORREF clrFg
Definition: imagelist.c:93
HBITMAP hbmMask
Definition: imagelist.c:98
HDC hdcMask
Definition: imagelist.c:100
UINT flags
Definition: imagelist.c:92
char * has_alpha
Definition: imagelist.c:111
INT cInitial
Definition: imagelist.c:109
HBRUSH hbrBlend25
Definition: imagelist.c:107
DWORD x4
Definition: imagelist.c:91
LONG ref
Definition: imagelist.c:114
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
Definition: send.c:48
USHORT biBitCount
Definition: precomp.h:46
ULONG biCompression
Definition: precomp.h:47
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1476
RGBQUAD bmiColors[1]
Definition: wingdi.h:1477
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
#define max(a, b)
Definition: svc.c:63
static UINT width_bytes(UINT width, UINT bpp)
Definition: tiffformat.c:859
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
int ret
HBITMAP WINAPI CreateDIBSection(HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
Definition: bitmap.c:245
UINT WINAPI GetDIBColorTable(HDC hDC, UINT iStartIndex, UINT cEntries, RGBQUAD *pColors)
Definition: palette.c:123
#define ZeroMemory
Definition: winbase.h:1743
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
DWORD COLORREF
Definition: windef.h:300
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
#define BLACKNESS
Definition: wingdi.h:323
#define DIB_RGB_COLORS
Definition: wingdi.h:367
HGDIOBJ WINAPI GetStockObject(_In_ int)
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)
struct tagBITMAPFILEHEADER BITMAPFILEHEADER
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
COLORREF WINAPI SetBkColor(_In_ HDC, _In_ COLORREF)
Definition: dc.c:999
int WINAPI GetDIBits(_In_ HDC hdc, _In_ HBITMAP hbm, _In_ UINT start, _In_ UINT cLines, _Out_opt_ LPVOID lpvBits, _At_((LPBITMAPINFOHEADER) lpbmi, _Inout_) LPBITMAPINFO lpbmi, _In_ UINT usage)
COLORREF WINAPI GetTextColor(_In_ HDC)
Definition: text.c:861
#define WHITENESS
Definition: wingdi.h:337
#define AC_SRC_OVER
Definition: wingdi.h:1369
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
#define DI_NORMAL
Definition: wingdi.h:72
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
BOOL WINAPI StretchBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
#define SRCCOPY
Definition: wingdi.h:333
COLORREF WINAPI GetBkColor(_In_ HDC)
Definition: dc.c:978
#define DI_IMAGE
Definition: wingdi.h:70
#define PATCOPY
Definition: wingdi.h:335
#define SRCPAINT
Definition: wingdi.h:334
_In_ UINT _In_ UINT cEntries
Definition: wingdi.h:3621
BOOL WINAPI PatBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
#define BLACK_BRUSH
Definition: wingdi.h:896
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
UINT WINAPI SetDIBColorTable(_In_ HDC hdc, _In_ UINT iStart, _In_ UINT cEntries, _In_reads_(cEntries) const RGBQUAD *prgbq)
#define GetAValue(rgb)
Definition: wingdi.h:2938
#define DI_MASK
Definition: wingdi.h:71
#define BITSPIXEL
Definition: wingdi.h:720
COLORREF WINAPI GetNearestColor(_In_ HDC, _In_ COLORREF)
struct tagBITMAPFILEHEADER * LPBITMAPFILEHEADER
#define RGBA(r, g, b, a)
Definition: wingdi.h:2941
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:918
#define NOTSRCCOPY
Definition: wingdi.h:325
HBRUSH WINAPI CreateSolidBrush(_In_ COLORREF)
BOOL WINAPI DeleteDC(_In_ HDC)
#define DI_DEFAULTSIZE
Definition: wingdi.h:69
#define SRCAND
Definition: wingdi.h:330
int WINAPI StretchDIBits(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ const VOID *, _In_ const BITMAPINFO *, _In_ UINT, _In_ DWORD)
HBRUSH WINAPI CreatePatternBrush(_In_ HBITMAP)
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
DWORD WINAPI GetSysColor(_In_ int)
#define IMAGE_BITMAP
Definition: winuser.h:211
HICON WINAPI CreateIconIndirect(_In_ PICONINFO)
Definition: cursoricon.c:2943
#define DCX_CACHE
Definition: winuser.h:2125
#define DCX_WINDOW
Definition: winuser.h:2124
#define IMAGE_ICON
Definition: winuser.h:212
BOOL WINAPI GetIconInfo(_In_ HICON, _Out_ PICONINFO)
Definition: cursoricon.c:2382
#define LR_COPYFROMRESOURCE
Definition: winuser.h:1110
#define COLOR_HIGHLIGHT
Definition: winuser.h:937
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
HANDLE WINAPI LoadImageW(_In_opt_ HINSTANCE hInst, _In_ LPCWSTR name, _In_ UINT type, _In_ int cx, _In_ int cy, _In_ UINT fuLoad)
Definition: cursoricon.c:2540
HDC WINAPI GetDCEx(_In_opt_ HWND, _In_opt_ HRGN, _In_ DWORD)
HANDLE WINAPI CopyImage(_In_ HANDLE, _In_ UINT, _In_ int, _In_ int, _In_ UINT)
Definition: cursoricon.c:2275
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628
BOOL WINAPI DrawIconEx(_In_ HDC, _In_ int, _In_ int, _In_ HICON, _In_ int, _In_ int, _In_ UINT, _In_opt_ HBRUSH, _In_ UINT)
Definition: cursoricon.c:2365
HDC WINAPI GetDC(_In_opt_ HWND)
#define IMAGE_CURSOR
Definition: winuser.h:213
#define DCX_LOCKWINDOWUPDATE
Definition: winuser.h:2131
#define SM_CXICON
Definition: winuser.h:983
int WINAPI GetSystemMetrics(_In_ int)
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2390
static HDC hdcSrc
Definition: xlate.c:32
static HDC hdcDst
Definition: xlate.c:32
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193