Propagate WM_QUIT messages to outer modal loops

Michael Kaufmann hallo at michael-kaufmann.ch
Tue Jun 20 17:04:24 CDT 2006


Changelog:
- Propagate WM_QUIT messages to outer modal loops as described at 
http://blogs.msdn.com/oldnewthing/archive/2005/02/22/378018.aspx
- Handle WM_QUIT messages even if a message filter has been specified 
for GetMessage() or PeekMessage(), since WM_QUIT is returned despite of 
the filter
- Fix bug 1918
-------------- next part --------------
Index: dlls/comctl32/propsheet.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/propsheet.c,v
retrieving revision 1.150
diff -u -r1.150 propsheet.c
--- dlls/comctl32/propsheet.c	14 Jun 2006 11:54:54 -0000	1.150
+++ dlls/comctl32/propsheet.c	20 Jun 2006 21:48:44 -0000
@@ -2745,6 +2745,8 @@
 
     if(ret == 0)
     {
+        /* Re-post the WM_QUIT message in order to notify the
+           outer message loop */
         PostQuitMessage(msg.wParam);
         ret = -1;
     }
Index: dlls/comctl32/toolbar.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/toolbar.c,v
retrieving revision 1.230
diff -u -r1.230 toolbar.c
--- dlls/comctl32/toolbar.c	23 May 2006 12:47:38 -0000	1.230
+++ dlls/comctl32/toolbar.c	20 Jun 2006 21:48:47 -0000
@@ -5975,7 +5975,15 @@
                  * so that we can get a toggle effect on the button */
                 while (PeekMessageW(&msg, hwnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_REMOVE) ||
                        PeekMessageW(&msg, hwnd, WM_LBUTTONDBLCLK, WM_LBUTTONDBLCLK, PM_REMOVE))
-                    ;
+                {
+                    if (msg.message == WM_QUIT)
+                    {
+                        /* Re-post the WM_QUIT message in order to notify the
+                           outer message loop */
+                        PostQuitMessage(msg.wParam);
+                        break;
+                    }
+                }
 
 		return 0;
             }
Index: dlls/comctl32/treeview.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/treeview.c,v
retrieving revision 1.182
diff -u -r1.182 treeview.c
--- dlls/comctl32/treeview.c	23 May 2006 12:47:38 -0000	1.182
+++ dlls/comctl32/treeview.c	20 Jun 2006 21:48:50 -0000
@@ -3847,7 +3847,14 @@
     {
 	if (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD))
 	{
-	    if (msg.message == WM_MOUSEMOVE)
+	    if (msg.message == WM_QUIT)
+	    {
+		/* Re-post the WM_QUIT message in order to notify the
+		   outer message loop */
+		PostQuitMessage(msg.wParam);
+		break;
+	    }
+	    else if (msg.message == WM_MOUSEMOVE)
 	    {
 		pt.x = (short)LOWORD(msg.lParam);
 		pt.y = (short)HIWORD(msg.lParam);
Index: dlls/msi/dialog.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/dialog.c,v
retrieving revision 1.78
diff -u -r1.78 dialog.c
--- dlls/msi/dialog.c	12 Jun 2006 12:12:27 -0000	1.78
+++ dlls/msi/dialog.c	20 Jun 2006 21:48:55 -0000
@@ -2332,6 +2332,13 @@
 
     while( PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ) )
     {
+        if (msg.message == WM_QUIT)
+        {
+            /* Re-post the WM_QUIT message in order to notify the
+               outer message loop */
+            PostQuitMessage(msg.wParam);
+            break;
+        }
         if( hdlg && IsDialogMessageW( hdlg, &msg ))
             continue;
         TranslateMessage( &msg );
Index: dlls/user/dde_client.c
===================================================================
RCS file: /home/wine/wine/dlls/user/dde_client.c,v
retrieving revision 1.6
diff -u -r1.6 dde_client.c
--- dlls/user/dde_client.c	23 May 2006 12:48:46 -0000	1.6
+++ dlls/user/dde_client.c	20 Jun 2006 21:49:00 -0000
@@ -1039,6 +1039,14 @@
                 WDML_CONV *pConv;
                 HDDEDATA hdd;
 
+                if (msg.message == WM_QUIT)
+                {
+                    /* Re-post the WM_QUIT message in order to notify the
+                       outer message loop */
+                    PostQuitMessage(msg.wParam);
+                    break;
+                }
+
                 EnterCriticalSection(&WDML_CritSect);
 
                 pConv = WDML_GetConv(hConv, FALSE);
Index: dlls/user/dialog.c
===================================================================
RCS file: /home/wine/wine/dlls/user/dialog.c,v
retrieving revision 1.11
diff -u -r1.11 dialog.c
--- dlls/user/dialog.c	23 May 2006 12:48:46 -0000	1.11
+++ dlls/user/dialog.c	20 Jun 2006 21:49:01 -0000
@@ -742,13 +742,21 @@
                     bFirstEmpty = FALSE;
                 }
                 if (!(GetWindowLongW( hwnd, GWL_STYLE ) & DS_NOIDLEMSG))
-               {
+                {
                     /* No message present -> send ENTERIDLE and wait */
                     SendMessageW( ownerMsg, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)hwnd );
                 }
-                if (!GetMessageW( &msg, 0, 0, 0 )) break;
+                GetMessageW( &msg, 0, 0, 0 );
             }
 
+            if (msg.message == WM_QUIT)
+            {
+                /* Re-post the WM_QUIT message in order to notify the
+                   outer message loop */
+                PostQuitMessage(msg.wParam);
+                dlgInfo->idResult = 1; /* Tested on Windows 95 and 2000 */
+                dlgInfo->flags |= DF_END;
+            }
             if (!IsWindow( hwnd )) return -1;
             if (!(dlgInfo->flags & DF_END) && !IsDialogMessageW( hwnd, &msg))
             {
Index: dlls/user/menu.c
===================================================================
RCS file: /home/wine/wine/dlls/user/menu.c,v
retrieving revision 1.65
diff -u -r1.65 menu.c
--- dlls/user/menu.c	12 Jun 2006 12:12:23 -0000	1.65
+++ dlls/user/menu.c	20 Jun 2006 21:49:03 -0000
@@ -2986,6 +2985,16 @@
 	    break;
 	}
 
+        if(msg.message == WM_QUIT)
+	{
+	    /* we are now out of the loop */
+    	    fEndMenu = TRUE;
+
+	    /* Don't remove the message from the queue
+	       and break out of internal loop */
+	    break;
+	}
+
         TranslateMessage( &msg );
         mt.pt = msg.pt;
 
Index: dlls/user/nonclient.c
===================================================================
RCS file: /home/wine/wine/dlls/user/nonclient.c,v
retrieving revision 1.10
diff -u -r1.10 nonclient.c
--- dlls/user/nonclient.c	23 May 2006 12:48:46 -0000	1.10
+++ dlls/user/nonclient.c	20 Jun 2006 21:49:04 -0000
@@ -1292,7 +1292,13 @@
     {
         BOOL oldstate = pressed;
 
-        if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
+        if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST ))
+        {
+            /* Re-post the WM_QUIT message in order to notify the
+               outer message loop */
+            PostQuitMessage(msg.wParam);
+            break;
+        }
         if (CallMsgFilterW( &msg, MSGF_MAX )) continue;
 
         if(msg.message == WM_LBUTTONUP)
@@ -1356,7 +1362,13 @@
     {
         BOOL oldstate = pressed;
 
-        if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
+        if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST ))
+        {
+            /* Re-post the WM_QUIT message in order to notify the
+               outer message loop */
+            PostQuitMessage(msg.wParam);
+            break;
+        }
         if (CallMsgFilterW( &msg, MSGF_MAX )) continue;
 
         if(msg.message == WM_LBUTTONUP)
Index: dlls/user/scroll.c
===================================================================
RCS file: /home/wine/wine/dlls/user/scroll.c,v
retrieving revision 1.21
diff -u -r1.21 scroll.c
--- dlls/user/scroll.c	23 May 2006 12:48:46 -0000	1.21
+++ dlls/user/scroll.c	20 Jun 2006 21:49:05 -0000
@@ -1088,7 +1088,13 @@
 
     do
     {
-        if (!GetMessageW( &msg, 0, 0, 0 )) break;
+        if (!GetMessageW( &msg, 0, 0, 0 ))
+        {
+            /* Re-post the WM_QUIT message in order to notify the
+               outer message loop */
+            PostQuitMessage(msg.wParam);
+            break;
+        }
         if (CallMsgFilterW( &msg, MSGF_SCROLLBAR )) continue;
         if (msg.message == WM_LBUTTONUP ||
             msg.message == WM_MOUSEMOVE ||
Index: dlls/user/user16.c
===================================================================
RCS file: /home/wine/wine/dlls/user/user16.c,v
retrieving revision 1.30
diff -u -r1.30 user16.c
--- dlls/user/user16.c	26 May 2006 18:57:28 -0000	1.30
+++ dlls/user/user16.c	20 Jun 2006 21:49:06 -0000
@@ -1571,7 +1571,13 @@
 
     do
     {
-        GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST );
+        if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST ))
+        {
+            /* Re-post the WM_QUIT message in order to notify the
+               outer message loop */
+            PostQuitMessage(msg.wParam);
+            break;
+        }
 
        *(lpDragInfo+1) = *lpDragInfo;
 
Index: dlls/user/win.c
===================================================================
RCS file: /home/wine/wine/dlls/user/win.c,v
retrieving revision 1.45
diff -u -r1.45 win.c
--- dlls/user/win.c	9 Jun 2006 16:18:26 -0000	1.45
+++ dlls/user/win.c	20 Jun 2006 21:49:07 -0000
@@ -3071,12 +3071,20 @@
     {
         while (PeekMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE ))
         {
-            if( msg.message == WM_LBUTTONUP )
+            if( msg.message == WM_QUIT )
             {
+                /* Re-post the WM_QUIT message in order to notify the
+                   outer message loop */
+                PostQuitMessage(msg.wParam);
                 ReleaseCapture();
                 return 0;
             }
-            if( msg.message == WM_MOUSEMOVE )
+            else if( msg.message == WM_LBUTTONUP )
+            {
+                ReleaseCapture();
+                return 0;
+            }
+            else if( msg.message == WM_MOUSEMOVE )
             {
                 POINT tmp;
                 tmp.x = LOWORD(msg.lParam);
Index: dlls/winedos/dosvm.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/dosvm.c,v
retrieving revision 1.66
diff -u -r1.66 dosvm.c
--- dlls/winedos/dosvm.c	23 May 2006 12:48:54 -0000	1.66
+++ dlls/winedos/dosvm.c	20 Jun 2006 21:49:09 -0000
@@ -447,6 +447,14 @@
             MSG msg;
             while (PeekMessageA(&msg,0,0,0,PM_REMOVE|PM_NOYIELD)) 
             {
+                if (msg.message == WM_QUIT)
+                {
+                    /* Re-post the WM_QUIT message in order to notify the
+                       outer message loop */
+                    PostQuitMessage(msg.wParam);
+                    break;
+                }
+
                 /* got a message */
                 DOSVM_ProcessMessage(&msg);
                 /* we don't need a TranslateMessage here */
Index: dlls/winmm/mci.c
===================================================================
RCS file: /home/wine/wine/dlls/winmm/mci.c,v
retrieving revision 1.70
diff -u -r1.70 mci.c
--- dlls/winmm/mci.c	15 Jun 2006 12:14:49 -0000	1.70
+++ dlls/winmm/mci.c	20 Jun 2006 21:49:11 -0000
@@ -2317,7 +2317,16 @@
 	MSG		msg;
 
 	msg.hwnd = HWND_32(HIWORD(data));
-	while (!PeekMessageW(&msg, msg.hwnd, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE));
+	while (!PeekMessageW(&msg, msg.hwnd, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
+        {
+            if (msg.message == WM_QUIT)
+            {
+                /* Re-post the WM_QUIT message in order to notify the
+                   outer message loop */
+                PostQuitMessage(msg.wParam);
+                break;
+            }
+        }
 	ret = -1;
     }
     return ret;
Index: dlls/x11drv/winpos.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/Attic/winpos.c,v
retrieving revision 1.154
diff -u -r1.154 winpos.c
--- dlls/x11drv/winpos.c	2 Jun 2006 09:57:03 -0000	1.154
+++ dlls/x11drv/winpos.c	20 Jun 2006 21:49:12 -0000
@@ -1378,7 +1378,14 @@
         pt.x = pt.y = 0;
         while(!hittest)
         {
-            GetMessageW( &msg, 0, WM_KEYFIRST, WM_MOUSELAST );
+            if (!GetMessageW( &msg, 0, WM_KEYFIRST, WM_MOUSELAST ))
+            {
+                /* Re-post the WM_QUIT message in order to notify the
+                   outer message loop */
+                PostQuitMessage(msg.wParam);
+                break;
+            }
+
             if (CallMsgFilterW( &msg, MSGF_SIZE )) continue;
 
             switch(msg.message)


More information about the wine-patches mailing list