blob: 4afb9eae0ec58feeffc31cc467c7d4a591c28de8 [file] [log] [blame]
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001/*
2 * ImageList implementation
3 *
4 * Copyright 1998 Eric Kohl
Dimitrie O. Paun318817f2002-09-12 00:51:09 +00005 * Copyright 2000 Jason Mawdsley
6 * Copyright 2001 Michael Stefaniuc
7 * Copyright 2001 Charles Loep for CodeWeavers
8 * Copyright 2002 Dimitrie O. Paun
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00009 *
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000010 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
Dimitrie O. Paunda9bac42002-10-16 18:57:14 +000024 * NOTE
25 *
26 * This code was audited for completeness against the documented features
27 * of Comctl32.dll version 6.0 on Sep. 12, 2002, by Dimitrie O. Paun.
28 *
29 * Unless otherwise noted, we belive this code to be complete, as per
30 * the specification mentioned above.
31 * If you discover missing features, or bugs, please note them below.
32 *
Alexandre Julliarda69b88b1998-03-15 20:29:56 +000033 * TODO:
Dimitrie O. Paun4d1e49d2002-09-04 23:31:48 +000034 * - Add support for ILD_PRESERVEALPHA, ILD_SCALE, ILD_DPISCALE
35 * - Add support for ILS_GLOW, ILS_SHADOW, ILS_SATURATE, ILS_ALPHA
Alexandre Julliard54c27111998-03-29 19:44:57 +000036 *
Dimitrie O. Paunda9bac42002-10-16 18:57:14 +000037 * FIXME:
Dave Hawkes770a5bf2002-02-26 00:33:51 +000038 * - Hotspot handling still not correct. The Hotspot passed to BeginDrag
39 * is the offset of the image position relative to the actual mouse pointer
40 * position. However the Hotspot passed to SetDragCursorImage is the
41 * offset of the mouse messages sent to the application...
Alexandre Julliarda69b88b1998-03-15 20:29:56 +000042 */
43
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +000044#include <stdlib.h>
James Juranf4d5fef2001-01-26 20:43:40 +000045#include <string.h>
Alexandre Julliard74af67e2000-09-26 00:00:55 +000046#include "winerror.h"
47#include "winbase.h"
Alexandre Julliard638f1691999-01-17 16:32:32 +000048#include "wine/obj_base.h"
49#include "wine/obj_storage.h"
Alexandre Julliarda69b88b1998-03-15 20:29:56 +000050#include "commctrl.h"
Alexandre Julliard70c9e092000-08-09 00:41:17 +000051#include "imagelist.h"
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000052#include "wine/debug.h"
Alexandre Julliarda69b88b1998-03-15 20:29:56 +000053
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000054WINE_DEFAULT_DEBUG_CHANNEL(imagelist);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000055
Alexandre Julliarda69b88b1998-03-15 20:29:56 +000056
Alexandre Julliard54c27111998-03-29 19:44:57 +000057#define MAX_OVERLAYIMAGE 15
58
Alexandre Julliarddadf78f1998-05-17 17:13:43 +000059/* internal image list data used for Drag & Drop operations */
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +000060typedef struct
61{
62 HWND hwnd;
63 HIMAGELIST himl;
64 /* position of the drag image relative to the window */
65 INT x;
66 INT y;
67 /* offset of the hotspot relative to the origin of the image */
68 INT dxHotspot;
69 INT dyHotspot;
70 /* is the drag image visible */
71 BOOL bShow;
72 /* saved background */
73 HBITMAP hbmBg;
Dave Hawkes770a5bf2002-02-26 00:33:51 +000074 BOOL bHSPending;
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +000075} INTERNALDRAG;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +000076
Dave Hawkes770a5bf2002-02-26 00:33:51 +000077static INTERNALDRAG InternalDrag = { 0, 0, 0, 0, 0, 0, FALSE, 0, FALSE };
Alexandre Julliard54c27111998-03-29 19:44:57 +000078
Alexandre Julliarda845b881998-06-01 10:44:35 +000079
Alexandre Julliard54c27111998-03-29 19:44:57 +000080
Alexandre Julliardc7c217b1998-04-13 12:21:30 +000081/*************************************************************************
Vincent Béron9a624912002-05-31 23:06:46 +000082 * IMAGELIST_InternalExpandBitmaps [Internal]
Alexandre Julliardc7c217b1998-04-13 12:21:30 +000083 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +000084 * Expands the bitmaps of an image list by the given number of images.
85 *
86 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +000087 * himl [I] handle to image list
88 * nImageCount [I] number of images to add
Alexandre Julliarddadf78f1998-05-17 17:13:43 +000089 *
90 * RETURNS
91 * nothing
92 *
93 * NOTES
94 * This function can NOT be used to reduce the number of images.
Alexandre Julliardc7c217b1998-04-13 12:21:30 +000095 */
Dimitrie O. Paund9696052002-09-06 18:32:46 +000096static void
Gerard Patel19cef6c2000-07-08 12:48:37 +000097IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl, INT nImageCount, INT cx, INT cy)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +000098{
Alexandre Julliarda3960291999-02-26 11:11:13 +000099 HDC hdcImageList, hdcBitmap;
100 HBITMAP hbmNewBitmap;
101 INT nNewWidth, nNewCount;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000102
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000103 if ((himl->cCurImage + nImageCount <= himl->cMaxImage)
Gerard Patel19cef6c2000-07-08 12:48:37 +0000104 && (himl->cy >= cy))
105 return;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000106
Gerard Patel19cef6c2000-07-08 12:48:37 +0000107 if (cy == 0) cy = himl->cy;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000108 nNewCount = himl->cCurImage + nImageCount + himl->cGrow;
109 nNewWidth = nNewCount * himl->cx;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000110
Gerard Patel19cef6c2000-07-08 12:48:37 +0000111 TRACE("Create expanded bitmaps : himl=%p x=%d y=%d count=%d\n", himl, nNewWidth, cy, nNewCount);
Alexandre Julliarda3960291999-02-26 11:11:13 +0000112 hdcImageList = CreateCompatibleDC (0);
113 hdcBitmap = CreateCompatibleDC (0);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000114
115 hbmNewBitmap =
Gerard Patel19cef6c2000-07-08 12:48:37 +0000116 CreateBitmap (nNewWidth, cy, 1, himl->uBitsPixel, NULL);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000117 if (hbmNewBitmap == 0)
Gerard Patel19cef6c2000-07-08 12:48:37 +0000118 ERR("creating new image bitmap (x=%d y=%d)!\n", nNewWidth, cy);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000119
Alexandre Julliarda3960291999-02-26 11:11:13 +0000120 SelectObject (hdcImageList, himl->hbmImage);
121 SelectObject (hdcBitmap, hbmNewBitmap);
Gerard Patel19cef6c2000-07-08 12:48:37 +0000122 BitBlt (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, cy,
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000123 hdcImageList, 0, 0, SRCCOPY);
124
Alexandre Julliarda3960291999-02-26 11:11:13 +0000125 DeleteObject (himl->hbmImage);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000126 himl->hbmImage = hbmNewBitmap;
127
128 if (himl->hbmMask) {
Vincent Béron9a624912002-05-31 23:06:46 +0000129 hbmNewBitmap =
Gerard Patel19cef6c2000-07-08 12:48:37 +0000130 CreateBitmap (nNewWidth, cy, 1, 1, NULL);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000131
132 if (hbmNewBitmap == 0)
Gerard Patel19cef6c2000-07-08 12:48:37 +0000133 ERR("creating new mask bitmap!\n");
Alexandre Julliard54c27111998-03-29 19:44:57 +0000134
Alexandre Julliarda3960291999-02-26 11:11:13 +0000135 SelectObject (hdcImageList, himl->hbmMask);
136 SelectObject (hdcBitmap, hbmNewBitmap);
Gerard Patel19cef6c2000-07-08 12:48:37 +0000137 BitBlt (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, cy,
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000138 hdcImageList, 0, 0, SRCCOPY);
Alexandre Julliarda3960291999-02-26 11:11:13 +0000139 DeleteObject (himl->hbmMask);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000140 himl->hbmMask = hbmNewBitmap;
141 }
142
Alexandre Julliard54c27111998-03-29 19:44:57 +0000143 himl->cMaxImage = nNewCount;
144
Alexandre Julliarda3960291999-02-26 11:11:13 +0000145 DeleteDC (hdcImageList);
146 DeleteDC (hdcBitmap);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000147}
148
149
Alexandre Julliard54c27111998-03-29 19:44:57 +0000150/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000151 * ImageList_Add [COMCTL32.@]
Alexandre Julliard54c27111998-03-29 19:44:57 +0000152 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000153 * Add an image or images to an image list.
Alexandre Julliard54c27111998-03-29 19:44:57 +0000154 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000155 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +0000156 * himl [I] handle to image list
157 * hbmImage [I] handle to image bitmap
158 * hbmMask [I] handle to mask bitmap
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000159 *
160 * RETURNS
161 * Success: Index of the first new image.
162 * Failure: -1
Alexandre Julliard54c27111998-03-29 19:44:57 +0000163 */
164
Alexandre Julliarda3960291999-02-26 11:11:13 +0000165INT WINAPI
166ImageList_Add (HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000167{
Pierre Mageau6231a171999-07-24 10:20:06 +0000168 HDC hdcImage, hdcBitmap;
169 INT nFirstIndex, nImageCount;
170 INT nStartX;
171 BITMAP bmp;
172 HBITMAP hOldBitmapImage, hOldBitmap;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000173
Michael Stefaniuc353529b2002-10-23 22:19:10 +0000174 TRACE("himl=%p hbmimage=%p hbmmask=%p\n", himl, hbmImage, hbmMask);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000175 if (!himl || !hbmImage)
Pierre Mageau6231a171999-07-24 10:20:06 +0000176 return -1;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000177
Alexandre Julliarda3960291999-02-26 11:11:13 +0000178 GetObjectA (hbmImage, sizeof(BITMAP), (LPVOID)&bmp);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000179 nImageCount = bmp.bmWidth / himl->cx;
180
Gerard Patel19cef6c2000-07-08 12:48:37 +0000181 IMAGELIST_InternalExpandBitmaps (himl, nImageCount, bmp.bmWidth, bmp.bmHeight);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000182
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000183 nStartX = himl->cCurImage * himl->cx;
184
Pierre Mageau6231a171999-07-24 10:20:06 +0000185 hdcImage = CreateCompatibleDC(0);
186 hdcBitmap = CreateCompatibleDC(0);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000187
Pierre Mageau6231a171999-07-24 10:20:06 +0000188 hOldBitmapImage = SelectObject(hdcImage, himl->hbmImage);
189 hOldBitmap = SelectObject(hdcBitmap, hbmImage);
190
191 /* Copy result to the imagelist
192 */
Gerard Patel19cef6c2000-07-08 12:48:37 +0000193 BitBlt (hdcImage, nStartX, 0, bmp.bmWidth, bmp.bmHeight,
Pierre Mageau6231a171999-07-24 10:20:06 +0000194 hdcBitmap, 0, 0, SRCCOPY);
195
196 if(himl->hbmMask)
197 {
Michael Stefaniucf3d18932002-10-23 20:19:22 +0000198 HDC hdcMask, hdcTemp;
199 HBITMAP hOldBitmapMask, hOldBitmapTemp;
Pierre Mageau6231a171999-07-24 10:20:06 +0000200
201 hdcMask = CreateCompatibleDC (0);
202 hdcTemp = CreateCompatibleDC(0);
Michael Stefaniucf3d18932002-10-23 20:19:22 +0000203 hOldBitmapMask = SelectObject(hdcMask, himl->hbmMask);
204 hOldBitmapTemp = SelectObject(hdcTemp, hbmMask);
Pierre Mageau6231a171999-07-24 10:20:06 +0000205
Vincent Béron9a624912002-05-31 23:06:46 +0000206 BitBlt (hdcMask,
Gerard Patel19cef6c2000-07-08 12:48:37 +0000207 nStartX, 0, bmp.bmWidth, bmp.bmHeight,
Vincent Béron9a624912002-05-31 23:06:46 +0000208 hdcTemp,
209 0, 0,
Pierre Mageau6231a171999-07-24 10:20:06 +0000210 SRCCOPY);
211
212 SelectObject(hdcTemp, hOldBitmapTemp);
213 DeleteDC(hdcTemp);
214
215 /* Remove the background from the image
216 */
Vincent Béron9a624912002-05-31 23:06:46 +0000217 BitBlt (hdcImage,
Gerard Patel19cef6c2000-07-08 12:48:37 +0000218 nStartX, 0, bmp.bmWidth, bmp.bmHeight,
Vincent Béron9a624912002-05-31 23:06:46 +0000219 hdcMask,
220 nStartX, 0,
Pierre Mageau6231a171999-07-24 10:20:06 +0000221 0x220326); /* NOTSRCAND */
222
223 SelectObject(hdcMask, hOldBitmapMask);
224 DeleteDC(hdcMask);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000225 }
226
Pierre Mageau6231a171999-07-24 10:20:06 +0000227 SelectObject(hdcImage, hOldBitmapImage);
228 SelectObject(hdcBitmap, hOldBitmap);
229 DeleteDC(hdcImage);
230 DeleteDC(hdcBitmap);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000231
232 nFirstIndex = himl->cCurImage;
233 himl->cCurImage += nImageCount;
234
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000235 return nFirstIndex;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000236}
237
238
Alexandre Julliard54c27111998-03-29 19:44:57 +0000239/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000240 * ImageList_AddIcon [COMCTL32.@]
Alexandre Julliarda845b881998-06-01 10:44:35 +0000241 *
242 * Adds an icon to an image list.
243 *
244 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +0000245 * himl [I] handle to image list
246 * hIcon [I] handle to icon
Alexandre Julliarda845b881998-06-01 10:44:35 +0000247 *
248 * RETURNS
249 * Success: index of the new image
250 * Failure: -1
251 */
252
Alexandre Julliarda3960291999-02-26 11:11:13 +0000253INT WINAPI
254ImageList_AddIcon (HIMAGELIST himl, HICON hIcon)
Alexandre Julliarda845b881998-06-01 10:44:35 +0000255{
Eric Kohlf2809611998-11-08 11:36:04 +0000256 return ImageList_ReplaceIcon (himl, -1, hIcon);
Alexandre Julliarda845b881998-06-01 10:44:35 +0000257}
258
259
260/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000261 * ImageList_AddMasked [COMCTL32.@]
Alexandre Julliard54c27111998-03-29 19:44:57 +0000262 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000263 * Adds an image or images to an image list and creates a mask from the
264 * specified bitmap using the mask color.
Alexandre Julliard54c27111998-03-29 19:44:57 +0000265 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000266 * PARAMS
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000267 * himl [I] handle to image list.
268 * hBitmap [I] handle to bitmap
269 * clrMask [I] mask color.
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000270 *
271 * RETURNS
272 * Success: Index of the first new image.
273 * Failure: -1
Alexandre Julliard54c27111998-03-29 19:44:57 +0000274 */
275
Alexandre Julliarda3960291999-02-26 11:11:13 +0000276INT WINAPI
277ImageList_AddMasked (HIMAGELIST himl, HBITMAP hBitmap, COLORREF clrMask)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000278{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000279 HDC hdcImage, hdcMask, hdcBitmap;
Pierre Mageau6231a171999-07-24 10:20:06 +0000280 INT nIndex, nImageCount, nMaskXOffset=0;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000281 BITMAP bmp;
Pierre Mageau6231a171999-07-24 10:20:06 +0000282 HBITMAP hOldBitmap, hOldBitmapMask, hOldBitmapImage;
283 HBITMAP hMaskBitmap=0;
284 COLORREF bkColor;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000285
Michael Stefaniuc353529b2002-10-23 22:19:10 +0000286 TRACE("himl=%p hbitmap=%p clrmask=%lx\n", himl, hBitmap, clrMask);
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000287 if (himl == NULL)
Pierre Mageau6231a171999-07-24 10:20:06 +0000288 return -1;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000289
Alexandre Julliarda3960291999-02-26 11:11:13 +0000290 if (!GetObjectA (hBitmap, sizeof(BITMAP), &bmp))
Pierre Mageau6231a171999-07-24 10:20:06 +0000291 return -1;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000292
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000293 nImageCount = bmp.bmWidth / himl->cx;
294
Gerard Patel19cef6c2000-07-08 12:48:37 +0000295 IMAGELIST_InternalExpandBitmaps (himl, nImageCount, bmp.bmWidth, bmp.bmHeight);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000296
297 nIndex = himl->cCurImage;
298 himl->cCurImage += nImageCount;
299
Pierre Mageau6231a171999-07-24 10:20:06 +0000300 hdcMask = CreateCompatibleDC (0);
301 hdcImage = CreateCompatibleDC(0);
302 hdcBitmap = CreateCompatibleDC(0);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000303
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000304
Pierre Mageau6231a171999-07-24 10:20:06 +0000305 hOldBitmapImage = SelectObject(hdcImage, himl->hbmImage);
306 hOldBitmap = SelectObject(hdcBitmap, hBitmap);
307 if(himl->hbmMask)
308 {
309 hOldBitmapMask = SelectObject(hdcMask, himl->hbmMask);
310 nMaskXOffset = nIndex * himl->cx;
311 }
312 else
313 {
314 /*
315 Create a temp Mask so we can remove the background of
316 the Image (Windows does this even if there is no mask)
317 */
Gerard Patel19cef6c2000-07-08 12:48:37 +0000318 hMaskBitmap = CreateBitmap(bmp.bmWidth, bmp.bmHeight, 1, 1, NULL);
Pierre Mageau6231a171999-07-24 10:20:06 +0000319 hOldBitmapMask = SelectObject(hdcMask, hMaskBitmap);
320 nMaskXOffset = 0;
321 }
322 /* create monochrome image to the mask bitmap */
323 bkColor = (clrMask != CLR_DEFAULT) ? clrMask :
324 GetPixel (hdcBitmap, 0, 0);
325 SetBkColor (hdcBitmap, bkColor);
Vincent Béron9a624912002-05-31 23:06:46 +0000326 BitBlt (hdcMask,
Gerard Patel19cef6c2000-07-08 12:48:37 +0000327 nMaskXOffset, 0, bmp.bmWidth, bmp.bmHeight,
Vincent Béron9a624912002-05-31 23:06:46 +0000328 hdcBitmap, 0, 0,
Pierre Mageau6231a171999-07-24 10:20:06 +0000329 SRCCOPY);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000330
Pierre Mageau6231a171999-07-24 10:20:06 +0000331 SetBkColor(hdcBitmap, RGB(255,255,255));
332 /*Remove the background from the image
333 */
334 /*
335 WINDOWS BUG ALERT!!!!!!
336 The statement below should not be done in common practice
337 but this is how ImageList_AddMasked works in Windows.
338 It overwrites the original bitmap passed, this was discovered
Andreas Mohr641405a2001-04-20 18:29:17 +0000339 by using the same bitmap to iterate the different styles
Pierre Mageau6231a171999-07-24 10:20:06 +0000340 on windows where it failed (BUT ImageList_Add is OK)
Andreas Mohr641405a2001-04-20 18:29:17 +0000341 This is here in case some apps rely on this bug
Pierre Mageau6231a171999-07-24 10:20:06 +0000342 */
Vincent Béron9a624912002-05-31 23:06:46 +0000343 BitBlt(hdcBitmap,
Gerard Patel19cef6c2000-07-08 12:48:37 +0000344 0, 0, bmp.bmWidth, bmp.bmHeight,
Vincent Béron9a624912002-05-31 23:06:46 +0000345 hdcMask,
346 nMaskXOffset, 0,
Pierre Mageau6231a171999-07-24 10:20:06 +0000347 0x220326); /* NOTSRCAND */
348 /* Copy result to the imagelist
349 */
Vincent Béron9a624912002-05-31 23:06:46 +0000350 BitBlt (hdcImage,
Gerard Patel19cef6c2000-07-08 12:48:37 +0000351 nIndex * himl->cx, 0, bmp.bmWidth, bmp.bmHeight,
Vincent Béron9a624912002-05-31 23:06:46 +0000352 hdcBitmap,
353 0, 0,
Pierre Mageau6231a171999-07-24 10:20:06 +0000354 SRCCOPY);
355 /* Clean up
356 */
357 SelectObject(hdcMask,hOldBitmapMask);
358 SelectObject(hdcImage, hOldBitmapImage);
359 SelectObject(hdcBitmap, hOldBitmap);
360 DeleteDC(hdcMask);
361 DeleteDC(hdcImage);
362 DeleteDC(hdcBitmap);
363 if(!himl->hbmMask)
364 {
365 DeleteObject(hMaskBitmap);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000366 }
367
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000368 return nIndex;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000369}
370
371
Alexandre Julliard54c27111998-03-29 19:44:57 +0000372/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000373 * ImageList_BeginDrag [COMCTL32.@]
Alexandre Julliard54c27111998-03-29 19:44:57 +0000374 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000375 * Creates a temporary image list that contains one image. It will be used
376 * as a drag image.
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000377 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000378 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +0000379 * himlTrack [I] handle to the source image list
380 * iTrack [I] index of the drag image in the source image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000381 * dxHotspot [I] X position of the hot spot of the drag image
382 * dyHotspot [I] Y position of the hot spot of the drag image
383 *
384 * RETURNS
385 * Success: TRUE
386 * Failure: FALSE
Alexandre Julliard54c27111998-03-29 19:44:57 +0000387 */
388
Alexandre Julliarda3960291999-02-26 11:11:13 +0000389BOOL WINAPI
390ImageList_BeginDrag (HIMAGELIST himlTrack, INT iTrack,
391 INT dxHotspot, INT dyHotspot)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000392{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000393 HDC hdcSrc, hdcDst;
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +0000394 INT cx, cy;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000395
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +0000396 TRACE("(himlTrack=%p iTrack=%d dx=%d dy=%d)\n", himlTrack, iTrack,
397 dxHotspot, dyHotspot);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000398
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000399 if (himlTrack == NULL)
Eric Kohlf2809611998-11-08 11:36:04 +0000400 return FALSE;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000401
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000402 if (InternalDrag.himl)
403 ImageList_EndDrag ();
404
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +0000405 cx = himlTrack->cx;
406 cy = himlTrack->cy;
407
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000408 InternalDrag.himl = ImageList_Create (cx, cy, himlTrack->flags, 1, 1);
409 if (InternalDrag.himl == NULL) {
Dimitrie O. Paun7ad3d122002-09-04 18:44:46 +0000410 WARN("Error creating drag image list!\n");
Eric Kohlf2809611998-11-08 11:36:04 +0000411 return FALSE;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000412 }
413
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000414 InternalDrag.dxHotspot = dxHotspot;
415 InternalDrag.dyHotspot = dyHotspot;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000416
Alexandre Julliarda3960291999-02-26 11:11:13 +0000417 hdcSrc = CreateCompatibleDC (0);
418 hdcDst = CreateCompatibleDC (0);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000419
420 /* copy image */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000421 SelectObject (hdcSrc, himlTrack->hbmImage);
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000422 SelectObject (hdcDst, InternalDrag.himl->hbmImage);
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +0000423 BitBlt (hdcDst, 0, 0, cx, cy, hdcSrc, iTrack * cx, 0, SRCCOPY);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000424
425 /* copy mask */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000426 SelectObject (hdcSrc, himlTrack->hbmMask);
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000427 SelectObject (hdcDst, InternalDrag.himl->hbmMask);
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +0000428 BitBlt (hdcDst, 0, 0, cx, cy, hdcSrc, iTrack * cx, 0, SRCCOPY);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000429
Alexandre Julliarda3960291999-02-26 11:11:13 +0000430 DeleteDC (hdcSrc);
431 DeleteDC (hdcDst);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000432
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000433 InternalDrag.himl->cCurImage = 1;
Dave Hawkes770a5bf2002-02-26 00:33:51 +0000434 InternalDrag.bHSPending = TRUE;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000435
Eric Kohlf2809611998-11-08 11:36:04 +0000436 return TRUE;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000437}
438
439
440/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000441 * ImageList_Copy [COMCTL32.@]
Alexandre Julliard54c27111998-03-29 19:44:57 +0000442 *
Vincent Béron9a624912002-05-31 23:06:46 +0000443 * Copies an image of the source image list to an image of the
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000444 * destination image list. Images can be copied or swapped.
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000445 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000446 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +0000447 * himlDst [I] handle to the destination image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000448 * iDst [I] destination image index.
Eric Kohlf2809611998-11-08 11:36:04 +0000449 * himlSrc [I] handle to the source image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000450 * iSrc [I] source image index
451 * uFlags [I] flags for the copy operation
452 *
453 * RETURNS
454 * Success: TRUE
455 * Failure: FALSE
456 *
457 * NOTES
458 * Copying from one image list to another is possible. The original
Andreas Mohr641405a2001-04-20 18:29:17 +0000459 * implementation just copies or swaps within one image list.
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000460 * Could this feature become a bug??? ;-)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000461 */
462
Alexandre Julliarda3960291999-02-26 11:11:13 +0000463BOOL WINAPI
464ImageList_Copy (HIMAGELIST himlDst, INT iDst, HIMAGELIST himlSrc,
465 INT iSrc, INT uFlags)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000466{
Vincent Béron9a624912002-05-31 23:06:46 +0000467 HDC hdcSrc, hdcDst;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000468
Alexandre Julliarda099a551999-06-12 15:45:58 +0000469 TRACE("iDst=%d iSrc=%d\n", iDst, iSrc);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000470
Eric Kohl978137d1998-10-11 13:12:54 +0000471 if ((himlSrc == NULL) || (himlDst == NULL))
472 return FALSE;
473 if ((iDst < 0) || (iDst >= himlDst->cCurImage))
474 return FALSE;
475 if ((iSrc < 0) || (iSrc >= himlSrc->cCurImage))
476 return FALSE;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000477
Alexandre Julliarda3960291999-02-26 11:11:13 +0000478 hdcSrc = CreateCompatibleDC (0);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000479 if (himlDst == himlSrc)
480 hdcDst = hdcSrc;
481 else
Alexandre Julliarda3960291999-02-26 11:11:13 +0000482 hdcDst = CreateCompatibleDC (0);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000483
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000484 if (uFlags & ILCF_SWAP) {
Alexandre Julliard54c27111998-03-29 19:44:57 +0000485 /* swap */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000486 HBITMAP hbmTempImage, hbmTempMask;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000487
488 /* create temporary bitmaps */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000489 hbmTempImage = CreateBitmap (himlSrc->cx, himlSrc->cy, 1,
Alexandre Julliard54c27111998-03-29 19:44:57 +0000490 himlSrc->uBitsPixel, NULL);
Alexandre Julliarda3960291999-02-26 11:11:13 +0000491 hbmTempMask = CreateBitmap (himlSrc->cx, himlSrc->cy, 1,
Alexandre Julliard829fe321998-07-26 14:27:39 +0000492 1, NULL);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000493
494 /* copy (and stretch) destination to temporary bitmaps.(save) */
495 /* image */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000496 SelectObject (hdcSrc, himlDst->hbmImage);
497 SelectObject (hdcDst, hbmTempImage);
498 StretchBlt (hdcDst, 0, 0, himlSrc->cx, himlSrc->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +0000499 hdcSrc, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
500 SRCCOPY);
501 /* mask */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000502 SelectObject (hdcSrc, himlDst->hbmMask);
503 SelectObject (hdcDst, hbmTempMask);
504 StretchBlt (hdcDst, 0, 0, himlSrc->cx, himlSrc->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +0000505 hdcSrc, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
506 SRCCOPY);
507
508 /* copy (and stretch) source to destination */
509 /* image */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000510 SelectObject (hdcSrc, himlSrc->hbmImage);
511 SelectObject (hdcDst, himlDst->hbmImage);
512 StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +0000513 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
514 SRCCOPY);
515 /* mask */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000516 SelectObject (hdcSrc, himlSrc->hbmMask);
517 SelectObject (hdcDst, himlDst->hbmMask);
518 StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +0000519 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
520 SRCCOPY);
521
522 /* copy (without stretching) temporary bitmaps to source (restore) */
523 /* image */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000524 SelectObject (hdcSrc, hbmTempImage);
525 SelectObject (hdcDst, himlSrc->hbmImage);
526 BitBlt (hdcDst, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +0000527 hdcSrc, 0, 0, SRCCOPY);
528 /* mask */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000529 SelectObject (hdcSrc, hbmTempMask);
530 SelectObject (hdcDst, himlSrc->hbmMask);
531 BitBlt (hdcDst, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +0000532 hdcSrc, 0, 0, SRCCOPY);
533
534 /* delete temporary bitmaps */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000535 DeleteObject (hbmTempMask);
536 DeleteObject (hbmTempImage);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000537 }
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000538 else {
Alexandre Julliard54c27111998-03-29 19:44:57 +0000539 /* copy image */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000540 SelectObject (hdcSrc, himlSrc->hbmImage);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000541 if (himlSrc == himlDst)
542 hdcDst = hdcSrc;
543 else
Alexandre Julliarda3960291999-02-26 11:11:13 +0000544 SelectObject (hdcDst, himlDst->hbmImage);
545 StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +0000546 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
547 SRCCOPY);
548
549 /* copy mask */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000550 SelectObject (hdcSrc, himlSrc->hbmMask);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000551 if (himlSrc == himlDst)
552 hdcDst = hdcSrc;
553 else
Alexandre Julliarda3960291999-02-26 11:11:13 +0000554 SelectObject (hdcDst, himlDst->hbmMask);
555 StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +0000556 hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
557 SRCCOPY);
558 }
559
Alexandre Julliarda3960291999-02-26 11:11:13 +0000560 DeleteDC (hdcSrc);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000561 if (himlSrc != himlDst)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000562 DeleteDC (hdcDst);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000563
Eric Kohl978137d1998-10-11 13:12:54 +0000564 return TRUE;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000565}
566
567
568/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000569 * ImageList_Create [COMCTL32.@] Creates a new image list.
Alexandre Julliard54c27111998-03-29 19:44:57 +0000570 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000571 * PARAMS
572 * cx [I] image height
573 * cy [I] image width
574 * flags [I] creation flags
575 * cInitial [I] initial number of images in the image list
576 * cGrow [I] number of images by which image list grows
577 *
578 * RETURNS
Eric Kohl978137d1998-10-11 13:12:54 +0000579 * Success: Handle to the created image list
580 * Failure: NULL
Alexandre Julliard54c27111998-03-29 19:44:57 +0000581 */
582
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000583HIMAGELIST WINAPI
Alexandre Julliarda3960291999-02-26 11:11:13 +0000584ImageList_Create (INT cx, INT cy, UINT flags,
585 INT cInitial, INT cGrow)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000586{
587 HIMAGELIST himl;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000588 HDC hdc;
589 INT nCount;
590 HBITMAP hbmTemp;
Vincent Béron9a624912002-05-31 23:06:46 +0000591 static WORD aBitBlend25[] =
Eric Kohl978137d1998-10-11 13:12:54 +0000592 {0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00};
593
594 static WORD aBitBlend50[] =
595 {0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA};
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000596
Alexandre Julliarda099a551999-06-12 15:45:58 +0000597 TRACE("(%d %d 0x%x %d %d)\n", cx, cy, flags, cInitial, cGrow);
Alexandre Julliard829fe321998-07-26 14:27:39 +0000598
Eric Kohl978137d1998-10-11 13:12:54 +0000599 himl = (HIMAGELIST)COMCTL32_Alloc (sizeof(struct _IMAGELIST));
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000600 if (!himl)
Eric Kohl978137d1998-10-11 13:12:54 +0000601 return NULL;
602
603 himl->cx = cx;
604 himl->cy = cy;
605 himl->flags = flags;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000606 himl->cMaxImage = cInitial + cGrow;
Eric Kohl978137d1998-10-11 13:12:54 +0000607 himl->cInitial = cInitial;
608 himl->cGrow = cGrow;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000609 himl->cCurImage = 0;
Eric Kohl978137d1998-10-11 13:12:54 +0000610 himl->clrFg = CLR_DEFAULT;
611 himl->clrBk = CLR_NONE;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000612
Alexandre Julliard54c27111998-03-29 19:44:57 +0000613 /* initialize overlay mask indices */
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000614 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000615 himl->nOvlIdx[nCount] = -1;
616
Alexandre Julliarda3960291999-02-26 11:11:13 +0000617 hdc = CreateCompatibleDC (0);
618 himl->uBitsPixel = (UINT)GetDeviceCaps (hdc, BITSPIXEL);
619 DeleteDC (hdc);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000620
Alexandre Julliarda099a551999-06-12 15:45:58 +0000621 TRACE("Image: %d Bits per Pixel\n", himl->uBitsPixel);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000622
Stephane Lussier25114771999-09-22 15:15:57 +0000623 if (himl->cMaxImage > 0) {
624 himl->hbmImage =
625 CreateBitmap (himl->cx * himl->cMaxImage, himl->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +0000626 1, himl->uBitsPixel, NULL);
Stephane Lussier25114771999-09-22 15:15:57 +0000627 if (himl->hbmImage == 0) {
628 ERR("Error creating image bitmap!\n");
629 return NULL;
630 }
Alexandre Julliard54c27111998-03-29 19:44:57 +0000631 }
Stephane Lussier25114771999-09-22 15:15:57 +0000632 else
633 himl->hbmImage = 0;
Vincent Béron9a624912002-05-31 23:06:46 +0000634
Mike McCormack5a6a71f2002-08-16 01:35:43 +0000635 if ( (himl->flags & ILC_MASK)) {
636 int images = himl->cMaxImage;
637 if (images <= 0)
638 images = 1;
639
640 himl->hbmMask = CreateBitmap (himl->cx * images, himl->cy,
Alexandre Julliard829fe321998-07-26 14:27:39 +0000641 1, 1, NULL);
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000642 if (himl->hbmMask == 0) {
Alexandre Julliarda099a551999-06-12 15:45:58 +0000643 ERR("Error creating mask bitmap!\n");
Alexandre Julliard54c27111998-03-29 19:44:57 +0000644 if (himl->hbmImage)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000645 DeleteObject (himl->hbmImage);
Eric Kohl978137d1998-10-11 13:12:54 +0000646 return NULL;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000647 }
648 }
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000649 else
650 himl->hbmMask = 0;
651
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000652 /* create blending brushes */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000653 hbmTemp = CreateBitmap (8, 8, 1, 1, &aBitBlend25);
654 himl->hbrBlend25 = CreatePatternBrush (hbmTemp);
655 DeleteObject (hbmTemp);
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000656
Alexandre Julliarda3960291999-02-26 11:11:13 +0000657 hbmTemp = CreateBitmap (8, 8, 1, 1, &aBitBlend50);
658 himl->hbrBlend50 = CreatePatternBrush (hbmTemp);
659 DeleteObject (hbmTemp);
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000660
Gerard Patel19cef6c2000-07-08 12:48:37 +0000661 TRACE("created imagelist %p\n", himl);
Eric Kohl978137d1998-10-11 13:12:54 +0000662 return himl;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000663}
664
665
Alexandre Julliard54c27111998-03-29 19:44:57 +0000666/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000667 * ImageList_Destroy [COMCTL32.@]
Alexandre Julliard54c27111998-03-29 19:44:57 +0000668 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000669 * Destroys an image list.
Alexandre Julliard54c27111998-03-29 19:44:57 +0000670 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000671 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +0000672 * himl [I] handle to image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000673 *
674 * RETURNS
675 * Success: TRUE
676 * Failure: FALSE
Alexandre Julliard54c27111998-03-29 19:44:57 +0000677 */
678
Alexandre Julliarda3960291999-02-26 11:11:13 +0000679BOOL WINAPI
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000680ImageList_Destroy (HIMAGELIST himl)
Vincent Béron9a624912002-05-31 23:06:46 +0000681{
Eric Kohl978137d1998-10-11 13:12:54 +0000682 if (!himl)
683 return FALSE;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000684
Eric Kohl978137d1998-10-11 13:12:54 +0000685 /* delete image bitmaps */
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000686 if (himl->hbmImage)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000687 DeleteObject (himl->hbmImage);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000688 if (himl->hbmMask)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000689 DeleteObject (himl->hbmMask);
Eric Kohl978137d1998-10-11 13:12:54 +0000690
691 /* delete blending brushes */
692 if (himl->hbrBlend25)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000693 DeleteObject (himl->hbrBlend25);
Eric Kohl978137d1998-10-11 13:12:54 +0000694 if (himl->hbrBlend50)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000695 DeleteObject (himl->hbrBlend50);
Vincent Béron9a624912002-05-31 23:06:46 +0000696
Eric Kohl978137d1998-10-11 13:12:54 +0000697 COMCTL32_Free (himl);
698
699 return TRUE;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000700}
701
702
Alexandre Julliard54c27111998-03-29 19:44:57 +0000703/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000704 * ImageList_DragEnter [COMCTL32.@]
Alexandre Julliard54c27111998-03-29 19:44:57 +0000705 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000706 * Locks window update and displays the drag image at the given position.
707 *
708 * PARAMS
709 * hwndLock [I] handle of the window that owns the drag image.
710 * x [I] X position of the drag image.
711 * y [I] Y position of the drag image.
712 *
713 * RETURNS
714 * Success: TRUE
715 * Failure: FALSE
716 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000717 * NOTES
718 * The position of the drag image is relative to the window, not
719 * the client area.
Alexandre Julliard54c27111998-03-29 19:44:57 +0000720 */
721
Alexandre Julliarda3960291999-02-26 11:11:13 +0000722BOOL WINAPI
723ImageList_DragEnter (HWND hwndLock, INT x, INT y)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000724{
Michael Stefaniuc353529b2002-10-23 22:19:10 +0000725 TRACE("(hwnd=%p x=%d y=%d)\n", hwndLock, x, y);
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +0000726
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000727 if (InternalDrag.himl == NULL)
Eric Kohlf2809611998-11-08 11:36:04 +0000728 return FALSE;
Alexandre Julliarda845b881998-06-01 10:44:35 +0000729
730 if (hwndLock)
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000731 InternalDrag.hwnd = hwndLock;
Alexandre Julliarda845b881998-06-01 10:44:35 +0000732 else
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000733 InternalDrag.hwnd = GetDesktopWindow ();
Alexandre Julliarda845b881998-06-01 10:44:35 +0000734
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000735 InternalDrag.x = x;
736 InternalDrag.y = y;
Alexandre Julliarda845b881998-06-01 10:44:35 +0000737
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000738 /* draw the drag image and save the background */
739 if (!ImageList_DragShowNolock(TRUE)) {
740 return FALSE;
741 }
Alexandre Julliarda845b881998-06-01 10:44:35 +0000742
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000743 return TRUE;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000744}
745
746
747/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000748 * ImageList_DragLeave [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000749 *
750 * Unlocks window update and hides the drag image.
751 *
752 * PARAMS
753 * hwndLock [I] handle of the window that owns the drag image.
754 *
755 * RETURNS
756 * Success: TRUE
757 * Failure: FALSE
Alexandre Julliard54c27111998-03-29 19:44:57 +0000758 */
759
Alexandre Julliarda3960291999-02-26 11:11:13 +0000760BOOL WINAPI
761ImageList_DragLeave (HWND hwndLock)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000762{
Dave Hawkes770a5bf2002-02-26 00:33:51 +0000763 /* As we don't save drag info in the window this can lead to problems if
764 an app does not supply the same window as DragEnter */
765 /* if (hwndLock)
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000766 InternalDrag.hwnd = hwndLock;
Alexandre Julliarda845b881998-06-01 10:44:35 +0000767 else
Dave Hawkes770a5bf2002-02-26 00:33:51 +0000768 InternalDrag.hwnd = GetDesktopWindow (); */
769 if(!hwndLock)
770 hwndLock = GetDesktopWindow();
771 if(InternalDrag.hwnd != hwndLock)
772 FIXME("DragLeave hWnd != DragEnter hWnd\n");
Alexandre Julliard54c27111998-03-29 19:44:57 +0000773
Alexandre Julliarda845b881998-06-01 10:44:35 +0000774 ImageList_DragShowNolock (FALSE);
775
Eric Kohl9d8e8641998-10-24 10:49:27 +0000776 return TRUE;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000777}
778
779
780/*************************************************************************
Dimitrie O. Paun318817f2002-09-12 00:51:09 +0000781 * ImageList_InternalDragDraw [Internal]
782 *
783 * Draws the drag image.
784 *
785 * PARAMS
786 * hdc [I] device context to draw into.
787 * x [I] X position of the drag image.
788 * y [I] Y position of the drag image.
789 *
790 * RETURNS
791 * Success: TRUE
792 * Failure: FALSE
793 *
794 * NOTES
795 * The position of the drag image is relative to the window, not
796 * the client area.
797 *
Dimitrie O. Paun318817f2002-09-12 00:51:09 +0000798 */
799
800static inline void
801ImageList_InternalDragDraw (HDC hdc, INT x, INT y)
802{
803 IMAGELISTDRAWPARAMS imldp;
804
805 ZeroMemory (&imldp, sizeof(imldp));
806 imldp.cbSize = sizeof(imldp);
807 imldp.himl = InternalDrag.himl;
808 imldp.i = 0;
809 imldp.hdcDst = hdc,
810 imldp.x = x;
811 imldp.y = y;
812 imldp.rgbBk = CLR_DEFAULT;
813 imldp.rgbFg = CLR_DEFAULT;
814 imldp.fStyle = ILD_NORMAL;
815 imldp.fState = ILS_ALPHA;
816 imldp.Frame = 128;
817
Dimitrie O. Paun326021b2002-09-24 18:26:42 +0000818 /* FIXME: instead of using the alpha blending, we should
819 * create a 50% mask, and draw it semitransparantly that way */
Dimitrie O. Paun318817f2002-09-12 00:51:09 +0000820 ImageList_DrawIndirect (&imldp);
821}
822
823/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000824 * ImageList_DragMove [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000825 *
826 * Moves the drag image.
827 *
828 * PARAMS
829 * x [I] X position of the drag image.
830 * y [I] Y position of the drag image.
831 *
832 * RETURNS
833 * Success: TRUE
834 * Failure: FALSE
835 *
836 * NOTES
837 * The position of the drag image is relative to the window, not
838 * the client area.
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000839 *
840 * BUGS
841 * The drag image should be drawn semitransparent.
Alexandre Julliard54c27111998-03-29 19:44:57 +0000842 */
843
Alexandre Julliarda3960291999-02-26 11:11:13 +0000844BOOL WINAPI
845ImageList_DragMove (INT x, INT y)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000846{
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +0000847 TRACE("(x=%d y=%d)\n", x, y);
848
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000849 if (!InternalDrag.himl) {
850 return FALSE;
851 }
Alexandre Julliarda845b881998-06-01 10:44:35 +0000852
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000853 /* draw/update the drag image */
854 if (InternalDrag.bShow) {
855 HDC hdcDrag;
856 HDC hdcOffScreen;
857 HDC hdcBg;
858 HBITMAP hbmOffScreen;
859 INT origNewX, origNewY;
860 INT origOldX, origOldY;
861 INT origRegX, origRegY;
862 INT sizeRegX, sizeRegY;
Vincent Béron9a624912002-05-31 23:06:46 +0000863
Alexandre Julliarda845b881998-06-01 10:44:35 +0000864
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000865 /* calculate the update region */
866 origNewX = x - InternalDrag.dxHotspot;
867 origNewY = y - InternalDrag.dyHotspot;
868 origOldX = InternalDrag.x - InternalDrag.dxHotspot;
869 origOldY = InternalDrag.y - InternalDrag.dyHotspot;
870 origRegX = min(origNewX, origOldX);
871 origRegY = min(origNewY, origOldY);
872 sizeRegX = InternalDrag.himl->cx + abs(x - InternalDrag.x);
873 sizeRegY = InternalDrag.himl->cy + abs(y - InternalDrag.y);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000874
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000875 hdcDrag = GetDCEx(InternalDrag.hwnd, 0,
876 DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
877 hdcOffScreen = CreateCompatibleDC(hdcDrag);
878 hdcBg = CreateCompatibleDC(hdcDrag);
879
880 hbmOffScreen = CreateCompatibleBitmap(hdcDrag, sizeRegX, sizeRegY);
881 SelectObject(hdcOffScreen, hbmOffScreen);
882 SelectObject(hdcBg, InternalDrag.hbmBg);
883
884 /* get the actual background of the update region */
885 BitBlt(hdcOffScreen, 0, 0, sizeRegX, sizeRegY, hdcDrag,
886 origRegX, origRegY, SRCCOPY);
887 /* erase the old image */
888 BitBlt(hdcOffScreen, origOldX - origRegX, origOldY - origRegY,
889 InternalDrag.himl->cx, InternalDrag.himl->cy, hdcBg, 0, 0,
890 SRCCOPY);
891 /* save the background */
892 BitBlt(hdcBg, 0, 0, InternalDrag.himl->cx, InternalDrag.himl->cy,
893 hdcOffScreen, origNewX - origRegX, origNewY - origRegY, SRCCOPY);
894 /* draw the image */
Dimitrie O. Paun318817f2002-09-12 00:51:09 +0000895 ImageList_InternalDragDraw(hdcOffScreen, origNewX - origRegX,
896 origNewY - origRegY);
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000897 /* draw the update region to the screen */
898 BitBlt(hdcDrag, origRegX, origRegY, sizeRegX, sizeRegY,
899 hdcOffScreen, 0, 0, SRCCOPY);
900
901 DeleteDC(hdcBg);
902 DeleteDC(hdcOffScreen);
Michael Stefaniuc00bd7992001-12-31 22:21:24 +0000903 DeleteObject(hbmOffScreen);
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000904 ReleaseDC(InternalDrag.hwnd, hdcDrag);
905 }
906
907 /* update the image position */
908 InternalDrag.x = x;
909 InternalDrag.y = y;
910
911 return TRUE;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000912}
913
914
915/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000916 * ImageList_DragShowNolock [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000917 *
918 * Shows or hides the drag image.
919 *
920 * PARAMS
921 * bShow [I] TRUE shows the drag image, FALSE hides it.
922 *
923 * RETURNS
924 * Success: TRUE
925 * Failure: FALSE
926 *
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000927 * BUGS
928 * The drag image should be drawn semitransparent.
Alexandre Julliard54c27111998-03-29 19:44:57 +0000929 */
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000930
Alexandre Julliarda3960291999-02-26 11:11:13 +0000931BOOL WINAPI
932ImageList_DragShowNolock (BOOL bShow)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +0000933{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000934 HDC hdcDrag;
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000935 HDC hdcBg;
936 INT x, y;
Alexandre Julliarda845b881998-06-01 10:44:35 +0000937
Alexandre Julliarda099a551999-06-12 15:45:58 +0000938 TRACE("bShow=0x%X!\n", bShow);
Alexandre Julliarda845b881998-06-01 10:44:35 +0000939
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000940 /* DragImage is already visible/hidden */
941 if ((InternalDrag.bShow && bShow) || (!InternalDrag.bShow && !bShow)) {
942 return FALSE;
943 }
944
945 /* position of the origin of the DragImage */
946 x = InternalDrag.x - InternalDrag.dxHotspot;
947 y = InternalDrag.y - InternalDrag.dyHotspot;
948
949 hdcDrag = GetDCEx (InternalDrag.hwnd, 0,
Alexandre Julliarda845b881998-06-01 10:44:35 +0000950 DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000951 if (!hdcDrag) {
952 return FALSE;
953 }
Alexandre Julliarda845b881998-06-01 10:44:35 +0000954
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000955 hdcBg = CreateCompatibleDC(hdcDrag);
956 if (!InternalDrag.hbmBg) {
957 InternalDrag.hbmBg = CreateCompatibleBitmap(hdcDrag,
958 InternalDrag.himl->cx, InternalDrag.himl->cy);
959 }
960 SelectObject(hdcBg, InternalDrag.hbmBg);
Vincent Béron9a624912002-05-31 23:06:46 +0000961
Alexandre Julliarda845b881998-06-01 10:44:35 +0000962 if (bShow) {
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000963 /* save the background */
964 BitBlt(hdcBg, 0, 0, InternalDrag.himl->cx, InternalDrag.himl->cy,
965 hdcDrag, x, y, SRCCOPY);
966 /* show the image */
Dimitrie O. Paun318817f2002-09-12 00:51:09 +0000967 ImageList_InternalDragDraw(hdcDrag, x, y);
Vincent Béron9a624912002-05-31 23:06:46 +0000968 } else {
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000969 /* hide the image */
970 BitBlt(hdcDrag, x, y, InternalDrag.himl->cx, InternalDrag.himl->cy,
971 hdcBg, 0, 0, SRCCOPY);
Alexandre Julliarda845b881998-06-01 10:44:35 +0000972 }
973
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000974 InternalDrag.bShow = !InternalDrag.bShow;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000975
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +0000976 DeleteDC(hdcBg);
977 ReleaseDC (InternalDrag.hwnd, hdcDrag);
978 return TRUE;
Alexandre Julliard54c27111998-03-29 19:44:57 +0000979}
980
981
982/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +0000983 * ImageList_Draw [COMCTL32.@] Draws an image.
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000984 *
985 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +0000986 * himl [I] handle to image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000987 * i [I] image index
Eric Kohlf2809611998-11-08 11:36:04 +0000988 * hdc [I] handle to device context
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000989 * x [I] x position
990 * y [I] y position
991 * fStyle [I] drawing flags
992 *
993 * RETURNS
994 * Success: TRUE
995 * Failure: FALSE
996 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000997 * SEE
Dimitrie O. Paun318817f2002-09-12 00:51:09 +0000998 * ImageList_DrawEx.
Alexandre Julliard54c27111998-03-29 19:44:57 +0000999 */
1000
Alexandre Julliarda3960291999-02-26 11:11:13 +00001001BOOL WINAPI
Dimitrie O. Paun318817f2002-09-12 00:51:09 +00001002ImageList_Draw (HIMAGELIST himl, INT i, HDC hdc, INT x, INT y, UINT fStyle)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001003{
Dimitrie O. Paun318817f2002-09-12 00:51:09 +00001004 return ImageList_DrawEx (himl, i, hdc, x, y, 0, 0,
1005 CLR_DEFAULT, CLR_DEFAULT, fStyle);
Alexandre Julliard54c27111998-03-29 19:44:57 +00001006}
1007
1008
1009/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001010 * ImageList_DrawEx [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001011 *
1012 * Draws an image and allows to use extended drawing features.
1013 *
1014 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +00001015 * himl [I] handle to image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001016 * i [I] image index
Eric Kohlf2809611998-11-08 11:36:04 +00001017 * hdc [I] handle to device context
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001018 * x [I] X position
1019 * y [I] Y position
Dimitrie O. Paun7ad3d122002-09-04 18:44:46 +00001020 * dx [I] X offset
1021 * dy [I] Y offset
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001022 * rgbBk [I] background color
1023 * rgbFg [I] foreground color
1024 * fStyle [I] drawing flags
1025 *
1026 * RETURNS
1027 * Success: TRUE
1028 * Failure: FALSE
1029 *
1030 * NOTES
1031 * Calls ImageList_DrawIndirect.
1032 *
1033 * SEE
1034 * ImageList_DrawIndirect.
Alexandre Julliard54c27111998-03-29 19:44:57 +00001035 */
1036
Alexandre Julliarda3960291999-02-26 11:11:13 +00001037BOOL WINAPI
1038ImageList_DrawEx (HIMAGELIST himl, INT i, HDC hdc, INT x, INT y,
1039 INT dx, INT dy, COLORREF rgbBk, COLORREF rgbFg,
1040 UINT fStyle)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001041{
1042 IMAGELISTDRAWPARAMS imldp;
1043
Dimitrie O. Paun318817f2002-09-12 00:51:09 +00001044 ZeroMemory (&imldp, sizeof(imldp));
1045 imldp.cbSize = sizeof(imldp);
Alexandre Julliard54c27111998-03-29 19:44:57 +00001046 imldp.himl = himl;
1047 imldp.i = i;
1048 imldp.hdcDst = hdc,
1049 imldp.x = x;
1050 imldp.y = y;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001051 imldp.cx = dx;
1052 imldp.cy = dy;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001053 imldp.rgbBk = rgbBk;
1054 imldp.rgbFg = rgbFg;
1055 imldp.fStyle = fStyle;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001056
Eric Kohl9d8e8641998-10-24 10:49:27 +00001057 return ImageList_DrawIndirect (&imldp);
Alexandre Julliard54c27111998-03-29 19:44:57 +00001058}
1059
1060
1061/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001062 * ImageList_DrawIndirect [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001063 *
1064 * Draws an image using ...
1065 *
1066 * PARAMS
Alexandre Julliarda845b881998-06-01 10:44:35 +00001067 * pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001068 *
1069 * RETURNS
Alexandre Julliarda845b881998-06-01 10:44:35 +00001070 * Success: TRUE
1071 * Failure: FALSE
Alexandre Julliard54c27111998-03-29 19:44:57 +00001072 */
1073
Alexandre Julliarda3960291999-02-26 11:11:13 +00001074BOOL WINAPI
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001075ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001076{
Dimitrie O. Paun318817f2002-09-12 00:51:09 +00001077 INT cx, cy, nOvlIdx;
1078 DWORD fState, dwRop;
1079 UINT fStyle;
1080 COLORREF clrBk, oldImageBk, oldImageFg;
1081 HDC hImageDC, hImageListDC, hMaskListDC;
1082 HBITMAP hImageBmp, hOldImageBmp, hOldImageListBmp, hOldMaskListBmp, hBlendMaskBmp;
1083 BOOL bIsTransparent, bBlend, bResult = FALSE;
1084 const HIMAGELIST himl = pimldp->himl;
1085 const INT lx = himl->cx * pimldp->i + pimldp->xBitmap;
1086 const INT ly = pimldp->yBitmap;
1087
1088 if (!pimldp || !himl) return FALSE;
1089 if ((pimldp->i < 0) || (pimldp->i >= himl->cCurImage)) return FALSE;
1090
1091 fState = pimldp->cbSize < sizeof(IMAGELISTDRAWPARAMS) ? ILS_NORMAL : pimldp->fState;
1092 fStyle = pimldp->fStyle & ~ILD_OVERLAYMASK;
1093 cx = (pimldp->cx == 0) ? himl->cx : pimldp->cx;
1094 cy = (pimldp->cy == 0) ? himl->cy : pimldp->cy;
1095 clrBk = (pimldp->rgbBk == CLR_DEFAULT) ? himl->clrBk : pimldp->rgbBk;
Dimitrie O. Paun0bc4b562002-10-15 02:15:09 +00001096 bIsTransparent = (fStyle & ILD_TRANSPARENT) || clrBk == CLR_NONE;
Dimitrie O. Paun318817f2002-09-12 00:51:09 +00001097 bBlend = fStyle & (ILD_BLEND25 | ILD_BLEND50);
Mike McCormack5a6a71f2002-08-16 01:35:43 +00001098
Michael Stefaniuc353529b2002-10-23 22:19:10 +00001099 TRACE("hbmMask(%p) iImage(%d) x(%d) y(%d) cx(%d) cy(%d)\n",
Dimitrie O. Paun318817f2002-09-12 00:51:09 +00001100 himl->hbmMask, pimldp->i, pimldp->x, pimldp->y, cx, cy);
Mike McCormack5a6a71f2002-08-16 01:35:43 +00001101
Dimitrie O. Paun318817f2002-09-12 00:51:09 +00001102 /* we will use these DCs to access the images and masks in the ImageList */
1103 hImageListDC = CreateCompatibleDC(0);
1104 hMaskListDC = himl->hbmMask ? CreateCompatibleDC(0) : 0;
1105
1106 /* these will accumulate the image and mask for the image we're drawing */
1107 hImageDC = CreateCompatibleDC( pimldp->hdcDst );
1108 hImageBmp = CreateCompatibleBitmap( pimldp->hdcDst, cx, cy );
1109 hBlendMaskBmp = bBlend ? CreateBitmap(cx, cy, 1, 1, NULL) : 0;
1110
1111 /* Create a compatible DC. */
1112 if (!hImageListDC || !hImageDC || !hImageBmp ||
1113 (bBlend && !hBlendMaskBmp) || (himl->hbmMask && !hMaskListDC))
1114 goto cleanup;
1115
1116 hOldImageListBmp = SelectObject(hImageListDC, himl->hbmImage);
1117 hOldImageBmp = SelectObject(hImageDC, hImageBmp);
1118 hOldMaskListBmp = hMaskListDC ? SelectObject(hMaskListDC, himl->hbmMask) : 0;
1119
Vincent Béron9a624912002-05-31 23:06:46 +00001120 /*
Dimitrie O. Paun318817f2002-09-12 00:51:09 +00001121 * To obtain a transparent look, background color should be set
1122 * to white and foreground color to black when blting the
1123 * monochrome mask.
1124 */
1125 oldImageFg = SetTextColor( hImageDC, RGB( 0, 0, 0 ) );
1126 oldImageBk = SetBkColor( hImageDC, RGB( 0xff, 0xff, 0xff ) );
1127
Dimitrie O. Paun318817f2002-09-12 00:51:09 +00001128 /*
Dimitrie O. Paun0bc4b562002-10-15 02:15:09 +00001129 * Draw the initial image
Dimitrie O. Paun318817f2002-09-12 00:51:09 +00001130 */
1131 if(fStyle & ILD_MASK) {
1132 if (himl->hbmMask) {
1133 BitBlt(hImageDC, 0, 0, cx, cy, hMaskListDC, lx, ly, SRCCOPY);
1134 } else {
1135 HBRUSH hOldBrush = SelectObject (hImageDC, GetStockObject(BLACK_BRUSH));
1136 PatBlt( hImageDC, 0, 0, cx, cy, PATCOPY);
1137 SelectObject(hImageDC, hOldBrush);
1138 }
Dimitrie O. Paun0bc4b562002-10-15 02:15:09 +00001139 } else if (himl->hbmMask && !bIsTransparent) {
1140 /* blend the image with the needed solid background */
1141 HBRUSH hOldBrush = SelectObject (hImageDC, CreateSolidBrush (clrBk));
1142 PatBlt( hImageDC, 0, 0, cx, cy, PATCOPY );
Dimitrie O. Paun318817f2002-09-12 00:51:09 +00001143 BitBlt( hImageDC, 0, 0, cx, cy, hMaskListDC, lx, ly, SRCAND );
1144 BitBlt( hImageDC, 0, 0, cx, cy, hImageListDC, lx, ly, SRCPAINT );
Dimitrie O. Paun0bc4b562002-10-15 02:15:09 +00001145 DeleteObject (SelectObject (hImageDC, hOldBrush));
Dimitrie O. Paun318817f2002-09-12 00:51:09 +00001146 } else {
Dimitrie O. Paun0bc4b562002-10-15 02:15:09 +00001147 /* start off with the image, if we have a mask, we'll use it later */
Dimitrie O. Paun318817f2002-09-12 00:51:09 +00001148 BitBlt( hImageDC, 0, 0, cx, cy, hImageListDC, lx, ly, SRCCOPY);
1149 }
1150
1151 /* Time for blending, if required */
1152 if (bBlend) {
1153 HBRUSH hBlendBrush, hOldBrush;
1154 COLORREF clrBlend = pimldp->rgbFg;
1155 HDC hBlendMaskDC = hImageListDC;
1156 HBITMAP hOldBitmap;
1157
1158 /* Create the blend Mask */
1159 hOldBitmap = SelectObject(hBlendMaskDC, hBlendMaskBmp);
1160 hBlendBrush = fStyle & ILD_BLEND50 ? himl->hbrBlend50 : himl->hbrBlend25;
1161 hOldBrush = (HBRUSH) SelectObject(hBlendMaskDC, hBlendBrush);
1162 PatBlt(hBlendMaskDC, 0, 0, cx, cy, PATCOPY);
1163 SelectObject(hBlendMaskDC, hOldBrush);
1164
1165 /* Modify the blend mask if an Image Mask exist */
1166 if(himl->hbmMask) {
1167 BitBlt(hBlendMaskDC, 0, 0, cx, cy, hMaskListDC, lx, ly, 0x220326); /* NOTSRCAND */
1168 BitBlt(hBlendMaskDC, 0, 0, cx, cy, hBlendMaskDC, 0, 0, NOTSRCCOPY);
1169 }
1170
1171 /* now apply blend to the current image given the BlendMask */
1172 if (clrBlend == CLR_DEFAULT) clrBlend = GetSysColor (COLOR_HIGHLIGHT);
1173 else if (clrBlend == CLR_NONE) clrBlend = GetTextColor (pimldp->hdcDst);
1174 hOldBrush = (HBRUSH) SelectObject (hImageDC, CreateSolidBrush(clrBlend));
1175 BitBlt (hImageDC, 0, 0, cx, cy, hBlendMaskDC, 0, 0, 0xB8074A); /* PSDPxax */
1176 DeleteObject(SelectObject(hImageDC, hOldBrush));
1177 SelectObject(hBlendMaskDC, hOldBitmap);
1178 }
1179
1180 /* Now do the overlay image, if any */
1181 nOvlIdx = (pimldp->fStyle & ILD_OVERLAYMASK) >> 8;
1182 if ( (nOvlIdx >= 1) && (nOvlIdx <= MAX_OVERLAYIMAGE)) {
1183 nOvlIdx = himl->nOvlIdx[nOvlIdx - 1];
1184 if ((nOvlIdx >= 0) && (nOvlIdx < himl->cCurImage)) {
1185 const INT ox = himl->cx * nOvlIdx + pimldp->xBitmap;
1186 if (himl->hbmMask && !(fStyle & ILD_IMAGE))
1187 BitBlt (hImageDC, 0, 0, cx, cy, hMaskListDC, ox, ly, SRCAND);
1188 BitBlt (hImageDC, 0, 0, cx, cy, hImageListDC, ox, ly, SRCPAINT);
1189 }
1190 }
1191
1192 if (fState & ILS_SATURATE) FIXME("ILS_SATURATE: unimplemented!\n");
1193 if (fState & ILS_GLOW) FIXME("ILS_GLOW: unimplemented!\n");
1194 if (fState & ILS_SHADOW) FIXME("ILS_SHADOW: unimplemented!\n");
1195 if (fState & ILS_ALPHA) FIXME("ILS_SHADOW: unimplemented!\n");
1196
1197 if (fStyle & ILD_PRESERVEALPHA) FIXME("ILD_PRESERVEALPHA: unimplemented!\n");
1198 if (fStyle & ILD_SCALE) FIXME("ILD_SCALE: unimplemented!\n");
1199 if (fStyle & ILD_DPISCALE) FIXME("ILD_DPISCALE: unimplemented!\n");
1200
1201 /* now copy the image to the screen */
1202 dwRop = SRCCOPY;
Dimitrie O. Paun0bc4b562002-10-15 02:15:09 +00001203 if (himl->hbmMask && bIsTransparent && !(fStyle & ILD_MASK)) {
Dimitrie O. Paun318817f2002-09-12 00:51:09 +00001204 COLORREF oldDstFg = SetTextColor(pimldp->hdcDst, RGB( 0, 0, 0 ) );
1205 COLORREF oldDstBk = SetBkColor(pimldp->hdcDst, RGB( 0xff, 0xff, 0xff ));
1206 BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy, hMaskListDC, lx, ly, SRCAND);
1207 SetBkColor(pimldp->hdcDst, oldDstBk);
1208 SetTextColor(pimldp->hdcDst, oldDstFg);
1209 dwRop = SRCPAINT;
1210 }
1211 if (fStyle & ILD_ROP) dwRop = pimldp->dwRop;
1212 BitBlt (pimldp->hdcDst, pimldp->x, pimldp->y, cx, cy, hImageDC, 0, 0, dwRop);
1213
1214 bResult = TRUE;
1215
1216 /* cleanup the mess */
1217 SetBkColor(hImageDC, oldImageBk);
1218 SetTextColor(hImageDC, oldImageFg);
1219 SelectObject(hImageDC, hOldImageBmp);
1220 SelectObject(hImageListDC, hOldImageListBmp);
1221 if (hMaskListDC) SelectObject(hMaskListDC, hOldMaskListBmp);
1222cleanup:
1223 DeleteObject(hBlendMaskBmp);
1224 DeleteObject(hImageBmp);
1225 DeleteObject(hImageDC);
1226 DeleteObject(hImageListDC);
1227 DeleteObject(hMaskListDC);
1228
1229 return bResult;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001230}
1231
1232
Alexandre Julliard54c27111998-03-29 19:44:57 +00001233/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001234 * ImageList_Duplicate [COMCTL32.@] Duplicates an image list.
Alexandre Julliard54c27111998-03-29 19:44:57 +00001235 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001236 * PARAMS
1237 * himlSrc [I] source image list handle
Alexandre Julliard54c27111998-03-29 19:44:57 +00001238 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001239 * RETURNS
1240 * Success: Handle of duplicated image list.
Alexandre Julliarda845b881998-06-01 10:44:35 +00001241 * Failure: NULL
Alexandre Julliard54c27111998-03-29 19:44:57 +00001242 */
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001243
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001244HIMAGELIST WINAPI
1245ImageList_Duplicate (HIMAGELIST himlSrc)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001246{
1247 HIMAGELIST himlDst;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001248 HDC hdcSrc, hdcDst;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001249
1250 if (himlSrc == NULL) {
Alexandre Julliarda099a551999-06-12 15:45:58 +00001251 ERR("Invalid image list handle!\n");
Eric Kohlf2809611998-11-08 11:36:04 +00001252 return NULL;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001253 }
1254
1255 himlDst = ImageList_Create (himlSrc->cx, himlSrc->cy, himlSrc->flags,
1256 himlSrc->cInitial, himlSrc->cGrow);
1257
1258 if (himlDst)
1259 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001260 hdcSrc = CreateCompatibleDC (0);
1261 hdcDst = CreateCompatibleDC (0);
1262 SelectObject (hdcSrc, himlSrc->hbmImage);
1263 SelectObject (hdcDst, himlDst->hbmImage);
1264 BitBlt (hdcDst, 0, 0, himlSrc->cCurImage * himlSrc->cx, himlSrc->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +00001265 hdcSrc, 0, 0, SRCCOPY);
1266
1267 if (himlDst->hbmMask)
1268 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001269 SelectObject (hdcSrc, himlSrc->hbmMask);
1270 SelectObject (hdcDst, himlDst->hbmMask);
1271 BitBlt (hdcDst, 0, 0, himlSrc->cCurImage * himlSrc->cx,
Alexandre Julliard54c27111998-03-29 19:44:57 +00001272 himlSrc->cy, hdcSrc, 0, 0, SRCCOPY);
1273 }
1274
Alexandre Julliarda3960291999-02-26 11:11:13 +00001275 DeleteDC (hdcDst);
1276 DeleteDC (hdcSrc);
Alexandre Julliard54c27111998-03-29 19:44:57 +00001277
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001278 himlDst->cCurImage = himlSrc->cCurImage;
1279 himlDst->cMaxImage = himlSrc->cMaxImage;
1280 }
Eric Kohlf2809611998-11-08 11:36:04 +00001281 return himlDst;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001282}
1283
1284
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001285/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001286 * ImageList_EndDrag [COMCTL32.@] Finishes a drag operation.
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001287 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001288 * Finishes a drag operation.
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001289 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001290 * PARAMS
Alexandre Julliarda845b881998-06-01 10:44:35 +00001291 * no Parameters
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001292 *
1293 * RETURNS
1294 * Success: TRUE
1295 * Failure: FALSE
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001296 */
1297
Alexandre Julliarda3960291999-02-26 11:11:13 +00001298BOOL WINAPI
Patrik Stridvall9e61c1c1999-06-12 08:27:49 +00001299ImageList_EndDrag (void)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001300{
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +00001301 /* cleanup the InternalDrag struct */
1302 InternalDrag.hwnd = 0;
1303 ImageList_Destroy (InternalDrag.himl);
1304 InternalDrag.himl = 0;
1305 InternalDrag.x= 0;
1306 InternalDrag.y= 0;
1307 InternalDrag.dxHotspot = 0;
1308 InternalDrag.dyHotspot = 0;
1309 InternalDrag.bShow = FALSE;
1310 DeleteObject(InternalDrag.hbmBg);
1311 InternalDrag.hbmBg = 0;
Dave Hawkes770a5bf2002-02-26 00:33:51 +00001312 InternalDrag.bHSPending = FALSE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001313
Eric Kohlf2809611998-11-08 11:36:04 +00001314 return TRUE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001315}
1316
1317
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001318/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001319 * ImageList_GetBkColor [COMCTL32.@]
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001320 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001321 * Returns the background color of an image list.
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001322 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001323 * PARAMS
1324 * himl [I] Image list handle.
1325 *
1326 * RETURNS
Alexandre Julliarda845b881998-06-01 10:44:35 +00001327 * Success: background color
1328 * Failure: CLR_NONE
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001329 */
1330
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001331COLORREF WINAPI
1332ImageList_GetBkColor (HIMAGELIST himl)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001333{
Dimitrie O. Paun4d1e49d2002-09-04 23:31:48 +00001334 return himl ? himl->clrBk : CLR_NONE;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001335}
1336
1337
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001338/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001339 * ImageList_GetDragImage [COMCTL32.@]
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001340 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001341 * Returns the handle to the internal drag image list.
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001342 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001343 * PARAMS
1344 * ppt [O] Pointer to the drag position. Can be NULL.
1345 * pptHotspot [O] Pointer to the position of the hot spot. Can be NULL.
1346 *
1347 * RETURNS
1348 * Success: Handle of the drag image list.
1349 * Failure: NULL.
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001350 */
1351
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001352HIMAGELIST WINAPI
Alexandre Julliarda3960291999-02-26 11:11:13 +00001353ImageList_GetDragImage (POINT *ppt, POINT *pptHotspot)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001354{
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +00001355 if (InternalDrag.himl) {
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +00001356 if (ppt) {
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +00001357 ppt->x = InternalDrag.x;
1358 ppt->y = InternalDrag.y;
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +00001359 }
1360 if (pptHotspot) {
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +00001361 pptHotspot->x = InternalDrag.dxHotspot;
1362 pptHotspot->y = InternalDrag.dyHotspot;
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +00001363 }
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +00001364 return (InternalDrag.himl);
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +00001365 }
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001366
Eric Kohlf2809611998-11-08 11:36:04 +00001367 return NULL;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001368}
1369
1370
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001371/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001372 * ImageList_GetFlags [COMCTL32.@]
Huw D M Davies1a65a7b2002-01-15 20:28:05 +00001373 *
1374 * BUGS
1375 * Stub.
1376 */
1377
1378DWORD WINAPI
1379ImageList_GetFlags(HIMAGELIST himl)
1380{
1381 FIXME("(%p):empty stub\n", himl);
1382 return 0;
1383}
1384
1385
1386/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001387 * ImageList_GetIcon [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001388 *
1389 * Creates an icon from a masked image of an image list.
1390 *
1391 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +00001392 * himl [I] handle to image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001393 * i [I] image index
1394 * flags [I] drawing style flags
1395 *
1396 * RETURNS
1397 * Success: icon handle
1398 * Failure: NULL
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001399 */
1400
Alexandre Julliarda3960291999-02-26 11:11:13 +00001401HICON WINAPI
1402ImageList_GetIcon (HIMAGELIST himl, INT i, UINT fStyle)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001403{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001404 ICONINFO ii;
Dimitrie O. Paun4d1e49d2002-09-04 23:31:48 +00001405 HICON hIcon;
1406 HBITMAP hOldDstBitmap;
1407 HDC hdcDst;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001408
Dimitrie O. Paun4d1e49d2002-09-04 23:31:48 +00001409 if ((himl == NULL) || (i < 0) || (i >= himl->cCurImage)) return 0;
Alexandre Julliarda845b881998-06-01 10:44:35 +00001410
Alexandre Julliarda3960291999-02-26 11:11:13 +00001411 hdcDst = CreateCompatibleDC(0);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001412
Alexandre Julliard54c27111998-03-29 19:44:57 +00001413 ii.fIcon = TRUE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001414
1415 /* draw mask*/
Dimitrie O. Paun4d1e49d2002-09-04 23:31:48 +00001416 ii.hbmMask = CreateCompatibleBitmap (hdcDst, himl->cx, himl->cy);
Pierre Mageau6231a171999-07-24 10:20:06 +00001417 hOldDstBitmap = (HBITMAP)SelectObject (hdcDst, ii.hbmMask);
Dimitrie O. Paun4d1e49d2002-09-04 23:31:48 +00001418 ImageList_Draw(himl, i, hdcDst, 0, 0, ILD_MASK);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001419
1420 /* draw image*/
Dimitrie O. Paun4d1e49d2002-09-04 23:31:48 +00001421 SelectObject (hdcDst, himl->hbmImage);
1422 ii.hbmColor = CreateCompatibleBitmap (hdcDst, himl->cx, himl->cy);
Luc Tourangeau296def21999-07-18 13:25:31 +00001423 SelectObject (hdcDst, ii.hbmColor);
Dimitrie O. Paun4d1e49d2002-09-04 23:31:48 +00001424 ImageList_Draw(himl, i, hdcDst, 0, 0, fStyle);
Alexandre Julliard54c27111998-03-29 19:44:57 +00001425
Pierre Mageau6231a171999-07-24 10:20:06 +00001426 /*
1427 * CreateIconIndirect requires us to deselect the bitmaps from
Vincent Béron9a624912002-05-31 23:06:46 +00001428 * the DCs before calling
Pierre Mageau6231a171999-07-24 10:20:06 +00001429 */
Pierre Mageau6231a171999-07-24 10:20:06 +00001430 SelectObject(hdcDst, hOldDstBitmap);
1431
Vincent Béron9a624912002-05-31 23:06:46 +00001432 hIcon = CreateIconIndirect (&ii);
Alexandre Julliard54c27111998-03-29 19:44:57 +00001433
Alexandre Julliarda3960291999-02-26 11:11:13 +00001434 DeleteObject (ii.hbmMask);
1435 DeleteObject (ii.hbmColor);
Dimitrie O. Paun4d1e49d2002-09-04 23:31:48 +00001436 DeleteDC (hdcDst);
Alexandre Julliard54c27111998-03-29 19:44:57 +00001437
Eric Kohl978137d1998-10-11 13:12:54 +00001438 return hIcon;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001439}
1440
1441
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001442/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001443 * ImageList_GetIconSize [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001444 *
1445 * Retrieves the size of an image in an image list.
1446 *
1447 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +00001448 * himl [I] handle to image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001449 * cx [O] pointer to the image width.
1450 * cy [O] pointer to the image height.
1451 *
1452 * RETURNS
1453 * Success: TRUE
1454 * Failure: FALSE
1455 *
1456 * NOTES
1457 * All images in an image list have the same size.
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001458 */
1459
Alexandre Julliarda3960291999-02-26 11:11:13 +00001460BOOL WINAPI
1461ImageList_GetIconSize (HIMAGELIST himl, INT *cx, INT *cy)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001462{
Eric Kohl978137d1998-10-11 13:12:54 +00001463 if (himl == NULL)
1464 return FALSE;
1465 if ((himl->cx <= 0) || (himl->cy <= 0))
1466 return FALSE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001467
1468 if (cx)
Eric Kohl978137d1998-10-11 13:12:54 +00001469 *cx = himl->cx;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001470 if (cy)
Eric Kohl978137d1998-10-11 13:12:54 +00001471 *cy = himl->cy;
1472
1473 return TRUE;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001474}
1475
1476
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001477/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001478 * ImageList_GetImageCount [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001479 *
1480 * Returns the number of images in an image list.
1481 *
1482 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +00001483 * himl [I] handle to image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001484 *
1485 * RETURNS
1486 * Success: Number of images.
Alexandre Julliarda845b881998-06-01 10:44:35 +00001487 * Failure: 0
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001488 */
1489
Alexandre Julliarda3960291999-02-26 11:11:13 +00001490INT WINAPI
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001491ImageList_GetImageCount (HIMAGELIST himl)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001492{
Alexandre Julliarda845b881998-06-01 10:44:35 +00001493 if (himl == NULL)
1494 return 0;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001495
Eric Kohl978137d1998-10-11 13:12:54 +00001496 return himl->cCurImage;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001497}
1498
1499
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001500/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001501 * ImageList_GetImageInfo [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001502 *
1503 * Returns information about an image in an image list.
1504 *
1505 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +00001506 * himl [I] handle to image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001507 * i [I] image index
Eric Kohlf2809611998-11-08 11:36:04 +00001508 * pImageInfo [O] pointer to the image information
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001509 *
1510 * RETURNS
1511 * Success: TRUE
1512 * Failure: FALSE
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001513 */
1514
Alexandre Julliarda3960291999-02-26 11:11:13 +00001515BOOL WINAPI
1516ImageList_GetImageInfo (HIMAGELIST himl, INT i, IMAGEINFO *pImageInfo)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001517{
Eric Kohl978137d1998-10-11 13:12:54 +00001518 if ((himl == NULL) || (pImageInfo == NULL))
1519 return FALSE;
1520 if ((i < 0) || (i >= himl->cCurImage))
1521 return FALSE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001522
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001523 pImageInfo->hbmImage = himl->hbmImage;
1524 pImageInfo->hbmMask = himl->hbmMask;
Vincent Béron9a624912002-05-31 23:06:46 +00001525
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001526 pImageInfo->rcImage.top = 0;
1527 pImageInfo->rcImage.bottom = himl->cy;
1528 pImageInfo->rcImage.left = i * himl->cx;
1529 pImageInfo->rcImage.right = (i+1) * himl->cx;
Vincent Béron9a624912002-05-31 23:06:46 +00001530
Eric Kohl978137d1998-10-11 13:12:54 +00001531 return TRUE;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001532}
1533
1534
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001535/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001536 * ImageList_GetImageRect [COMCTL32.@]
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001537 *
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001538 * Retrieves the rectangle of the specified image in an image list.
1539 *
1540 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +00001541 * himl [I] handle to image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001542 * i [I] image index
1543 * lpRect [O] pointer to the image rectangle
1544 *
1545 * RETURNS
Alexandre Julliarda845b881998-06-01 10:44:35 +00001546 * Success: TRUE
1547 * Failure: FALSE
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001548 *
1549 * NOTES
1550 * This is an UNDOCUMENTED function!!!
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001551 */
Alexandre Julliard54c27111998-03-29 19:44:57 +00001552
Alexandre Julliarda3960291999-02-26 11:11:13 +00001553BOOL WINAPI
1554ImageList_GetImageRect (HIMAGELIST himl, INT i, LPRECT lpRect)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001555{
Eric Kohl978137d1998-10-11 13:12:54 +00001556 if ((himl == NULL) || (lpRect == NULL))
1557 return FALSE;
1558 if ((i < 0) || (i >= himl->cCurImage))
1559 return FALSE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001560
Eric Kohl978137d1998-10-11 13:12:54 +00001561 lpRect->left = i * himl->cx;
1562 lpRect->top = 0;
1563 lpRect->right = lpRect->left + himl->cx;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001564 lpRect->bottom = himl->cy;
1565
Eric Kohl978137d1998-10-11 13:12:54 +00001566 return TRUE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001567}
1568
1569
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001570/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001571 * ImageList_LoadImage [COMCTL32.@]
1572 * ImageList_LoadImageA [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001573 *
1574 * Creates an image list from a bitmap, icon or cursor.
1575 *
1576 * PARAMS
Alexandre Julliarda845b881998-06-01 10:44:35 +00001577 * hi [I] instance handle
1578 * lpbmp [I] name or id of the image
1579 * cx [I] width of each image
1580 * cGrow [I] number of images to expand
1581 * clrMask [I] mask color
1582 * uType [I] type of image to load
1583 * uFlags [I] loading flags
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001584 *
1585 * RETURNS
Eric Kohld68d5011999-01-24 19:14:58 +00001586 * Success: handle to the loaded image list
Alexandre Julliarda845b881998-06-01 10:44:35 +00001587 * Failure: NULL
1588 *
1589 * SEE
1590 * LoadImage ()
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001591 */
1592
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001593HIMAGELIST WINAPI
Andreas Mohr641405a2001-04-20 18:29:17 +00001594ImageList_LoadImageA (HINSTANCE hi, LPCSTR lpbmp, INT cx, INT cGrow,
1595 COLORREF clrMask, UINT uType, UINT uFlags)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001596{
1597 HIMAGELIST himl = NULL;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001598 HANDLE handle;
1599 INT nImageCount;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001600
Alexandre Julliarda3960291999-02-26 11:11:13 +00001601 handle = LoadImageA (hi, lpbmp, uType, 0, 0, uFlags);
Eric Kohlf2809611998-11-08 11:36:04 +00001602 if (!handle) {
Alexandre Julliarda099a551999-06-12 15:45:58 +00001603 ERR("Error loading image!\n");
Eric Kohlf2809611998-11-08 11:36:04 +00001604 return NULL;
1605 }
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001606
1607 if (uType == IMAGE_BITMAP) {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001608 BITMAP bmp;
1609 GetObjectA (handle, sizeof(BITMAP), &bmp);
Francois Boisvert0e6f0611999-06-22 19:02:07 +00001610
1611 /* To match windows behavior, if cx is set to zero and
1612 the flag DI_DEFAULTSIZE is specified, cx becomes the
1613 system metric value for icons. If the flag is not specified
1614 the function sets the size to the height of the bitmap */
1615 if (cx == 0)
1616 {
1617 if (uFlags & DI_DEFAULTSIZE)
1618 cx = GetSystemMetrics (SM_CXICON);
1619 else
1620 cx = bmp.bmHeight;
1621 }
1622
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001623 nImageCount = bmp.bmWidth / cx;
1624
1625 himl = ImageList_Create (cx, bmp.bmHeight, ILC_MASK | ILC_COLOR,
1626 nImageCount, cGrow);
Alexandre Julliarda3960291999-02-26 11:11:13 +00001627 ImageList_AddMasked (himl, (HBITMAP)handle, clrMask);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001628 }
1629 else if ((uType == IMAGE_ICON) || (uType == IMAGE_CURSOR)) {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001630 ICONINFO ii;
1631 BITMAP bmp;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001632
Alexandre Julliarda3960291999-02-26 11:11:13 +00001633 GetIconInfo (handle, &ii);
1634 GetObjectA (ii.hbmColor, sizeof(BITMAP), (LPVOID)&bmp);
Vincent Béron9a624912002-05-31 23:06:46 +00001635 himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight,
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001636 ILC_MASK | ILC_COLOR, 1, cGrow);
Alexandre Julliard829fe321998-07-26 14:27:39 +00001637 ImageList_Add (himl, ii.hbmColor, ii.hbmMask);
Alexandre Julliarda3960291999-02-26 11:11:13 +00001638 DeleteObject (ii.hbmColor);
1639 DeleteObject (ii.hbmMask);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001640 }
1641
Alexandre Julliarda3960291999-02-26 11:11:13 +00001642 DeleteObject (handle);
Vincent Béron9a624912002-05-31 23:06:46 +00001643
Eric Kohlf2809611998-11-08 11:36:04 +00001644 return himl;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001645}
1646
1647
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001648/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001649 * ImageList_LoadImageW [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001650 *
1651 * Creates an image list from a bitmap, icon or cursor.
1652 *
1653 * PARAMS
Alexandre Julliarda845b881998-06-01 10:44:35 +00001654 * hi [I] instance handle
1655 * lpbmp [I] name or id of the image
1656 * cx [I] width of each image
1657 * cGrow [I] number of images to expand
1658 * clrMask [I] mask color
1659 * uType [I] type of image to load
1660 * uFlags [I] loading flags
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001661 *
1662 * RETURNS
Eric Kohld68d5011999-01-24 19:14:58 +00001663 * Success: handle to the loaded image list
Alexandre Julliarda845b881998-06-01 10:44:35 +00001664 * Failure: NULL
1665 *
1666 * SEE
1667 * LoadImage ()
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001668 */
1669
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001670HIMAGELIST WINAPI
Alexandre Julliarda3960291999-02-26 11:11:13 +00001671ImageList_LoadImageW (HINSTANCE hi, LPCWSTR lpbmp, INT cx, INT cGrow,
1672 COLORREF clrMask, UINT uType, UINT uFlags)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001673{
1674 HIMAGELIST himl = NULL;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001675 HANDLE handle;
1676 INT nImageCount;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001677
Alexandre Julliarda3960291999-02-26 11:11:13 +00001678 handle = LoadImageW (hi, lpbmp, uType, 0, 0, uFlags);
Alexandre Julliard54c27111998-03-29 19:44:57 +00001679 if (!handle) {
Alexandre Julliarda099a551999-06-12 15:45:58 +00001680 ERR("Error loading image!\n");
Eric Kohlf2809611998-11-08 11:36:04 +00001681 return NULL;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001682 }
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001683
1684 if (uType == IMAGE_BITMAP) {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001685 BITMAP bmp;
1686 GetObjectA (handle, sizeof(BITMAP), &bmp);
Sander van Leeuwen9851f7a2002-05-30 20:38:13 +00001687
1688 /* To match windows behavior, if cx is set to zero and
1689 the flag DI_DEFAULTSIZE is specified, cx becomes the
1690 system metric value for icons. If the flag is not specified
1691 the function sets the size to the height of the bitmap */
1692 if (cx == 0)
1693 {
1694 if (uFlags & DI_DEFAULTSIZE)
1695 cx = GetSystemMetrics (SM_CXICON);
1696 else
1697 cx = bmp.bmHeight;
1698 }
1699
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001700 nImageCount = bmp.bmWidth / cx;
1701
1702 himl = ImageList_Create (cx, bmp.bmHeight, ILC_MASK | ILC_COLOR,
1703 nImageCount, cGrow);
Alexandre Julliarda3960291999-02-26 11:11:13 +00001704 ImageList_AddMasked (himl, (HBITMAP)handle, clrMask);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001705 }
1706 else if ((uType == IMAGE_ICON) || (uType == IMAGE_CURSOR)) {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001707 ICONINFO ii;
1708 BITMAP bmp;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001709
Alexandre Julliarda3960291999-02-26 11:11:13 +00001710 GetIconInfo (handle, &ii);
1711 GetObjectA (ii.hbmMask, sizeof(BITMAP), (LPVOID)&bmp);
Vincent Béron9a624912002-05-31 23:06:46 +00001712 himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight,
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001713 ILC_MASK | ILC_COLOR, 1, cGrow);
Alexandre Julliard829fe321998-07-26 14:27:39 +00001714 ImageList_Add (himl, ii.hbmColor, ii.hbmMask);
Alexandre Julliarda3960291999-02-26 11:11:13 +00001715 DeleteObject (ii.hbmColor);
1716 DeleteObject (ii.hbmMask);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001717 }
1718
Alexandre Julliarda3960291999-02-26 11:11:13 +00001719 DeleteObject (handle);
Vincent Béron9a624912002-05-31 23:06:46 +00001720
Eric Kohlf2809611998-11-08 11:36:04 +00001721 return himl;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001722}
1723
1724
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001725/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001726 * ImageList_Merge [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001727 *
1728 * Creates a new image list that contains a merged image from the specified
1729 * images of both source image lists.
1730 *
1731 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +00001732 * himl1 [I] handle to first image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001733 * i1 [I] first image index
Eric Kohlf2809611998-11-08 11:36:04 +00001734 * himl2 [I] handle to second image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001735 * i2 [I] second image index
1736 * dx [I] X offset of the second image relative to the first.
1737 * dy [I] Y offset of the second image relative to the first.
1738 *
1739 * RETURNS
Alexandre Julliarda845b881998-06-01 10:44:35 +00001740 * Success: handle of the merged image list.
1741 * Failure: NULL
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001742 */
1743
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001744HIMAGELIST WINAPI
Alexandre Julliarda3960291999-02-26 11:11:13 +00001745ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2,
1746 INT dx, INT dy)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001747{
1748 HIMAGELIST himlDst = NULL;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001749 HDC hdcSrcImage, hdcDstImage;
1750 INT cxDst, cyDst;
1751 INT xOff1, yOff1, xOff2, yOff2;
1752 INT nX1, nX2;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001753
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +00001754 TRACE("(himl1=%p i1=%d himl2=%p i2=%d dx=%d dy=%d)\n", himl1, i1, himl2,
1755 i2, dx, dy);
1756
Eric Kohl978137d1998-10-11 13:12:54 +00001757 if ((himl1 == NULL) || (himl2 == NULL))
1758 return NULL;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001759
1760 /* check indices */
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001761 if ((i1 < 0) || (i1 >= himl1->cCurImage)) {
Alexandre Julliarda099a551999-06-12 15:45:58 +00001762 ERR("Index 1 out of range! %d\n", i1);
Eric Kohl978137d1998-10-11 13:12:54 +00001763 return NULL;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001764 }
Alexandre Julliard54c27111998-03-29 19:44:57 +00001765
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001766 if ((i2 < 0) || (i2 >= himl2->cCurImage)) {
Alexandre Julliarda099a551999-06-12 15:45:58 +00001767 ERR("Index 2 out of range! %d\n", i2);
Eric Kohl978137d1998-10-11 13:12:54 +00001768 return NULL;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001769 }
Alexandre Julliard54c27111998-03-29 19:44:57 +00001770
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001771 if (dx > 0) {
Patrik Stridvall35669732001-09-10 23:09:04 +00001772 cxDst = max (himl1->cx, dx + himl2->cx);
Alexandre Julliard54c27111998-03-29 19:44:57 +00001773 xOff1 = 0;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001774 xOff2 = dx;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001775 }
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001776 else if (dx < 0) {
Patrik Stridvall35669732001-09-10 23:09:04 +00001777 cxDst = max (himl2->cx, himl1->cx - dx);
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001778 xOff1 = -dx;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001779 xOff2 = 0;
1780 }
1781 else {
Patrik Stridvall35669732001-09-10 23:09:04 +00001782 cxDst = max (himl1->cx, himl2->cx);
Alexandre Julliard54c27111998-03-29 19:44:57 +00001783 xOff1 = 0;
1784 xOff2 = 0;
1785 }
1786
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001787 if (dy > 0) {
Patrik Stridvall35669732001-09-10 23:09:04 +00001788 cyDst = max (himl1->cy, dy + himl2->cy);
Alexandre Julliard54c27111998-03-29 19:44:57 +00001789 yOff1 = 0;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001790 yOff2 = dy;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001791 }
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001792 else if (dy < 0) {
Patrik Stridvall35669732001-09-10 23:09:04 +00001793 cyDst = max (himl2->cy, himl1->cy - dy);
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001794 yOff1 = -dy;
Alexandre Julliard54c27111998-03-29 19:44:57 +00001795 yOff2 = 0;
1796 }
1797 else {
Patrik Stridvall35669732001-09-10 23:09:04 +00001798 cyDst = max (himl1->cy, himl2->cy);
Alexandre Julliard54c27111998-03-29 19:44:57 +00001799 yOff1 = 0;
1800 yOff2 = 0;
1801 }
1802
1803 himlDst = ImageList_Create (cxDst, cyDst, ILC_MASK | ILC_COLOR, 1, 1);
1804
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001805 if (himlDst) {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001806 hdcSrcImage = CreateCompatibleDC (0);
1807 hdcDstImage = CreateCompatibleDC (0);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001808 nX1 = i1 * himl1->cx;
1809 nX2 = i2 * himl2->cx;
Vincent Béron9a624912002-05-31 23:06:46 +00001810
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001811 /* copy image */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001812 SelectObject (hdcSrcImage, himl1->hbmImage);
1813 SelectObject (hdcDstImage, himlDst->hbmImage);
Vincent Béron9a624912002-05-31 23:06:46 +00001814 BitBlt (hdcDstImage, 0, 0, cxDst, cyDst,
Alexandre Julliard54c27111998-03-29 19:44:57 +00001815 hdcSrcImage, 0, 0, BLACKNESS);
Vincent Béron9a624912002-05-31 23:06:46 +00001816 BitBlt (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +00001817 hdcSrcImage, nX1, 0, SRCCOPY);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001818
Alexandre Julliarda3960291999-02-26 11:11:13 +00001819 SelectObject (hdcSrcImage, himl2->hbmMask);
Vincent Béron9a624912002-05-31 23:06:46 +00001820 BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001821 hdcSrcImage, nX2, 0, SRCAND);
1822
Alexandre Julliarda3960291999-02-26 11:11:13 +00001823 SelectObject (hdcSrcImage, himl2->hbmImage);
Vincent Béron9a624912002-05-31 23:06:46 +00001824 BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001825 hdcSrcImage, nX2, 0, SRCPAINT);
1826
1827 /* copy mask */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001828 SelectObject (hdcSrcImage, himl1->hbmMask);
1829 SelectObject (hdcDstImage, himlDst->hbmMask);
Vincent Béron9a624912002-05-31 23:06:46 +00001830 BitBlt (hdcDstImage, 0, 0, cxDst, cyDst,
Alexandre Julliard54c27111998-03-29 19:44:57 +00001831 hdcSrcImage, 0, 0, WHITENESS);
Vincent Béron9a624912002-05-31 23:06:46 +00001832 BitBlt (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy,
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001833 hdcSrcImage, nX1, 0, SRCCOPY);
1834
Alexandre Julliarda3960291999-02-26 11:11:13 +00001835 SelectObject (hdcSrcImage, himl2->hbmMask);
Vincent Béron9a624912002-05-31 23:06:46 +00001836 BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001837 hdcSrcImage, nX2, 0, SRCAND);
1838
Alexandre Julliarda3960291999-02-26 11:11:13 +00001839 DeleteDC (hdcSrcImage);
1840 DeleteDC (hdcDstImage);
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +00001841 himlDst->cCurImage = 1;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001842 }
Vincent Béron9a624912002-05-31 23:06:46 +00001843
Eric Kohl978137d1998-10-11 13:12:54 +00001844 return himlDst;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00001845}
1846
1847
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001848/* helper for _read_bitmap currently unused */
Serge Ivanova39cbbc2000-02-25 20:47:26 +00001849#if 0
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001850static int may_use_dibsection(HDC hdc) {
1851 int bitspixel = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES);
1852 if (bitspixel>8)
1853 return TRUE;
1854 if (bitspixel<=4)
1855 return FALSE;
Brian Teague161bc832000-11-29 20:02:46 +00001856 return GetDeviceCaps(hdc,CAPS1) & C1_DIBENGINE;
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001857}
Serge Ivanova39cbbc2000-02-25 20:47:26 +00001858#endif
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001859
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001860/* helper for ImageList_Read, see comments below */
1861static HBITMAP _read_bitmap(LPSTREAM pstm,int ilcFlag,int cx,int cy) {
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001862 HDC xdc = 0;
1863 BITMAPFILEHEADER bmfh;
1864 BITMAPINFOHEADER bmih;
1865 int bitsperpixel,palspace,longsperline,width,height;
1866 LPBITMAPINFOHEADER bmihc = NULL;
1867 int result = 0;
1868 HBITMAP hbitmap = 0;
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001869 LPBYTE bits = NULL,nbits = NULL;
1870 int nbytesperline,bytesperline;
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001871
1872 if (!SUCCEEDED(IStream_Read ( pstm, &bmfh, sizeof(bmfh), NULL)) ||
1873 (bmfh.bfType != (('M'<<8)|'B')) ||
1874 !SUCCEEDED(IStream_Read ( pstm, &bmih, sizeof(bmih), NULL)) ||
1875 (bmih.biSize != sizeof(bmih))
1876 )
1877 return 0;
1878
1879 bitsperpixel = bmih.biPlanes * bmih.biBitCount;
1880 if (bitsperpixel<=8)
1881 palspace = (1<<bitsperpixel)*sizeof(RGBQUAD);
1882 else
1883 palspace = 0;
1884 width = bmih.biWidth;
1885 height = bmih.biHeight;
1886 bmihc = (LPBITMAPINFOHEADER)LocalAlloc(LMEM_ZEROINIT,sizeof(bmih)+palspace);
1887 memcpy(bmihc,&bmih,sizeof(bmih));
1888 longsperline = ((width*bitsperpixel+31)&~0x1f)>>5;
1889 bmihc->biSizeImage = (longsperline*height)<<2;
1890
1891 /* read the palette right after the end of the bitmapinfoheader */
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001892 if (palspace)
1893 if (!SUCCEEDED(IStream_Read ( pstm, bmihc+1, palspace, NULL)))
1894 goto ret1;
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001895
1896 xdc = GetDC(0);
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001897#if 0 /* Magic for NxM -> 1x(N*M) not implemented for DIB Sections */
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001898 if ((bitsperpixel>1) &&
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001899 ((ilcFlag!=ILC_COLORDDB) && (!ilcFlag || may_use_dibsection(xdc)))
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001900 ) {
1901 hbitmap = CreateDIBSection(xdc,(BITMAPINFO*)bmihc,0,(LPVOID*)&bits,0,0);
1902 if (!hbitmap)
1903 goto ret1;
1904 if (!SUCCEEDED(IStream_Read( pstm, bits, bmihc->biSizeImage, NULL)))
1905 goto ret1;
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001906 result = 1;
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001907 } else
1908#endif
1909 {
1910 int i,nwidth,nheight;
1911
1912 nwidth = width*(height/cy);
1913 nheight = cy;
1914
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001915 if (bitsperpixel==1)
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001916 hbitmap = CreateBitmap(nwidth,nheight,1,1,NULL);
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001917 else
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001918 hbitmap = CreateCompatibleBitmap(xdc,nwidth,nheight);
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001919
1920 /* Might be a bit excessive memory use here */
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001921 bits = (LPBYTE)LocalAlloc(LMEM_ZEROINIT,bmihc->biSizeImage);
1922 nbits = (LPBYTE)LocalAlloc(LMEM_ZEROINIT,bmihc->biSizeImage);
1923 if (!SUCCEEDED(IStream_Read ( pstm, bits, bmihc->biSizeImage, NULL)))
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001924 goto ret1;
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001925
1926 /* Copy the NxM bitmap into a 1x(N*M) bitmap we need, linewise */
1927 /* Do not forget that windows bitmaps are bottom->top */
1928 bytesperline = longsperline*4;
1929 nbytesperline = (height/cy)*bytesperline;
1930 for (i=0;i<height;i++) {
1931 memcpy(
Marcus Meissnerbd26e4d2000-02-07 16:00:33 +00001932 nbits+((height-1-i)%cy)*nbytesperline+(i/cy)*bytesperline,
1933 bits+bytesperline*(height-1-i),
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001934 bytesperline
1935 );
1936 }
1937 bmihc->biWidth = nwidth;
1938 bmihc->biHeight = nheight;
1939 if (!SetDIBits(xdc,hbitmap,0,nheight,nbits,(BITMAPINFO*)bmihc,0))
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001940 goto ret1;
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001941 LocalFree((HLOCAL)nbits);
1942 LocalFree((HLOCAL)bits);
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001943 result = 1;
1944 }
1945ret1:
1946 if (xdc) ReleaseDC(0,xdc);
1947 if (bmihc) LocalFree((HLOCAL)bmihc);
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001948 if (!result) {
1949 if (hbitmap) {
1950 DeleteObject(hbitmap);
1951 hbitmap = 0;
1952 }
1953 }
1954 return hbitmap;
1955}
1956
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001957/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00001958 * ImageList_Read [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001959 *
1960 * Reads an image list from a stream.
1961 *
1962 * PARAMS
1963 * pstm [I] pointer to a stream
1964 *
1965 * RETURNS
Eric Kohlf2809611998-11-08 11:36:04 +00001966 * Success: handle to image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001967 * Failure: NULL
Alexandre Julliarda845b881998-06-01 10:44:35 +00001968 *
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001969 * The format is like this:
1970 * ILHEAD ilheadstruct;
1971 *
1972 * for the color image part:
Vincent Béron9a624912002-05-31 23:06:46 +00001973 * BITMAPFILEHEADER bmfh;
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001974 * BITMAPINFOHEADER bmih;
1975 * only if it has a palette:
Vincent Béron9a624912002-05-31 23:06:46 +00001976 * RGBQUAD rgbs[nr_of_paletted_colors];
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001977 *
1978 * BYTE colorbits[imagesize];
1979 *
1980 * the following only if the ILC_MASK bit is set in ILHEAD.ilFlags:
1981 * BITMAPFILEHEADER bmfh_mask;
1982 * BITMAPINFOHEADER bmih_mask;
1983 * only if it has a palette (it usually does not):
Vincent Béron9a624912002-05-31 23:06:46 +00001984 * RGBQUAD rgbs[nr_of_paletted_colors];
Marcus Meissner9c978ab2000-01-30 22:21:22 +00001985 *
1986 * BYTE maskbits[imagesize];
1987 *
1988 * CAVEAT: Those images are within a NxM bitmap, not the 1xN we expect.
1989 * _read_bitmap needs to convert them.
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001990 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001991HIMAGELIST WINAPI ImageList_Read (LPSTREAM pstm)
Alexandre Julliard54c27111998-03-29 19:44:57 +00001992{
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001993 ILHEAD ilHead;
1994 HIMAGELIST himl;
1995 HBITMAP hbmColor=0,hbmMask=0;
1996 int i;
Eric Kohl69a93591999-11-23 23:40:01 +00001997
Marcus Meissnerd40170d2000-01-29 21:00:25 +00001998 if (!SUCCEEDED(IStream_Read (pstm, &ilHead, sizeof(ILHEAD), NULL)))
1999 return NULL;
2000 if (ilHead.usMagic != (('L' << 8) | 'I'))
2001 return NULL;
2002 if (ilHead.usVersion != 0x101) /* probably version? */
2003 return NULL;
Eric Kohl69a93591999-11-23 23:40:01 +00002004
Marcus Meissnerd40170d2000-01-29 21:00:25 +00002005#if 0
2006 FIXME(" ilHead.cCurImage = %d\n",ilHead.cCurImage);
2007 FIXME(" ilHead.cMaxImage = %d\n",ilHead.cMaxImage);
Marcus Meissner9c978ab2000-01-30 22:21:22 +00002008 FIXME(" ilHead.cGrow = %d\n",ilHead.cGrow);
Marcus Meissnerd40170d2000-01-29 21:00:25 +00002009 FIXME(" ilHead.cx = %d\n",ilHead.cx);
2010 FIXME(" ilHead.cy = %d\n",ilHead.cy);
2011 FIXME(" ilHead.flags = %x\n",ilHead.flags);
2012 FIXME(" ilHead.ovls[0] = %d\n",ilHead.ovls[0]);
2013 FIXME(" ilHead.ovls[1] = %d\n",ilHead.ovls[1]);
2014 FIXME(" ilHead.ovls[2] = %d\n",ilHead.ovls[2]);
2015 FIXME(" ilHead.ovls[3] = %d\n",ilHead.ovls[3]);
2016#endif
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002017
Marcus Meissner9c978ab2000-01-30 22:21:22 +00002018 hbmColor = _read_bitmap(pstm,ilHead.flags & ~ILC_MASK,ilHead.cx,ilHead.cy);
Marcus Meissnerd40170d2000-01-29 21:00:25 +00002019 if (!hbmColor)
2020 return NULL;
Marcus Meissner9c978ab2000-01-30 22:21:22 +00002021 if (ilHead.flags & ILC_MASK) {
2022 hbmMask = _read_bitmap(pstm,0,ilHead.cx,ilHead.cy);
Marcus Meissnerd40170d2000-01-29 21:00:25 +00002023 if (!hbmMask) {
2024 DeleteObject(hbmColor);
2025 return NULL;
2026 }
2027 }
Eric Kohl69a93591999-11-23 23:40:01 +00002028
Marcus Meissnerd40170d2000-01-29 21:00:25 +00002029 himl = ImageList_Create (
2030 ilHead.cx,
2031 ilHead.cy,
2032 ilHead.flags,
2033 1, /* initial */
Marcus Meissner9c978ab2000-01-30 22:21:22 +00002034 ilHead.cGrow
Marcus Meissnerd40170d2000-01-29 21:00:25 +00002035 );
2036 if (!himl) {
2037 DeleteObject(hbmColor);
2038 DeleteObject(hbmMask);
2039 return NULL;
Marcus Meissner9c978ab2000-01-30 22:21:22 +00002040 }
Marcus Meissnerd40170d2000-01-29 21:00:25 +00002041 himl->hbmImage = hbmColor;
2042 himl->hbmMask = hbmMask;
Marcus Meissner9c978ab2000-01-30 22:21:22 +00002043 himl->cCurImage = ilHead.cCurImage;
2044 himl->cMaxImage = ilHead.cMaxImage;
Marcus Meissnerd40170d2000-01-29 21:00:25 +00002045
2046 ImageList_SetBkColor(himl,ilHead.bkcolor);
Marcus Meissnerd40170d2000-01-29 21:00:25 +00002047 for (i=0;i<4;i++)
2048 ImageList_SetOverlayImage(himl,ilHead.ovls[i],i+1);
Eric Kohl69a93591999-11-23 23:40:01 +00002049 return himl;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002050}
Alexandre Julliard54c27111998-03-29 19:44:57 +00002051
2052
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002053/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00002054 * ImageList_Remove [COMCTL32.@] Removes an image from an image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002055 *
2056 * PARAMS
2057 * himl [I] image list handle
2058 * i [I] image index
2059 *
2060 * RETURNS
2061 * Success: TRUE
2062 * Failure: FALSE
2063 */
2064
Alexandre Julliarda3960291999-02-26 11:11:13 +00002065BOOL WINAPI
2066ImageList_Remove (HIMAGELIST himl, INT i)
Alexandre Julliard54c27111998-03-29 19:44:57 +00002067{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002068 HBITMAP hbmNewImage, hbmNewMask;
2069 HDC hdcSrc, hdcDst;
2070 INT cxNew, nCount;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002071
Michael Stefaniuc15fc2362002-07-22 20:38:41 +00002072 TRACE("(himl=%p i=%d)\n", himl, i);
2073
Andreas Mohr641405a2001-04-20 18:29:17 +00002074 if (himl == NULL) {
2075 ERR("Invalid image list handle!\n");
2076 return FALSE;
2077 }
Vincent Béron9a624912002-05-31 23:06:46 +00002078
Alexandre Julliard54c27111998-03-29 19:44:57 +00002079 if ((i < -1) || (i >= himl->cCurImage)) {
Alexandre Julliarda099a551999-06-12 15:45:58 +00002080 ERR("index out of range! %d\n", i);
Eric Kohl978137d1998-10-11 13:12:54 +00002081 return FALSE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002082 }
2083
Alexandre Julliard54c27111998-03-29 19:44:57 +00002084 if (i == -1) {
2085 /* remove all */
Michael Stefaniuc15fc2362002-07-22 20:38:41 +00002086 if (himl->cCurImage == 0) {
2087 /* remove all on empty ImageList is allowed */
2088 TRACE("remove all on empty ImageList!\n");
2089 return TRUE;
2090 }
Alexandre Julliard54c27111998-03-29 19:44:57 +00002091
2092 himl->cMaxImage = himl->cInitial + himl->cGrow;
2093 himl->cCurImage = 0;
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002094 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
Alexandre Julliard54c27111998-03-29 19:44:57 +00002095 himl->nOvlIdx[nCount] = -1;
2096
Alexandre Julliarda3960291999-02-26 11:11:13 +00002097 DeleteObject (himl->hbmImage);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002098 himl->hbmImage =
Alexandre Julliarda3960291999-02-26 11:11:13 +00002099 CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +00002100 1, himl->uBitsPixel, NULL);
2101
2102 if (himl->hbmMask) {
Alexandre Julliarda3960291999-02-26 11:11:13 +00002103 DeleteObject (himl->hbmMask);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002104 himl->hbmMask =
Alexandre Julliarda3960291999-02-26 11:11:13 +00002105 CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
Alexandre Julliard829fe321998-07-26 14:27:39 +00002106 1, 1, NULL);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002107 }
2108 }
2109 else {
2110 /* delete one image */
Alexandre Julliarda099a551999-06-12 15:45:58 +00002111 TRACE("Remove single image! %d\n", i);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002112
2113 /* create new bitmap(s) */
2114 cxNew = (himl->cCurImage + himl->cGrow - 1) * himl->cx;
2115
Alexandre Julliarda099a551999-06-12 15:45:58 +00002116 TRACE(" - Number of images: %d / %d (Old/New)\n",
Alexandre Julliard54c27111998-03-29 19:44:57 +00002117 himl->cCurImage, himl->cCurImage - 1);
Alexandre Julliarda099a551999-06-12 15:45:58 +00002118 TRACE(" - Max. number of images: %d / %d (Old/New)\n",
Alexandre Julliard54c27111998-03-29 19:44:57 +00002119 himl->cMaxImage, himl->cCurImage + himl->cGrow - 1);
Vincent Béron9a624912002-05-31 23:06:46 +00002120
Alexandre Julliard54c27111998-03-29 19:44:57 +00002121 hbmNewImage =
Alexandre Julliarda3960291999-02-26 11:11:13 +00002122 CreateBitmap (cxNew, himl->cy, 1, himl->uBitsPixel, NULL);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002123
2124 if (himl->hbmMask)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002125 hbmNewMask = CreateBitmap (cxNew, himl->cy, 1, 1, NULL);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002126 else
2127 hbmNewMask = 0; /* Just to keep compiler happy! */
2128
Alexandre Julliarda3960291999-02-26 11:11:13 +00002129 hdcSrc = CreateCompatibleDC (0);
2130 hdcDst = CreateCompatibleDC (0);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002131
2132 /* copy all images and masks prior to the "removed" image */
2133 if (i > 0) {
Alexandre Julliarda099a551999-06-12 15:45:58 +00002134 TRACE("Pre image copy: Copy %d images\n", i);
Vincent Béron9a624912002-05-31 23:06:46 +00002135
Alexandre Julliarda3960291999-02-26 11:11:13 +00002136 SelectObject (hdcSrc, himl->hbmImage);
2137 SelectObject (hdcDst, hbmNewImage);
2138 BitBlt (hdcDst, 0, 0, i * himl->cx, himl->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +00002139 hdcSrc, 0, 0, SRCCOPY);
2140
2141 if (himl->hbmMask) {
Alexandre Julliarda3960291999-02-26 11:11:13 +00002142 SelectObject (hdcSrc, himl->hbmMask);
2143 SelectObject (hdcDst, hbmNewMask);
2144 BitBlt (hdcDst, 0, 0, i * himl->cx, himl->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +00002145 hdcSrc, 0, 0, SRCCOPY);
2146 }
2147 }
2148
2149 /* copy all images and masks behind the removed image */
2150 if (i < himl->cCurImage - 1) {
Alexandre Julliarda099a551999-06-12 15:45:58 +00002151 TRACE("Post image copy!\n");
Alexandre Julliarda3960291999-02-26 11:11:13 +00002152 SelectObject (hdcSrc, himl->hbmImage);
2153 SelectObject (hdcDst, hbmNewImage);
2154 BitBlt (hdcDst, i * himl->cx, 0, (himl->cCurImage - i - 1) * himl->cx,
Alexandre Julliard54c27111998-03-29 19:44:57 +00002155 himl->cy, hdcSrc, (i + 1) * himl->cx, 0, SRCCOPY);
2156
2157 if (himl->hbmMask) {
Alexandre Julliarda3960291999-02-26 11:11:13 +00002158 SelectObject (hdcSrc, himl->hbmMask);
2159 SelectObject (hdcDst, hbmNewMask);
2160 BitBlt (hdcDst, i * himl->cx, 0,
Alexandre Julliard54c27111998-03-29 19:44:57 +00002161 (himl->cCurImage - i - 1) * himl->cx,
2162 himl->cy, hdcSrc, (i + 1) * himl->cx, 0, SRCCOPY);
2163 }
2164 }
2165
Alexandre Julliarda3960291999-02-26 11:11:13 +00002166 DeleteDC (hdcSrc);
2167 DeleteDC (hdcDst);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002168
2169 /* delete old images and insert new ones */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002170 DeleteObject (himl->hbmImage);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002171 himl->hbmImage = hbmNewImage;
2172 if (himl->hbmMask) {
Alexandre Julliarda3960291999-02-26 11:11:13 +00002173 DeleteObject (himl->hbmMask);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002174 himl->hbmMask = hbmNewMask;
2175 }
2176
2177 himl->cCurImage--;
2178 himl->cMaxImage = himl->cCurImage + himl->cGrow;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002179 }
2180
Eric Kohl978137d1998-10-11 13:12:54 +00002181 return TRUE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002182}
2183
2184
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002185/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00002186 * ImageList_Replace [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002187 *
2188 * Replaces an image in an image list with a new image.
2189 *
2190 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +00002191 * himl [I] handle to image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002192 * i [I] image index
Eric Kohlf2809611998-11-08 11:36:04 +00002193 * hbmImage [I] handle to image bitmap
2194 * hbmMask [I] handle to mask bitmap. Can be NULL.
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002195 *
2196 * RETURNS
2197 * Success: TRUE
2198 * Failure: FALSE
2199 */
2200
Alexandre Julliarda3960291999-02-26 11:11:13 +00002201BOOL WINAPI
2202ImageList_Replace (HIMAGELIST himl, INT i, HBITMAP hbmImage,
2203 HBITMAP hbmMask)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002204{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002205 HDC hdcImageList, hdcImage;
2206 BITMAP bmp;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002207
Michael Stefaniuc353529b2002-10-23 22:19:10 +00002208 TRACE("%p %d %p %p\n", himl, i, hbmImage, hbmMask);
Mike McCormack5a6a71f2002-08-16 01:35:43 +00002209
Alexandre Julliard54c27111998-03-29 19:44:57 +00002210 if (himl == NULL) {
Alexandre Julliarda099a551999-06-12 15:45:58 +00002211 ERR("Invalid image list handle!\n");
Eric Kohl978137d1998-10-11 13:12:54 +00002212 return FALSE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002213 }
Vincent Béron9a624912002-05-31 23:06:46 +00002214
Andreas Mohrd31c1f62000-08-26 20:28:17 +00002215 if ((i >= himl->cMaxImage) || (i < 0)) {
Alexandre Julliarda099a551999-06-12 15:45:58 +00002216 ERR("Invalid image index!\n");
Eric Kohl978137d1998-10-11 13:12:54 +00002217 return FALSE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002218 }
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002219
Alexandre Julliarda3960291999-02-26 11:11:13 +00002220 hdcImageList = CreateCompatibleDC (0);
2221 hdcImage = CreateCompatibleDC (0);
2222 GetObjectA (hbmImage, sizeof(BITMAP), (LPVOID)&bmp);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002223
2224 /* Replace Image */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002225 SelectObject (hdcImageList, himl->hbmImage);
2226 SelectObject (hdcImage, hbmImage);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002227
Alexandre Julliarda3960291999-02-26 11:11:13 +00002228 StretchBlt (hdcImageList, i * himl->cx, 0, himl->cx, himl->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +00002229 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002230
Alexandre Julliard54c27111998-03-29 19:44:57 +00002231 if (himl->hbmMask)
2232 {
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002233 /* Replace Mask */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002234 SelectObject (hdcImageList, himl->hbmMask);
2235 SelectObject (hdcImage, hbmMask);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002236
Alexandre Julliarda3960291999-02-26 11:11:13 +00002237 StretchBlt (hdcImageList, i * himl->cx, 0, himl->cx, himl->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +00002238 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
Aric Stewart031793e2000-05-11 21:39:45 +00002239
2240
2241 /* Remove the background from the image
2242 */
2243 SelectObject (hdcImageList, himl->hbmImage);
Vincent Béron9a624912002-05-31 23:06:46 +00002244 StretchBlt (hdcImageList,
Aric Stewart031793e2000-05-11 21:39:45 +00002245 i*himl->cx, 0, himl->cx, himl->cy,
Vincent Béron9a624912002-05-31 23:06:46 +00002246 hdcImage,
2247 0, 0, bmp.bmWidth, bmp.bmHeight,
Aric Stewart031793e2000-05-11 21:39:45 +00002248 0x220326); /* NOTSRCAND */
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002249 }
2250
Alexandre Julliarda3960291999-02-26 11:11:13 +00002251 DeleteDC (hdcImage);
2252 DeleteDC (hdcImageList);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002253
Eric Kohl978137d1998-10-11 13:12:54 +00002254 return TRUE;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002255}
2256
2257
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002258/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00002259 * ImageList_ReplaceIcon [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002260 *
2261 * Replaces an image in an image list using an icon.
2262 *
2263 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +00002264 * himl [I] handle to image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002265 * i [I] image index
Eric Kohlf2809611998-11-08 11:36:04 +00002266 * hIcon [I] handle to icon
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002267 *
2268 * RETURNS
2269 * Success: index of the replaced image
2270 * Failure: -1
2271 */
2272
Alexandre Julliarda3960291999-02-26 11:11:13 +00002273INT WINAPI
2274ImageList_ReplaceIcon (HIMAGELIST himl, INT i, HICON hIcon)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002275{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002276 HDC hdcImageList, hdcImage;
2277 INT nIndex;
Pierre Mageau4ac8db71999-09-04 11:16:48 +00002278 HICON hBestFitIcon;
Alexandre Julliarda3960291999-02-26 11:11:13 +00002279 HBITMAP hbmOldSrc, hbmOldDst;
2280 ICONINFO ii;
2281 BITMAP bmp;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002282
Michael Stefaniuc353529b2002-10-23 22:19:10 +00002283 TRACE("(0x%lx 0x%x %p)\n", (DWORD)himl, i, hIcon);
Alexandre Julliard642d3131998-07-12 19:29:36 +00002284
Eric Kohl978137d1998-10-11 13:12:54 +00002285 if (himl == NULL)
2286 return -1;
Andreas Mohrd31c1f62000-08-26 20:28:17 +00002287 if ((i >= himl->cMaxImage) || (i < -1))
Eric Kohl978137d1998-10-11 13:12:54 +00002288 return -1;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002289
Pierre Mageau4ac8db71999-09-04 11:16:48 +00002290 hBestFitIcon = CopyImage(
Vincent Béron9a624912002-05-31 23:06:46 +00002291 hIcon, IMAGE_ICON,
2292 himl->cx, himl->cy,
Pierre Mageau4ac8db71999-09-04 11:16:48 +00002293 LR_COPYFROMRESOURCE);
2294
2295 GetIconInfo (hBestFitIcon, &ii);
Alexandre Julliard829fe321998-07-26 14:27:39 +00002296 if (ii.hbmMask == 0)
Alexandre Julliarda099a551999-06-12 15:45:58 +00002297 ERR("no mask!\n");
Alexandre Julliard829fe321998-07-26 14:27:39 +00002298 if (ii.hbmColor == 0)
Alexandre Julliarda099a551999-06-12 15:45:58 +00002299 ERR("no color!\n");
Alexandre Julliarda3960291999-02-26 11:11:13 +00002300 GetObjectA (ii.hbmMask, sizeof(BITMAP), (LPVOID)&bmp);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002301
2302 if (i == -1) {
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +00002303 if (himl->cCurImage + 1 > himl->cMaxImage)
Gerard Patel19cef6c2000-07-08 12:48:37 +00002304 IMAGELIST_InternalExpandBitmaps (himl, 1, 0, 0);
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00002305
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002306 nIndex = himl->cCurImage;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00002307 himl->cCurImage++;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002308 }
2309 else
2310 nIndex = i;
2311
Alexandre Julliarda3960291999-02-26 11:11:13 +00002312 hdcImageList = CreateCompatibleDC (0);
Michael Stefaniuc353529b2002-10-23 22:19:10 +00002313 TRACE("hdcImageList=%p!\n", hdcImageList);
Alexandre Julliard829fe321998-07-26 14:27:39 +00002314 if (hdcImageList == 0)
Alexandre Julliarda099a551999-06-12 15:45:58 +00002315 ERR("invalid hdcImageList!\n");
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002316
Alexandre Julliarda3960291999-02-26 11:11:13 +00002317 hdcImage = CreateCompatibleDC (0);
Michael Stefaniuc353529b2002-10-23 22:19:10 +00002318 TRACE("hdcImage=%p!\n", hdcImage);
Alexandre Julliard829fe321998-07-26 14:27:39 +00002319 if (hdcImage == 0)
Alexandre Julliarda099a551999-06-12 15:45:58 +00002320 ERR("invalid hdcImage!\n");
Alexandre Julliard829fe321998-07-26 14:27:39 +00002321
Alexandre Julliarda3960291999-02-26 11:11:13 +00002322 hbmOldDst = SelectObject (hdcImageList, himl->hbmImage);
2323 SetTextColor( hdcImageList, RGB(0,0,0));
2324 SetBkColor( hdcImageList, RGB(255,255,255));
2325 hbmOldSrc = SelectObject (hdcImage, ii.hbmColor);
2326 StretchBlt (hdcImageList, nIndex * himl->cx, 0, himl->cx, himl->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +00002327 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002328
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002329 if (himl->hbmMask) {
Alexandre Julliarda3960291999-02-26 11:11:13 +00002330 SelectObject (hdcImageList, himl->hbmMask);
2331 SelectObject (hdcImage, ii.hbmMask);
2332 StretchBlt (hdcImageList, nIndex * himl->cx, 0, himl->cx, himl->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +00002333 hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002334 }
2335
Alexandre Julliarda3960291999-02-26 11:11:13 +00002336 SelectObject (hdcImage, hbmOldSrc);
2337 SelectObject (hdcImageList, hbmOldDst);
Alexandre Julliard829fe321998-07-26 14:27:39 +00002338
Pierre Mageau4ac8db71999-09-04 11:16:48 +00002339 if(hBestFitIcon)
2340 DestroyIcon(hBestFitIcon);
Alexandre Julliard829fe321998-07-26 14:27:39 +00002341 if (hdcImageList)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002342 DeleteDC (hdcImageList);
Alexandre Julliard829fe321998-07-26 14:27:39 +00002343 if (hdcImage)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002344 DeleteDC (hdcImage);
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002345 if (ii.hbmColor)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002346 DeleteObject (ii.hbmColor);
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002347 if (ii.hbmMask)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002348 DeleteObject (ii.hbmMask);
Alexandre Julliard829fe321998-07-26 14:27:39 +00002349
Eric Kohl978137d1998-10-11 13:12:54 +00002350 return nIndex;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002351}
2352
2353
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002354/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00002355 * ImageList_SetBkColor [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002356 *
2357 * Sets the background color of an image list.
2358 *
2359 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +00002360 * himl [I] handle to image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002361 * clrBk [I] background color
2362 *
2363 * RETURNS
2364 * Success: previous background color
2365 * Failure: CLR_NONE
2366 */
2367
2368COLORREF WINAPI
2369ImageList_SetBkColor (HIMAGELIST himl, COLORREF clrBk)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002370{
2371 COLORREF clrOldBk;
2372
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002373 if (himl == NULL)
Eric Kohl978137d1998-10-11 13:12:54 +00002374 return CLR_NONE;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002375
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002376 clrOldBk = himl->clrBk;
2377 himl->clrBk = clrBk;
Eric Kohl978137d1998-10-11 13:12:54 +00002378 return clrOldBk;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002379}
2380
2381
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002382/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00002383 * ImageList_SetDragCursorImage [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002384 *
2385 * Combines the specified image with the current drag image
2386 *
2387 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +00002388 * himlDrag [I] handle to drag image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002389 * iDrag [I] drag image index
2390 * dxHotspot [I] X position of the hot spot
2391 * dyHotspot [I] Y position of the hot spot
2392 *
2393 * RETURNS
2394 * Success: TRUE
2395 * Failure: FALSE
2396 *
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +00002397 * NOTES
2398 * When this function is called and the drag image is visible, a
2399 * short flickering occurs but this matches the Win9x behavior. It is
2400 * possible to fix the flickering using code like in ImageList_DragMove.
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002401 */
2402
Alexandre Julliarda3960291999-02-26 11:11:13 +00002403BOOL WINAPI
2404ImageList_SetDragCursorImage (HIMAGELIST himlDrag, INT iDrag,
2405 INT dxHotspot, INT dyHotspot)
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002406{
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002407 HIMAGELIST himlTemp;
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +00002408 INT dx, dy;
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +00002409 BOOL visible;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002410
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +00002411 if (InternalDrag.himl == NULL)
Eric Kohl978137d1998-10-11 13:12:54 +00002412 return FALSE;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002413
Alexandre Julliarda099a551999-06-12 15:45:58 +00002414 TRACE(" dxH=%d dyH=%d nX=%d nY=%d\n",
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +00002415 dxHotspot, dyHotspot, InternalDrag.dxHotspot, InternalDrag.dyHotspot);
2416
2417 visible = InternalDrag.bShow;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002418
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +00002419 /* Calculate the offset between the origin of the old image and the
2420 * origin of the second image.
2421 * dxHotspot, dyHotspot is the offset of THE Hotspot (there is only one
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +00002422 * hotspot) to the origin of the second image.
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +00002423 * See M$DN for details */
Dave Hawkes770a5bf2002-02-26 00:33:51 +00002424 if(InternalDrag.bHSPending) {
2425 dx = 0;
2426 dy = 0;
2427 InternalDrag.bHSPending = FALSE;
2428 } else {
2429 dx = InternalDrag.dxHotspot - dxHotspot;
2430 dy = InternalDrag.dyHotspot - dyHotspot;
2431 }
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +00002432 himlTemp = ImageList_Merge (InternalDrag.himl, 0, himlDrag, iDrag, dx, dy);
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002433
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +00002434 if (visible) {
2435 /* hide the drag image */
2436 ImageList_DragShowNolock(FALSE);
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +00002437 }
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +00002438 if ((InternalDrag.himl->cx != himlTemp->cx) ||
2439 (InternalDrag.himl->cy != himlTemp->cy)) {
2440 /* the size of the drag image changed, invalidate the buffer */
2441 DeleteObject(InternalDrag.hbmBg);
2442 InternalDrag.hbmBg = 0;
2443 }
2444
2445 ImageList_Destroy (InternalDrag.himl);
2446 InternalDrag.himl = himlTemp;
2447
2448 /* update the InternalDragOffset, if the origin of the
2449 * DragImage was changed by ImageList_Merge. */
Dave Hawkes770a5bf2002-02-26 00:33:51 +00002450 if (dx <= 0)
2451 InternalDrag.dxHotspot = dxHotspot;
2452 if (dy <= 0)
2453 InternalDrag.dyHotspot = dyHotspot;
Michael Stefaniuc3bc5ffd2001-12-19 18:47:14 +00002454
2455 if (visible) {
2456 /* show the drag image */
2457 ImageList_DragShowNolock(TRUE);
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +00002458 }
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002459
Michael Stefaniuccaf81dc2001-11-30 23:15:00 +00002460 return TRUE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002461}
2462
2463
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002464/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00002465 * ImageList_SetFilter [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002466 *
2467 * Sets a filter (or does something completely different)!!???
Dimitrie O. Paund9696052002-09-06 18:32:46 +00002468 * It removes 12 Bytes from the stack (3 Parameters).
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002469 *
2470 * PARAMS
Dimitrie O. Paund9696052002-09-06 18:32:46 +00002471 * himl [I] SHOULD be a handle to image list
2472 * i [I] COULD be an index?
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002473 * dwFilter [I] ???
2474 *
2475 * RETURNS
Alexandre Julliarda845b881998-06-01 10:44:35 +00002476 * Success: TRUE ???
2477 * Failure: FALSE ???
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002478 *
2479 * BUGS
Alexandre Julliarda845b881998-06-01 10:44:35 +00002480 * This is an UNDOCUMENTED function!!!!
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002481 * empty stub.
2482 */
2483
Alexandre Julliarda3960291999-02-26 11:11:13 +00002484BOOL WINAPI
2485ImageList_SetFilter (HIMAGELIST himl, INT i, DWORD dwFilter)
Alexandre Julliard54c27111998-03-29 19:44:57 +00002486{
Dimitrie O. Paund9696052002-09-06 18:32:46 +00002487 FIXME("(%p 0x%x 0x%lx):empty stub!\n", himl, i, dwFilter);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002488
Alexandre Julliard642d3131998-07-12 19:29:36 +00002489 return FALSE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002490}
Alexandre Julliard54c27111998-03-29 19:44:57 +00002491
2492
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002493/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00002494 * ImageList_SetFlags [COMCTL32.@]
Huw D M Davies1a65a7b2002-01-15 20:28:05 +00002495 *
2496 * BUGS
2497 * Stub.
2498 */
2499
2500DWORD WINAPI
2501ImageList_SetFlags(HIMAGELIST himl, DWORD flags)
2502{
2503 FIXME("(%p %08lx):empty stub\n", himl, flags);
2504 return 0;
2505}
2506
2507
2508/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00002509 * ImageList_SetIconSize [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002510 *
2511 * Sets the image size of the bitmap and deletes all images.
2512 *
2513 * PARAMS
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002514 * himl [I] handle to image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002515 * cx [I] image width
2516 * cy [I] image height
2517 *
2518 * RETURNS
2519 * Success: TRUE
2520 * Failure: FALSE
2521 */
2522
Alexandre Julliarda3960291999-02-26 11:11:13 +00002523BOOL WINAPI
2524ImageList_SetIconSize (HIMAGELIST himl, INT cx, INT cy)
Alexandre Julliard54c27111998-03-29 19:44:57 +00002525{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002526 INT nCount;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002527
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002528 if (!himl)
2529 return FALSE;
Alexandre Julliarda845b881998-06-01 10:44:35 +00002530
Andreas Mohrd31c1f62000-08-26 20:28:17 +00002531 /* remove all images */
Eric Kohl978137d1998-10-11 13:12:54 +00002532 himl->cMaxImage = himl->cInitial + himl->cGrow;
2533 himl->cCurImage = 0;
2534 himl->cx = cx;
2535 himl->cy = cy;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002536
2537 /* initialize overlay mask indices */
2538 for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
2539 himl->nOvlIdx[nCount] = -1;
2540
Alexandre Julliarda3960291999-02-26 11:11:13 +00002541 DeleteObject (himl->hbmImage);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002542 himl->hbmImage =
Alexandre Julliarda3960291999-02-26 11:11:13 +00002543 CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +00002544 1, himl->uBitsPixel, NULL);
2545
2546 if (himl->hbmMask) {
Alexandre Julliarda3960291999-02-26 11:11:13 +00002547 DeleteObject (himl->hbmMask);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002548 himl->hbmMask =
Alexandre Julliarda3960291999-02-26 11:11:13 +00002549 CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
Alexandre Julliard829fe321998-07-26 14:27:39 +00002550 1, 1, NULL);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002551 }
2552
Eric Kohl978137d1998-10-11 13:12:54 +00002553 return TRUE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002554}
2555
2556
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002557/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00002558 * ImageList_SetImageCount [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002559 *
2560 * Resizes an image list to the specified number of images.
2561 *
2562 * PARAMS
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002563 * himl [I] handle to image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002564 * iImageCount [I] number of images in the image list
2565 *
2566 * RETURNS
2567 * Success: TRUE
2568 * Failure: FALSE
2569 */
2570
Alexandre Julliarda3960291999-02-26 11:11:13 +00002571BOOL WINAPI
2572ImageList_SetImageCount (HIMAGELIST himl, INT iImageCount)
Alexandre Julliard54c27111998-03-29 19:44:57 +00002573{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002574 HDC hdcImageList, hdcBitmap;
2575 HBITMAP hbmNewBitmap;
2576 INT nNewCount, nCopyCount;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002577
Mike McCormack5a6a71f2002-08-16 01:35:43 +00002578 TRACE("%p %d\n",himl,iImageCount);
2579
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002580 if (!himl)
2581 return FALSE;
Pascal Lessard60935ec1999-03-25 16:42:27 +00002582 if (himl->cCurImage >= iImageCount)
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002583 return FALSE;
2584 if (himl->cMaxImage > iImageCount)
Mike McCormack5a6a71f2002-08-16 01:35:43 +00002585 {
2586 himl->cCurImage = iImageCount;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002587 return TRUE;
Mike McCormack5a6a71f2002-08-16 01:35:43 +00002588 }
Alexandre Julliard54c27111998-03-29 19:44:57 +00002589
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00002590 nNewCount = iImageCount + himl->cGrow;
Patrik Stridvall35669732001-09-10 23:09:04 +00002591 nCopyCount = min(himl->cCurImage, iImageCount);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002592
Alexandre Julliarda3960291999-02-26 11:11:13 +00002593 hdcImageList = CreateCompatibleDC (0);
2594 hdcBitmap = CreateCompatibleDC (0);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002595
Alexandre Julliarda3960291999-02-26 11:11:13 +00002596 hbmNewBitmap = CreateBitmap (nNewCount * himl->cx, himl->cy,
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00002597 1, himl->uBitsPixel, NULL);
Francis Beaudet64307f31999-04-01 10:11:23 +00002598 if (hbmNewBitmap != 0)
Alexandre Julliard54c27111998-03-29 19:44:57 +00002599 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00002600 SelectObject (hdcImageList, himl->hbmImage);
2601 SelectObject (hdcBitmap, hbmNewBitmap);
Eric Kohl978137d1998-10-11 13:12:54 +00002602
2603 /* copy images */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002604 BitBlt (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +00002605 hdcImageList, 0, 0, SRCCOPY);
Eric Kohl69a93591999-11-23 23:40:01 +00002606#if 0
Eric Kohl978137d1998-10-11 13:12:54 +00002607 /* delete 'empty' image space */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002608 SetBkColor (hdcBitmap, RGB(255, 255, 255));
2609 SetTextColor (hdcBitmap, RGB(0, 0, 0));
Vincent Béron9a624912002-05-31 23:06:46 +00002610 PatBlt (hdcBitmap, nCopyCount * himl->cx, 0,
Eric Kohl978137d1998-10-11 13:12:54 +00002611 (nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS);
Eric Kohl69a93591999-11-23 23:40:01 +00002612#endif
Alexandre Julliarda3960291999-02-26 11:11:13 +00002613 DeleteObject (himl->hbmImage);
Eric Kohl9d8e8641998-10-24 10:49:27 +00002614 himl->hbmImage = hbmNewBitmap;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002615 }
2616 else
Alexandre Julliarda099a551999-06-12 15:45:58 +00002617 ERR("Could not create new image bitmap !\n");
Alexandre Julliard54c27111998-03-29 19:44:57 +00002618
2619 if (himl->hbmMask)
2620 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00002621 hbmNewBitmap = CreateBitmap (nNewCount * himl->cx, himl->cy,
Alexandre Julliard829fe321998-07-26 14:27:39 +00002622 1, 1, NULL);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002623 if (hbmNewBitmap != 0)
2624 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00002625 SelectObject (hdcImageList, himl->hbmMask);
2626 SelectObject (hdcBitmap, hbmNewBitmap);
Eric Kohl978137d1998-10-11 13:12:54 +00002627
2628 /* copy images */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002629 BitBlt (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
Alexandre Julliard54c27111998-03-29 19:44:57 +00002630 hdcImageList, 0, 0, SRCCOPY);
Eric Kohl69a93591999-11-23 23:40:01 +00002631#if 0
Eric Kohl978137d1998-10-11 13:12:54 +00002632 /* delete 'empty' image space */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002633 SetBkColor (hdcBitmap, RGB(255, 255, 255));
2634 SetTextColor (hdcBitmap, RGB(0, 0, 0));
Vincent Béron9a624912002-05-31 23:06:46 +00002635 PatBlt (hdcBitmap, nCopyCount * himl->cx, 0,
Eric Kohl978137d1998-10-11 13:12:54 +00002636 (nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS);
Eric Kohl69a93591999-11-23 23:40:01 +00002637#endif
Alexandre Julliarda3960291999-02-26 11:11:13 +00002638 DeleteObject (himl->hbmMask);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002639 himl->hbmMask = hbmNewBitmap;
2640 }
2641 else
Alexandre Julliarda099a551999-06-12 15:45:58 +00002642 ERR("Could not create new mask bitmap!\n");
Alexandre Julliard54c27111998-03-29 19:44:57 +00002643 }
2644
Alexandre Julliarda3960291999-02-26 11:11:13 +00002645 DeleteDC (hdcImageList);
2646 DeleteDC (hdcBitmap);
Alexandre Julliard54c27111998-03-29 19:44:57 +00002647
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00002648 /* Update max image count and current image count */
2649 himl->cMaxImage = nNewCount;
Mike McCormack5a6a71f2002-08-16 01:35:43 +00002650 himl->cCurImage = iImageCount;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002651
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002652 return TRUE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002653}
2654
2655
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002656/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00002657 * ImageList_SetOverlayImage [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002658 *
2659 * Assigns an overlay mask index to an existing image in an image list.
2660 *
2661 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +00002662 * himl [I] handle to image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002663 * iImage [I] image index
2664 * iOverlay [I] overlay mask index
2665 *
2666 * RETURNS
2667 * Success: TRUE
2668 * Failure: FALSE
2669 */
2670
Alexandre Julliarda3960291999-02-26 11:11:13 +00002671BOOL WINAPI
2672ImageList_SetOverlayImage (HIMAGELIST himl, INT iImage, INT iOverlay)
Alexandre Julliard54c27111998-03-29 19:44:57 +00002673{
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002674 if (!himl)
2675 return FALSE;
2676 if ((iOverlay < 1) || (iOverlay > MAX_OVERLAYIMAGE))
2677 return FALSE;
Marcus Meissner9c978ab2000-01-30 22:21:22 +00002678 if ((iImage!=-1) && ((iImage < 0) || (iImage > himl->cCurImage)))
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002679 return FALSE;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002680 himl->nOvlIdx[iOverlay - 1] = iImage;
Alexandre Julliarda845b881998-06-01 10:44:35 +00002681 return TRUE;
Alexandre Julliarda69b88b1998-03-15 20:29:56 +00002682}
2683
Alexandre Julliard54c27111998-03-29 19:44:57 +00002684
Charles Loep02cbb362002-01-29 17:12:20 +00002685
Vincent Béron9a624912002-05-31 23:06:46 +00002686/* helper for ImageList_Write - write bitmap to pstm
Charles Loep02cbb362002-01-29 17:12:20 +00002687 * currently everything is written as 24 bit RGB, except masks
2688 */
Vincent Béron9a624912002-05-31 23:06:46 +00002689static BOOL
Charles Loep02cbb362002-01-29 17:12:20 +00002690_write_bitmap(HBITMAP hBitmap, LPSTREAM pstm, int cx, int cy)
2691{
2692 LPBITMAPFILEHEADER bmfh;
2693 LPBITMAPINFOHEADER bmih;
2694 LPBYTE data, lpBits, lpBitsOrg;
2695 BITMAP bm;
2696 INT bitCount, sizeImage, offBits, totalSize;
2697 INT nwidth, nheight, nsizeImage, icount;
2698 HDC xdc;
2699 BOOL result = FALSE;
2700
2701
2702 xdc = GetDC(0);
2703 GetObjectA(hBitmap, sizeof(BITMAP), (LPVOID)&bm);
Vincent Béron9a624912002-05-31 23:06:46 +00002704
Charles Loep02cbb362002-01-29 17:12:20 +00002705 /* XXX is this always correct? */
2706 icount = bm.bmWidth / cx;
2707 nwidth = cx << 2;
2708 nheight = cy * ((icount+3)>>2);
2709
2710 bitCount = bm.bmBitsPixel == 1 ? 1 : 24;
2711 sizeImage = ((((bm.bmWidth * bitCount)+31) & ~31) >> 3) * bm.bmHeight;
2712 nsizeImage = ((((nwidth * bitCount)+31) & ~31) >> 3) * nheight;
2713
2714 totalSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
2715 if(bitCount != 24)
2716 totalSize += (1 << bitCount) * sizeof(RGBQUAD);
2717 offBits = totalSize;
2718 totalSize += nsizeImage;
2719
2720 data = (LPBYTE)LocalAlloc(LMEM_ZEROINIT, totalSize);
2721 bmfh = (LPBITMAPFILEHEADER)data;
2722 bmih = (LPBITMAPINFOHEADER)(data + sizeof(BITMAPFILEHEADER));
2723 lpBits = data + offBits;
2724
2725 /* setup BITMAPFILEHEADER */
2726 bmfh->bfType = (('M' << 8) | 'B');
2727 bmfh->bfSize = 0;
2728 bmfh->bfReserved1 = 0;
2729 bmfh->bfReserved2 = 0;
2730 bmfh->bfOffBits = offBits;
2731
2732 /* setup BITMAPINFOHEADER */
2733 bmih->biSize = sizeof(BITMAPINFOHEADER);
2734 bmih->biWidth = bm.bmWidth;
2735 bmih->biHeight = bm.bmHeight;
2736 bmih->biPlanes = 1;
2737 bmih->biBitCount = bitCount;
2738 bmih->biCompression = BI_RGB;
2739 bmih->biSizeImage = nsizeImage;
2740 bmih->biXPelsPerMeter = 0;
2741 bmih->biYPelsPerMeter = 0;
2742 bmih->biClrUsed = 0;
2743 bmih->biClrImportant = 0;
2744
2745 lpBitsOrg = (LPBYTE)LocalAlloc(LMEM_ZEROINIT, nsizeImage);
Vincent Béron9a624912002-05-31 23:06:46 +00002746 if(!GetDIBits(xdc, hBitmap, 0, bm.bmHeight, lpBitsOrg,
Charles Loep02cbb362002-01-29 17:12:20 +00002747 (BITMAPINFO *)bmih, DIB_RGB_COLORS))
2748 goto failed;
2749 else {
2750 int i;
2751 int obpl = (((bm.bmWidth*bitCount+31) & ~31)>>3);
2752 int nbpl = (((nwidth*bitCount+31) & ~31)>>3);
Vincent Béron9a624912002-05-31 23:06:46 +00002753
Charles Loep02cbb362002-01-29 17:12:20 +00002754 for(i = 0; i < nheight; i++) {
2755 int ooff = ((nheight-1-i)%cy) * obpl + ((i/cy) * nbpl);
2756 int noff = (nbpl * (nheight-1-i));
2757 memcpy(lpBits + noff, lpBitsOrg + ooff, nbpl);
2758 }
2759 }
Vincent Béron9a624912002-05-31 23:06:46 +00002760
Charles Loep02cbb362002-01-29 17:12:20 +00002761 bmih->biWidth = nwidth;
2762 bmih->biHeight = nheight;
2763
2764 if(bitCount == 1) {
Patrik Stridvallfc2be7e2002-04-29 18:48:56 +00002765 /* Hack. */
Charles Loep02cbb362002-01-29 17:12:20 +00002766 LPBITMAPINFO inf = (LPBITMAPINFO)bmih;
2767 inf->bmiColors[0].rgbRed = inf->bmiColors[0].rgbGreen = inf->bmiColors[0].rgbBlue = 0;
2768 inf->bmiColors[1].rgbRed = inf->bmiColors[1].rgbGreen = inf->bmiColors[1].rgbBlue = 0xff;
2769 }
2770
2771 if(!SUCCEEDED(IStream_Write(pstm, data, totalSize, NULL)))
2772 goto failed;
2773
2774 result = TRUE;
2775
2776 failed:
2777 ReleaseDC(0, xdc);
2778 LocalFree((HLOCAL)lpBitsOrg);
2779
2780 return result;
2781}
2782
2783
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002784/*************************************************************************
Patrik Stridvall43255542002-08-09 01:07:29 +00002785 * ImageList_Write [COMCTL32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002786 *
2787 * Writes an image list to a stream.
2788 *
2789 * PARAMS
Eric Kohlf2809611998-11-08 11:36:04 +00002790 * himl [I] handle to image list
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002791 * pstm [O] Pointer to a stream.
2792 *
2793 * RETURNS
2794 * Success: TRUE
2795 * Failure: FALSE
2796 *
2797 * BUGS
Charles Loep02cbb362002-01-29 17:12:20 +00002798 * probably.
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00002799 */
2800
Alexandre Julliarda3960291999-02-26 11:11:13 +00002801BOOL WINAPI
2802ImageList_Write (HIMAGELIST himl, LPSTREAM pstm)
Alexandre Julliard54c27111998-03-29 19:44:57 +00002803{
Charles Loep02cbb362002-01-29 17:12:20 +00002804 ILHEAD ilHead;
2805 int i;
2806
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002807 if (!himl)
2808 return FALSE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002809
Charles Loep02cbb362002-01-29 17:12:20 +00002810 ilHead.usMagic = (('L' << 8) | 'I');
2811 ilHead.usVersion = 0x101;
2812 ilHead.cCurImage = himl->cCurImage;
2813 ilHead.cMaxImage = himl->cMaxImage;
2814 ilHead.cGrow = himl->cGrow;
2815 ilHead.cx = himl->cx;
2816 ilHead.cy = himl->cy;
2817 ilHead.bkcolor = himl->clrBk;
2818 ilHead.flags = himl->flags;
2819 for(i = 0; i < 4; i++) {
2820 ilHead.ovls[i] = himl->nOvlIdx[i];
2821 }
Alexandre Julliard54c27111998-03-29 19:44:57 +00002822
Charles Loep02cbb362002-01-29 17:12:20 +00002823 if(!SUCCEEDED(IStream_Write(pstm, &ilHead, sizeof(ILHEAD), NULL)))
2824 return FALSE;
2825
2826 /* write the bitmap */
2827 if(!_write_bitmap(himl->hbmImage, pstm, himl->cx, himl->cy))
2828 return FALSE;
2829
2830 /* write the mask if we have one */
2831 if(himl->flags & ILC_MASK) {
2832 if(!_write_bitmap(himl->hbmMask, pstm, himl->cx, himl->cy))
2833 return FALSE;
2834 }
2835
2836 return TRUE;
Alexandre Julliard54c27111998-03-29 19:44:57 +00002837}