Alexandre Julliard : user32: Fix destruction of the active cursor.
Alexandre Julliard
julliard at winehq.org
Wed Oct 13 11:43:09 CDT 2010
Module: wine
Branch: master
Commit: e8723a5dee0134f9a0470d3850eebbdf0bef9889
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e8723a5dee0134f9a0470d3850eebbdf0bef9889
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Oct 13 15:38:06 2010 +0200
user32: Fix destruction of the active cursor.
---
dlls/user32/cursoricon.c | 44 ++++++++++++++++++---------------------
dlls/user32/tests/cursoricon.c | 10 ++++----
2 files changed, 25 insertions(+), 29 deletions(-)
diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c
index 9732db6..eeaae7a 100644
--- a/dlls/user32/cursoricon.c
+++ b/dlls/user32/cursoricon.c
@@ -387,22 +387,6 @@ static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
}
/**********************************************************************
- * is_icon_shared
- */
-static BOOL is_icon_shared( HICON handle )
-{
- struct cursoricon_object *info;
- BOOL ret = FALSE;
-
- if ((info = get_icon_ptr( handle )))
- {
- ret = info->rsrc != NULL;
- release_icon_ptr( handle, info );
- }
- return ret;
-}
-
-/**********************************************************************
* get_icon_size
*/
BOOL get_icon_size( HICON handle, SIZE *size )
@@ -1357,7 +1341,11 @@ HICON WINAPI CopyIcon( HICON hIcon )
struct cursoricon_object *ptrOld, *ptrNew;
HICON hNew;
- if (!(ptrOld = get_icon_ptr( hIcon ))) return 0;
+ if (!(ptrOld = get_icon_ptr( hIcon )))
+ {
+ SetLastError( ERROR_INVALID_CURSOR_HANDLE );
+ return 0;
+ }
if ((hNew = alloc_icon_handle(1)))
{
ptrNew = get_icon_ptr( hNew );
@@ -1381,10 +1369,19 @@ HICON WINAPI CopyIcon( HICON hIcon )
*/
BOOL WINAPI DestroyIcon( HICON hIcon )
{
+ BOOL ret = FALSE;
+ struct cursoricon_object *obj = get_icon_ptr( hIcon );
+
TRACE_(icon)("%p\n", hIcon );
- if (!is_icon_shared( hIcon )) free_icon_handle( hIcon );
- return TRUE;
+ if (obj)
+ {
+ BOOL shared = (obj->rsrc != NULL);
+ release_icon_ptr( hIcon, obj );
+ ret = (GetCursor() != hIcon);
+ if (!shared) free_icon_handle( hIcon );
+ }
+ return ret;
}
@@ -1393,11 +1390,6 @@ BOOL WINAPI DestroyIcon( HICON hIcon )
*/
BOOL WINAPI DestroyCursor( HCURSOR hCursor )
{
- if (GetCursor() == hCursor)
- {
- WARN_(cursor)("Destroying active cursor!\n" );
- return FALSE;
- }
return DestroyIcon( hCursor );
}
@@ -1419,6 +1411,7 @@ BOOL WINAPI DrawIcon( HDC hdc, INT x, INT y, HICON hIcon )
*/
HCURSOR WINAPI DECLSPEC_HOTPATCH SetCursor( HCURSOR hCursor /* [in] Handle of cursor to show */ )
{
+ struct cursoricon_object *obj;
HCURSOR hOldCursor;
int show_count;
BOOL ret;
@@ -1441,6 +1434,9 @@ HCURSOR WINAPI DECLSPEC_HOTPATCH SetCursor( HCURSOR hCursor /* [in] Handle of cu
/* Change the cursor shape only if it is visible */
if (show_count >= 0 && hOldCursor != hCursor) USER_Driver->pSetCursor( hCursor );
+
+ if (!(obj = get_icon_ptr( hOldCursor ))) return 0;
+ release_icon_ptr( hOldCursor, obj );
return hOldCursor;
}
diff --git a/dlls/user32/tests/cursoricon.c b/dlls/user32/tests/cursoricon.c
index 57419e5..8f7db52 100644
--- a/dlls/user32/tests/cursoricon.c
+++ b/dlls/user32/tests/cursoricon.c
@@ -82,7 +82,7 @@ static LRESULT CALLBACK callback_child(HWND hwnd, UINT msg, WPARAM wParam, LPARA
SetLastError(0xdeadbeef);
ret = DestroyCursor((HCURSOR) lParam);
error = GetLastError();
- todo_wine ok(!ret || broken(ret) /* win9x */, "DestroyCursor on the active cursor succeeded.\n");
+ ok(!ret || broken(ret) /* win9x */, "DestroyCursor on the active cursor succeeded.\n");
ok(error == ERROR_DESTROY_OBJECT_OF_OTHER_THREAD ||
error == 0xdeadbeef, /* vista */
"Last error: %u\n", error);
@@ -1769,8 +1769,8 @@ static void test_DestroyCursor(void)
SetLastError(0xdeadbeef);
ret = GetIconInfo( cursor, &new_info );
- todo_wine ok( !ret || broken(ret), /* nt4 */ "GetIconInfo succeeded\n" );
- todo_wine ok( GetLastError() == ERROR_INVALID_CURSOR_HANDLE ||
+ ok( !ret || broken(ret), /* nt4 */ "GetIconInfo succeeded\n" );
+ ok( GetLastError() == ERROR_INVALID_CURSOR_HANDLE ||
broken(GetLastError() == 0xdeadbeef), /* win9x */
"wrong error %u\n", GetLastError() );
@@ -1824,7 +1824,7 @@ static void test_DestroyCursor(void)
if (new_cursor != cursor) /* win9x */
ok(cursor2 == new_cursor, "SetCursor returned %p/%p\n", cursor2, cursor);
else
- todo_wine ok(!cursor2, "SetCursor returned %p/%p\n", cursor2, cursor);
+ ok(!cursor2, "SetCursor returned %p/%p\n", cursor2, cursor);
ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
cursor2 = GetCursor();
@@ -1835,7 +1835,7 @@ static void test_DestroyCursor(void)
if (new_cursor != cursor) /* win9x */
ok( ret, "DestroyCursor succeeded\n" );
else
- todo_wine ok( !ret, "DestroyCursor succeeded\n" );
+ ok( !ret, "DestroyCursor succeeded\n" );
error = GetLastError();
ok( GetLastError() == ERROR_INVALID_CURSOR_HANDLE || GetLastError() == 0xdeadbeef,
"wrong error %u\n", GetLastError() );
More information about the wine-cvs
mailing list