2 * Unit test suite for cursors and icons.
4 * Copyright 2006 Michael Kaufmann
5 * Copyright 2007 Dmitry Timoshkov
6 * Copyright 2007 Andrew Riedi
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.
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.
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
28 #include "wine/test.h"
35 static char **test_argv
;
37 static HWND child
= 0;
38 static HWND parent
= 0;
39 static HANDLE child_process
;
41 #define PROC_INIT (WM_USER+1)
43 static LRESULT CALLBACK
callback_child(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
50 /* Destroy the cursor. */
52 SetLastError(0xdeadbeef);
53 ret
= DestroyCursor((HCURSOR
) lParam
);
54 error
= GetLastError();
56 ok(!ret
, "DestroyCursor on the active cursor succeeded.\n");
57 ok(error
== ERROR_DESTROY_OBJECT_OF_OTHER_THREAD
,
58 "Last error: %u\n", error
);
66 return DefWindowProc(hwnd
, msg
, wParam
, lParam
);
69 static LRESULT CALLBACK
callback_parent(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
73 child
= (HWND
) wParam
;
77 return DefWindowProc(hwnd
, msg
, wParam
, lParam
);
80 static void do_child(void)
86 /* Register a new class. */
87 class.style
= CS_GLOBALCLASS
;
88 class.lpfnWndProc
= callback_child
;
91 class.hInstance
= GetModuleHandle(NULL
);
94 class.hbrBackground
= NULL
;
95 class.lpszMenuName
= NULL
;
96 class.lpszClassName
= "cursor_child";
98 SetLastError(0xdeadbeef);
99 ret
= RegisterClass(&class);
100 ok(ret
, "Failed to register window class. Error: %u\n", GetLastError());
102 /* Create a window. */
103 child
= CreateWindowA("cursor_child", "cursor_child", WS_POPUP
| WS_VISIBLE
,
104 0, 0, 200, 200, 0, 0, 0, NULL
);
105 ok(child
!= 0, "CreateWindowA failed. Error: %u\n", GetLastError());
107 /* Let the parent know our HWND. */
108 PostMessage(parent
, PROC_INIT
, (WPARAM
) child
, 0);
110 /* Receive messages. */
111 while ((ret
= GetMessage(&msg
, child
, 0, 0)))
113 ok(ret
!= -1, "GetMessage failed. Error: %u\n", GetLastError());
114 TranslateMessage(&msg
);
115 DispatchMessage(&msg
);
119 static void do_parent(void)
121 char path_name
[MAX_PATH
];
122 PROCESS_INFORMATION info
;
123 STARTUPINFOA startup
;
128 /* Register a new class. */
129 class.style
= CS_GLOBALCLASS
;
130 class.lpfnWndProc
= callback_parent
;
131 class.cbClsExtra
= 0;
132 class.cbWndExtra
= 0;
133 class.hInstance
= GetModuleHandle(NULL
);
135 class.hCursor
= NULL
;
136 class.hbrBackground
= NULL
;
137 class.lpszMenuName
= NULL
;
138 class.lpszClassName
= "cursor_parent";
140 SetLastError(0xdeadbeef);
141 ret
= RegisterClass(&class);
142 ok(ret
, "Failed to register window class. Error: %u\n", GetLastError());
144 /* Create a window. */
145 parent
= CreateWindowA("cursor_parent", "cursor_parent", WS_POPUP
| WS_VISIBLE
,
146 0, 0, 200, 200, 0, 0, 0, NULL
);
147 ok(parent
!= 0, "CreateWindowA failed. Error: %u\n", GetLastError());
149 /* Start child process. */
150 memset(&startup
, 0, sizeof(startup
));
151 startup
.cb
= sizeof(startup
);
152 startup
.dwFlags
= STARTF_USESHOWWINDOW
;
153 startup
.wShowWindow
= SW_SHOWNORMAL
;
155 sprintf(path_name
, "%s cursoricon %x", test_argv
[0], (unsigned int) parent
);
156 ok(CreateProcessA(NULL
, path_name
, NULL
, NULL
, FALSE
, 0L, NULL
, NULL
, &startup
, &info
), "CreateProcess failed.\n");
157 child_process
= info
.hProcess
;
159 /* Wait for child window handle. */
160 while ((child
== 0) && (ret
= GetMessage(&msg
, parent
, 0, 0)))
162 ok(ret
!= -1, "GetMessage failed. Error: %u\n", GetLastError());
163 TranslateMessage(&msg
);
164 DispatchMessage(&msg
);
168 static void finish_child_process(void)
170 SendMessage(child
, WM_CLOSE
, 0, 0);
171 winetest_wait_child_process( child_process
);
172 CloseHandle(child_process
);
175 static void test_child_process(void)
177 static const BYTE bmp_bits
[4096];
183 /* Create and set a dummy cursor. */
185 display_bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
188 cursorInfo
.fIcon
= FALSE
;
189 cursorInfo
.xHotspot
= 0;
190 cursorInfo
.yHotspot
= 0;
191 cursorInfo
.hbmMask
= CreateBitmap(32, 32, 1, 1, bmp_bits
);
192 cursorInfo
.hbmColor
= CreateBitmap(32, 32, 1, display_bpp
, bmp_bits
);
194 cursor
= CreateIconIndirect(&cursorInfo
);
195 ok(cursor
!= NULL
, "CreateIconIndirect returned %p.\n", cursor
);
199 /* Destroy the cursor. */
200 SendMessage(child
, WM_USER
+1, 0, (LPARAM
) cursor
);
203 static void test_CopyImage_Check(HBITMAP bitmap
, UINT flags
, INT copyWidth
, INT copyHeight
,
204 INT expectedWidth
, INT expectedHeight
, WORD expectedDepth
, BOOL dibExpected
)
212 copy
= (HBITMAP
) CopyImage(bitmap
, IMAGE_BITMAP
, copyWidth
, copyHeight
, flags
);
213 ok(copy
!= NULL
, "CopyImage() failed\n");
216 GetObject(bitmap
, sizeof(origBitmap
), &origBitmap
);
217 GetObject(copy
, sizeof(copyBitmap
), ©Bitmap
);
218 orig_is_dib
= (origBitmap
.bmBits
!= NULL
);
219 copy_is_dib
= (copyBitmap
.bmBits
!= NULL
);
221 if (copy_is_dib
&& dibExpected
222 && copyBitmap
.bmBitsPixel
== 24
223 && (expectedDepth
== 16 || expectedDepth
== 32))
225 /* Windows 95 doesn't create DIBs with a depth of 16 or 32 bit */
226 if (GetVersion() & 0x80000000)
232 if (copy_is_dib
&& !dibExpected
&& !(flags
& LR_CREATEDIBSECTION
))
234 /* It's not forbidden to create a DIB section if the flag
235 LR_CREATEDIBSECTION is absent.
236 Windows 9x does this if the bitmap has a depth that doesn't
237 match the screen depth, Windows NT doesn't */
239 expectedDepth
= origBitmap
.bmBitsPixel
;
242 ok((!(dibExpected
^ copy_is_dib
)
243 && (copyBitmap
.bmWidth
== expectedWidth
)
244 && (copyBitmap
.bmHeight
== expectedHeight
)
245 && (copyBitmap
.bmBitsPixel
== expectedDepth
)),
246 "CopyImage ((%s, %dx%d, %u bpp), %d, %d, %#x): Expected (%s, %dx%d, %u bpp), got (%s, %dx%d, %u bpp)\n",
247 orig_is_dib
? "DIB" : "DDB", origBitmap
.bmWidth
, origBitmap
.bmHeight
, origBitmap
.bmBitsPixel
,
248 copyWidth
, copyHeight
, flags
,
249 dibExpected
? "DIB" : "DDB", expectedWidth
, expectedHeight
, expectedDepth
,
250 copy_is_dib
? "DIB" : "DDB", copyBitmap
.bmWidth
, copyBitmap
.bmHeight
, copyBitmap
.bmBitsPixel
);
256 static void test_CopyImage_Bitmap(int depth
)
265 /* Create a device-independent bitmap (DIB) */
266 info
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
));
267 info
->bmiHeader
.biSize
= sizeof(info
->bmiHeader
);
268 info
->bmiHeader
.biWidth
= 2;
269 info
->bmiHeader
.biHeight
= 2;
270 info
->bmiHeader
.biPlanes
= 1;
271 info
->bmiHeader
.biBitCount
= depth
;
272 info
->bmiHeader
.biCompression
= BI_RGB
;
274 for (i
=0; i
< 256; i
++)
276 info
->bmiColors
[i
].rgbRed
= i
;
277 info
->bmiColors
[i
].rgbGreen
= i
;
278 info
->bmiColors
[i
].rgbBlue
= 255 - i
;
279 info
->bmiColors
[i
].rgbReserved
= 0;
282 dib
= CreateDIBSection(NULL
, info
, DIB_RGB_COLORS
, &bits
, NULL
, 0);
284 /* Create a device-dependent bitmap (DDB) */
285 screenDC
= GetDC(NULL
);
286 screen_depth
= GetDeviceCaps(screenDC
, BITSPIXEL
);
287 if (depth
== 1 || depth
== screen_depth
)
289 ddb
= CreateBitmap(2, 2, 1, depth
, NULL
);
295 ReleaseDC(NULL
, screenDC
);
299 test_CopyImage_Check(ddb
, 0, 0, 0, 2, 2, depth
== 1 ? 1 : screen_depth
, FALSE
);
300 test_CopyImage_Check(ddb
, 0, 0, 5, 2, 5, depth
== 1 ? 1 : screen_depth
, FALSE
);
301 test_CopyImage_Check(ddb
, 0, 5, 0, 5, 2, depth
== 1 ? 1 : screen_depth
, FALSE
);
302 test_CopyImage_Check(ddb
, 0, 5, 5, 5, 5, depth
== 1 ? 1 : screen_depth
, FALSE
);
304 test_CopyImage_Check(ddb
, LR_MONOCHROME
, 0, 0, 2, 2, 1, FALSE
);
305 test_CopyImage_Check(ddb
, LR_MONOCHROME
, 5, 0, 5, 2, 1, FALSE
);
306 test_CopyImage_Check(ddb
, LR_MONOCHROME
, 0, 5, 2, 5, 1, FALSE
);
307 test_CopyImage_Check(ddb
, LR_MONOCHROME
, 5, 5, 5, 5, 1, FALSE
);
309 test_CopyImage_Check(ddb
, LR_CREATEDIBSECTION
, 0, 0, 2, 2, depth
, TRUE
);
310 test_CopyImage_Check(ddb
, LR_CREATEDIBSECTION
, 5, 0, 5, 2, depth
, TRUE
);
311 test_CopyImage_Check(ddb
, LR_CREATEDIBSECTION
, 0, 5, 2, 5, depth
, TRUE
);
312 test_CopyImage_Check(ddb
, LR_CREATEDIBSECTION
, 5, 5, 5, 5, depth
, TRUE
);
314 /* LR_MONOCHROME is ignored if LR_CREATEDIBSECTION is present */
315 test_CopyImage_Check(ddb
, LR_MONOCHROME
| LR_CREATEDIBSECTION
, 0, 0, 2, 2, depth
, TRUE
);
316 test_CopyImage_Check(ddb
, LR_MONOCHROME
| LR_CREATEDIBSECTION
, 5, 0, 5, 2, depth
, TRUE
);
317 test_CopyImage_Check(ddb
, LR_MONOCHROME
| LR_CREATEDIBSECTION
, 0, 5, 2, 5, depth
, TRUE
);
318 test_CopyImage_Check(ddb
, LR_MONOCHROME
| LR_CREATEDIBSECTION
, 5, 5, 5, 5, depth
, TRUE
);
325 test_CopyImage_Check(dib
, 0, 0, 0, 2, 2, screen_depth
, FALSE
);
326 test_CopyImage_Check(dib
, 0, 5, 0, 5, 2, screen_depth
, FALSE
);
327 test_CopyImage_Check(dib
, 0, 0, 5, 2, 5, screen_depth
, FALSE
);
328 test_CopyImage_Check(dib
, 0, 5, 5, 5, 5, screen_depth
, FALSE
);
331 test_CopyImage_Check(dib
, LR_MONOCHROME
, 0, 0, 2, 2, 1, FALSE
);
332 test_CopyImage_Check(dib
, LR_MONOCHROME
, 5, 0, 5, 2, 1, FALSE
);
333 test_CopyImage_Check(dib
, LR_MONOCHROME
, 0, 5, 2, 5, 1, FALSE
);
334 test_CopyImage_Check(dib
, LR_MONOCHROME
, 5, 5, 5, 5, 1, FALSE
);
336 test_CopyImage_Check(dib
, LR_CREATEDIBSECTION
, 0, 0, 2, 2, depth
, TRUE
);
337 test_CopyImage_Check(dib
, LR_CREATEDIBSECTION
, 5, 0, 5, 2, depth
, TRUE
);
338 test_CopyImage_Check(dib
, LR_CREATEDIBSECTION
, 0, 5, 2, 5, depth
, TRUE
);
339 test_CopyImage_Check(dib
, LR_CREATEDIBSECTION
, 5, 5, 5, 5, depth
, TRUE
);
341 /* LR_MONOCHROME is ignored if LR_CREATEDIBSECTION is present */
342 test_CopyImage_Check(dib
, LR_MONOCHROME
| LR_CREATEDIBSECTION
, 0, 0, 2, 2, depth
, TRUE
);
343 test_CopyImage_Check(dib
, LR_MONOCHROME
| LR_CREATEDIBSECTION
, 5, 0, 5, 2, depth
, TRUE
);
344 test_CopyImage_Check(dib
, LR_MONOCHROME
| LR_CREATEDIBSECTION
, 0, 5, 2, 5, depth
, TRUE
);
345 test_CopyImage_Check(dib
, LR_MONOCHROME
| LR_CREATEDIBSECTION
, 5, 5, 5, 5, depth
, TRUE
);
351 /* Special case: A monochrome DIB is converted to a monochrome DDB if
352 the colors in the color table are black and white.
354 Skip this test on Windows 95, it always creates a monochrome DDB
357 if (!(GetVersion() & 0x80000000))
359 info
->bmiHeader
.biBitCount
= 1;
360 info
->bmiColors
[0].rgbRed
= 0xFF;
361 info
->bmiColors
[0].rgbGreen
= 0;
362 info
->bmiColors
[0].rgbBlue
= 0;
363 info
->bmiColors
[1].rgbRed
= 0;
364 info
->bmiColors
[1].rgbGreen
= 0xFF;
365 info
->bmiColors
[1].rgbBlue
= 0;
367 dib
= CreateDIBSection(NULL
, info
, DIB_RGB_COLORS
, &bits
, NULL
, 0);
368 test_CopyImage_Check(dib
, 0, 0, 0, 2, 2, screen_depth
, FALSE
);
369 test_CopyImage_Check(dib
, 0, 5, 0, 5, 2, screen_depth
, FALSE
);
370 test_CopyImage_Check(dib
, 0, 0, 5, 2, 5, screen_depth
, FALSE
);
371 test_CopyImage_Check(dib
, 0, 5, 5, 5, 5, screen_depth
, FALSE
);
374 info
->bmiHeader
.biBitCount
= 1;
375 info
->bmiColors
[0].rgbRed
= 0;
376 info
->bmiColors
[0].rgbGreen
= 0;
377 info
->bmiColors
[0].rgbBlue
= 0;
378 info
->bmiColors
[1].rgbRed
= 0xFF;
379 info
->bmiColors
[1].rgbGreen
= 0xFF;
380 info
->bmiColors
[1].rgbBlue
= 0xFF;
382 dib
= CreateDIBSection(NULL
, info
, DIB_RGB_COLORS
, &bits
, NULL
, 0);
383 test_CopyImage_Check(dib
, 0, 0, 0, 2, 2, 1, FALSE
);
384 test_CopyImage_Check(dib
, 0, 5, 0, 5, 2, 1, FALSE
);
385 test_CopyImage_Check(dib
, 0, 0, 5, 2, 5, 1, FALSE
);
386 test_CopyImage_Check(dib
, 0, 5, 5, 5, 5, 1, FALSE
);
389 info
->bmiHeader
.biBitCount
= 1;
390 info
->bmiColors
[0].rgbRed
= 0xFF;
391 info
->bmiColors
[0].rgbGreen
= 0xFF;
392 info
->bmiColors
[0].rgbBlue
= 0xFF;
393 info
->bmiColors
[1].rgbRed
= 0;
394 info
->bmiColors
[1].rgbGreen
= 0;
395 info
->bmiColors
[1].rgbBlue
= 0;
397 dib
= CreateDIBSection(NULL
, info
, DIB_RGB_COLORS
, &bits
, NULL
, 0);
398 test_CopyImage_Check(dib
, 0, 0, 0, 2, 2, 1, FALSE
);
399 test_CopyImage_Check(dib
, 0, 5, 0, 5, 2, 1, FALSE
);
400 test_CopyImage_Check(dib
, 0, 0, 5, 2, 5, 1, FALSE
);
401 test_CopyImage_Check(dib
, 0, 5, 5, 5, 5, 1, FALSE
);
406 HeapFree(GetProcessHeap(), 0, info
);
409 static void test_initial_cursor(void)
411 HCURSOR cursor
, cursor2
;
414 cursor
= GetCursor();
416 /* Check what handle GetCursor() returns if a cursor is not set yet. */
417 SetLastError(0xdeadbeef);
418 cursor2
= LoadCursor(NULL
, IDC_WAIT
);
420 ok(cursor
== cursor2
, "cursor (%p) is not IDC_WAIT (%p).\n", cursor
, cursor2
);
422 error
= GetLastError();
423 ok(error
== 0xdeadbeef, "Last error: 0x%08x\n", error
);
426 static void test_icon_info_dbg(HICON hIcon
, UINT exp_cx
, UINT exp_cy
, UINT exp_bpp
, int line
)
430 BITMAP bmMask
, bmColor
;
432 ret
= GetIconInfo(hIcon
, &info
);
433 ok_(__FILE__
, line
)(ret
, "GetIconInfo failed\n");
435 /* CreateIcon under XP causes info.fIcon to be 0 */
436 ok_(__FILE__
, line
)(info
.xHotspot
== exp_cx
/2, "info.xHotspot = %u\n", info
.xHotspot
);
437 ok_(__FILE__
, line
)(info
.yHotspot
== exp_cy
/2, "info.yHotspot = %u\n", info
.yHotspot
);
438 ok_(__FILE__
, line
)(info
.hbmMask
!= 0, "info.hbmMask is NULL\n");
440 ret
= GetObject(info
.hbmMask
, sizeof(bmMask
), &bmMask
);
441 ok_(__FILE__
, line
)(ret
== sizeof(bmMask
), "GetObject(info.hbmMask) failed, ret %u\n", ret
);
444 ok_(__FILE__
, line
)(info
.hbmColor
== 0, "info.hbmColor should be NULL\n");
452 display_bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
455 ret
= GetObject(info
.hbmColor
, sizeof(bmColor
), &bmColor
);
456 ok_(__FILE__
, line
)(ret
== sizeof(bmColor
), "GetObject(info.hbmColor) failed, ret %u\n", ret
);
458 ok_(__FILE__
, line
)(bmColor
.bmBitsPixel
== display_bpp
/* XP */ ||
459 bmColor
.bmBitsPixel
== exp_bpp
/* Win98 */,
460 "bmColor.bmBitsPixel = %d\n", bmColor
.bmBitsPixel
);
461 ok_(__FILE__
, line
)(bmColor
.bmWidth
== exp_cx
, "bmColor.bmWidth = %d\n", bmColor
.bmWidth
);
462 ok_(__FILE__
, line
)(bmColor
.bmHeight
== exp_cy
, "bmColor.bmHeight = %d\n", bmColor
.bmHeight
);
464 ok_(__FILE__
, line
)(bmMask
.bmBitsPixel
== 1, "bmMask.bmBitsPixel = %d\n", bmMask
.bmBitsPixel
);
465 ok_(__FILE__
, line
)(bmMask
.bmWidth
== exp_cx
, "bmMask.bmWidth = %d\n", bmMask
.bmWidth
);
466 ok_(__FILE__
, line
)(bmMask
.bmHeight
== exp_cy
, "bmMask.bmHeight = %d\n", bmMask
.bmHeight
);
470 ok_(__FILE__
, line
)(bmMask
.bmBitsPixel
== 1, "bmMask.bmBitsPixel = %d\n", bmMask
.bmBitsPixel
);
471 ok_(__FILE__
, line
)(bmMask
.bmWidth
== exp_cx
, "bmMask.bmWidth = %d\n", bmMask
.bmWidth
);
472 ok_(__FILE__
, line
)(bmMask
.bmHeight
== exp_cy
* 2, "bmMask.bmHeight = %d\n", bmMask
.bmHeight
);
476 #define test_icon_info(a,b,c,d) test_icon_info_dbg((a),(b),(c),(d),__LINE__)
478 static void test_CreateIcon(void)
480 static const BYTE bmp_bits
[1024];
482 HBITMAP hbmMask
, hbmColor
;
488 display_bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
491 /* these crash under XP
492 hIcon = CreateIcon(0, 16, 16, 1, 1, bmp_bits, NULL);
493 hIcon = CreateIcon(0, 16, 16, 1, 1, NULL, bmp_bits);
496 hIcon
= CreateIcon(0, 16, 16, 1, 1, bmp_bits
, bmp_bits
);
497 ok(hIcon
!= 0, "CreateIcon failed\n");
498 test_icon_info(hIcon
, 16, 16, 1);
501 hIcon
= CreateIcon(0, 16, 16, 1, display_bpp
, bmp_bits
, bmp_bits
);
502 ok(hIcon
!= 0, "CreateIcon failed\n");
503 test_icon_info(hIcon
, 16, 16, display_bpp
);
506 hbmMask
= CreateBitmap(16, 16, 1, 1, bmp_bits
);
507 ok(hbmMask
!= 0, "CreateBitmap failed\n");
508 hbmColor
= CreateBitmap(16, 16, 1, display_bpp
, bmp_bits
);
509 ok(hbmColor
!= 0, "CreateBitmap failed\n");
516 SetLastError(0xdeadbeaf);
517 hIcon
= CreateIconIndirect(&info
);
518 ok(!hIcon
, "CreateIconIndirect should fail\n");
519 ok(GetLastError() == 0xdeadbeaf, "wrong error %u\n", GetLastError());
525 info
.hbmColor
= hbmColor
;
526 SetLastError(0xdeadbeaf);
527 hIcon
= CreateIconIndirect(&info
);
528 ok(!hIcon
, "CreateIconIndirect should fail\n");
529 ok(GetLastError() == 0xdeadbeaf, "wrong error %u\n", GetLastError());
534 info
.hbmMask
= hbmMask
;
535 info
.hbmColor
= hbmColor
;
536 hIcon
= CreateIconIndirect(&info
);
537 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
538 test_icon_info(hIcon
, 16, 16, display_bpp
);
541 DeleteObject(hbmMask
);
542 DeleteObject(hbmColor
);
544 hbmMask
= CreateBitmap(16, 32, 1, 1, bmp_bits
);
545 ok(hbmMask
!= 0, "CreateBitmap failed\n");
550 info
.hbmMask
= hbmMask
;
552 SetLastError(0xdeadbeaf);
553 hIcon
= CreateIconIndirect(&info
);
554 ok(hIcon
!= 0, "CreateIconIndirect failed\n");
555 test_icon_info(hIcon
, 16, 16, 1);
558 DeleteObject(hbmMask
);
559 DeleteObject(hbmColor
);
562 static void test_DestroyCursor(void)
564 static const BYTE bmp_bits
[4096];
566 HCURSOR cursor
, cursor2
;
573 display_bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
576 cursorInfo
.fIcon
= FALSE
;
577 cursorInfo
.xHotspot
= 0;
578 cursorInfo
.yHotspot
= 0;
579 cursorInfo
.hbmMask
= CreateBitmap(32, 32, 1, 1, bmp_bits
);
580 cursorInfo
.hbmColor
= CreateBitmap(32, 32, 1, display_bpp
, bmp_bits
);
582 cursor
= CreateIconIndirect(&cursorInfo
);
583 ok(cursor
!= NULL
, "CreateIconIndirect returned %p\n", cursor
);
589 SetLastError(0xdeadbeef);
590 ret
= DestroyCursor(cursor
);
591 ok(!ret
, "DestroyCursor on the active cursor succeeded\n");
592 error
= GetLastError();
593 ok(error
== 0xdeadbeef, "Last error: %u\n", error
);
595 cursor2
= GetCursor();
596 ok(cursor2
== cursor
, "Active was set to %p when trying to destroy it\n", cursor2
);
600 /* Trying to destroy the cursor properly fails now with
601 * ERROR_INVALID_CURSOR_HANDLE. This happens because we called
602 * DestroyCursor() 2+ times after calling SetCursor(). The calls to
603 * GetCursor() and SetCursor(NULL) in between make no difference. */
604 ret
= DestroyCursor(cursor
);
606 ok(!ret
, "DestroyCursor succeeded.\n");
607 error
= GetLastError();
608 ok(error
== ERROR_INVALID_CURSOR_HANDLE
, "Last error: 0x%08x\n", error
);
611 DeleteObject(cursorInfo
.hbmMask
);
612 DeleteObject(cursorInfo
.hbmColor
);
614 /* Try testing DestroyCursor() now using LoadCursor() cursors. */
615 cursor
= LoadCursor(NULL
, IDC_ARROW
);
617 SetLastError(0xdeadbeef);
618 ret
= DestroyCursor(cursor
);
619 ok(ret
, "DestroyCursor on the active cursor failed.\n");
620 error
= GetLastError();
621 ok(error
== 0xdeadbeef, "Last error: 0x%08x\n", error
);
623 /* Try setting the cursor to a destroyed OEM cursor. */
624 SetLastError(0xdeadbeef);
626 error
= GetLastError();
628 ok(error
== 0xdeadbeef, "Last error: 0x%08x\n", error
);
631 /* Check if LoadCursor() returns the same handle with the same icon. */
632 cursor2
= LoadCursor(NULL
, IDC_ARROW
);
633 ok(cursor2
== cursor
, "cursor == %p, cursor2 == %p\n", cursor
, cursor2
);
635 /* Check if LoadCursor() returns the same handle with a different icon. */
636 cursor2
= LoadCursor(NULL
, IDC_WAIT
);
637 ok(cursor2
!= cursor
, "cursor == %p, cursor2 == %p\n", cursor
, cursor2
);
640 START_TEST(cursoricon
)
642 test_argc
= winetest_get_mainargs(&test_argv
);
647 sscanf (test_argv
[2], "%x", (unsigned int *) &parent
);
649 ok(parent
!= NULL
, "Parent not found.\n");
657 test_CopyImage_Bitmap(1);
658 test_CopyImage_Bitmap(4);
659 test_CopyImage_Bitmap(8);
660 test_CopyImage_Bitmap(16);
661 test_CopyImage_Bitmap(24);
662 test_CopyImage_Bitmap(32);
663 test_initial_cursor();
665 test_DestroyCursor();
667 test_child_process();
668 finish_child_process();