From 1aad2a50ceebc6ee69728f278dc32ce58758023a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 24 Feb 2005 17:03:51 +0000 Subject: [PATCH] Authors: Mike McCormack , Dmitry Timoshkov Release capture before sending WM_NCDESTROY message, do not send WM_CAPTURECHANGED in that case. Add a test case for that behaviour. --- dlls/user/tests/msg.c | 8 ++++++++ windows/win.c | 20 +++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/dlls/user/tests/msg.c b/dlls/user/tests/msg.c index 0881115cfc7..70bae3646c8 100644 --- a/dlls/user/tests/msg.c +++ b/dlls/user/tests/msg.c @@ -4342,6 +4342,7 @@ static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPAR { case WM_NCDESTROY: ok(!GetWindow(hwnd, GW_CHILD), "children should be unlinked at this point\n"); + ok(GetCapture() != hwnd, "capture should be released at this point\n"); /* fall through */ case WM_DESTROY: if (pGetAncestor) @@ -5504,6 +5505,10 @@ static void test_DestroyWindow(void) trace("parent %p, child1 %p, child2 %p, child3 %p, child4 %p\n", parent, child1, child2, child3, child4); + SetCapture(child3); + test = GetCapture(); + ok(test == child3, "wrong capture window %p\n", test); + test_DestroyWindow_flag = TRUE; ok(DestroyWindow(parent), "DestroyWindow() error %ld\n", GetLastError()); test_DestroyWindow_flag = FALSE; @@ -5514,6 +5519,9 @@ static void test_DestroyWindow(void) ok(!IsWindow(child2), "child2 still exists"); ok(!IsWindow(child3), "child3 still exists"); ok(!IsWindow(child4), "child4 still exists"); + + test = GetCapture(); + ok(!test, "wrong capture window %p\n", test); } diff --git a/windows/win.c b/windows/win.c index f443206e58a..1f671703a84 100644 --- a/windows/win.c +++ b/windows/win.c @@ -613,6 +613,23 @@ BOOL WIN_GetRectangles( HWND hwnd, RECT *rectWindow, RECT *rectClient ) } +/*********************************************************************** + * WIN_ReleaseCapture + * + * Internal version of ReleaseCapture which doesn't send WM_CAPTURECHANGED + * message. Used at the window destruction time. + */ +static void WIN_ReleaseCapture( void ) +{ + SERVER_START_REQ( set_capture_window ) + { + req->handle = 0; + req->flags = 0; + wine_server_call_err( req ); + } + SERVER_END_REQ; +} + /*********************************************************************** * WIN_DestroyWindow * @@ -650,6 +667,8 @@ LRESULT WIN_DestroyWindow( HWND hwnd ) RedrawWindow( hwnd, NULL, 0, RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_NOCHILDREN); + if (hwnd == GetCapture()) WIN_ReleaseCapture(); + /* Unlink now so we won't bother with the children later on */ WIN_UnlinkWindow( hwnd ); @@ -661,7 +680,6 @@ LRESULT WIN_DestroyWindow( HWND hwnd ) /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */ WINPOS_CheckInternalPos( hwnd ); - if( hwnd == GetCapture()) ReleaseCapture(); /* free resources associated with the window */