Module: wine Branch: master Commit: e8723a5dee0134f9a0470d3850eebbdf0bef9889 URL: http://source.winehq.org/git/wine.git/?a=commit;h=e8723a5dee0134f9a0470d3850...
Author: Alexandre Julliard julliard@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() );