ReactOS 0.4.16-dev-2473-gb34a1f1
cursoricon.c
Go to the documentation of this file.
1/*
2 * Unit test suite for cursors and icons.
3 *
4 * Copyright 2006 Michael Kaufmann
5 * Copyright 2007 Dmitry Timoshkov
6 * Copyright 2007-2008 Andrew Riedi
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23#include <stdlib.h>
24#include <stdarg.h>
25#include <stdio.h>
26
27#include "wine/test.h"
28#include "windef.h"
29#include "winbase.h"
30#include "winreg.h"
31#include "wingdi.h"
32#include "winuser.h"
33
34#include "pshpack1.h"
35
36typedef struct
37{
38 BYTE bWidth;
39 BYTE bHeight;
40 BYTE bColorCount;
41 BYTE bReserved;
42 WORD xHotspot;
43 WORD yHotspot;
44 DWORD dwDIBSize;
45 DWORD dwDIBOffset;
47
48typedef struct
49{
50 WORD idReserved;
51 WORD idType;
52 WORD idCount;
53 CURSORICONFILEDIRENTRY idEntries[1];
55
56#define RIFF_FOURCC( c0, c1, c2, c3 ) \
57 ( (DWORD)(BYTE)(c0) | ( (DWORD)(BYTE)(c1) << 8 ) | \
58 ( (DWORD)(BYTE)(c2) << 16 ) | ( (DWORD)(BYTE)(c3) << 24 ) )
59
60#define ANI_RIFF_ID RIFF_FOURCC('R', 'I', 'F', 'F')
61#define ANI_LIST_ID RIFF_FOURCC('L', 'I', 'S', 'T')
62#define ANI_ACON_ID RIFF_FOURCC('A', 'C', 'O', 'N')
63#define ANI_anih_ID RIFF_FOURCC('a', 'n', 'i', 'h')
64#define ANI_seq__ID RIFF_FOURCC('s', 'e', 'q', ' ')
65#define ANI_fram_ID RIFF_FOURCC('f', 'r', 'a', 'm')
66#define ANI_icon_ID RIFF_FOURCC('i', 'c', 'o', 'n')
67#define ANI_rate_ID RIFF_FOURCC('r', 'a', 't', 'e')
68
69#define ANI_FLAG_ICON 0x1
70#define ANI_FLAG_SEQUENCE 0x2
71
72typedef struct {
83
84typedef struct {
85 BYTE data[32*32*4];
86 BYTE mask_data[32*32/8];
88
89typedef struct {
90 CURSORICONFILEDIR icon_info; /* animated cursor frame information */
91 BITMAPINFOHEADER bmi_header; /* animated cursor frame header */
92 ani_data32x32x32 bmi_data; /* animated cursor frame DIB data */
94
95typedef struct {
96 DWORD chunk_id; /* ANI_anih_ID */
97 DWORD chunk_size; /* actual size of data */
98 ani_header header; /* animated cursor header */
100
101typedef struct {
102 DWORD chunk_id; /* ANI_LIST_ID */
103 DWORD chunk_size; /* actual size of data */
104 DWORD chunk_type; /* ANI_fram_ID */
106
107typedef struct {
108 DWORD chunk_id; /* ANI_icon_ID */
109 DWORD chunk_size; /* actual size of data */
110 ani_frame32x32x32 data; /* animated cursor frame */
112
113typedef struct {
114 DWORD chunk_id; /* ANI_RIFF_ID */
115 DWORD chunk_size; /* actual size of data */
116 DWORD chunk_type; /* ANI_ACON_ID */
117 riff_header_t header; /* RIFF animated cursor header */
118 riff_list_t frame_list; /* RIFF animated cursor frame list info */
119 riff_icon32x32x32_t frames[1]; /* array of animated cursor frames */
121
122typedef struct {
123 DWORD chunk_id; /* ANI_RIFF_ID */
124 DWORD chunk_size; /* actual size of data */
125 DWORD chunk_type; /* ANI_ACON_ID */
126 riff_header_t header; /* RIFF animated cursor header */
127 riff_list_t frame_list; /* RIFF animated cursor frame list info */
128 riff_icon32x32x32_t frames[3]; /* array of three animated cursor frames */
130
131typedef struct {
132 DWORD chunk_id; /* ANI_rate_ID */
133 DWORD chunk_size; /* actual size of data */
134 DWORD rate[3]; /* animated cursor rate data */
136
137typedef struct {
138 DWORD chunk_id; /* ANI_seq__ID */
139 DWORD chunk_size; /* actual size of data */
140 DWORD order[3]; /* animated cursor sequence data */
142
143typedef struct {
144 DWORD chunk_id; /* ANI_RIFF_ID */
145 DWORD chunk_size; /* actual size of data */
146 DWORD chunk_type; /* ANI_ACON_ID */
147 riff_header_t header; /* RIFF animated cursor header */
148 riff_seq3_t seq; /* sequence data for three cursor frames */
149 riff_rate3_t rates; /* rate data for three cursor frames */
150 riff_list_t frame_list; /* RIFF animated cursor frame list info */
151 riff_icon32x32x32_t frames[3]; /* array of three animated cursor frames */
153
154#define EMPTY_ICON32 \
155{ \
156 ANI_icon_ID, \
157 sizeof(ani_frame32x32x32), \
158 { \
159 { \
160 0x0, /* reserved */ \
161 0, /* type: icon(1), cursor(2) */ \
162 1, /* count */ \
163 { \
164 { \
165 32, /* width */ \
166 32, /* height */ \
167 0, /* color count */ \
168 0x0, /* reserved */ \
169 16, /* x hotspot */ \
170 16, /* y hotspot */ \
171 sizeof(ani_data32x32x32), /* DIB size */ \
172 sizeof(CURSORICONFILEDIR) /* DIB offset */ \
173 } \
174 } \
175 }, \
176 { \
177 sizeof(BITMAPINFOHEADER), /* structure for DIB-type data */ \
178 32, /* width */ \
179 32*2, /* actual height times two */ \
180 1, /* planes */ \
181 32, /* bpp */ \
182 BI_RGB, /* compression */ \
183 0, /* image size */ \
184 0, /* biXPelsPerMeter */ \
185 0, /* biYPelsPerMeter */ \
186 0, /* biClrUsed */ \
187 0 /* biClrImportant */ \
188 } \
189 /* DIB data: left uninitialized */ \
190 } \
191}
192
195 sizeof(empty_anicursor) - sizeof(DWORD)*2,
197 {
199 sizeof(ani_header),
200 {
201 sizeof(ani_header),
202 1, /* frames */
203 1, /* steps */
204 32, /* width */
205 32, /* height */
206 32, /* depth */
207 1, /* planes */
208 10, /* display rate in jiffies */
209 ANI_FLAG_ICON /* flags */
210 }
211 },
212 {
214 sizeof(riff_icon32x32x32_t)*(1 /*frames*/) + sizeof(DWORD),
216 },
217 {
219 }
220};
221
224 sizeof(empty_anicursor3) - sizeof(DWORD)*2,
226 {
228 sizeof(ani_header),
229 {
230 sizeof(ani_header),
231 3, /* frames */
232 3, /* steps */
233 32, /* width */
234 32, /* height */
235 32, /* depth */
236 1, /* planes */
237 0xbeef, /* display rate in jiffies */
238 ANI_FLAG_ICON /* flags */
239 }
240 },
241 {
243 sizeof(riff_icon32x32x32_t)*(3 /*frames*/) + sizeof(DWORD),
245 },
246 {
250 }
251};
252
255 sizeof(empty_anicursor3_seq) - sizeof(DWORD)*2,
257 {
259 sizeof(ani_header),
260 {
261 sizeof(ani_header),
262 3, /* frames */
263 3, /* steps */
264 32, /* width */
265 32, /* height */
266 32, /* depth */
267 1, /* planes */
268 0xbeef, /* display rate in jiffies */
270 }
271 },
272 {
274 sizeof(riff_seq3_t) - sizeof(DWORD)*2,
275 { 2, 0, 1} /* show frames in a uniquely identifiable order */
276 },
277 {
279 sizeof(riff_rate3_t) - sizeof(DWORD)*2,
280 { 0xc0de, 0xcafe, 0xbabe}
281 },
282 {
284 sizeof(riff_icon32x32x32_t)*(3 /*frames*/) + sizeof(DWORD),
286 },
287 {
291 }
292};
293
294#include "poppack.h"
295
296static char **test_argv;
297static int test_argc;
298static HWND child = 0;
299static HWND parent = 0;
301
302#define PROC_INIT (WM_USER+1)
303
304static BOOL (WINAPI *pGetCursorInfo)(CURSORINFO *);
305static BOOL (WINAPI *pGetIconInfoExA)(HICON,ICONINFOEXA *);
306static BOOL (WINAPI *pGetIconInfoExW)(HICON,ICONINFOEXW *);
307
308static const BOOL is_win64 = (sizeof(void *) > sizeof(int));
309
311{
312 switch (msg)
313 {
314 /* Destroy the cursor. */
315 case WM_USER+1:
316 {
319 BOOL ret;
320 DWORD error;
321
322 memset(&info, 0, sizeof(info));
324 todo_wine ok(ret, "GetIconInfoEx failed with error %lu\n", GetLastError());
325 todo_wine ok(info.hbmColor != NULL, "info.hmbColor was not set\n");
326 todo_wine ok(info.hbmMask != NULL, "info.hmbColor was not set\n");
327 DeleteObject(info.hbmColor);
328 DeleteObject(info.hbmMask);
329
330 SetLastError(0xdeadbeef);
333 ok(!ret, "DestroyCursor on the active cursor succeeded.\n");
335 error == 0xdeadbeef, /* vista */
336 "Last error: %lu\n", error);
337 return TRUE;
338 }
339 case WM_DESTROY:
341 return 0;
342 }
343
345}
346
348{
349 if (msg == PROC_INIT)
350 {
351 child = (HWND) wParam;
352 return TRUE;
353 }
354
356}
357
358static void do_child(void)
359{
360 WNDCLASSA class;
361 MSG msg;
362 BOOL ret;
363
364 /* Register a new class. */
365 class.style = CS_GLOBALCLASS;
366 class.lpfnWndProc = callback_child;
367 class.cbClsExtra = 0;
368 class.cbWndExtra = 0;
369 class.hInstance = GetModuleHandleA(NULL);
370 class.hIcon = NULL;
371 class.hCursor = NULL;
372 class.hbrBackground = NULL;
373 class.lpszMenuName = NULL;
374 class.lpszClassName = "cursor_child";
375
376 SetLastError(0xdeadbeef);
377 ret = RegisterClassA(&class);
378 ok(ret, "Failed to register window class. Error: %lu\n", GetLastError());
379
380 /* Create a window. */
381 child = CreateWindowA("cursor_child", "cursor_child", WS_POPUP | WS_VISIBLE,
382 0, 0, 200, 200, 0, 0, 0, NULL);
383 ok(child != 0, "CreateWindowA failed. Error: %lu\n", GetLastError());
384
385 /* Let the parent know our HWND. */
387
388 /* Receive messages. */
389 while ((ret = GetMessageA(&msg, 0, 0, 0)))
390 {
391 ok(ret != -1, "GetMessage failed. Error: %lu\n", GetLastError());
394 }
395}
396
397static void do_parent(void)
398{
399 char path_name[MAX_PATH];
402 WNDCLASSA class;
403 MSG msg;
404 BOOL ret;
405
406 /* Register a new class. */
407 class.style = CS_GLOBALCLASS;
408 class.lpfnWndProc = callback_parent;
409 class.cbClsExtra = 0;
410 class.cbWndExtra = 0;
411 class.hInstance = GetModuleHandleA(NULL);
412 class.hIcon = NULL;
413 class.hCursor = NULL;
414 class.hbrBackground = NULL;
415 class.lpszMenuName = NULL;
416 class.lpszClassName = "cursor_parent";
417
418 SetLastError(0xdeadbeef);
419 ret = RegisterClassA(&class);
420 ok(ret, "Failed to register window class. Error: %lu\n", GetLastError());
421
422 /* Create a window. */
423 parent = CreateWindowA("cursor_parent", "cursor_parent", WS_POPUP | WS_VISIBLE,
424 0, 0, 200, 200, 0, 0, 0, NULL);
425 ok(parent != 0, "CreateWindowA failed. Error: %lu\n", GetLastError());
426
427 /* Start child process. */
428 memset(&startup, 0, sizeof(startup));
429 startup.cb = sizeof(startup);
431 startup.wShowWindow = SW_SHOWNORMAL;
432
433 sprintf(path_name, "%s cursoricon %Ix", test_argv[0], (INT_PTR)parent);
434 ok(CreateProcessA(NULL, path_name, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess failed.\n");
435 child_process = info.hProcess;
436
437 /* Wait for child window handle. */
438 while ((child == 0) && (ret = GetMessageA(&msg, parent, 0, 0)))
439 {
440 ok(ret != -1, "GetMessage failed. Error: %lu\n", GetLastError());
443 }
444}
445
446static void finish_child_process(void)
447{
451}
452
453static void test_child_process(void)
454{
455 static const BYTE bmp_bits[4096];
457 ICONINFO cursorInfo;
458 UINT display_bpp;
459 HDC hdc;
460
461 /* Create and set a dummy cursor. */
462 hdc = GetDC(0);
463 display_bpp = GetDeviceCaps(hdc, BITSPIXEL);
464 ReleaseDC(0, hdc);
465
466 cursorInfo.fIcon = FALSE;
467 cursorInfo.xHotspot = 0;
468 cursorInfo.yHotspot = 0;
469 cursorInfo.hbmMask = CreateBitmap(32, 32, 1, 1, bmp_bits);
470 cursorInfo.hbmColor = CreateBitmap(32, 32, 1, display_bpp, bmp_bits);
471
472 cursor = CreateIconIndirect(&cursorInfo);
473 ok(cursor != NULL, "CreateIconIndirect returned %p.\n", cursor);
474
476
477 /* Destroy the cursor. */
479}
480
482{
483 /* 5-bit accuracy is a sufficient test. This will match as long as
484 * colors are never truncated to less that 3x5-bit accuracy i.e.
485 * palettized. */
486 return (a & 0x00F8F8F8) == (b & 0x00F8F8F8);
487}
488
489static void check_copy_image(HBITMAP bitmap, UINT type, UINT flags, INT copyWidth, INT copyHeight,
490 INT expectedWidth, INT expectedHeight, WORD expectedDepth, BOOL dibExpected)
491{
493 BITMAP origBitmap;
494 BITMAP copyBitmap;
495 BOOL copy_is_dib;
496 BOOL ret;
497#ifdef __REACTOS__
498 UINT display_bpp;
499 HDC hdc;
500
501 hdc = GetDC(0);
502 display_bpp = GetDeviceCaps(hdc, BITSPIXEL);
503 ReleaseDC(0, hdc);
504#endif
505
506 GetObjectA(bitmap, sizeof(origBitmap), &origBitmap);
507
508 winetest_push_context("%s, type %#x, flags %#x, size %ux%u",
509 origBitmap.bmBits ? "DIB" : "DDB", type, flags, copyWidth, copyHeight);
510
511 if (type == IMAGE_BITMAP)
512 {
513 copy = CopyImage(bitmap, type, copyWidth, copyHeight, flags);
514 }
515 else
516 {
517 ICONINFO info =
518 {
519 .fIcon = (type == IMAGE_ICON),
520 .hbmColor = bitmap,
521 .hbmMask = bitmap,
522 };
524 ok(!!icon, "Failed to create icon, error %lu\n", GetLastError());
525 copy = CopyImage(icon, type, copyWidth, copyHeight, flags);
526 ret = DestroyIcon(icon);
527 ok(ret, "Failed to destroy icon, error %lu\n", GetLastError());
528 }
529 ok(copy != NULL, "CopyImage() failed\n");
530 if (copy != NULL)
531 {
532 if (type == IMAGE_BITMAP)
533 {
534 GetObjectA(copy, sizeof(copyBitmap), &copyBitmap);
535 }
536 else
537 {
539
541 ok(ret, "Failed to get icon info, error %lu\n", GetLastError());
542 GetObjectA(info.hbmColor, sizeof(copyBitmap), &copyBitmap);
543 }
544 copy_is_dib = (copyBitmap.bmBits != NULL);
545
546 if (copy_is_dib && dibExpected
547 && copyBitmap.bmBitsPixel == 24
548 && (expectedDepth == 16 || expectedDepth == 32))
549 {
550 /* Windows 95 doesn't create DIBs with a depth of 16 or 32 bit */
551 if (GetVersion() & 0x80000000)
552 {
553 expectedDepth = 24;
554 }
555 }
556
557 if (copy_is_dib && !dibExpected && !(flags & LR_CREATEDIBSECTION))
558 {
559 /* It's not forbidden to create a DIB section if the flag
560 LR_CREATEDIBSECTION is absent.
561 Windows 9x does this if the bitmap has a depth that doesn't
562 match the screen depth, Windows NT doesn't */
563 dibExpected = TRUE;
564 expectedDepth = origBitmap.bmBitsPixel;
565 }
566
567 if (type != IMAGE_BITMAP)
568 {
569 dibExpected = FALSE;
570 expectedDepth = 32;
571 }
572
573 ok(copy_is_dib == dibExpected, "Expected %s, got %s\n",
574 dibExpected ? "DIB" : "DDB", copy_is_dib ? "DIB" : "DDB");
575 ok(copyBitmap.bmWidth == expectedWidth, "Expected width %u, got %u\n",
576 expectedWidth, copyBitmap.bmWidth);
577 ok(copyBitmap.bmHeight == expectedHeight, "Expected height %u, got %u\n",
578 expectedHeight, copyBitmap.bmHeight);
579#ifdef __REACTOS__
580 ok(copyBitmap.bmBitsPixel == expectedDepth || broken(copyBitmap.bmBitsPixel == display_bpp && expectedDepth == 32), "Expected depth %u, got %u\n",
581 expectedDepth, copyBitmap.bmBitsPixel);
582#else
583 ok(copyBitmap.bmBitsPixel == expectedDepth, "Expected depth %u, got %u\n",
584 expectedDepth, copyBitmap.bmBitsPixel);
585#endif
586
587 if (type != IMAGE_BITMAP)
588 {
590
592 ok(ret, "Failed to get icon info, error %lu\n", GetLastError());
593 GetObjectA(info.hbmMask, sizeof(copyBitmap), &copyBitmap);
594
595 ok(!copyBitmap.bmBits, "Expected DDB\n");
596 ok(copyBitmap.bmWidth == expectedWidth, "Expected mask width %u, got %u\n",
597 expectedWidth, copyBitmap.bmWidth);
598 ok(copyBitmap.bmHeight == expectedHeight, "Expected mask height %u, got %u\n",
599 expectedHeight, copyBitmap.bmHeight);
600 ok(copyBitmap.bmBitsPixel == 1, "Got mask depth %u\n", copyBitmap.bmBitsPixel);
601 }
602
603 if (type == IMAGE_BITMAP)
605 else if (type == IMAGE_ICON)
607 else
609 }
610
612}
613
615{
616 HBITMAP ddb, dib;
617 HDC screenDC;
619 VOID * bits;
620 int screen_depth;
621 unsigned int i;
622
623 /* Create a device-independent bitmap (DIB) */
624 info = calloc(1, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
625 info->bmiHeader.biSize = sizeof(info->bmiHeader);
626 info->bmiHeader.biWidth = 2;
627 info->bmiHeader.biHeight = 2;
628 info->bmiHeader.biPlanes = 1;
629 info->bmiHeader.biBitCount = depth;
630 info->bmiHeader.biCompression = BI_RGB;
631
632 for (i=0; i < 256; i++)
633 {
634 info->bmiColors[i].rgbRed = i;
635 info->bmiColors[i].rgbGreen = i;
636 info->bmiColors[i].rgbBlue = 255 - i;
637 info->bmiColors[i].rgbReserved = 0;
638 }
639
641
642 /* Create a device-dependent bitmap (DDB) */
643 screenDC = GetDC(NULL);
644 screen_depth = GetDeviceCaps(screenDC, BITSPIXEL);
645 if (depth == 1 || depth == screen_depth)
646 {
647 ddb = CreateBitmap(2, 2, 1, depth, NULL);
648 }
649 else
650 {
651 ddb = NULL;
652 }
653 ReleaseDC(NULL, screenDC);
654
655 if (ddb != NULL)
656 {
657 check_copy_image(ddb, type, 0, 0, 0, 2, 2, depth == 1 ? 1 : screen_depth, FALSE);
658 check_copy_image(ddb, type, 0, 0, 5, 2, 5, depth == 1 ? 1 : screen_depth, FALSE);
659 check_copy_image(ddb, type, 0, 5, 0, 5, 2, depth == 1 ? 1 : screen_depth, FALSE);
660 check_copy_image(ddb, type, 0, 5, 5, 5, 5, depth == 1 ? 1 : screen_depth, FALSE);
661
662 check_copy_image(ddb, type, LR_MONOCHROME, 0, 0, 2, 2, 1, FALSE);
663 check_copy_image(ddb, type, LR_MONOCHROME, 5, 0, 5, 2, 1, FALSE);
664 check_copy_image(ddb, type, LR_MONOCHROME, 0, 5, 2, 5, 1, FALSE);
665 check_copy_image(ddb, type, LR_MONOCHROME, 5, 5, 5, 5, 1, FALSE);
666
671
672 /* LR_MONOCHROME is ignored if LR_CREATEDIBSECTION is present */
677
678 DeleteObject(ddb);
679 }
680
681 if (depth != 1)
682 {
683 check_copy_image(dib, type, 0, 0, 0, 2, 2, screen_depth, FALSE);
684 check_copy_image(dib, type, 0, 5, 0, 5, 2, screen_depth, FALSE);
685 check_copy_image(dib, type, 0, 0, 5, 2, 5, screen_depth, FALSE);
686 check_copy_image(dib, type, 0, 5, 5, 5, 5, screen_depth, FALSE);
687 }
688
689 check_copy_image(dib, type, LR_MONOCHROME, 0, 0, 2, 2, 1, FALSE);
690 check_copy_image(dib, type, LR_MONOCHROME, 5, 0, 5, 2, 1, FALSE);
691 check_copy_image(dib, type, LR_MONOCHROME, 0, 5, 2, 5, 1, FALSE);
692 check_copy_image(dib, type, LR_MONOCHROME, 5, 5, 5, 5, 1, FALSE);
693
698
699 /* LR_MONOCHROME is ignored if LR_CREATEDIBSECTION is present */
704
705 DeleteObject(dib);
706
707 if (depth == 1)
708 {
709 /* Special case: A monochrome DIB is converted to a monochrome DDB if
710 the colors in the color table are black and white.
711
712 Skip this test on Windows 95, it always creates a monochrome DDB
713 in this case */
714
715 if (!(GetVersion() & 0x80000000))
716 {
717 info->bmiHeader.biBitCount = 1;
718 info->bmiColors[0].rgbRed = 0xFF;
719 info->bmiColors[0].rgbGreen = 0;
720 info->bmiColors[0].rgbBlue = 0;
721 info->bmiColors[1].rgbRed = 0;
722 info->bmiColors[1].rgbGreen = 0xFF;
723 info->bmiColors[1].rgbBlue = 0;
724
726 check_copy_image(dib, type, 0, 0, 0, 2, 2, screen_depth, FALSE);
727 check_copy_image(dib, type, 0, 5, 0, 5, 2, screen_depth, FALSE);
728 check_copy_image(dib, type, 0, 0, 5, 2, 5, screen_depth, FALSE);
729 check_copy_image(dib, type, 0, 5, 5, 5, 5, screen_depth, FALSE);
730 DeleteObject(dib);
731
732 info->bmiHeader.biBitCount = 1;
733 info->bmiColors[0].rgbRed = 0;
734 info->bmiColors[0].rgbGreen = 0;
735 info->bmiColors[0].rgbBlue = 0;
736 info->bmiColors[1].rgbRed = 0xFF;
737 info->bmiColors[1].rgbGreen = 0xFF;
738 info->bmiColors[1].rgbBlue = 0xFF;
739
741 check_copy_image(dib, type, 0, 0, 0, 2, 2, 1, FALSE);
742 check_copy_image(dib, type, 0, 5, 0, 5, 2, 1, FALSE);
743 check_copy_image(dib, type, 0, 0, 5, 2, 5, 1, FALSE);
744 check_copy_image(dib, type, 0, 5, 5, 5, 5, 1, FALSE);
745 DeleteObject(dib);
746
747 info->bmiHeader.biBitCount = 1;
748 info->bmiColors[0].rgbRed = 0xFF;
749 info->bmiColors[0].rgbGreen = 0xFF;
750 info->bmiColors[0].rgbBlue = 0xFF;
751 info->bmiColors[1].rgbRed = 0;
752 info->bmiColors[1].rgbGreen = 0;
753 info->bmiColors[1].rgbBlue = 0;
754
756 check_copy_image(dib, type, 0, 0, 0, 2, 2, 1, FALSE);
757 check_copy_image(dib, type, 0, 5, 0, 5, 2, 1, FALSE);
758 check_copy_image(dib, type, 0, 0, 5, 2, 5, 1, FALSE);
759 check_copy_image(dib, type, 0, 5, 5, 5, 5, 1, FALSE);
760 DeleteObject(dib);
761 }
762 }
763
764 free(info);
765}
766
767static void test_initial_cursor(void)
768{
769 HCURSOR cursor, cursor2;
770 DWORD error;
771
772 cursor = GetCursor();
773
774 /* Check what handle GetCursor() returns if a cursor is not set yet. */
775 SetLastError(0xdeadbeef);
776 cursor2 = LoadCursorA(NULL, (LPCSTR)IDC_WAIT);
777 todo_wine {
778 ok(cursor == cursor2, "cursor (%p) is not IDC_WAIT (%p).\n", cursor, cursor2);
779 }
781 ok(error == 0xdeadbeef, "Last error: 0x%08lx\n", error);
782}
783
784static void test_icon_info_(HICON hIcon, UINT exp_cx, UINT exp_cy,
785 UINT exp_mask_cy, UINT exp_bpp, const BYTE *mask_bits, UINT has_color, int line)
786{
787 BYTE ret_bits[1024];
789 DWORD ret;
790 BITMAP bmMask, bmColor;
791
793 ok_(__FILE__, line)(ret, "GetIconInfo failed\n");
794
795 /* CreateIcon under XP causes info.fIcon to be 0 */
796 ok_(__FILE__, line)(info.xHotspot == exp_cx/2, "info.xHotspot = %lu\n", info.xHotspot);
797 ok_(__FILE__, line)(info.yHotspot == exp_cy/2, "info.yHotspot = %lu\n", info.yHotspot);
798 ok_(__FILE__, line)(info.hbmMask != 0, "info.hbmMask is NULL\n");
799
800 if (mask_bits)
801 {
802 unsigned int exp_stride = (exp_cx + 7) / 8;
803 exp_stride = (exp_stride + 1) & ~1;
804 ret = GetBitmapBits(info.hbmMask, sizeof(ret_bits), ret_bits);
805 ok_(__FILE__, line)(ret == exp_stride * exp_mask_cy, "GetBitmapBits returned %lu\n", ret);
806 ok_(__FILE__, line)(!memcmp(ret_bits, mask_bits, ret), "mask bitmap didn't match\n");
807 }
808
809 ret = GetObjectA(info.hbmMask, sizeof(bmMask), &bmMask);
810 ok_(__FILE__, line)(ret == sizeof(bmMask), "GetObject(info.hbmMask) failed, ret %lu\n", ret);
811
812 ok_(__FILE__, line)(!!info.hbmColor == has_color, "got hbmColor %p\n", info.hbmColor);
813
814 if (info.hbmColor)
815 {
816 HDC hdc;
817 UINT display_bpp;
818
819 hdc = GetDC(0);
820 display_bpp = GetDeviceCaps(hdc, BITSPIXEL);
821 ReleaseDC(0, hdc);
822
823 ret = GetObjectA(info.hbmColor, sizeof(bmColor), &bmColor);
824 ok_(__FILE__, line)(ret == sizeof(bmColor), "GetObject(info.hbmColor) failed, ret %lu\n", ret);
825
826#ifdef __REACTOS__
827 ok_(__FILE__, line)(bmColor.bmBitsPixel == display_bpp || broken(!bmColor.bmBits && bmColor.bmBitsPixel == 32) /* Happens with PrivateExtractIcons test */,
828 "bmColor.bmBitsPixel = %d\n", bmColor.bmBitsPixel);
829#else
830 ok_(__FILE__, line)(bmColor.bmBitsPixel == display_bpp,
831 "bmColor.bmBitsPixel = %d\n", bmColor.bmBitsPixel);
832#endif
833 ok_(__FILE__, line)(bmColor.bmWidth == exp_cx, "bmColor.bmWidth = %d\n", bmColor.bmWidth);
834 ok_(__FILE__, line)(bmColor.bmHeight == exp_cy, "bmColor.bmHeight = %d\n", bmColor.bmHeight);
835
836 ok_(__FILE__, line)(bmMask.bmBitsPixel == 1, "bmMask.bmBitsPixel = %d\n", bmMask.bmBitsPixel);
837 ok_(__FILE__, line)(bmMask.bmWidth == exp_cx, "bmMask.bmWidth = %d\n", bmMask.bmWidth);
838 ok_(__FILE__, line)(bmMask.bmHeight == exp_mask_cy, "bmMask.bmHeight = %d\n", bmMask.bmHeight);
839 }
840 else
841 {
842 ok_(__FILE__, line)(bmMask.bmBitsPixel == 1, "bmMask.bmBitsPixel = %d\n", bmMask.bmBitsPixel);
843 ok_(__FILE__, line)(bmMask.bmWidth == exp_cx, "bmMask.bmWidth = %d\n", bmMask.bmWidth);
844 ok_(__FILE__, line)(bmMask.bmHeight == exp_mask_cy, "bmMask.bmHeight = %d\n", bmMask.bmHeight);
845 }
846 if (pGetIconInfoExA)
847 {
848 ICONINFOEXA infoex;
849
850 memset( &infoex, 0xcc, sizeof(infoex) );
851 SetLastError( 0xdeadbeef );
852 infoex.cbSize = sizeof(infoex) - 1;
853 ret = pGetIconInfoExA( hIcon, &infoex );
854 ok_(__FILE__, line)(!ret, "GetIconInfoEx succeeded\n");
855 ok_(__FILE__, line)(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %ld\n", GetLastError());
856
857 SetLastError( 0xdeadbeef );
858 infoex.cbSize = sizeof(infoex) + 1;
859 ret = pGetIconInfoExA( hIcon, &infoex );
860 ok_(__FILE__, line)(!ret, "GetIconInfoEx succeeded\n");
861 ok_(__FILE__, line)(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %ld\n", GetLastError());
862
863 SetLastError( 0xdeadbeef );
864 infoex.cbSize = sizeof(infoex);
865 ret = pGetIconInfoExA( (HICON)0xdeadbabe, &infoex );
866 ok_(__FILE__, line)(!ret, "GetIconInfoEx succeeded\n");
868 "wrong error %ld\n", GetLastError());
869
870 infoex.cbSize = sizeof(infoex);
871 ret = pGetIconInfoExA( hIcon, &infoex );
872 ok_(__FILE__, line)(ret, "GetIconInfoEx failed err %ld\n", GetLastError());
873 ok_(__FILE__, line)(infoex.wResID == 0, "GetIconInfoEx wrong resid %x\n", infoex.wResID);
874 ok_(__FILE__, line)(infoex.szModName[0] == 0, "GetIconInfoEx wrong module %s\n", infoex.szModName);
875 ok_(__FILE__, line)(infoex.szResName[0] == 0, "GetIconInfoEx wrong name %s\n", infoex.szResName);
876 }
877}
878
879#define test_icon_info(a,b,c,d,e,f,g) test_icon_info_(a,b,c,d,e,f,g,__LINE__)
880
881static void test_CreateIcon(void)
882{
883 BYTE bmp_bits[1024];
884 HICON hIcon;
885 HBITMAP hbmMask, hbmColor;
886 BITMAPINFO *bmpinfo;
888 HDC hdc;
889 void *bits;
890 UINT display_bpp;
891 int i;
892
893 for (i = 0; i < sizeof(bmp_bits); ++i)
894 bmp_bits[i] = 111 * i;
895
896 hdc = GetDC(0);
897 display_bpp = GetDeviceCaps(hdc, BITSPIXEL);
898
899 /* these crash under XP
900 hIcon = CreateIcon(0, 16, 16, 1, 1, bmp_bits, NULL);
901 hIcon = CreateIcon(0, 16, 16, 1, 1, NULL, bmp_bits);
902 */
903
904 hIcon = CreateIcon(0, 16, 16, 1, 1, bmp_bits, &bmp_bits[16 * 16 / 8]);
905 ok(hIcon != 0, "CreateIcon failed\n");
906 test_icon_info(hIcon, 16, 16, 32, 1, bmp_bits, FALSE);
908
909 hIcon = CreateCursor(0, 8, 8, 16, 16, bmp_bits, &bmp_bits[16 * 16 / 8]);
910 ok(hIcon != 0, "CreateCursor failed\n");
911 test_icon_info(hIcon, 16, 16, 32, 1, bmp_bits, FALSE);
913
914 hIcon = CreateIcon(0, 16, 16, 1, display_bpp, bmp_bits, bmp_bits);
915 ok(hIcon != 0, "CreateIcon failed\n");
916 test_icon_info(hIcon, 16, 16, 16, display_bpp, bmp_bits, TRUE);
918
919 hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits);
920 ok(hbmMask != 0, "CreateBitmap failed\n");
921 hbmColor = CreateBitmap(16, 16, 1, display_bpp, bmp_bits);
922 ok(hbmColor != 0, "CreateBitmap failed\n");
923
924 info.fIcon = TRUE;
925 info.xHotspot = 8;
926 info.yHotspot = 8;
927 info.hbmMask = 0;
928 info.hbmColor = 0;
929 SetLastError(0xdeadbeaf);
931 ok(!hIcon, "CreateIconIndirect should fail\n");
932 ok(GetLastError() == 0xdeadbeaf, "wrong error %lu\n", GetLastError());
933
934 info.fIcon = TRUE;
935 info.xHotspot = 8;
936 info.yHotspot = 8;
937 info.hbmMask = 0;
938 info.hbmColor = hbmColor;
939 SetLastError(0xdeadbeaf);
941 ok(!hIcon, "CreateIconIndirect should fail\n");
942 ok(GetLastError() == 0xdeadbeaf, "wrong error %lu\n", GetLastError());
943
944 info.fIcon = TRUE;
945 info.xHotspot = 8;
946 info.yHotspot = 8;
947 info.hbmMask = hbmMask;
948 info.hbmColor = hbmColor;
950 ok(hIcon != 0, "CreateIconIndirect failed\n");
951 test_icon_info(hIcon, 16, 16, 16, display_bpp, bmp_bits, TRUE);
953
954 DeleteObject(hbmMask);
955 DeleteObject(hbmColor);
956
957 hbmMask = CreateBitmap(16, 32, 1, 1, bmp_bits);
958 ok(hbmMask != 0, "CreateBitmap failed\n");
959
960 info.fIcon = TRUE;
961 info.xHotspot = 8;
962 info.yHotspot = 8;
963 info.hbmMask = hbmMask;
964 info.hbmColor = 0;
965 SetLastError(0xdeadbeaf);
967 ok(hIcon != 0, "CreateIconIndirect failed\n");
968 test_icon_info(hIcon, 16, 16, 32, 1, bmp_bits, FALSE);
970
971 info.hbmMask = hbmMask;
972 info.hbmColor = hbmMask;
973 SetLastError(0xdeadbeaf);
975 ok(hIcon != 0, "CreateIconIndirect failed\n");
976 test_icon_info(hIcon, 16, 32, 32, 1, bmp_bits, TRUE);
978
979 DeleteObject(hbmMask);
980
981 for (i = 0; i <= 4; i++)
982 {
983 hbmMask = CreateBitmap(1, i, 1, 1, bmp_bits);
984 ok(hbmMask != 0, "CreateBitmap failed\n");
985
986 info.fIcon = TRUE;
987 info.xHotspot = 0;
988 info.yHotspot = 0;
989 info.hbmMask = hbmMask;
990 info.hbmColor = 0;
991 SetLastError(0xdeadbeaf);
993 ok(hIcon != 0, "CreateIconIndirect failed\n");
994 test_icon_info(hIcon, 1, i / 2, max(i,1), 1, NULL, FALSE);
996 DeleteObject(hbmMask);
997 }
998
999 hbmMask = CreateBitmap(16, 32, 1, 16, bmp_bits);
1000 ok(hbmMask != 0, "CreateBitmap failed\n");
1001
1002 info.hbmMask = hbmMask;
1003 info.hbmColor = 0;
1004 SetLastError(0xdeadbeaf);
1006 ok(hIcon != 0, "CreateIconIndirect failed\n");
1007 test_icon_info(hIcon, 16, 16, 32, 1, NULL, FALSE);
1009
1010 DeleteObject(hbmMask);
1011
1012 /* test creating an icon from a DIB section */
1013
1014 bmpinfo = calloc( 1, FIELD_OFFSET(BITMAPINFO,bmiColors[256]) );
1015 bmpinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1016 bmpinfo->bmiHeader.biWidth = 32;
1017 bmpinfo->bmiHeader.biHeight = 32;
1018 bmpinfo->bmiHeader.biPlanes = 1;
1019 bmpinfo->bmiHeader.biBitCount = 8;
1020 bmpinfo->bmiHeader.biCompression = BI_RGB;
1021 hbmColor = CreateDIBSection( hdc, bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
1022 ok(hbmColor != NULL, "Expected a handle to the DIB\n");
1023 if (bits)
1024 memset( bits, 0x55, 32 * 32 * bmpinfo->bmiHeader.biBitCount / 8 );
1025 bmpinfo->bmiHeader.biBitCount = 1;
1026 hbmMask = CreateDIBSection( hdc, bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
1027 ok(hbmMask != NULL, "Expected a handle to the DIB\n");
1028 if (bits)
1029 memset( bits, 0x55, 32 * 32 * bmpinfo->bmiHeader.biBitCount / 8 );
1030
1031 info.fIcon = TRUE;
1032 info.xHotspot = 8;
1033 info.yHotspot = 8;
1034 info.hbmMask = hbmColor;
1035 info.hbmColor = hbmMask;
1036 SetLastError(0xdeadbeaf);
1038 ok(hIcon != 0, "CreateIconIndirect failed\n");
1039 test_icon_info(hIcon, 32, 32, 32, 8, NULL, TRUE);
1041 DeleteObject(hbmColor);
1042
1043 bmpinfo->bmiHeader.biBitCount = 16;
1044 hbmColor = CreateDIBSection( hdc, bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
1045 ok(hbmColor != NULL, "Expected a handle to the DIB\n");
1046 if (bits)
1047 memset( bits, 0x55, 32 * 32 * bmpinfo->bmiHeader.biBitCount / 8 );
1048
1049 info.fIcon = TRUE;
1050 info.xHotspot = 8;
1051 info.yHotspot = 8;
1052 info.hbmMask = hbmColor;
1053 info.hbmColor = hbmMask;
1054 SetLastError(0xdeadbeaf);
1056 ok(hIcon != 0, "CreateIconIndirect failed\n");
1057 test_icon_info(hIcon, 32, 32, 32, 8, NULL, TRUE);
1059 DeleteObject(hbmColor);
1060
1061 bmpinfo->bmiHeader.biBitCount = 32;
1062 hbmColor = CreateDIBSection( hdc, bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
1063 ok(hbmColor != NULL, "Expected a handle to the DIB\n");
1064 if (bits)
1065 memset( bits, 0x55, 32 * 32 * bmpinfo->bmiHeader.biBitCount / 8 );
1066
1067 info.fIcon = TRUE;
1068 info.xHotspot = 8;
1069 info.yHotspot = 8;
1070 info.hbmMask = hbmColor;
1071 info.hbmColor = hbmMask;
1072 SetLastError(0xdeadbeaf);
1074 ok(hIcon != 0, "CreateIconIndirect failed\n");
1075 test_icon_info(hIcon, 32, 32, 32, 8, NULL, TRUE);
1077
1078 DeleteObject(hbmMask);
1079 DeleteObject(hbmColor);
1080 free(bmpinfo);
1081
1082 ReleaseDC(0, hdc);
1083}
1084
1085/* Shamelessly ripped from dlls/oleaut32/tests/olepicture.c */
1086/* 1x1 pixel gif */
1087static const unsigned char gifimage[35] = {
10880x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
10890xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
10900x01,0x00,0x3b
1091};
1092
1093/* 1x1 pixel jpg */
1094static const unsigned char jpgimage[285] = {
10950xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
10960x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
10970x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
10980x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
10990x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
11000x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
11010x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
11020x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
11030x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
11040x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
11050x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
11060x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
11070x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
11080x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
11090x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
11100x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
11110x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
11120x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1113};
1114
1115/* 1x1 pixel png */
1116static const unsigned char pngimage[285] = {
11170x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
11180x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
11190xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
11200x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
11210x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
11220x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
11230xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1124};
1125
1126/* 1x1 pixel bmp with gap between palette and bitmap. Correct bitmap contains only
1127 zeroes, gap is 0xFF. */
1128static unsigned char bmpimage[70] = {
11290x42,0x4d,0x46,0x00,0x00,0x00,0xDE,0xAD,0xBE,0xEF,0x42,0x00,0x00,0x00,0x28,0x00,
11300x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
11310x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
11320x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0x55,0x55,0x55,0x00,0xFF,0xFF,
11330xFF,0xFF,0x00,0x00,0x00,0x00
1134};
1135
1136/* 1x1 pixel bmp using BITMAPCOREHEADER with 24 bits colors (1 bit color fails to load) */
1137static const unsigned char bmpcoreimage[38] = {
11380x42,0x4d,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x00,0x00,0x00,0x0c,0x00,
11390x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x18,0x00,0xff,0xff,0xff,0x00
1140};
1141
1142/* 2x2 pixel gif */
1143static const unsigned char gif4pixel[42] = {
11440x47,0x49,0x46,0x38,0x37,0x61,0x02,0x00,0x02,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
11450x39,0x62,0xfc,0xff,0x1a,0xe5,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x02,0x00,
11460x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b
1147};
1148
1149/* An invalid cursor with an invalid dwDIBOffset */
1150static const unsigned char invalid_dwDIBOffset[] = {
1151 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00
1153};
1154
1155static const DWORD biSize_tests[] = {
1156 0,
1157 sizeof(BITMAPCOREHEADER) - 1,
1158 sizeof(BITMAPCOREHEADER) + 1,
1159 sizeof(BITMAPINFOHEADER) - 1,
1160 sizeof(BITMAPINFOHEADER) + 1,
1161 sizeof(BITMAPV4HEADER) - 1,
1162 sizeof(BITMAPV4HEADER) + 1,
1163 sizeof(BITMAPV5HEADER) - 1,
1164 sizeof(BITMAPV5HEADER) + 1,
1165 (sizeof(BITMAPCOREHEADER) + sizeof(BITMAPINFOHEADER)) / 2,
1166 (sizeof(BITMAPV4HEADER) + sizeof(BITMAPV5HEADER)) / 2,
1167 0xdeadbeef,
1168 0xffffffff
1169};
1170
1172{
1173 BITMAP bm;
1174 BITMAPINFO bmi;
1175 DWORD ret, pixel = 0;
1176 HDC hdc = GetDC(NULL);
1177
1178 ret = GetObjectA(hbm, sizeof(bm), &bm);
1179 ok(ret == sizeof(bm), "GetObject returned %ld\n", ret);
1180
1181 memset(&bmi, 0, sizeof(bmi));
1182 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
1183 bmi.bmiHeader.biWidth = bm.bmWidth;
1184 bmi.bmiHeader.biHeight = bm.bmHeight;
1185 bmi.bmiHeader.biPlanes = 1;
1186 bmi.bmiHeader.biBitCount= 24;
1188 ret = GetDIBits(hdc, hbm, 0, bm.bmHeight, &pixel, &bmi, DIB_RGB_COLORS);
1189 ok(ret == bm.bmHeight, "%ld lines were converted, not %d\n", ret, bm.bmHeight);
1190
1191 ok(color_match(pixel, 0x00ffffff), "Pixel is 0x%08lx\n", pixel);
1192
1193 ReleaseDC(NULL, hdc);
1194}
1195
1196static void test_LoadImageFile(const char * test_desc, const unsigned char * image_data,
1197 unsigned int image_size, const char * ext, BOOL expect_success)
1198{
1199 HANDLE handle;
1200 BOOL ret;
1201 DWORD error, bytes_written;
1202 char filename[64];
1203
1204 winetest_push_context("%s", test_desc);
1205 strcpy(filename, "test.");
1207
1208 /* Create the test image. */
1211 ok(handle != INVALID_HANDLE_VALUE, "CreateFileA failed. %lu\n", GetLastError());
1212 ret = WriteFile(handle, image_data, image_size, &bytes_written, NULL);
1213 ok(ret && bytes_written == image_size, "test file created improperly.\n");
1215
1216 /* Load as cursor. For all tested formats, this should fail */
1217 SetLastError(0xdeadbeef);
1219 ok(handle == NULL, "IMAGE_CURSOR succeeded incorrectly\n");
1220 error = GetLastError();
1221 ok(error == 0, "Last error: %lu\n", error);
1223
1224 /* Load as icon. For all tested formats, this should fail */
1225 SetLastError(0xdeadbeef);
1227 ok(handle == NULL, "IMAGE_ICON succeeded incorrectly\n");
1228 error = GetLastError();
1229 ok(error == 0, "Last error: %lu\n", error);
1230 if (handle != NULL) DestroyIcon(handle);
1231
1232 /* Load as bitmap. Should succeed for correct bmp, fail for everything else */
1233 SetLastError(0xdeadbeef);
1235 error = GetLastError();
1236 ok(error == 0, "Last error: %lu\n", error);
1237
1238 if (expect_success) {
1239 ok(handle != NULL || broken(image_data == bmpcoreimage) /* pre-security update */,
1240 "IMAGE_BITMAP failed\n");
1242 }
1243 else ok(handle == NULL, "IMAGE_BITMAP succeeded incorrectly\n");
1244
1245 if (handle != NULL) DeleteObject(handle);
1248}
1249
1250typedef struct {
1251 unsigned width;
1252 unsigned height;
1255
1256static void create_ico_file(const char *filename, const test_icon_entries_t *test_icon_entries, unsigned entry_cnt)
1257{
1258 CURSORICONFILEDIRENTRY *icon_entry;
1259 BITMAPINFOHEADER *icon_header;
1261 BYTE *buf, *bitmap_ptr;
1262 DWORD bytes_written;
1263 size_t icon_size;
1264 HANDLE file;
1265 unsigned i;
1266 BOOL ret;
1267
1268 const unsigned icon_bpp = 32;
1269
1270 icon_size = FIELD_OFFSET(CURSORICONFILEDIR, idEntries[entry_cnt]) + sizeof(BITMAPINFOHEADER)*entry_cnt;
1271 for(i=0; i<entry_cnt; i++)
1272 icon_size += icon_bpp * test_icon_entries[i].width * test_icon_entries[i].height / 8;
1273
1274 buf = calloc(1, icon_size);
1276
1277 dir->idReserved = 0;
1278 dir->idType = 1;
1279 dir->idCount = entry_cnt;
1280
1281 bitmap_ptr = buf + FIELD_OFFSET(CURSORICONFILEDIR, idEntries[entry_cnt]);
1282 for(i=0; i<entry_cnt; i++) {
1283 icon_entry = dir->idEntries+i;
1284 icon_entry->bWidth = test_icon_entries[i].width;
1285 icon_entry->bHeight = test_icon_entries[i].height;
1286 icon_entry->bColorCount = 0;
1287 icon_entry->bReserved = 0;
1288 icon_entry->xHotspot = 1;
1289 icon_entry->yHotspot = 1;
1290 icon_entry->dwDIBSize = sizeof(BITMAPINFOHEADER) + icon_entry->bWidth * icon_entry->bHeight * icon_bpp / 8;
1291 icon_entry->dwDIBOffset = test_icon_entries[i].invalid_offset ? 0xffffffff : bitmap_ptr - buf;
1292
1293 icon_header = (BITMAPINFOHEADER*)bitmap_ptr;
1294 bitmap_ptr += icon_entry->dwDIBSize;
1295
1296 icon_header->biSize = sizeof(BITMAPINFOHEADER);
1297 icon_header->biWidth = icon_entry->bWidth;
1298 icon_header->biHeight = icon_entry->bHeight;
1299 icon_header->biPlanes = 1;
1300 icon_header->biBitCount = icon_bpp;
1301 icon_header->biSizeImage = 0; /* Uncompressed bitmap. */
1302 }
1303
1304 memset(bitmap_ptr, 0xf0, buf+icon_size-bitmap_ptr);
1305
1306 /* Create the icon. */
1308 ok(file != INVALID_HANDLE_VALUE, "CreateFileA failed. %lu\n", GetLastError());
1309 ret = WriteFile(file, buf, icon_size, &bytes_written, NULL);
1310 ok(ret && bytes_written == icon_size, "icon.ico created improperly.\n");
1312
1313 free(buf);
1314}
1315
1316static void create_bitmap_file(const char *filename, const BITMAPINFO *bmi, const unsigned char *bits)
1317{
1318 unsigned int clr_used, bmi_size, bits_size, stride;
1319 const BITMAPINFOHEADER *h = &bmi->bmiHeader;
1321 DWORD bytes_written;
1322 HANDLE file;
1323 BOOL ret;
1324
1325 clr_used = h->biBitCount <= 8 ? 1u << h->biBitCount : 0;
1326 stride = ((h->biBitCount * h->biWidth + 7) / 8 + 3) & ~3;
1327 bits_size = h->biHeight * stride;
1328 bmi_size = h->biSize + clr_used * sizeof(RGBQUAD);
1329
1330 hdr.bfType = 0x4d42;
1331 hdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + bmi_size;
1332 hdr.bfSize = hdr.bfOffBits + bits_size;
1333 hdr.bfReserved1 = 0;
1334 hdr.bfReserved2 = 0;
1335
1337 ok(file != INVALID_HANDLE_VALUE, "CreateFileA failed, result %lu.\n", GetLastError());
1338 ret = WriteFile(file, &hdr, sizeof(hdr), &bytes_written, NULL);
1339 ok(ret && bytes_written == sizeof(hdr), "Unexpected WriteFile() result, ret %#x, bytes_written %lu.\n",
1340 ret, bytes_written);
1341 ret = WriteFile(file, bmi, bmi_size, &bytes_written, NULL);
1342 ok(ret && bytes_written == bmi_size, "Unexpected WriteFile() result, ret %#x, bytes_written %lu.\n",
1343 ret, bytes_written);
1344 ret = WriteFile(file, bits, bits_size, &bytes_written, NULL);
1345 ok(ret && bytes_written == bits_size, "Unexpected WriteFile() result, ret %#x, bytes_written %lu.\n",
1346 ret, bytes_written);
1348}
1349
1351{
1352 DWORD bytes_written;
1353 HANDLE handle;
1354 BOOL ret;
1355 char path_icon[MAX_PATH];
1356 char path_image[MAX_PATH];
1357 static const test_icon_entries_t icon_desc = {32, 32};
1358
1359 sprintf(path_icon, "%s\\icon.ico", path);
1360 sprintf(path_image, "%s\\test.bmp", path);
1361
1362 /* Create Files */
1363 create_ico_file(path_icon, &icon_desc, 1);
1364
1366 ok(handle != INVALID_HANDLE_VALUE, "run %s: CreateFileA failed. %lu\n", path, GetLastError());
1367 ret = WriteFile(handle, bmpimage, sizeof(bmpimage), &bytes_written, NULL);
1368 ok(ret && bytes_written == sizeof(bmpimage), "run %s: Test file created improperly.\n", path);
1370
1371 /* Test cursor */
1372 handle = LoadImageA(NULL, "icon.ico", IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE);
1373 ok(handle != NULL, "run %s: LoadImage() failed.\n", path);
1374
1376 ok(ret, "run %s: DestroyIcon failed: %ld\n", path, GetLastError());
1377
1378 /* Test image */
1379 handle = LoadImageA(NULL, "test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
1380 ok(handle != NULL, "run %s: LoadImageA failed.\n", path);
1381
1383 ok(ret, "run %s: DeleteObject failed: %ld\n", path, GetLastError());
1384
1385 /* Cleanup */
1386 ret = DeleteFileA(path_image);
1387 ok(ret, "run %s: DeleteFileA failed: %ld\n", path, GetLastError());
1388 ret = DeleteFileA(path_icon);
1389 ok(ret, "run %s: DeleteFileA failed: %ld\n", path, GetLastError());
1390}
1391
1393{
1394 char old_working_dir[MAX_PATH];
1395 char temp_dir_current[MAX_PATH];
1396 char temp_dir_PATH[MAX_PATH];
1397 char executable_path[MAX_PATH];
1398 int pos_slash;
1399 char old_PATH[10000];
1400 char new_PATH[10000 + MAX_PATH];
1401 BOOL ret;
1402
1403 GetCurrentDirectoryA(ARRAY_SIZE(old_working_dir), old_working_dir);
1404
1405 GetTempPathA(ARRAY_SIZE(temp_dir_current), temp_dir_current);
1406 strcat(temp_dir_current, "wine-test-dir-current\\");
1407 GetTempPathA(ARRAY_SIZE(temp_dir_PATH), temp_dir_PATH);
1408 strcat(temp_dir_PATH, "wine-test-dir-path\\");
1409
1410 GetModuleFileNameA(NULL, executable_path, ARRAY_SIZE(executable_path));
1411 pos_slash = strrchr(executable_path, '\\') - executable_path;
1412 executable_path[pos_slash + 1] = 0;
1413
1414 CreateDirectoryA(temp_dir_current, NULL);
1415 CreateDirectoryA(temp_dir_PATH, NULL);
1416
1417 SetCurrentDirectoryA(temp_dir_current);
1418
1419 GetEnvironmentVariableA("PATH", old_PATH, ARRAY_SIZE(old_PATH));
1420 sprintf(new_PATH, "%s;%s", old_PATH, temp_dir_PATH);
1421 SetEnvironmentVariableA("PATH", new_PATH);
1422
1423 test_LoadImage_working_directory_run(temp_dir_current);
1424 test_LoadImage_working_directory_run(executable_path);
1426
1427 SetCurrentDirectoryA(old_working_dir);
1428 SetEnvironmentVariableA("PATH", old_PATH);
1429
1430 ret = RemoveDirectoryA(temp_dir_current);
1431 ok(ret, "RemoveDirectoryA failed: %ld\n", GetLastError());
1432 ret = RemoveDirectoryA(temp_dir_PATH);
1433 ok(ret, "RemoveDirectoryA failed: %ld\n", GetLastError());
1434}
1435
1436static void test_LoadImage(void)
1437{
1438 HANDLE handle;
1439 BOOL ret;
1440 DWORD error;
1441 BITMAPINFOHEADER *bitmap_header;
1442 ICONINFO icon_info;
1443 int i;
1444
1445#define ICON_WIDTH 32
1446#define ICON_HEIGHT 32
1447#define ICON_AND_SIZE (ICON_WIDTH*ICON_HEIGHT/8)
1448#define ICON_BPP 32
1449#define ICON_SIZE \
1450 (sizeof(CURSORICONFILEDIR) + sizeof(BITMAPINFOHEADER) \
1451 + ICON_AND_SIZE + ICON_AND_SIZE*ICON_BPP)
1452
1453 static const test_icon_entries_t icon_desc = {32, 32};
1454
1455 create_ico_file("icon.ico", &icon_desc, 1);
1456
1457 /* Test loading an icon as a cursor. */
1458 SetLastError(0xdeadbeef);
1459 handle = LoadImageA(NULL, "icon.ico", IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE);
1460 ok(handle != NULL, "LoadImage() failed.\n");
1461 error = GetLastError();
1462 ok(error == 0, "Last error: %lu\n", error);
1463
1464 /* Test the icon information. */
1465 SetLastError(0xdeadbeef);
1466 ret = GetIconInfo(handle, &icon_info);
1467 ok(ret, "GetIconInfo() failed.\n");
1468 error = GetLastError();
1469 ok(error == 0xdeadbeef, "Last error: %lu\n", error);
1470
1471 if (ret)
1472 {
1473 ok(icon_info.fIcon == FALSE, "fIcon != FALSE.\n");
1474 ok(icon_info.xHotspot == 1, "xHotspot is %lu.\n", icon_info.xHotspot);
1475 ok(icon_info.yHotspot == 1, "yHotspot is %lu.\n", icon_info.yHotspot);
1476 ok(icon_info.hbmColor != NULL, "No hbmColor!\n");
1477 ok(icon_info.hbmMask != NULL, "No hbmMask!\n");
1478 }
1479
1480 if (pGetIconInfoExA)
1481 {
1482 ICONINFOEXA infoex;
1483 infoex.cbSize = sizeof(infoex);
1484 ret = pGetIconInfoExA( handle, &infoex );
1485 ok( ret, "GetIconInfoEx failed err %ld\n", GetLastError() );
1486 ok( infoex.wResID == 0, "GetIconInfoEx wrong resid %x\n", infoex.wResID );
1487 ok( infoex.szModName[0] == 0, "GetIconInfoEx wrong module %s\n", infoex.szModName );
1488 ok( infoex.szResName[0] == 0, "GetIconInfoEx wrong name %s\n", infoex.szResName );
1489 }
1490 else win_skip( "GetIconInfoEx not available\n" );
1491
1492 /* Clean up. */
1493 SetLastError(0xdeadbeef);
1495 ok(ret, "DestroyCursor() failed.\n");
1496 error = GetLastError();
1497 ok(error == 0xdeadbeef, "Last error: %lu\n", error);
1498
1499 DeleteFileA("icon.ico");
1500
1501 /* Test a system icon */
1503 ok(handle != NULL, "LoadImage() failed.\n");
1504 if (pGetIconInfoExA)
1505 {
1506 ICONINFOEXA infoexA;
1507 ICONINFOEXW infoexW;
1508 infoexA.cbSize = sizeof(infoexA);
1509 ret = pGetIconInfoExA( handle, &infoexA );
1510 ok( ret, "GetIconInfoEx failed err %ld\n", GetLastError() );
1511 ok( infoexA.wResID == (UINT_PTR)IDI_HAND, "GetIconInfoEx wrong resid %x\n", infoexA.wResID );
1512 /* the A version is broken on 64-bit, it truncates the string after the first char */
1513 if (is_win64 && infoexA.szModName[0] && infoexA.szModName[1] == 0)
1514 trace( "GetIconInfoExA broken on Win64\n" );
1515 else
1516 ok( GetModuleHandleA(infoexA.szModName) == GetModuleHandleA("user32.dll"),
1517 "GetIconInfoEx wrong module %s\n", infoexA.szModName );
1518 ok( infoexA.szResName[0] == 0, "GetIconInfoEx wrong name %s\n", infoexA.szResName );
1519 infoexW.cbSize = sizeof(infoexW);
1520 ret = pGetIconInfoExW( handle, &infoexW );
1521 ok( ret, "GetIconInfoEx failed err %ld\n", GetLastError() );
1522 ok( infoexW.wResID == (UINT_PTR)IDI_HAND, "GetIconInfoEx wrong resid %x\n", infoexW.wResID );
1523 ok( GetModuleHandleW(infoexW.szModName) == GetModuleHandleA("user32.dll"),
1524 "GetIconInfoEx wrong module %s\n", wine_dbgstr_w(infoexW.szModName) );
1525 ok( infoexW.szResName[0] == 0, "GetIconInfoEx wrong name %s\n", wine_dbgstr_w(infoexW.szResName) );
1526 }
1527 SetLastError(0xdeadbeef);
1529
1530 test_LoadImageFile("BMP", bmpimage, sizeof(bmpimage), "bmp", 1);
1531 test_LoadImageFile("BMP (coreinfo)", bmpcoreimage, sizeof(bmpcoreimage), "bmp", 1);
1532 test_LoadImageFile("GIF", gifimage, sizeof(gifimage), "gif", 0);
1533 test_LoadImageFile("GIF (2x2 pixel)", gif4pixel, sizeof(gif4pixel), "gif", 0);
1534 test_LoadImageFile("JPG", jpgimage, sizeof(jpgimage), "jpg", 0);
1535 test_LoadImageFile("PNG", pngimage, sizeof(pngimage), "png", 0);
1536
1537 /* Check failure for broken BMP images */
1538 bitmap_header = (BITMAPINFOHEADER *)(bmpimage + sizeof(BITMAPFILEHEADER));
1539
1540 bitmap_header->biHeight = 65536;
1541 test_LoadImageFile("BMP (too high)", bmpimage, sizeof(bmpimage), "bmp", 0);
1542 bitmap_header->biHeight = 1;
1543
1544 bitmap_header->biWidth = 65536;
1545 test_LoadImageFile("BMP (too wide)", bmpimage, sizeof(bmpimage), "bmp", 0);
1546 bitmap_header->biWidth = 1;
1547
1548 for (i = 0; i < ARRAY_SIZE(biSize_tests); i++) {
1549 bitmap_header->biSize = biSize_tests[i];
1550 test_LoadImageFile("BMP (broken biSize)", bmpimage, sizeof(bmpimage), "bmp", 0);
1551 }
1552 bitmap_header->biSize = sizeof(BITMAPINFOHEADER);
1553
1554 test_LoadImageFile("Cursor (invalid dwDIBOffset)", invalid_dwDIBOffset, sizeof(invalid_dwDIBOffset), "cur", 0);
1555
1556 /* Test in which paths images with a relative path can be found */
1558}
1559
1561{
1562 char **res_name = (char **)param;
1563 *res_name = name;
1564 return FALSE;
1565}
1566
1568{
1569 HANDLE handle, old_handle;
1570 BOOL ret;
1571 DWORD error;
1572 BITMAPINFOHEADER *icon_header;
1573 INT16 *hotspot;
1574 ICONINFO icon_info;
1575 HMODULE user32;
1576 char *res_name;
1577 HRSRC rsrc;
1578 HGLOBAL res;
1579 BYTE *bits;
1580 UINT size;
1581
1582
1583#define ICON_RES_WIDTH 32
1584#define ICON_RES_HEIGHT 32
1585#define ICON_RES_AND_SIZE (ICON_WIDTH*ICON_HEIGHT/8)
1586#define ICON_RES_BPP 32
1587#define ICON_RES_SIZE \
1588 (sizeof(BITMAPINFOHEADER) + ICON_AND_SIZE + ICON_AND_SIZE*ICON_BPP)
1589#define CRSR_RES_SIZE (2*sizeof(INT16) + ICON_RES_SIZE)
1590
1591 /* Set icon data. */
1592 hotspot = calloc(1, CRSR_RES_SIZE);
1593
1594 /* Cursor resources have an extra hotspot, icon resources not. */
1595 hotspot[0] = 3;
1596 hotspot[1] = 3;
1597
1598 icon_header = (BITMAPINFOHEADER *) (hotspot + 2);
1599 icon_header->biSize = sizeof(BITMAPINFOHEADER);
1600 icon_header->biWidth = ICON_WIDTH;
1601 icon_header->biHeight = ICON_HEIGHT*2;
1602 icon_header->biPlanes = 1;
1603 icon_header->biBitCount = ICON_BPP;
1604 icon_header->biSizeImage = 0; /* Uncompressed bitmap. */
1605
1606 /* Test creating a cursor. */
1607 SetLastError(0xdeadbeef);
1608 handle = CreateIconFromResource((PBYTE) hotspot, CRSR_RES_SIZE, FALSE, 0x00030000);
1609 ok(handle != NULL, "Create cursor failed.\n");
1611 ok(ret, "Destroy cursor failed, error %lu.\n", GetLastError());
1612
1613 /* Test the icon information. */
1614 SetLastError(0xdeadbeef);
1615 ret = GetIconInfo(handle, &icon_info);
1616 ok(ret, "GetIconInfo() failed.\n");
1617 error = GetLastError();
1618 ok(error == 0xdeadbeef, "Last error: %lu\n", error);
1619
1620 if (ret)
1621 {
1622 ok(icon_info.fIcon == FALSE, "fIcon != FALSE.\n");
1623 ok(icon_info.xHotspot == 3, "xHotspot is %lu.\n", icon_info.xHotspot);
1624 ok(icon_info.yHotspot == 3, "yHotspot is %lu.\n", icon_info.yHotspot);
1625 ok(icon_info.hbmColor != NULL, "No hbmColor!\n");
1626 ok(icon_info.hbmMask != NULL, "No hbmMask!\n");
1627 }
1628
1629 if (pGetIconInfoExA)
1630 {
1631 ICONINFOEXA infoex;
1632 infoex.cbSize = sizeof(infoex);
1633 ret = pGetIconInfoExA( handle, &infoex );
1634 ok( ret, "GetIconInfoEx failed err %ld\n", GetLastError() );
1635 ok( infoex.wResID == 0, "GetIconInfoEx wrong resid %x\n", infoex.wResID );
1636 ok( infoex.szModName[0] == 0, "GetIconInfoEx wrong module %s\n", infoex.szModName );
1637 ok( infoex.szResName[0] == 0, "GetIconInfoEx wrong name %s\n", infoex.szResName );
1638 }
1639
1640 /* Test creating an icon. */
1641 SetLastError(0xdeadbeef);
1643 0x00030000);
1644 ok(handle != NULL, "Create icon failed.\n");
1646 ok(ret, "Destroy icon failed, error %lu.\n", GetLastError());
1647
1648 /* Test the icon information. */
1649 SetLastError(0xdeadbeef);
1650 ret = GetIconInfo(handle, &icon_info);
1651 ok(ret, "GetIconInfo() failed.\n");
1652 error = GetLastError();
1653 ok(error == 0xdeadbeef, "Last error: %lu\n", error);
1654
1655 if (ret)
1656 {
1657 ok(icon_info.fIcon == TRUE, "fIcon != TRUE.\n");
1658 /* Icons always have hotspot in the middle */
1659 ok(icon_info.xHotspot == ICON_WIDTH/2, "xHotspot is %lu.\n", icon_info.xHotspot);
1660 ok(icon_info.yHotspot == ICON_HEIGHT/2, "yHotspot is %lu.\n", icon_info.yHotspot);
1661 ok(icon_info.hbmColor != NULL, "No hbmColor!\n");
1662 ok(icon_info.hbmMask != NULL, "No hbmMask!\n");
1663 }
1664
1665 /* Rejection of NULL pointer crashes at least on WNT4WSSP6, W2KPROSP4, WXPPROSP3
1666 *
1667 * handle = CreateIconFromResource(NULL, ICON_RES_SIZE, TRUE, 0x00030000);
1668 * ok(handle == NULL, "Invalid pointer accepted (%p)\n", handle);
1669 */
1670
1671 /* Test creating an animated cursor. */
1672 empty_anicursor.frames[0].data.icon_info.idType = 2; /* type: cursor */
1676 ok(handle != NULL, "Create cursor failed.\n");
1678 ok(ret, "Destroy cursor failed, error %lu.\n", GetLastError());
1679
1680 /* Test the animated cursor's information. */
1681 SetLastError(0xdeadbeef);
1682 ret = GetIconInfo(handle, &icon_info);
1683 todo_wine
1684 ok(ret, "GetIconInfo() failed.\n");
1685 error = GetLastError();
1686 todo_wine
1687 ok(error == 0xdeadbeef, "Last error: %lu\n", error);
1688
1689 if (ret)
1690 {
1691 ok(icon_info.fIcon == FALSE, "fIcon != FALSE.\n");
1692 ok(icon_info.xHotspot == 3, "xHotspot is %lu.\n", icon_info.xHotspot);
1693 ok(icon_info.yHotspot == 3, "yHotspot is %lu.\n", icon_info.yHotspot);
1694 ok(icon_info.hbmColor != NULL, "No hbmColor!\n");
1695 ok(icon_info.hbmMask != NULL, "No hbmMask!\n");
1696 }
1697
1698 /* Test creating and destroying a non-shared icon. */
1699 handle = CreateIconFromResourceEx((BYTE *)icon_header, ICON_RES_SIZE, TRUE, 0x00030000,
1700 0, 0, LR_DEFAULTSIZE);
1701 ok(handle != NULL, "Create icon failed, error %lu.\n", GetLastError());
1703 ok(ret, "Destroy icon failed, error %lu.\n", GetLastError());
1704 ret = GetIconInfo(handle, &icon_info);
1705 ok(!ret, "Get info succeeded.\n");
1706 ok(GetLastError() == ERROR_INVALID_CURSOR_HANDLE, "Got unexpected error %lu.\n", error);
1707
1708 /* Test creating and destroying a shared icon from heap bits. */
1709 handle = CreateIconFromResourceEx((BYTE *)icon_header, ICON_RES_SIZE, TRUE, 0x00030000,
1710 0, 0, LR_DEFAULTSIZE | LR_SHARED);
1711 ok(handle != NULL, "Create icon failed, error %lu.\n", GetLastError());
1713 ok(ret, "Destroy icon failed, error %lu.\n", GetLastError());
1714 ret = GetIconInfo(handle, &icon_info);
1715 ok(ret, "Get info failed, error %lu.\n", GetLastError());
1716
1717 /* Test creating a shared icon from heap bits that has been created before. */
1718 old_handle = handle;
1719 handle = CreateIconFromResourceEx((BYTE *)icon_header, ICON_RES_SIZE, TRUE, 0x00030000,
1720 0, 0, LR_DEFAULTSIZE | LR_SHARED);
1721 ok(handle != NULL, "Create icon failed, error %lu.\n", GetLastError());
1722 ok(handle != old_handle, "Expect a different handle.\n");
1723
1724 free(hotspot);
1725
1726 /* Get icon resource bits */
1727 user32 = GetModuleHandleA("user32.dll");
1728 EnumResourceNamesA(user32, (const char *)RT_GROUP_ICON, find_res_proc, (LONG_PTR)&res_name);
1729 rsrc = FindResourceA(user32, res_name, (const char *)RT_GROUP_ICON);
1730 ok(rsrc != NULL, "Find resource failed, error %lu.\n", GetLastError());
1731 res = LoadResource(user32, rsrc);
1732 ok(res != NULL, "Load resource failed, error %lu.\n", GetLastError());
1734 ok(bits != NULL, "Lock resource failed, error %lu.\n", GetLastError());
1735
1737 rsrc = FindResourceA(user32, res_name, (const char *)RT_ICON);
1738 ok(rsrc != NULL, "Find resource failed, error %lu.\n", GetLastError());
1739 size = SizeofResource(user32, rsrc);
1740 ok(size != 0, "Get resource size failed, error %lu.\n", GetLastError());
1741 res = LoadResource(user32, rsrc);
1742 ok(res != NULL, "Load resource failed, error %lu.\n", GetLastError());
1744 ok(bits != NULL, "Lock resource failed, error %lu.\n", GetLastError());
1745
1746 /* Test creating and destroying a shared icon from resource bits. */
1748 ok(handle != NULL, "Create icon failed, error %lu\n", GetLastError());
1750 ok(ret, "Destroy icon failed, error %lu.\n", GetLastError());
1751 ret = GetIconInfo(handle, &icon_info);
1752 ok(ret, "Get info failed, error %lu.\n", GetLastError());
1753
1754 /* Test creating a shared icon from resource bits that has been created before. */
1755 old_handle = handle;
1757 ok(handle != NULL, "Create icon failed, error %lu.\n", GetLastError());
1758 ok(handle != old_handle, "Expect a different handle.\n");
1759}
1760
1761static int check_cursor_data( HDC hdc, HCURSOR hCursor, void *data, int length)
1762{
1763 char *image = NULL;
1765 ICONINFO iinfo;
1766 DWORD ret;
1767 int i;
1768
1769 ret = GetIconInfo( hCursor, &iinfo );
1770 ok(ret, "GetIconInfo() failed\n");
1771 if (!ret) return 0;
1772 ret = 0;
1773 info = malloc( FIELD_OFFSET( BITMAPINFO, bmiColors[256] ));
1774 ok(info != NULL, "malloc() failed\n");
1775 if (!info) return 0;
1776
1777 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1778 info->bmiHeader.biWidth = 32;
1779 info->bmiHeader.biHeight = 32;
1780 info->bmiHeader.biPlanes = 1;
1781 info->bmiHeader.biBitCount = 32;
1782 info->bmiHeader.biCompression = BI_RGB;
1783 info->bmiHeader.biSizeImage = 32 * 32 * 4;
1784 info->bmiHeader.biXPelsPerMeter = 0;
1785 info->bmiHeader.biYPelsPerMeter = 0;
1786 info->bmiHeader.biClrUsed = 0;
1787 info->bmiHeader.biClrImportant = 0;
1788 image = malloc( info->bmiHeader.biSizeImage );
1789 ok(image != NULL, "malloc() failed\n");
1790 if (!image) goto cleanup;
1791 ret = GetDIBits( hdc, iinfo.hbmColor, 0, 32, image, info, DIB_RGB_COLORS );
1792 ok(ret, "GetDIBits() failed\n");
1793 for (i = 0; ret && i < length / sizeof(COLORREF); i++)
1794 {
1795 ret = color_match( ((COLORREF *)data)[i], ((COLORREF *)image)[i] );
1796 ok(ret, "%04x: Expected 0x%lx, actually 0x%lx\n", i, ((COLORREF *)data)[i], ((COLORREF *)image)[i] );
1797 }
1798cleanup:
1799 free( image );
1800 free( info );
1801 return ret;
1802}
1803
1804static HCURSOR (WINAPI *pGetCursorFrameInfo)(HCURSOR hCursor, DWORD unk1, DWORD istep, DWORD *rate, DWORD *steps);
1806{
1807 DWORD frame_identifier[] = { 0x10Ad, 0xc001, 0x1c05 };
1808 HBITMAP bmp = NULL, bmpOld = NULL;
1809 DWORD rate, steps;
1810 BITMAPINFOHEADER *icon_header;
1811 BITMAPINFO bitmapInfo;
1812 HDC hdc = NULL;
1813 void *bits = 0;
1814 INT16 *hotspot;
1815 HANDLE h1, h2;
1816 BOOL ret;
1817 int i;
1818
1819 if (!pGetCursorFrameInfo)
1820 {
1821 win_skip( "GetCursorFrameInfo not supported, skipping tests.\n" );
1822 return;
1823 }
1824
1826 ok(hdc != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
1827 if (!hdc)
1828 return;
1829
1830 memset(&bitmapInfo, 0, sizeof(bitmapInfo));
1831 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1832 bitmapInfo.bmiHeader.biWidth = 3;
1833 bitmapInfo.bmiHeader.biHeight = 3;
1834 bitmapInfo.bmiHeader.biBitCount = 32;
1835 bitmapInfo.bmiHeader.biPlanes = 1;
1836 bitmapInfo.bmiHeader.biCompression = BI_RGB;
1837 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
1838 bmp = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, &bits, NULL, 0);
1839 ok (bmp && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
1840 if (!bmp || !bits)
1841 goto cleanup;
1842 bmpOld = SelectObject(hdc, bmp);
1843
1844#define ICON_RES_WIDTH 32
1845#define ICON_RES_HEIGHT 32
1846#define ICON_RES_AND_SIZE (ICON_WIDTH*ICON_HEIGHT/8)
1847#define ICON_RES_BPP 32
1848#define ICON_RES_SIZE \
1849 (sizeof(BITMAPINFOHEADER) + ICON_AND_SIZE + ICON_AND_SIZE*ICON_BPP)
1850#define CRSR_RES_SIZE (2*sizeof(INT16) + ICON_RES_SIZE)
1851
1852 /* Set icon data. */
1853 hotspot = calloc(1, CRSR_RES_SIZE);
1854
1855 /* Cursor resources have an extra hotspot, icon resources not. */
1856 hotspot[0] = 3;
1857 hotspot[1] = 3;
1858
1859 icon_header = (BITMAPINFOHEADER *) (hotspot + 2);
1860 icon_header->biSize = sizeof(BITMAPINFOHEADER);
1861 icon_header->biWidth = ICON_WIDTH;
1862 icon_header->biHeight = ICON_HEIGHT*2;
1863 icon_header->biPlanes = 1;
1864 icon_header->biBitCount = ICON_BPP;
1865 icon_header->biSizeImage = 0; /* Uncompressed bitmap. */
1866
1867 /* Creating a static cursor. */
1868 SetLastError(0xdeadbeef);
1869 h1 = CreateIconFromResource((PBYTE) hotspot, CRSR_RES_SIZE, FALSE, 0x00030000);
1870 ok(h1 != NULL, "Create cursor failed (error = %ld).\n", GetLastError());
1871
1872 /* Check GetCursorFrameInfo behavior on a static cursor */
1873 rate = steps = 0xdead;
1874 h2 = pGetCursorFrameInfo(h1, 0xdead, 0xdead, &rate, &steps);
1875 ok(h1 == h2, "GetCursorFrameInfo() failed: (%p != %p).\n", h1, h2);
1876 ok(rate == 0, "GetCursorFrameInfo() unexpected param 4 value (0x%lx != 0x0).\n", rate);
1877 ok(steps == 1, "GetCursorFrameInfo() unexpected param 5 value (%ld != 1).\n", steps);
1878
1879 /* Clean up static cursor. */
1880 SetLastError(0xdeadbeef);
1881 ret = DestroyCursor(h1);
1882 ok(ret, "DestroyCursor() failed (error = %ld).\n", GetLastError());
1883
1884 /* Creating a single-frame animated cursor. */
1885 empty_anicursor.frames[0].data.icon_info.idType = 2; /* type: cursor */
1888 memcpy( &empty_anicursor.frames[0].data.bmi_data.data[0], &frame_identifier[0], sizeof(DWORD) );
1889 SetLastError(0xdeadbeef);
1890 h1 = CreateIconFromResource((PBYTE) &empty_anicursor, sizeof(empty_anicursor), FALSE, 0x00030000);
1891 ok(h1 != NULL, "Create cursor failed (error = %ld).\n", GetLastError());
1892
1893 /* Check GetCursorFrameInfo behavior on a single-frame animated cursor */
1894 rate = steps = 0xdead;
1895 h2 = pGetCursorFrameInfo(h1, 0xdead, 0, &rate, &steps);
1896 ok(h1 == h2, "GetCursorFrameInfo() failed: (%p != %p).\n", h1, h2);
1897 ret = check_cursor_data( hdc, h2, &frame_identifier[0], sizeof(DWORD) );
1898 ok(ret, "GetCursorFrameInfo() returned wrong cursor data for frame 0.\n");
1899 ok(rate == 0x0, "GetCursorFrameInfo() unexpected param 4 value (0x%lx != 0x0).\n", rate);
1901 "GetCursorFrameInfo() unexpected param 5 value (%ld != 1).\n", steps);
1902
1903 /* Clean up single-frame animated cursor. */
1904 SetLastError(0xdeadbeef);
1905 ret = DestroyCursor(h1);
1906 ok(ret, "DestroyCursor() failed (error = %ld).\n", GetLastError());
1907
1908 /* Creating a multi-frame animated cursor. */
1910 {
1911 empty_anicursor3.frames[i].data.icon_info.idType = 2; /* type: cursor */
1914 memcpy( &empty_anicursor3.frames[i].data.bmi_data.data[0], &frame_identifier[i], sizeof(DWORD) );
1915 }
1916 SetLastError(0xdeadbeef);
1918 ok(h1 != NULL, "Create cursor failed (error = %ld).\n", GetLastError());
1919
1920 /* Check number of steps in multi-frame animated cursor */
1921 i=0;
1922 while (DrawIconEx(hdc, 0, 0, h1, 32, 32, i, NULL, DI_NORMAL))
1923 i++;
1925 "Unexpected number of steps in cursor (%d != %ld)\n",
1927
1928 /* Check GetCursorFrameInfo behavior on a multi-frame animated cursor */
1930 {
1931 rate = steps = 0xdead;
1932 h2 = pGetCursorFrameInfo(h1, 0xdead, i, &rate, &steps);
1933 ok(h1 != h2 && h2 != 0, "GetCursorFrameInfo() failed for cursor %p: (%p, %p).\n", h1, h1, h2);
1934 ret = check_cursor_data( hdc, h2, &frame_identifier[i], sizeof(DWORD) );
1935 ok(ret, "GetCursorFrameInfo() returned wrong cursor data for frame %d.\n", i);
1937 "GetCursorFrameInfo() unexpected param 4 value (0x%lx != 0x%lx).\n",
1940 "GetCursorFrameInfo() unexpected param 5 value (%ld != %ld).\n",
1942 }
1943
1944 /* Check GetCursorFrameInfo behavior on rate 3 of a multi-frame animated cursor */
1945 rate = steps = 0xdead;
1946 h2 = pGetCursorFrameInfo(h1, 0xdead, 3, &rate, &steps);
1947 ok(h2 == 0, "GetCursorFrameInfo() failed for cursor %p: (%p != 0).\n", h1, h2);
1948 ok(rate == 0xdead, "GetCursorFrameInfo() unexpected param 4 value (0x%lx != 0xdead).\n", rate);
1949 ok(steps == 0xdead, "GetCursorFrameInfo() unexpected param 5 value (0x%lx != 0xdead).\n", steps);
1950
1951 /* Clean up multi-frame animated cursor. */
1952 SetLastError(0xdeadbeef);
1953 ret = DestroyCursor(h1);
1954 ok(ret, "DestroyCursor() failed (error = %ld).\n", GetLastError());
1955
1956 /* Create a multi-frame animated cursor with num_steps == 1 */
1958 SetLastError(0xdeadbeef);
1960 ok(h1 != NULL, "Create cursor failed (error = %ld).\n", GetLastError());
1961
1962 /* Check number of steps in multi-frame animated cursor (mismatch between steps and frames) */
1963 i=0;
1964 while (DrawIconEx(hdc, 0, 0, h1, 32, 32, i, NULL, DI_NORMAL))
1965 i++;
1967 "Unexpected number of steps in cursor (%d != %ld)\n",
1969
1970 /* Check GetCursorFrameInfo behavior on rate 0 for a multi-frame animated cursor (with num_steps == 1) */
1971 rate = steps = 0xdead;
1972 h2 = pGetCursorFrameInfo(h1, 0xdead, 0, &rate, &steps);
1973 ok(h1 != h2 && h2 != 0, "GetCursorFrameInfo() failed for cursor %p: (%p, %p).\n", h1, h1, h2);
1974 ret = check_cursor_data( hdc, h2, &frame_identifier[0], sizeof(DWORD) );
1975 ok(ret, "GetCursorFrameInfo() returned wrong cursor data for frame 0.\n");
1977 "GetCursorFrameInfo() unexpected param 4 value (0x%lx != 0x%lx).\n",
1979 todo_wine
1981 "GetCursorFrameInfo() unexpected param 5 value (%ld != ~0).\n", steps);
1982
1983 /* Check GetCursorFrameInfo behavior on rate 1 for a multi-frame animated cursor (with num_steps == 1) */
1984 rate = steps = 0xdead;
1985 h2 = pGetCursorFrameInfo(h1, 0xdead, 1, &rate, &steps);
1986 ok(h2 == 0, "GetCursorFrameInfo() failed for cursor %p: (%p != 0).\n", h1, h2);
1987 ok(rate == 0xdead, "GetCursorFrameInfo() unexpected param 4 value (0x%lx != 0xdead).\n", rate);
1988 ok(steps == 0xdead, "GetCursorFrameInfo() unexpected param 5 value (%ld != 0xdead).\n", steps);
1989
1990 /* Clean up multi-frame animated cursor. */
1991 SetLastError(0xdeadbeef);
1992 ret = DestroyCursor(h1);
1993 ok(ret, "DestroyCursor() failed (error = %ld).\n", GetLastError());
1994
1995 /* Creating a multi-frame animated cursor with rate data. */
1997 {
1998 empty_anicursor3_seq.frames[i].data.icon_info.idType = 2; /* type: cursor */
2001 memcpy( &empty_anicursor3_seq.frames[i].data.bmi_data.data[0], &frame_identifier[i], sizeof(DWORD) );
2002 }
2003 SetLastError(0xdeadbeef);
2005 ok(h1 != NULL, "Create cursor failed (error = %lx).\n", GetLastError());
2006
2007 /* Check number of steps in multi-frame animated cursor with rate data */
2008 i=0;
2009 while (DrawIconEx(hdc, 0, 0, h1, 32, 32, i, NULL, DI_NORMAL))
2010 i++;
2012 "Unexpected number of steps in cursor (%d != %ld)\n",
2014
2015 /* Check GetCursorFrameInfo behavior on a multi-frame animated cursor with rate data */
2017 {
2018 int frame_id = empty_anicursor3_seq.seq.order[i];
2019
2020 rate = steps = 0xdead;
2021 h2 = pGetCursorFrameInfo(h1, 0xdead, i, &rate, &steps);
2022 ok(h1 != h2 && h2 != 0, "GetCursorFrameInfo() failed for cursor %p: (%p, %p).\n", h1, h1, h2);
2023 ret = check_cursor_data( hdc, h2, &frame_identifier[frame_id], sizeof(DWORD) );
2024 ok(ret, "GetCursorFrameInfo() returned wrong cursor data for frame %d.\n", i);
2026 "GetCursorFrameInfo() unexpected param 4 value (0x%lx != 0x%lx).\n",
2029 "GetCursorFrameInfo() unexpected param 5 value (%ld != %ld).\n",
2031 }
2032
2033 /* Clean up multi-frame animated cursor with rate data. */
2034 SetLastError(0xdeadbeef);
2035 ret = DestroyCursor(h1);
2036 ok(ret, "DestroyCursor() failed (error = %ld).\n", GetLastError());
2037
2038 free(hotspot);
2039cleanup:
2040 if(bmpOld) SelectObject(hdc, bmpOld);
2041 if(bmp) DeleteObject(bmp);
2042 if(hdc) DeleteDC(hdc);
2043}
2044
2046 BOOL maskvalue, UINT32 *color, int colorSize)
2047{
2048 ICONINFO iconInfo;
2049 BITMAPINFO bitmapInfo;
2050 void *buffer = NULL;
2051 UINT32 mask = maskvalue ? 0xFFFFFFFF : 0x00000000;
2052
2053 memset(&bitmapInfo, 0, sizeof(bitmapInfo));
2054 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2055 bitmapInfo.bmiHeader.biWidth = width;
2056 bitmapInfo.bmiHeader.biHeight = height;
2057 bitmapInfo.bmiHeader.biPlanes = 1;
2058 bitmapInfo.bmiHeader.biBitCount = bpp;
2059 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2060 bitmapInfo.bmiHeader.biSizeImage = colorSize;
2061
2062 iconInfo.fIcon = TRUE;
2063 iconInfo.xHotspot = 0;
2064 iconInfo.yHotspot = 0;
2065
2066 iconInfo.hbmMask = CreateBitmap( width, height, 1, 1, &mask );
2067 if(!iconInfo.hbmMask) return NULL;
2068
2069 iconInfo.hbmColor = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, &buffer, NULL, 0);
2070 if(!iconInfo.hbmColor || !buffer)
2071 {
2072 DeleteObject(iconInfo.hbmMask);
2073 return NULL;
2074 }
2075
2076 memcpy(buffer, color, colorSize);
2077
2078 return CreateIconIndirect(&iconInfo);
2079}
2080
2081static void check_alpha_draw(HDC hdc, BOOL drawiconex, BOOL alpha, int bpp, int line)
2082{
2083 HICON hicon;
2084 UINT32 color[2];
2085 COLORREF modern_expected, legacy_expected, result;
2086
2087 color[0] = 0x00A0B0C0;
2088 color[1] = alpha ? 0xFF000000 : 0x00000000;
2089 modern_expected = alpha ? 0x00FFFFFF : 0x00C0B0A0;
2090 legacy_expected = 0x00C0B0A0;
2091
2092 hicon = create_test_icon(hdc, 2, 1, bpp, 0, color, sizeof(color));
2093 if (!hicon) return;
2094
2095 SetPixelV(hdc, 0, 0, 0x00FFFFFF);
2096
2097 if(drawiconex)
2098 DrawIconEx(hdc, 0, 0, hicon, 2, 1, 0, NULL, DI_NORMAL);
2099 else
2100 DrawIcon(hdc, 0, 0, hicon);
2101
2102 result = GetPixel(hdc, 0, 0);
2103 ok (color_match(result, modern_expected),
2104 "%s. Expected a close match to %06lX (modern) or %06lX (legacy) with %s. "
2105 "Got %06lX from line %d\n",
2106 alpha ? "Alpha blending" : "Not alpha blending", modern_expected, legacy_expected,
2107 drawiconex ? "DrawIconEx" : "DrawIcon", result, line);
2108}
2109
2110static void check_DrawIcon(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, COLORREF background,
2111 COLORREF modern_expected, COLORREF legacy_expected, int line)
2112{
2114 HICON hicon = create_test_icon(hdc, 1, 1, bpp, maskvalue, &color, sizeof(color));
2115 if (!hicon) return;
2116 SetPixelV(hdc, 0, 0, background);
2119 DrawIcon(hdc, 0, 0, hicon);
2120 result = GetPixel(hdc, 0, 0);
2121
2122 ok (color_match(result, modern_expected),
2123 "Overlaying Mask %d on Color %06X with DrawIcon. "
2124 "Expected a close match to %06lX (modern), or %06lX (legacy). Got %06lX from line %d\n",
2125 maskvalue, color, modern_expected, legacy_expected, result, line);
2126
2128
2129 ok (color_match(result, modern_expected),
2130 "Overlaying Mask %d on Color %06X with DrawIcon. "
2131 "Expected a close match to %06lX (modern), or %06lX (legacy). Got %06lX from line %d\n",
2132 maskvalue, color, modern_expected, legacy_expected, result, line);
2133
2135
2136 ok (color_match(result, background),
2137 "Overlaying Mask %d on Color %06X with DrawIcon. "
2138 "Expected unchanged background color %06lX. Got %06lX from line %d\n",
2139 maskvalue, color, background, result, line);
2140}
2141
2142static void test_DrawIcon(void)
2143{
2144 BITMAPINFO bitmapInfo;
2145 HDC hdcDst = NULL;
2146 HBITMAP bmpDst = NULL;
2147 HBITMAP bmpOld = NULL;
2148 void *bits = 0;
2149
2151 ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
2152 if (!hdcDst)
2153 return;
2154
2155 if(GetDeviceCaps(hdcDst, BITSPIXEL) <= 8)
2156 {
2157 skip("Windows will distort DrawIcon colors at 8-bpp and less due to palettizing.\n");
2158 goto cleanup;
2159 }
2160
2161 memset(&bitmapInfo, 0, sizeof(bitmapInfo));
2162 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2165 bitmapInfo.bmiHeader.biBitCount = 32;
2166 bitmapInfo.bmiHeader.biPlanes = 1;
2167 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2168 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2169
2170 bmpDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, &bits, NULL, 0);
2171 ok (bmpDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
2172 if (!bmpDst || !bits)
2173 goto cleanup;
2174 bmpOld = SelectObject(hdcDst, bmpDst);
2175
2176 /* Mask is only heeded if alpha channel is always zero */
2177 check_DrawIcon(hdcDst, FALSE, 0x00A0B0C0, 32, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__);
2178 check_DrawIcon(hdcDst, TRUE, 0x00A0B0C0, 32, 0x00FFFFFF, 0x003F4F5F, 0x003F4F5F, __LINE__);
2179
2180 /* Test alpha blending */
2181 /* Windows 2000 and up will alpha blend, earlier Windows versions will not */
2182 check_DrawIcon(hdcDst, FALSE, 0xFFA0B0C0, 32, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__);
2183 check_DrawIcon(hdcDst, TRUE, 0xFFA0B0C0, 32, 0x00FFFFFF, 0x00C0B0A0, 0x003F4F5F, __LINE__);
2184
2185 check_DrawIcon(hdcDst, FALSE, 0x80A0B0C0, 32, 0x00000000, 0x00605850, 0x00C0B0A0, __LINE__);
2186 check_DrawIcon(hdcDst, TRUE, 0x80A0B0C0, 32, 0x00000000, 0x00605850, 0x00C0B0A0, __LINE__);
2187 check_DrawIcon(hdcDst, FALSE, 0x80A0B0C0, 32, 0x00FFFFFF, 0x00DFD7CF, 0x00C0B0A0, __LINE__);
2188 check_DrawIcon(hdcDst, TRUE, 0x80A0B0C0, 32, 0x00FFFFFF, 0x00DFD7CF, 0x003F4F5F, __LINE__);
2189
2190 check_DrawIcon(hdcDst, FALSE, 0x01FFFFFF, 32, 0x00000000, 0x00010101, 0x00FFFFFF, __LINE__);
2191 check_DrawIcon(hdcDst, TRUE, 0x01FFFFFF, 32, 0x00000000, 0x00010101, 0x00FFFFFF, __LINE__);
2192
2193 /* Test detecting of alpha channel */
2194 /* If a single pixel's alpha channel is non-zero, the icon
2195 will be alpha blended, otherwise it will be draw with
2196 and + xor blts. */
2197 check_alpha_draw(hdcDst, FALSE, FALSE, 32, __LINE__);
2198 check_alpha_draw(hdcDst, FALSE, TRUE, 32, __LINE__);
2199
2200cleanup:
2201 if(bmpOld)
2202 SelectObject(hdcDst, bmpOld);
2203 if(bmpDst)
2204 DeleteObject(bmpDst);
2205 if(hdcDst)
2207}
2208
2209static void check_DrawIconEx(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, UINT flags, COLORREF background,
2210 COLORREF modern_expected, COLORREF legacy_expected, int line)
2211{
2213 HICON hicon = create_test_icon(hdc, 1, 1, bpp, maskvalue, &color, sizeof(color));
2214 if (!hicon) return;
2215 SetPixelV(hdc, 0, 0, background);
2216 DrawIconEx(hdc, 0, 0, hicon, 1, 1, 0, NULL, flags);
2217 result = GetPixel(hdc, 0, 0);
2218
2219 ok (color_match(result, modern_expected),
2220 "Overlaying Mask %d on Color %06X with DrawIconEx flags %08X. "
2221 "Expected a close match to %06lX (modern) or %06lX (legacy). Got %06lX from line %d\n",
2222 maskvalue, color, flags, modern_expected, legacy_expected, result, line);
2223}
2224
2225static void test_DrawIconEx(void)
2226{
2227 BITMAPINFO bitmapInfo;
2228 HDC hdcDst = NULL;
2229 HBITMAP bmpDst = NULL;
2230 HBITMAP bmpOld = NULL;
2231 void *bits = 0;
2232
2234 ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
2235 if (!hdcDst)
2236 return;
2237
2238 if(GetDeviceCaps(hdcDst, BITSPIXEL) <= 8)
2239 {
2240 skip("Windows will distort DrawIconEx colors at 8-bpp and less due to palettizing.\n");
2241 goto cleanup;
2242 }
2243
2244 memset(&bitmapInfo, 0, sizeof(bitmapInfo));
2245 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2246 bitmapInfo.bmiHeader.biWidth = 1;
2247 bitmapInfo.bmiHeader.biHeight = 1;
2248 bitmapInfo.bmiHeader.biBitCount = 32;
2249 bitmapInfo.bmiHeader.biPlanes = 1;
2250 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2251 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2252 bmpDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, &bits, NULL, 0);
2253 ok (bmpDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
2254 if (!bmpDst || !bits)
2255 goto cleanup;
2256 bmpOld = SelectObject(hdcDst, bmpDst);
2257
2258 /* Test null, image only, and mask only drawing */
2259 check_DrawIconEx(hdcDst, FALSE, 0x00A0B0C0, 32, 0, 0x00102030, 0x00102030, 0x00102030, __LINE__);
2260 check_DrawIconEx(hdcDst, TRUE, 0x00A0B0C0, 32, 0, 0x00102030, 0x00102030, 0x00102030, __LINE__);
2261
2262 check_DrawIconEx(hdcDst, FALSE, 0x80A0B0C0, 32, DI_MASK, 0x00123456, 0x00000000, 0x00000000, __LINE__);
2263 check_DrawIconEx(hdcDst, TRUE, 0x80A0B0C0, 32, DI_MASK, 0x00123456, 0x00FFFFFF, 0x00FFFFFF, __LINE__);
2264
2265 check_DrawIconEx(hdcDst, FALSE, 0x00A0B0C0, 32, DI_IMAGE, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__);
2266 check_DrawIconEx(hdcDst, TRUE, 0x00A0B0C0, 32, DI_IMAGE, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__);
2267
2268 /* Test normal drawing */
2269 check_DrawIconEx(hdcDst, FALSE, 0x00A0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__);
2270 check_DrawIconEx(hdcDst, TRUE, 0x00A0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x003F4F5F, 0x003F4F5F, __LINE__);
2271 check_DrawIconEx(hdcDst, FALSE, 0xFFA0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__);
2272
2273 /* Test alpha blending */
2274 /* Windows 2000 and up will alpha blend, earlier Windows versions will not */
2275 check_DrawIconEx(hdcDst, TRUE, 0xFFA0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00C0B0A0, 0x003F4F5F, __LINE__);
2276
2277 check_DrawIconEx(hdcDst, FALSE, 0x80A0B0C0, 32, DI_NORMAL, 0x00000000, 0x00605850, 0x00C0B0A0, __LINE__);
2278 check_DrawIconEx(hdcDst, TRUE, 0x80A0B0C0, 32, DI_NORMAL, 0x00000000, 0x00605850, 0x00C0B0A0, __LINE__);
2279 check_DrawIconEx(hdcDst, FALSE, 0x80A0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00DFD7CF, 0x00C0B0A0, __LINE__);
2280 check_DrawIconEx(hdcDst, TRUE, 0x80A0B0C0, 32, DI_NORMAL, 0x00FFFFFF, 0x00DFD7CF, 0x003F4F5F, __LINE__);
2281
2282 check_DrawIconEx(hdcDst, FALSE, 0x01FFFFFF, 32, DI_NORMAL, 0x00000000, 0x00010101, 0x00FFFFFF, __LINE__);
2283 check_DrawIconEx(hdcDst, TRUE, 0x01FFFFFF, 32, DI_NORMAL, 0x00000000, 0x00010101, 0x00FFFFFF, __LINE__);
2284
2285 /* Test detecting of alpha channel */
2286 /* If a single pixel's alpha channel is non-zero, the icon
2287 will be alpha blended, otherwise it will be draw with
2288 and + xor blts. */
2289 check_alpha_draw(hdcDst, TRUE, FALSE, 32, __LINE__);
2290 check_alpha_draw(hdcDst, TRUE, TRUE, 32, __LINE__);
2291
2292cleanup:
2293 if(bmpOld)
2294 SelectObject(hdcDst, bmpOld);
2295 if(bmpDst)
2296 DeleteObject(bmpDst);
2297 if(hdcDst)
2299}
2300
2301static void check_DrawState_Size(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, HBRUSH hbr, UINT flags, int line)
2302{
2303 COLORREF result, background;
2304 BOOL passed[2];
2305 HICON hicon = create_test_icon(hdc, 1, 1, bpp, maskvalue, &color, sizeof(color));
2306 background = 0x00FFFFFF;
2307 /* Set color of the 2 pixels that will be checked afterwards */
2308 SetPixelV(hdc, 0, 0, background);
2309 SetPixelV(hdc, 2, 2, background);
2310
2311 /* Let DrawState calculate the size of the icon (it's 1x1) */
2312 DrawStateA(hdc, hbr, NULL, (LPARAM) hicon, 0, 1, 1, 0, 0, (DST_ICON | flags ));
2313
2314 result = GetPixel(hdc, 0, 0);
2315 passed[0] = color_match(result, background);
2316 result = GetPixel(hdc, 2, 2);
2317 passed[0] = passed[0] & color_match(result, background);
2318
2319 /* Check if manually specifying the icon size DOESN'T work */
2320
2321 /* IMPORTANT: For Icons, DrawState wants the size of the source image, not the
2322 * size in which it should be ultimately drawn. Therefore giving
2323 * width/height 2x2 if the icon is only 1x1 pixels in size should
2324 * result in drawing it with size 1x1. The size parameters must be
2325 * ignored if a Icon has to be drawn! */
2326 DrawStateA(hdc, hbr, NULL, (LPARAM) hicon, 0, 1, 1, 2, 2, (DST_ICON | flags ));
2327
2328 result = GetPixel(hdc, 0, 0);
2329 passed[1] = color_match(result, background);
2330 result = GetPixel(hdc, 2, 2);
2331 passed[1] = passed[0] & color_match(result, background);
2332
2333 if(!passed[0]&&!passed[1])
2334 ok (passed[1],
2335 "DrawState failed to draw a 1x1 Icon in the correct size, independent of the "
2336 "width and height settings passed to it, for Icon with: Overlaying Mask %d on "
2337 "Color %06X with flags %08X. Line %d\n",
2338 maskvalue, color, (DST_ICON | flags), line);
2339 else if(!passed[1])
2340 ok (passed[1],
2341 "DrawState failed to draw a 1x1 Icon in the correct size, if the width and height "
2342 "parameters passed to it are bigger than the real Icon size, for Icon with: Overlaying "
2343 "Mask %d on Color %06X with flags %08X. Line %d\n",
2344 maskvalue, color, (DST_ICON | flags), line);
2345 else
2346 ok (passed[0],
2347 "DrawState failed to draw a 1x1 Icon in the correct size, if the width and height "
2348 "parameters passed to it are 0, for Icon with: Overlaying Mask %d on "
2349 "Color %06X with flags %08X. Line %d\n",
2350 maskvalue, color, (DST_ICON | flags), line);
2351}
2352
2353static void check_DrawState_Color(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, HBRUSH hbr, UINT flags,
2354 COLORREF background, COLORREF modern_expected, COLORREF legacy_expected, int line)
2355{
2357 HICON hicon = create_test_icon(hdc, 1, 1, bpp, maskvalue, &color, sizeof(color));
2358 if (!hicon) return;
2359 /* Set color of the pixel that will be checked afterwards */
2360 SetPixelV(hdc, 1, 1, background);
2361
2362 DrawStateA(hdc, hbr, NULL, (LPARAM) hicon, 0, 1, 1, 0, 0, ( DST_ICON | flags ));
2363
2364 /* Check the color of the pixel is correct */
2365 result = GetPixel(hdc, 1, 1);
2366
2367 ok (color_match(result, modern_expected),
2368 "DrawState drawing Icon with Overlaying Mask %d on Color %06X with flags %08X. "
2369 "Expected a close match to %06lX (modern) or %06lX (legacy). Got %06lX from line %d\n",
2370 maskvalue, color, (DST_ICON | flags), modern_expected, legacy_expected, result, line);
2371}
2372
2373static void test_DrawState(void)
2374{
2375 BITMAPINFO bitmapInfo;
2376 HDC hdcDst = NULL;
2377 HBITMAP bmpDst = NULL;
2378 HBITMAP bmpOld = NULL;
2379 void *bits = 0;
2380
2382 ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
2383 if (!hdcDst)
2384 return;
2385
2386 if(GetDeviceCaps(hdcDst, BITSPIXEL) <= 8)
2387 {
2388 skip("Windows will distort DrawIconEx colors at 8-bpp and less due to palettizing.\n");
2389 goto cleanup;
2390 }
2391
2392 memset(&bitmapInfo, 0, sizeof(bitmapInfo));
2393 bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2394 bitmapInfo.bmiHeader.biWidth = 3;
2395 bitmapInfo.bmiHeader.biHeight = 3;
2396 bitmapInfo.bmiHeader.biBitCount = 32;
2397 bitmapInfo.bmiHeader.biPlanes = 1;
2398 bitmapInfo.bmiHeader.biCompression = BI_RGB;
2399 bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2400 bmpDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, &bits, NULL, 0);
2401 ok (bmpDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
2402 if (!bmpDst || !bits)
2403 goto cleanup;
2404 bmpOld = SelectObject(hdcDst, bmpDst);
2405
2406 /* potential flags to test with DrawState are: */
2407 /* DSS_DISABLED embosses the icon */
2408 /* DSS_MONO draw Icon using a brush as parameter 5 */
2409 /* DSS_NORMAL draw Icon without any modifications */
2410 /* DSS_UNION draw the Icon dithered */
2411
2412 check_DrawState_Size(hdcDst, FALSE, 0x00A0B0C0, 32, 0, DSS_NORMAL, __LINE__);
2413 check_DrawState_Color(hdcDst, FALSE, 0x00A0B0C0, 32, 0, DSS_NORMAL, 0x00FFFFFF, 0x00C0B0A0, 0x00C0B0A0, __LINE__);
2414
2415cleanup:
2416 if(bmpOld)
2417 SelectObject(hdcDst, bmpOld);
2418 if(bmpDst)
2419 DeleteObject(bmpDst);
2420 if(hdcDst)
2422}
2423
2425
2427{
2428 HCURSOR ret;
2429
2430 PeekMessageA( 0, 0, 0, 0, PM_NOREMOVE ); /* create a msg queue */
2431 if (parent_id)
2432 {
2434 ok( ret, "AttachThreadInput failed\n" );
2435 }
2436 if (arg) ret = SetCursor( (HCURSOR)arg );
2437 else ret = GetCursor();
2438 return (DWORD_PTR)ret;
2439}
2440
2441static void test_SetCursor(void)
2442{
2443 static const BYTE bmp_bits[4096];
2444 ICONINFO cursorInfo;
2445 HCURSOR cursor, old_cursor, global_cursor = 0;
2446 DWORD error, id, result;
2447 UINT display_bpp;
2448 HDC hdc;
2449 HANDLE thread;
2451
2452 if (pGetCursorInfo)
2453 {
2454 memset( &info, 0, sizeof(info) );
2455 info.cbSize = sizeof(info);
2456 if (!pGetCursorInfo( &info ))
2457 {
2458 win_skip( "GetCursorInfo not working\n" );
2459 pGetCursorInfo = NULL;
2460 }
2461 else global_cursor = info.hCursor;
2462 }
2463 cursor = GetCursor();
2464 thread = CreateThread( NULL, 0, set_cursor_thread, 0, 0, &id );
2465 WaitForSingleObject( thread, 1000 );
2467 ok( result == (DWORD_PTR)cursor, "wrong thread cursor %lx/%p\n", result, cursor );
2468
2469 hdc = GetDC(0);
2470 display_bpp = GetDeviceCaps(hdc, BITSPIXEL);
2471 ReleaseDC(0, hdc);
2472
2473 cursorInfo.fIcon = FALSE;
2474 cursorInfo.xHotspot = 0;
2475 cursorInfo.yHotspot = 0;
2476 cursorInfo.hbmMask = CreateBitmap(32, 32, 1, 1, bmp_bits);
2477 cursorInfo.hbmColor = CreateBitmap(32, 32, 1, display_bpp, bmp_bits);
2478
2479 cursor = CreateIconIndirect(&cursorInfo);
2480 ok(cursor != NULL, "CreateIconIndirect returned %p\n", cursor);
2481 old_cursor = SetCursor( cursor );
2482
2483 if (pGetCursorInfo)
2484 {
2485 info.cbSize = sizeof(info);
2486 ok( pGetCursorInfo( &info ), "GetCursorInfo failed\n" );
2487 /* global cursor doesn't change since we don't have a window */
2488 ok( info.hCursor == global_cursor, "expected global cursor %p\n", global_cursor );
2489 }
2490 thread = CreateThread( NULL, 0, set_cursor_thread, 0, 0, &id );
2491 WaitForSingleObject( thread, 1000 );
2493 ok( result == (DWORD_PTR)old_cursor, "wrong thread cursor %lx/%p\n", result, old_cursor );
2494
2495 SetCursor( 0 );
2496 ok( GetCursor() == 0, "wrong cursor %p\n", GetCursor() );
2497 thread = CreateThread( NULL, 0, set_cursor_thread, 0, 0, &id );
2498 WaitForSingleObject( thread, 1000 );
2500 ok( result == (DWORD_PTR)old_cursor, "wrong thread cursor %lx/%p\n", result, old_cursor );
2501
2503 WaitForSingleObject( thread, 1000 );
2505 ok( result == (DWORD_PTR)old_cursor, "wrong thread cursor %lx/%p\n", result, old_cursor );
2506 ok( GetCursor() == 0, "wrong cursor %p/0\n", GetCursor() );
2507
2510 WaitForSingleObject( thread, 1000 );
2512 ok( result == (DWORD_PTR)old_cursor, "wrong thread cursor %lx/%p\n", result, old_cursor );
2513 ok( GetCursor() == cursor, "wrong cursor %p/0\n", cursor );
2514
2515 if (pGetCursorInfo)
2516 {
2517 info.cbSize = sizeof(info);
2518 ok( pGetCursorInfo( &info ), "GetCursorInfo failed\n" );
2519 ok( info.hCursor == global_cursor, "expected global cursor %p\n", global_cursor );
2520 }
2521 SetCursor( old_cursor );
2523
2524 SetLastError( 0xdeadbeef );
2525 cursor = SetCursor( (HCURSOR)0xbadbad );
2526 error = GetLastError();
2527 ok( cursor == 0, "wrong cursor %p/0\n", cursor );
2528 ok( error == ERROR_INVALID_CURSOR_HANDLE, "wrong error %lu\n", error );
2529
2530 if (pGetCursorInfo)
2531 {
2532 info.cbSize = sizeof(info);
2533 ok( pGetCursorInfo( &info ), "GetCursorInfo failed\n" );
2534 ok( info.hCursor == global_cursor, "expected global cursor %p\n", global_cursor );
2535 }
2536}
2537
2539
2541{
2543 int ret;
2544
2545 PeekMessageA( 0, 0, 0, 0, PM_NOREMOVE ); /* create a msg queue */
2546 if (parent_id)
2547 {
2549 ok( ret, "AttachThreadInput failed\n" );
2550 }
2551 if (!count) ret = ShowCursor( FALSE );
2552 else while (count--) ret = ShowCursor( TRUE );
2555 return ret;
2556}
2557
2558static void test_ShowCursor(void)
2559{
2560 int count;
2561 DWORD id, result;
2562 HANDLE thread;
2564
2565 if (pGetCursorInfo)
2566 {
2567 memset( &info, 0, sizeof(info) );
2568 info.cbSize = sizeof(info);
2569 ok( pGetCursorInfo( &info ), "GetCursorInfo failed\n" );
2570 ok( info.flags & (CURSOR_SHOWING | CURSOR_SUPPRESSED), "Got unexpected cursor state\n" );
2571 }
2572
2575
2576 count = ShowCursor( TRUE );
2577 ok( count == 1, "wrong count %d\n", count );
2578 count = ShowCursor( TRUE );
2579 ok( count == 2, "wrong count %d\n", count );
2580 count = ShowCursor( FALSE );
2581 ok( count == 1, "wrong count %d\n", count );
2582 count = ShowCursor( FALSE );
2583 ok( count == 0, "wrong count %d\n", count );
2584 count = ShowCursor( FALSE );
2585 ok( count == -1, "wrong count %d\n", count );
2586 count = ShowCursor( FALSE );
2587 ok( count == -2, "wrong count %d\n", count );
2588
2589 if (pGetCursorInfo)
2590 {
2591 info.cbSize = sizeof(info);
2592 ok( pGetCursorInfo( &info ), "GetCursorInfo failed\n" );
2593 /* global show count is not affected since we don't have a window */
2594 ok( info.flags & (CURSOR_SHOWING | CURSOR_SUPPRESSED), "Got unexpected cursor state\n" );
2595 }
2596
2597 parent_id = 0;
2600 count = ShowCursor( FALSE );
2601 ok( count == -3, "wrong count %d\n", count );
2603 WaitForSingleObject( thread, 1000 );
2605 ok( result == -1, "wrong thread count %ld\n", result );
2606 count = ShowCursor( FALSE );
2607 ok( count == -4, "wrong count %d\n", count );
2608
2609 thread = CreateThread( NULL, 0, show_cursor_thread, (void *)1, 0, &id );
2611 count = ShowCursor( TRUE );
2612 ok( count == -3, "wrong count %d\n", count );
2614 WaitForSingleObject( thread, 1000 );
2616 ok( result == 1, "wrong thread count %ld\n", result );
2617 count = ShowCursor( TRUE );
2618 ok( count == -2, "wrong count %d\n", count );
2619
2623 count = ShowCursor( TRUE );
2624 ok( count == -2, "wrong count %d\n", count );
2626 WaitForSingleObject( thread, 1000 );
2628 ok( result == -3, "wrong thread count %ld\n", result );
2629 count = ShowCursor( FALSE );
2630 ok( count == -2, "wrong count %d\n", count );
2631
2632 thread = CreateThread( NULL, 0, show_cursor_thread, (void *)3, 0, &id );
2634 count = ShowCursor( TRUE );
2635 ok( count == 2, "wrong count %d\n", count );
2637 WaitForSingleObject( thread, 1000 );
2639 ok( result == 1, "wrong thread count %ld\n", result );
2640 count = ShowCursor( FALSE );
2641 ok( count == -2, "wrong count %d\n", count );
2642
2643 if (pGetCursorInfo)
2644 {
2645 info.cbSize = sizeof(info);
2646 ok( pGetCursorInfo( &info ), "GetCursorInfo failed\n" );
2647 ok( info.flags & (CURSOR_SHOWING | CURSOR_SUPPRESSED), "Got unexpected cursor state\n" );
2648 }
2649
2650 count = ShowCursor( TRUE );
2651 ok( count == -1, "wrong count %d\n", count );
2652 count = ShowCursor( TRUE );
2653 ok( count == 0, "wrong count %d\n", count );
2654
2655 if (pGetCursorInfo)
2656 {
2657 info.cbSize = sizeof(info);
2658 ok( pGetCursorInfo( &info ), "GetCursorInfo failed\n" );
2659 ok( info.flags & (CURSOR_SHOWING | CURSOR_SUPPRESSED), "Got unexpected cursor state\n" );
2660 }
2661}
2662
2663
2664static void test_DestroyCursor(void)
2665{
2666 static const BYTE bmp_bits[4096];
2667 ICONINFO cursorInfo, new_info;
2668 HCURSOR cursor, cursor2, new_cursor;
2669 BOOL ret;
2670 DWORD error;
2671 UINT display_bpp;
2672 HDC hdc;
2673
2674 hdc = GetDC(0);
2675 display_bpp = GetDeviceCaps(hdc, BITSPIXEL);
2676 ReleaseDC(0, hdc);
2677
2678 cursorInfo.fIcon = FALSE;
2679 cursorInfo.xHotspot = 0;
2680 cursorInfo.yHotspot = 0;
2681 cursorInfo.hbmMask = CreateBitmap(32, 32, 1, 1, bmp_bits);
2682 cursorInfo.hbmColor = CreateBitmap(32, 32, 1, display_bpp, bmp_bits);
2683
2684 cursor = CreateIconIndirect(&cursorInfo);
2685 ok(cursor != NULL, "CreateIconIndirect returned %p\n", cursor);
2686 if(!cursor) {
2687 return;
2688 }
2690
2691 SetLastError(0xdeadbeef);
2693 ok(!ret, "DestroyCursor on the active cursor succeeded\n");
2694 error = GetLastError();
2695 ok(error == 0xdeadbeef, "Last error: %lu\n", error);
2696
2697 new_cursor = GetCursor();
2698 ok(new_cursor == cursor, "GetCursor returned %p/%p\n", new_cursor, cursor);
2699
2700 SetLastError(0xdeadbeef);
2701 ret = GetIconInfo( cursor, &new_info );
2702 ok( !ret, "GetIconInfo succeeded\n" );
2703 ok( GetLastError() == ERROR_INVALID_CURSOR_HANDLE, "wrong error %lu\n", GetLastError() );
2704
2705 if (ret) /* nt4 delays destruction until cursor changes */
2706 {
2707 DeleteObject( new_info.hbmColor );
2708 DeleteObject( new_info.hbmMask );
2709
2710 SetLastError(0xdeadbeef);
2712 ok( !ret, "DestroyCursor succeeded\n" );
2714 "wrong error %lu\n", GetLastError() );
2715
2716 SetLastError(0xdeadbeef);
2717 cursor2 = SetCursor( cursor );
2718 ok( cursor2 == cursor, "SetCursor returned %p/%p\n", cursor2, cursor);
2720 "wrong error %lu\n", GetLastError() );
2721 }
2722 else
2723 {
2724 SetLastError(0xdeadbeef);
2725 cursor2 = CopyCursor( cursor );
2726 ok(!cursor2, "CopyCursor succeeded\n" );
2727 ok( GetLastError() == ERROR_INVALID_CURSOR_HANDLE, "wrong error %lu\n", GetLastError() );
2728
2729 SetLastError(0xdeadbeef);
2731 ok( !ret, "DestroyCursor succeeded\n" );
2733 "wrong error %lu\n", GetLastError() );
2734
2735 SetLastError(0xdeadbeef);
2736 cursor2 = SetCursor( cursor );
2737 ok(!cursor2, "SetCursor returned %p/%p\n", cursor2, cursor);
2739 "wrong error %lu\n", GetLastError() );
2740 }
2741
2742 cursor2 = GetCursor();
2743 ok(cursor2 == new_cursor, "GetCursor returned %p/%p\n", cursor2, new_cursor);
2744
2745 SetLastError(0xdeadbeef);
2746 cursor2 = SetCursor( 0 );
2747 ok( cursor2 != new_cursor, "SetCursor returned %p/%p\n", cursor2, cursor );
2748 ok( GetLastError() == 0xdeadbeef, "wrong error %lu\n", GetLastError() );
2749
2750 cursor2 = GetCursor();
2751 ok(!cursor2, "GetCursor returned %p/%p\n", cursor2, cursor);
2752
2753 SetLastError(0xdeadbeef);
2755 ok( !ret, "DestroyCursor succeeded\n" );
2757 "wrong error %lu\n", GetLastError() );
2758
2759 DeleteObject(cursorInfo.hbmMask);
2760 DeleteObject(cursorInfo.hbmColor);
2761
2762 /* Try testing DestroyCursor() now using LoadCursor() cursors. */
2764
2765 SetLastError(0xdeadbeef);
2767 ok(ret, "DestroyCursor on the active cursor failed.\n");
2768 error = GetLastError();
2769 ok(error == 0xdeadbeef, "Last error: 0x%08lx\n", error);
2770
2771 /* Try setting the cursor to a destroyed OEM cursor. */
2772 SetLastError(0xdeadbeef);
2774 error = GetLastError();
2775 ok(error == 0xdeadbeef, "Last error: 0x%08lx\n", error);
2776
2777 /* Check if LoadCursor() returns the same handle with the same icon. */
2778 cursor2 = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
2779 ok(cursor2 == cursor, "cursor == %p, cursor2 == %p\n", cursor, cursor2);
2780
2781 /* Check if LoadCursor() returns the same handle with a different icon. */
2782 cursor2 = LoadCursorA(NULL, (LPCSTR)IDC_WAIT);
2783 ok(cursor2 != cursor, "cursor == %p, cursor2 == %p\n", cursor, cursor2);
2784}
2785
2787{
2788 HICON icon;
2789 UINT ret;
2790
2791 static const test_icon_entries_t icon_desc[] = {{0,0,TRUE}, {16,16,TRUE}, {32,32}, {64,64,TRUE}};
2792
2793 create_ico_file("extract.ico", icon_desc, ARRAY_SIZE(icon_desc));
2794
2795 ret = PrivateExtractIconsA("extract.ico", 0, 32, 32, &icon, NULL, 1, 0);
2796 ok(ret == 1, "PrivateExtractIconsA returned %u\n", ret);
2797 ok(icon != NULL, "icon == NULL\n");
2798
2799 test_icon_info(icon, 32, 32, 32, 32, NULL, TRUE);
2800 DestroyIcon(icon);
2801
2802 DeleteFileA("extract.ico");
2803}
2804
2805static void test_monochrome_icon(void)
2806{
2807 HANDLE handle;
2808 BOOL ret;
2809 DWORD bytes_written;
2810 CURSORICONFILEDIR *icon_data;
2811 CURSORICONFILEDIRENTRY *icon_entry;
2812 BITMAPINFO *bitmap_info;
2813 BITMAPCOREINFO *core_info;
2814 ICONINFO icon_info;
2816 BOOL monochrome, use_core_info;
2817
2818 icon_data = malloc(sizeof(CURSORICONFILEDIR) + sizeof(BITMAPINFOHEADER) +
2819 2 * sizeof(RGBQUAD) + sizeof(ULONG));
2820
2821 for (monochrome = FALSE; monochrome <= TRUE; monochrome++)
2822 for (use_core_info = FALSE; use_core_info <= TRUE; use_core_info++)
2823 {
2824 trace("%s, %s\n",
2825 monochrome ? "monochrome" : "colored",
2826 use_core_info ? "core info" : "bitmap info");
2827
2828 icon_size = sizeof(CURSORICONFILEDIR) +
2829 (use_core_info ? sizeof(BITMAPCOREHEADER) : sizeof(BITMAPINFOHEADER)) +
2830 /* 2 * sizeof(RGBTRIPLE) + padding comes out the same */
2831 2 * sizeof(RGBQUAD) +
2832 sizeof(ULONG);
2833 ZeroMemory(icon_data, icon_size);
2834 icon_data->idReserved = 0;
2835 icon_data->idType = 1;
2836 icon_data->idCount = 1;
2837
2838 icon_entry = icon_data->idEntries;
2839 icon_entry->bWidth = 1;
2840 icon_entry->bHeight = 1;
2841 icon_entry->bColorCount = 0;
2842 icon_entry->bReserved = 0;
2843 icon_entry->xHotspot = 0;
2844 icon_entry->yHotspot = 0;
2845 icon_entry->dwDIBSize = icon_size - sizeof(CURSORICONFILEDIR);
2846 icon_entry->dwDIBOffset = sizeof(CURSORICONFILEDIR);
2847
2848 if (use_core_info)
2849 {
2850 core_info = (BITMAPCOREINFO *) ((BYTE *) icon_data + icon_entry->dwDIBOffset);
2851 core_info->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2852 core_info->bmciHeader.bcWidth = 1;
2853 core_info->bmciHeader.bcHeight = 2;
2854 core_info->bmciHeader.bcPlanes = 1;
2855 core_info->bmciHeader.bcBitCount = 1;
2856 core_info->bmciColors[0].rgbtBlue = monochrome ? 0x00 : 0xff;
2857 core_info->bmciColors[0].rgbtGreen = 0x00;
2858 core_info->bmciColors[0].rgbtRed = 0x00;
2859 core_info->bmciColors[1].rgbtBlue = 0xff;
2860 core_info->bmciColors[1].rgbtGreen = 0xff;
2861 core_info->bmciColors[1].rgbtRed = 0xff;
2862 }
2863 else
2864 {
2865 bitmap_info = (BITMAPINFO *) ((BYTE *) icon_data + icon_entry->dwDIBOffset);
2866 bitmap_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2867 bitmap_info->bmiHeader.biWidth = 1;
2868 bitmap_info->bmiHeader.biHeight = 2;
2869 bitmap_info->bmiHeader.biPlanes = 1;
2870 bitmap_info->bmiHeader.biBitCount = 1;
2871 bitmap_info->bmiHeader.biSizeImage = 0; /* Uncompressed bitmap. */
2872 bitmap_info->bmiColors[0].rgbBlue = monochrome ? 0x00 : 0xff;
2873 bitmap_info->bmiColors[0].rgbGreen = 0x00;
2874 bitmap_info->bmiColors[0].rgbRed = 0x00;
2875 bitmap_info->bmiColors[1].rgbBlue = 0xff;
2876 bitmap_info->bmiColors[1].rgbGreen = 0xff;
2877 bitmap_info->bmiColors[1].rgbRed = 0xff;
2878 }
2879
2880 handle = CreateFileA("icon.ico", GENERIC_WRITE, 0, NULL, CREATE_NEW,
2882 ok(handle != INVALID_HANDLE_VALUE, "CreateFileA failed. %lu\n", GetLastError());
2883 ret = WriteFile(handle, icon_data, icon_size, &bytes_written, NULL);
2884 ok(ret && bytes_written == icon_size, "icon.ico created improperly.\n");
2886
2887 handle = LoadImageA(NULL, "icon.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
2888 if (!monochrome && !use_core_info) ok(handle != NULL, "LoadImage() failed with %lu.\n", GetLastError());
2889#ifdef __REACTOS__
2890 else todo_wine ok(handle == NULL || broken(!use_core_info) /* Win7 */ || broken(GetLastError() == ERROR_SUCCESS) /* WS03 */, "LoadImage() failed with %lu.\n", GetLastError());
2891#else
2892 else todo_wine ok(handle == NULL || broken(!use_core_info) /* Win7 */, "LoadImage() failed with %lu.\n", GetLastError());
2893#endif
2894 if (handle == NULL)
2895 {
2896 skip("Icon failed to load: %s, %s\n",
2897 monochrome ? "monochrome" : "colored",
2898 use_core_info ? "core info" : "bitmap info");
2899 DeleteFileA("icon.ico");
2900 continue;
2901 }
2902
2903 ret = GetIconInfo(handle, &icon_info);
2904 ok(ret, "GetIconInfo() failed with %lu.\n", GetLastError());
2905 if (ret)
2906 {
2907 ok(icon_info.fIcon == TRUE, "fIcon is %u.\n", icon_info.fIcon);
2908 ok(icon_info.xHotspot == 0, "xHotspot is %lu.\n", icon_info.xHotspot);
2909 ok(icon_info.yHotspot == 0, "yHotspot is %lu.\n", icon_info.yHotspot);
2910 if (monochrome)
2911 ok(icon_info.hbmColor == NULL, "Got hbmColor %p!\n", icon_info.hbmColor);
2912 else
2913 ok(icon_info.hbmColor != NULL, "No hbmColor!\n");
2914 ok(icon_info.hbmMask != NULL, "No hbmMask!\n");
2915 }
2916
2918 ok(ret, "DestroyIcon() failed with %lu.\n", GetLastError());
2919 DeleteFileA("icon.ico");
2920 }
2921
2922 free(icon_data);
2923}
2924
2925static COLORREF get_color_from_bits(const unsigned char *bits, const BITMAPINFO *bmi,
2926 unsigned int row, unsigned int column)
2927{
2928 const BITMAPINFOHEADER *h = &bmi->bmiHeader;
2929 unsigned int stride, shift, mask;
2930 const unsigned char *data;
2931 RGBQUAD color;
2932 WORD color16;
2933
2934 stride = ((h->biBitCount * h->biWidth + 7) / 8 + 3) & ~3;
2935 data = bits + row * stride + column * h->biBitCount / 8;
2936 if (h->biBitCount >= 24)
2937 return RGB(data[2], data[1], data[0]);
2938
2939 if (h->biBitCount == 16)
2940 {
2941 color16 = ((WORD)data[1] << 8) | data[0];
2942 return RGB(((color16 >> 10) & 0x1f) << 3, ((color16 >> 5) & 0x1f) << 3,
2943 (color16 & 0x1f) << 3);
2944 }
2945 shift = 8 - h->biBitCount - (column * h->biBitCount) % 8;
2946 mask = ~(~0u << h->biBitCount);
2947 color = bmi->bmiColors[(data[0] >> shift) & mask];
2948 return RGB(color.rgbRed, color.rgbGreen, color.rgbBlue);
2949}
2950
2951#define compare_bitmap_bits(a, b, c, d, e, f, g, h) compare_bitmap_bits_(__LINE__, a, b, c, d, e, f, g, h)
2952static void compare_bitmap_bits_(unsigned int line, HDC hdc, HBITMAP bitmap, BITMAPINFO *bmi,
2953 size_t result_bits_size, const unsigned char *expected_bits, unsigned int test_index,
2954 BOOL allow_todo, const unsigned char *expected_broken_bits)
2955{
2956 unsigned char *result_bits;
2957 unsigned int row, column;
2958 int ret;
2959
2960 result_bits = malloc(result_bits_size);
2962 result_bits, bmi, DIB_RGB_COLORS);
2963 ok(ret == bmi->bmiHeader.biHeight, "Unexpected GetDIBits result %d, GetLastError() %lu.\n",
2964 ret, GetLastError());
2965 for (row = 0; row < bmi->bmiHeader.biHeight; ++row)
2966 for (column = 0; column < bmi->bmiHeader.biWidth; ++column)
2967 {
2969
2970 result = get_color_from_bits(result_bits, bmi, row, column);
2971 expected = get_color_from_bits(expected_bits, bmi, row, column);
2972
2973 todo_wine_if(allow_todo && result != expected)
2974 ok_(__FILE__, line)(result == expected || broken(expected_broken_bits
2975 && result == get_color_from_bits(expected_broken_bits, bmi, row, column)),
2976 "Colors do not match, got 0x%06lx, expected 0x%06lx, test_index %u, row %u, column %u.\n",
2977 result, expected, test_index, row, column);
2978 }
2979 free(result_bits);
2980}
2981
2982static void test_Image_StretchMode(void)
2983{
2984 static const unsigned char test_bits_24[] =
2985 {
2986 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
2987 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00,
2988 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00,
2989 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
2990 };
2991 static const unsigned char expected_broken_bits_24[] =
2992 {
2993 0x3f, 0xff, 0x00, 0x3f, 0xff, 0x3f, 0x00, 0x00,
2994 0x3f, 0xff, 0x7f, 0x00, 0xff, 0x3f, 0x00, 0x00,
2995 };
2996 static const unsigned char expected_bits_24[] =
2997 {
2998 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
2999 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
3000 };
3001#define rgb16(r, g, b) ((WORD)(((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3)))
3002 static const WORD test_bits_16[] =
3003 {
3004 rgb16(0x00, 0x20, 0x00), rgb16(0x00, 0x40, 0x00), rgb16(0x00, 0x40, 0xff), rgb16(0x00, 0x20, 0x00),
3005 rgb16(0x00, 0x60, 0x00), rgb16(0xff, 0x80, 0x00), rgb16(0xff, 0x60, 0x00), rgb16(0x00, 0x80, 0x00),
3006 rgb16(0x00, 0x20, 0xff), rgb16(0x00, 0x40, 0x00), rgb16(0x00, 0x40, 0xff), rgb16(0x00, 0x20, 0x00),
3007 rgb16(0xff, 0x80, 0x00), rgb16(0x00, 0x60, 0xff), rgb16(0x00, 0x80, 0x00), rgb16(0x00, 0x60, 0x00),
3008 };
3009 static const WORD expected_bits_16[] =
3010 {
3011 rgb16(0x00, 0x40, 0x00), rgb16(0x00, 0x20, 0x00),
3012 rgb16(0x00, 0x40, 0x00), rgb16(0x00, 0x20, 0x00),
3013 };
3014#undef rgb16
3015 static const unsigned char test_bits_8[] =
3016 {
3017 0x00, 0xff, 0x00, 0xff,
3018 0x00, 0x00, 0x00, 0x00,
3019 0xff, 0x55, 0x00, 0xff,
3020 0x00, 0xff, 0xff, 0x00,
3021 };
3022 static const unsigned char expected_bits_8[] =
3023 {
3024 0xff, 0xff, 0x00, 0x00,
3025 0x55, 0xff, 0x00, 0x00,
3026 };
3027 static const unsigned char test_bits_1[] =
3028 {
3029 0x30, 0x0, 0x0, 0x0,
3030 0x30, 0x0, 0x0, 0x0,
3031 0x40, 0x0, 0x0, 0x0,
3032 0xc0, 0x0, 0x0, 0x0,
3033 };
3034 static const unsigned char expected_bits_1[] =
3035 {
3036 0x40, 0x0, 0x0, 0x0,
3037 0x0, 0x0, 0x0, 0x0,
3038 };
3039 static const RGBQUAD colors_bits_1[] =
3040 {
3041 {0, 0, 0},
3042 {0xff, 0xff, 0xff},
3043 };
3044 static RGBQUAD colors_bits_8[256];
3045
3046 static const struct
3047 {
3048 LONG width, height, output_width, output_height;
3049 WORD bit_count;
3050 const unsigned char *test_bits, *expected_bits;
3051 size_t test_bits_size, result_bits_size;
3052 const RGBQUAD *bmi_colors;
3053 size_t bmi_colors_size;
3054 BOOL allow_todo;
3055 const unsigned char *expected_broken_bits;
3056 }
3057 tests[] =
3058 {
3059 {4, 4, 2, 2, 24, test_bits_24, expected_bits_24,
3060 sizeof(test_bits_24), sizeof(expected_bits_24), NULL, 0, TRUE,
3061 /* Broken on Windows before Win10 1607+ */ expected_broken_bits_24},
3062 {4, 4, 2, 2, 1, test_bits_1, expected_bits_1,
3063 sizeof(test_bits_1), sizeof(expected_bits_1), colors_bits_1,
3064 sizeof(colors_bits_1)},
3065 {4, 4, 2, 2, 8, test_bits_8, expected_bits_8,
3066 sizeof(test_bits_8), sizeof(expected_bits_8), colors_bits_8,
3067 sizeof(colors_bits_8), TRUE},
3068 {4, 4, 2, 2, 16, (const unsigned char *)test_bits_16, (const unsigned char *)expected_bits_16,
3069 sizeof(test_bits_16), sizeof(expected_bits_16), NULL, 0, TRUE},
3070 };
3071 static const char filename[] = "test.bmp";
3072 BITMAPINFO *bmi, *bmi_output;
3073 HBITMAP bitmap, bitmap_copy;
3074 unsigned int test_index;
3075 unsigned char *bits;
3076 size_t bmi_size;
3077 unsigned int i;
3078 HDC hdc;
3079
3080 bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
3081 bmi = calloc(1, bmi_size);
3082 bmi_output = calloc(1, bmi_size);
3083 bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3084 bmi->bmiHeader.biPlanes = 1;
3086
3087 for (i = 0; i < 256; ++i)
3088 colors_bits_8[i].rgbRed = colors_bits_8[i].rgbGreen = colors_bits_8[i].rgbBlue = i;
3089
3090 hdc = GetDC(NULL);
3091
3092 for (test_index = 0; test_index < ARRAY_SIZE(tests); ++test_index)
3093 {
3094 if (tests[test_index].bmi_colors)
3095 memcpy(bmi->bmiColors, tests[test_index].bmi_colors, tests[test_index].bmi_colors_size);
3096 else
3097 memset(bmi->bmiColors, 0, 256 * sizeof(RGBQUAD));
3098
3099 bmi->bmiHeader.biWidth = tests[test_index].width;
3100 bmi->bmiHeader.biHeight = tests[test_index].height;
3101 bmi->bmiHeader.biBitCount = tests[test_index].bit_count;
3102 memcpy(bmi_output, bmi, bmi_size);
3103 bmi_output->bmiHeader.biWidth = tests[test_index].output_width;
3104 bmi_output->bmiHeader.biHeight = tests[test_index].output_height;
3105
3106 bitmap = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, (void **)&bits, NULL, 0);
3107 ok(bitmap && bits, "CreateDIBSection() failed, result %lu.\n", GetLastError());
3108 memcpy(bits, tests[test_index].test_bits, tests[test_index].test_bits_size);
3109
3110 bitmap_copy = CopyImage(bitmap, IMAGE_BITMAP, tests[test_index].output_width,
3111 tests[test_index].output_height, LR_CREATEDIBSECTION);
3112 ok(!!bitmap_copy, "CopyImage() failed, result %lu.\n", GetLastError());
3113
3114 compare_bitmap_bits(hdc, bitmap_copy, bmi_output, tests[test_index].result_bits_size,
3115 tests[test_index].expected_bits, test_index, tests[test_index].allow_todo,
3116 tests[test_index].expected_broken_bits);
3118 DeleteObject(bitmap_copy);
3119
3120 create_bitmap_file(filename, bmi, tests[test_index].test_bits);
3121 bitmap = LoadImageA(NULL, filename, IMAGE_BITMAP, tests[test_index].output_width,
3122 tests[test_index].output_height, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
3123 ok(!!bitmap, "LoadImageA() failed, result %lu.\n", GetLastError());
3125 compare_bitmap_bits(hdc, bitmap, bmi_output, tests[test_index].result_bits_size,
3126 tests[test_index].expected_bits, test_index, tests[test_index].allow_todo,
3127 tests[test_index].expected_broken_bits);
3129 }
3130 ReleaseDC(0, hdc);
3131 free(bmi_output);
3132 free(bmi);
3133}
3134
3135static void test_copy_image(void)
3136{
3137 static const UINT types[] = {IMAGE_BITMAP, IMAGE_ICON, IMAGE_CURSOR};
3138 static const UINT depths[] = {1, 4, 8, 16, 24, 32};
3139 unsigned int i, j;
3140
3141 for (i = 0; i < ARRAY_SIZE(types); ++i)
3142 {
3143 for (j = 0; j < ARRAY_SIZE(depths); ++j)
3144 do_test_copy_image(types[i], depths[j]);
3145 }
3146}
3147
3148START_TEST(cursoricon)
3149{
3150 pGetCursorInfo = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetCursorInfo" );
3151 pGetIconInfoExA = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetIconInfoExA" );
3152 pGetIconInfoExW = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetIconInfoExW" );
3153 pGetCursorFrameInfo = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetCursorFrameInfo" );
3155
3156 if (test_argc >= 3)
3157 {
3158 /* Child process. */
3159 sscanf (test_argv[2], "%x", (unsigned int *) &parent);
3160
3161 ok(parent != NULL, "Parent not found.\n");
3162 if (parent == NULL)
3163 ExitProcess(1);
3164
3165 do_child();
3166 return;
3167 }
3168
3176 test_DrawIcon();
3184 do_parent();
3187}
short INT16
Definition: actypes.h:130
static void startup(void)
unsigned int dir
Definition: maze.c:112
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
#define msg(x)
Definition: auth_time.c:54
#define ARRAY_SIZE(A)
Definition: main.h:20
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
static HANDLE thread
Definition: service.c:33
DWORD GetPixel(LPDIRECTDRAWSURFACE7 Surface, UINT x, UINT y)
Definition: blt.cpp:2
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
DWORD bpp
Definition: surface.c:185
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define GENERIC_READ
Definition: compat.h:135
HANDLE HWND
Definition: compat.h:19
#define MAX_PATH
Definition: compat.h:34
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define CALLBACK
Definition: compat.h:35
#define GetEnvironmentVariableA(x, y, z)
Definition: compat.h:754
static const WCHAR *const ext[]
Definition: module.c:53
static void cleanup(void)
Definition: main.c:1335
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableA(IN LPCSTR lpName, IN LPCSTR lpValue)
Definition: environ.c:219
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:682
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:539
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2065
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2125
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:1973
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1331
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:541
HRSRC WINAPI FindResourceA(HMODULE hModule, LPCSTR name, LPCSTR type)
Definition: res.c:155
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
BOOL WINAPI EnumResourceNamesA(HMODULE hmod, LPCSTR type, ENUMRESNAMEPROCA lpfun, LONG_PTR lparam)
Definition: res.c:285
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(const char *app_name, char *cmd_line, SECURITY_ATTRIBUTES *process_attr, SECURITY_ATTRIBUTES *thread_attr, BOOL inherit, DWORD flags, void *env, const char *cur_dir, STARTUPINFOA *startup_info, PROCESS_INFORMATION *info)
Definition: process.c:686
DWORD WINAPI GetVersion(void)
Definition: version.c:1458
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
_ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl sscanf(const char *, const char *,...) __WINE_CRT_SCANF_ATTR(2
_ACRTIMP char *__cdecl strrchr(const char *, int)
Definition: string.c:3298
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
#define BI_RGB
Definition: precomp.h:44
#define RGB(r, g, b)
Definition: precomp.h:67
ULONG RGBQUAD
Definition: precomp.h:47
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
static char * path_name(DOS_FILE *file)
Definition: check.c:208
pKey DeleteObject()
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLsizei stride
Definition: glext.h:5848
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLuint color
Definition: glext.h:6243
GLenum GLint GLuint mask
Definition: glext.h:6028
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint64EXT * result
Definition: glext.h:11304
GLfloat param
Definition: glext.h:5796
GLuint GLdouble GLdouble GLint GLint order
Definition: glext.h:11194
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLuint id
Definition: glext.h:5910
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
const char cursor[]
Definition: icontest.c:13
#define bits
Definition: infblock.c:15
const char * filename
Definition: ioapi.h:137
char hdr[14]
Definition: iptest.cpp:33
#define wine_dbgstr_w
Definition: kernel32.h:34
#define win_skip
Definition: minitest.h:67
#define todo_wine_if(is_todo)
Definition: minitest.h:81
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:537
#define todo_wine
Definition: minitest.h:80
#define ZeroMemory
Definition: minwinbase.h:31
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
Definition: mipmap.c:4858
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define CREATE_NEW
Definition: disk.h:69
static struct test_info tests[]
#define sprintf
Definition: sprintf.c:45
BITMAP bmp
Definition: alphablend.c:62
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:88
static HICON
Definition: imagelist.c:80
BOOL expected
Definition: store.c:2000
static void test_SetCursor(void)
Definition: cursoricon.c:2441
#define ANI_FLAG_SEQUENCE
Definition: cursoricon.c:70
static LRESULT CALLBACK callback_parent(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: cursoricon.c:347
static DWORD DWORD DWORD DWORD * steps
Definition: cursoricon.c:1804
static DWORD unk1
Definition: cursoricon.c:1804
riff_cursor3_t empty_anicursor3
Definition: cursoricon.c:222
static DWORD DWORD DWORD * rate
Definition: cursoricon.c:1804
static DWORD parent_id
Definition: cursoricon.c:2424
static void test_LoadImageBitmap(HBITMAP hbm)
Definition: cursoricon.c:1171
static void do_child(void)
Definition: cursoricon.c:358
static void check_DrawState_Color(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, HBRUSH hbr, UINT flags, COLORREF background, COLORREF modern_expected, COLORREF legacy_expected, int line)
Definition: cursoricon.c:2353
static void test_GetCursorFrameInfo(void)
Definition: cursoricon.c:1805
static void finish_child_process(void)
Definition: cursoricon.c:446
#define ICON_RES_SIZE
#define EMPTY_ICON32
Definition: cursoricon.c:154
static void test_ShowCursor(void)
Definition: cursoricon.c:2558
static char ** test_argv
Definition: cursoricon.c:296
static HANDLE event_next
Definition: cursoricon.c:2538
static void test_DrawIcon(void)
Definition: cursoricon.c:2142
static HANDLE event_start
Definition: cursoricon.c:2538
static void test_initial_cursor(void)
Definition: cursoricon.c:767
static const unsigned char bmpcoreimage[38]
Definition: cursoricon.c:1137
static void test_LoadImage(void)
Definition: cursoricon.c:1436
static void do_test_copy_image(UINT type, UINT depth)
Definition: cursoricon.c:614
#define ANI_fram_ID
Definition: cursoricon.c:65
#define ANI_RIFF_ID
Definition: cursoricon.c:60
#define rgb16(r, g, b)
static DWORD CALLBACK set_cursor_thread(void *arg)
Definition: cursoricon.c:2426
#define PROC_INIT
Definition: cursoricon.c:302
#define ANI_LIST_ID
Definition: cursoricon.c:61
static void check_alpha_draw(HDC hdc, BOOL drawiconex, BOOL alpha, int bpp, int line)
Definition: cursoricon.c:2081
static void test_child_process(void)
Definition: cursoricon.c:453
#define CRSR_RES_SIZE
static const unsigned char gifimage[35]
Definition: cursoricon.c:1087
#define ICON_WIDTH
static unsigned char bmpimage[70]
Definition: cursoricon.c:1128
static BOOL color_match(COLORREF a, COLORREF b)
Definition: cursoricon.c:481
static HICON create_test_icon(HDC hdc, int width, int height, int bpp, BOOL maskvalue, UINT32 *color, int colorSize)
Definition: cursoricon.c:2045
static void check_copy_image(HBITMAP bitmap, UINT type, UINT flags, INT copyWidth, INT copyHeight, INT expectedWidth, INT expectedHeight, WORD expectedDepth, BOOL dibExpected)
Definition: cursoricon.c:489
static void test_icon_info_(HICON hIcon, UINT exp_cx, UINT exp_cy, UINT exp_mask_cy, UINT exp_bpp, const BYTE *mask_bits, UINT has_color, int line)
Definition: cursoricon.c:784
riff_cursor1_t empty_anicursor
Definition: cursoricon.c:193
static HANDLE child_process
Definition: cursoricon.c:300
static void create_ico_file(const char *filename, const test_icon_entries_t *test_icon_entries, unsigned entry_cnt)
Definition: cursoricon.c:1256
riff_cursor3_seq_t empty_anicursor3_seq
Definition: cursoricon.c:253
#define compare_bitmap_bits(a, b, c, d, e, f, g, h)
Definition: cursoricon.c:2951
static ICONINFOEXA *static ICONINFOEXW *static const BOOL is_win64
Definition: cursoricon.c:308
static void test_DrawIconEx(void)
Definition: cursoricon.c:2225
static HWND parent
Definition: cursoricon.c:299
static void test_monochrome_icon(void)
Definition: cursoricon.c:2805
static void test_LoadImageFile(const char *test_desc, const unsigned char *image_data, unsigned int image_size, const char *ext, BOOL expect_success)
Definition: cursoricon.c:1196
#define test_icon_info(a, b, c, d, e, f, g)
Definition: cursoricon.c:879
#define ANI_ACON_ID
Definition: cursoricon.c:62
static void test_DrawState(void)
Definition: cursoricon.c:2373
#define ICON_HEIGHT
static void test_LoadImage_working_directory(void)
Definition: cursoricon.c:1392
static void test_LoadImage_working_directory_run(char *path)
Definition: cursoricon.c:1350
static void create_bitmap_file(const char *filename, const BITMAPINFO *bmi, const unsigned char *bits)
Definition: cursoricon.c:1316
static void test_DestroyCursor(void)
Definition: cursoricon.c:2664
static void test_CreateIcon(void)
Definition: cursoricon.c:881
#define ANI_FLAG_ICON
Definition: cursoricon.c:69
static void check_DrawIcon(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, COLORREF background, COLORREF modern_expected, COLORREF legacy_expected, int line)
Definition: cursoricon.c:2110
static void test_CreateIconFromResource(void)
Definition: cursoricon.c:1567
static HWND child
Definition: cursoricon.c:298
static DWORD CALLBACK show_cursor_thread(void *arg)
Definition: cursoricon.c:2540
static int check_cursor_data(HDC hdc, HCURSOR hCursor, void *data, int length)
Definition: cursoricon.c:1761
static int test_argc
Definition: cursoricon.c:297
static void test_PrivateExtractIcons(void)
Definition: cursoricon.c:2786
static const DWORD biSize_tests[]
Definition: cursoricon.c:1155
static LRESULT CALLBACK callback_child(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: cursoricon.c:310
#define ANI_anih_ID
Definition: cursoricon.c:63
static void test_Image_StretchMode(void)
Definition: cursoricon.c:2982
static const unsigned char invalid_dwDIBOffset[]
Definition: cursoricon.c:1150
static const unsigned char pngimage[285]
Definition: cursoricon.c:1116
static void do_parent(void)
Definition: cursoricon.c:397
static COLORREF get_color_from_bits(const unsigned char *bits, const BITMAPINFO *bmi, unsigned int row, unsigned int column)
Definition: cursoricon.c:2925
#define ICON_BPP
static const unsigned char jpgimage[285]
Definition: cursoricon.c:1094
static void test_copy_image(void)
Definition: cursoricon.c:3135
static BOOL CALLBACK find_res_proc(HMODULE module, LPCSTR type, LPSTR name, LONG_PTR param)
Definition: cursoricon.c:1560
static DWORD DWORD istep
Definition: cursoricon.c:1804
#define ANI_seq__ID
Definition: cursoricon.c:64
static void check_DrawState_Size(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, HBRUSH hbr, UINT flags, int line)
Definition: cursoricon.c:2301
static const unsigned char gif4pixel[42]
Definition: cursoricon.c:1143
#define ANI_rate_ID
Definition: cursoricon.c:67
static void check_DrawIconEx(HDC hdc, BOOL maskvalue, UINT32 color, int bpp, UINT flags, COLORREF background, COLORREF modern_expected, COLORREF legacy_expected, int line)
Definition: cursoricon.c:2209
static void compare_bitmap_bits_(unsigned int line, HDC hdc, HBITMAP bitmap, BITMAPINFO *bmi, size_t result_bits_size, const unsigned char *expected_bits, unsigned int test_index, BOOL allow_todo, const unsigned char *expected_broken_bits)
Definition: cursoricon.c:2952
#define shift
Definition: input.c:3271
HICON hIcon
Definition: msconfig.c:44
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
#define BOOL
Definition: nt_native.h:43
#define DWORD
Definition: nt_native.h:44
#define GENERIC_WRITE
Definition: nt_native.h:90
_In_ HBITMAP hbm
Definition: ntgdi.h:2776
BYTE * PBYTE
Definition: pedump.c:66
#define WS_POPUP
Definition: pedump.c:616
#define WS_VISIBLE
Definition: pedump.c:620
#define RT_ICON
Definition: pedump.c:365
long LONG
Definition: pedump.c:60
#define RT_GROUP_ICON
Definition: pedump.c:375
#define calloc
Definition: rosglue.h:14
strcat
Definition: string.h:92
strcpy
Definition: string.h:131
int winetest_get_mainargs(char ***pargv)
#define wait_child_process
Definition: test.h:159
#define memset(x, y, z)
Definition: compat.h:39
iconPos iconPos icon_size
Definition: startmenu.cpp:1416
DWORD biSizeImage
Definition: amvideo.idl:36
CURSORICONFILEDIRENTRY idEntries[1]
Definition: olepicture.c:100
BITMAPCOREHEADER bmciHeader
Definition: wingdi.h:1899
RGBTRIPLE bmciColors[1]
Definition: wingdi.h:1900
CHAR szResName[MAX_PATH]
Definition: winuser.h:3247
DWORD cbSize
Definition: winuser.h:3239
WORD wResID
Definition: winuser.h:3245
CHAR szModName[MAX_PATH]
Definition: winuser.h:3246
DWORD cbSize
Definition: winuser.h:3252
WCHAR szModName[MAX_PATH]
Definition: winuser.h:3259
WORD wResID
Definition: winuser.h:3258
WCHAR szResName[MAX_PATH]
Definition: winuser.h:3260
DWORD yHotspot
Definition: winuser.h:3232
BOOL fIcon
Definition: winuser.h:3230
DWORD xHotspot
Definition: winuser.h:3231
HBITMAP hbmColor
Definition: winuser.h:3234
HBITMAP hbmMask
Definition: winuser.h:3233
BYTE data[32 *32 *4]
Definition: cursoricon.c:85
BITMAPINFOHEADER bmi_header
Definition: cursoricon.c:91
CURSORICONFILEDIR icon_info
Definition: cursoricon.c:90
ani_data32x32x32 bmi_data
Definition: cursoricon.c:92
DWORD num_frames
Definition: cursoricon.c:74
DWORD flags
Definition: cursoricon.c:81
DWORD width
Definition: cursoricon.c:76
DWORD display_rate
Definition: cursoricon.c:80
DWORD height
Definition: cursoricon.c:77
DWORD num_planes
Definition: cursoricon.c:79
DWORD header_size
Definition: cursoricon.c:73
DWORD bpp
Definition: cursoricon.c:78
DWORD num_steps
Definition: cursoricon.c:75
Definition: uimain.c:89
Definition: fci.c:127
Definition: parser.c:49
Definition: name.c:39
DWORD chunk_size
Definition: cursoricon.c:115
riff_icon32x32x32_t frames[1]
Definition: cursoricon.c:119
riff_list_t frame_list
Definition: cursoricon.c:118
DWORD chunk_type
Definition: cursoricon.c:116
riff_header_t header
Definition: cursoricon.c:117
riff_icon32x32x32_t frames[3]
Definition: cursoricon.c:151
riff_list_t frame_list
Definition: cursoricon.c:150
riff_rate3_t rates
Definition: cursoricon.c:149
riff_seq3_t seq
Definition: cursoricon.c:148
riff_header_t header
Definition: cursoricon.c:147
riff_icon32x32x32_t frames[3]
Definition: cursoricon.c:128
riff_header_t header
Definition: cursoricon.c:126
riff_list_t frame_list
Definition: cursoricon.c:127
DWORD chunk_size
Definition: cursoricon.c:124
DWORD chunk_type
Definition: cursoricon.c:125
DWORD chunk_id
Definition: cursoricon.c:96
ani_header header
Definition: cursoricon.c:98
DWORD chunk_size
Definition: cursoricon.c:97
ani_frame32x32x32 data
Definition: cursoricon.c:110
DWORD chunk_size
Definition: cursoricon.c:103
DWORD chunk_type
Definition: cursoricon.c:104
DWORD chunk_id
Definition: cursoricon.c:102
DWORD chunk_size
Definition: cursoricon.c:133
DWORD rate[3]
Definition: cursoricon.c:134
DWORD chunk_id
Definition: cursoricon.c:132
DWORD order[3]
Definition: cursoricon.c:140
DWORD chunk_size
Definition: cursoricon.c:139
DWORD chunk_id
Definition: cursoricon.c:138
USHORT biBitCount
Definition: precomp.h:34
ULONG biCompression
Definition: precomp.h:35
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1922
RGBQUAD bmiColors[1]
Definition: wingdi.h:1923
LONG bmHeight
Definition: wingdi.h:1869
LONG bmWidth
Definition: wingdi.h:1868
LPVOID bmBits
Definition: wingdi.h:1873
WORD bmBitsPixel
Definition: wingdi.h:1872
UCHAR rgbBlue
Definition: bootanim.c:103
UCHAR rgbRed
Definition: bootanim.c:105
UCHAR rgbGreen
Definition: bootanim.c:104
BYTE rgbtGreen
Definition: wingdi.h:1885
BYTE rgbtBlue
Definition: wingdi.h:1884
BYTE rgbtRed
Definition: wingdi.h:1886
Definition: cmds.c:130
#define max(a, b)
Definition: svc.c:63
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:587
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
#define DWORD_PTR
Definition: treelist.c:76
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int32_t INT_PTR
Definition: typedefs.h:64
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
int32_t INT
Definition: typedefs.h:58
uint32_t UINT32
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59
HBITMAP WINAPI CreateDIBSection(HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
Definition: bitmap.c:245
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define STARTF_USESHOWWINDOW
Definition: winbase.h:468
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
DWORD COLORREF
Definition: windef.h:100
HICON HCURSOR
Definition: windef.h:99
#define WINAPI
Definition: msvc.h:6
#define ERROR_DESTROY_OBJECT_OF_OTHER_THREAD
Definition: winerror.h:1261
#define ERROR_INVALID_CURSOR_HANDLE
Definition: winerror.h:1228
#define DIB_RGB_COLORS
Definition: wingdi.h:367
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
int WINAPI GetObjectA(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
int WINAPI GetDIBits(_In_ HDC hdc, _In_ HBITMAP hbm, _In_ UINT start, _In_ UINT cLines, _Out_opt_ LPVOID lpvBits, _At_((LPBITMAPINFOHEADER) lpbmi, _Inout_) LPBITMAPINFO lpbmi, _In_ UINT usage)
struct tagBITMAPCOREHEADER BITMAPCOREHEADER
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
#define DI_NORMAL
Definition: wingdi.h:72
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
#define DI_IMAGE
Definition: wingdi.h:70
LONG WINAPI GetBitmapBits(_In_ HBITMAP hbit, _In_ LONG cb, _Out_writes_bytes_(cb) LPVOID lpvBits)
HCURSOR WINAPI GetCursor(void)
Definition: cursoricon.c:3078
BOOL WINAPI SetPixelV(_In_ HDC, _In_ int, _In_ int, _In_ COLORREF)
#define DI_MASK
Definition: wingdi.h:71
#define BITSPIXEL
Definition: wingdi.h:720
BOOL WINAPI DeleteDC(_In_ HDC)
#define SW_SHOWNORMAL
Definition: winuser.h:781
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
HICON WINAPI CreateIconFromResource(_In_reads_bytes_(dwResSize) PBYTE presbits, _In_ DWORD dwResSize, _In_ BOOL fIcon, _In_ DWORD dwVer)
#define WM_CLOSE
Definition: winuser.h:1649
#define IMAGE_BITMAP
Definition: winuser.h:211
HICON WINAPI CreateIconIndirect(_In_ PICONINFO)
Definition: cursoricon.c:2975
BOOL WINAPI DestroyCursor(_In_ HCURSOR)
Definition: cursoricon.c:3083
BOOL WINAPI TranslateMessage(_In_ const MSG *)
#define LR_LOADFROMFILE
Definition: winuser.h:1103
BOOL WINAPI AttachThreadInput(_In_ DWORD, _In_ DWORD, _In_ BOOL)
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define IMAGE_ICON
Definition: winuser.h:212
HICON WINAPI CreateIcon(_In_opt_ HINSTANCE, _In_ int, _In_ int, _In_ BYTE, _In_ BYTE, _In_ const BYTE *, _In_ const BYTE *)
Definition: cursoricon.c:2764
BOOL WINAPI GetIconInfo(_In_ HICON, _Out_ PICONINFO)
Definition: cursoricon.c:2414
#define IDI_HAND
Definition: winuser.h:713
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4468
int WINAPI LookupIconIdFromDirectory(_In_reads_bytes_(sizeof(NEWHEADER)) PBYTE, _In_ BOOL)
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define LR_CREATEDIBSECTION
Definition: winuser.h:1109
BOOL WINAPI DrawIcon(_In_ HDC, _In_ int, _In_ int, _In_ HICON)
Definition: cursoricon.c:2387
#define IDC_ARROW
Definition: winuser.h:695
#define LR_MONOCHROME
Definition: winuser.h:1099
int WINAPI ShowCursor(_In_ BOOL)
Definition: cursoricon.c:3071
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define CURSOR_SHOWING
Definition: winuser.h:2700
HCURSOR WINAPI SetCursor(_In_opt_ HCURSOR)
#define DST_ICON
Definition: winuser.h:515
#define CopyCursor(c)
Definition: winuser.h:4388
HANDLE WINAPI CopyImage(_In_ HANDLE, _In_ UINT, _In_ int, _In_ int, _In_ UINT)
Definition: cursoricon.c:2307
HICON WINAPI CreateIconFromResourceEx(_In_reads_bytes_(dwResSize) PBYTE presbits, _In_ DWORD dwResSize, _In_ BOOL fIcon, _In_ DWORD dwVer, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT Flags)
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
#define SM_CYICON
Definition: winuser.h:984
HICON WINAPI LoadIconA(_In_opt_ HINSTANCE hInstance, _In_ LPCSTR lpIconName)
Definition: cursoricon.c:2429
BOOL WINAPI DrawIconEx(_In_ HDC, _In_ int, _In_ int, _In_ HICON, _In_ int, _In_ int, _In_ UINT, _In_opt_ HBRUSH, _In_ UINT)
Definition: cursoricon.c:2397
HDC WINAPI GetDC(_In_opt_ HWND)
#define LR_SHARED
Definition: winuser.h:1111
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
UINT WINAPI PrivateExtractIconsA(_In_reads_(MAX_PATH) LPCSTR szFileName, _In_ int nIconIndex, _In_ int cxIcon, _In_ int cyIcon, _Out_writes_opt_(nIcons) HICON *phicon, _Out_writes_opt_(nIcons) UINT *piconid, _In_ UINT nIcons, _In_ UINT flags)
#define IMAGE_CURSOR
Definition: winuser.h:213
BOOL WINAPI DrawStateA(_In_ HDC, _In_opt_ HBRUSH, _In_opt_ DRAWSTATEPROC, _In_ LPARAM, _In_ WPARAM, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define CS_GLOBALCLASS
Definition: winuser.h:660
HANDLE WINAPI LoadImageA(_In_opt_ HINSTANCE hInst, _In_ LPCSTR name, _In_ UINT type, _In_ int cx, _In_ int cy, _In_ UINT fuLoad)
Definition: cursoricon.c:2547
#define DSS_NORMAL
Definition: winuser.h:517
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define WM_USER
Definition: winuser.h:1923
#define IDC_WAIT
Definition: winuser.h:697
#define WM_DESTROY
Definition: winuser.h:1637
#define LR_DEFAULTSIZE
Definition: winuser.h:1105
HCURSOR WINAPI CreateCursor(_In_opt_ HINSTANCE, _In_ int, _In_ int, _In_ int, _In_ int, _In_ CONST VOID *, _In_ CONST VOID *)
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
#define SM_CXICON
Definition: winuser.h:983
BOOL WINAPI PostMessageA(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define PM_NOREMOVE
Definition: winuser.h:1206
int WINAPI GetSystemMetrics(_In_ int)
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2459
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2422
static HDC hdcDst
Definition: xlate.c:32
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
unsigned char BYTE
Definition: xxhash.c:193