Release capture before sending WM_NCDESTROY message
Dmitry Timoshkov
dmitry at baikal.ru
Thu Feb 24 07:28:23 CST 2005
Hello,
this patch proves that the fix in the Crossover tree which makes sure that
a capture should be released before WM_NCDESTROY was sent is almost correct.
Changelog:
Mike McCormack <mike at codeweavers.com>
Dmitry Timoshkov <dmitry at codeweavers.com>
Release capture before sending WM_NCDESTROY message, do not send
WM_CAPTURECHANGED in that case. Add a test case for that behaviour.
diff -up cvs/hq/wine/dlls/user/tests/msg.c wine/dlls/user/tests/msg.c
--- cvs/hq/wine/dlls/user/tests/msg.c 2005-02-24 16:30:20.000000000 +0800
+++ wine/dlls/user/tests/msg.c 2005-02-24 20:54:58.000000000 +0800
@@ -4342,6 +4342,7 @@ static LRESULT WINAPI MsgCheckProcA(HWND
{
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 -up cvs/hq/wine/windows/win.c wine/windows/win.c
--- cvs/hq/wine/windows/win.c 2005-02-20 20:03:11.000000000 +0800
+++ wine/windows/win.c 2005-02-24 20:58:43.000000000 +0800
@@ -614,6 +614,23 @@ BOOL WIN_GetRectangles( HWND hwnd, RECT
/***********************************************************************
+ * 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
*
* Destroy storage associated to a window. "Internals" p.358
@@ -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 */
More information about the wine-patches
mailing list