propsheet: run our own message loop for modal propsheets

Huw D M Davies h.davies1 at physics.ox.ac.uk
Wed Jun 15 09:32:15 CDT 2005


On Wed, Jun 15, 2005 at 09:12:12AM -0500, Robert Shearman wrote:
> If you get a WM_QUIT message while in the loop, then you have to repost 
> it so that the application sees it and shuts down properly.

True.  Note, there are lots of places where we don't do this though.

Here's a better version.

      Huw Davies <huw at codeweavers.com>
      For modal propsheets we should run our own message loop rather than
      use a modal dialogbox just like Windows does.  This helps apps that
      subclass the propsheet's wndproc.


-- 
Huw Davies
huw at codeweavers.com
Index: dlls/comctl32/propsheet.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/propsheet.c,v
retrieving revision 1.127
diff -u -p -r1.127 propsheet.c
--- dlls/comctl32/propsheet.c	9 Jun 2005 09:50:56 -0000	1.127
+++ dlls/comctl32/propsheet.c	15 Jun 2005 14:28:07 -0000
@@ -131,6 +131,7 @@ typedef struct tagPropSheetInfo
   int width;
   int height;
   HIMAGELIST hImageList;
+  BOOL ended;
 } PropSheetInfo;
 
 typedef struct
@@ -707,39 +708,21 @@ int PROPSHEET_CreateDialog(PropSheetInfo
    * -1 (error). */
   if( psInfo->unicode )
   {
-    if (!(psInfo->ppshheader.dwFlags & PSH_MODELESS))
-      ret = DialogBoxIndirectParamW(psInfo->ppshheader.hInstance,
-                                    (LPDLGTEMPLATEW) temp,
-                                    psInfo->ppshheader.hwndParent,
-                                    PROPSHEET_DialogProc,
-                                    (LPARAM)psInfo);
-    else
-    {
-      ret = (int)CreateDialogIndirectParamW(psInfo->ppshheader.hInstance,
-                                            (LPDLGTEMPLATEW) temp,
-                                            psInfo->ppshheader.hwndParent,
-                                            PROPSHEET_DialogProc,
-                                            (LPARAM)psInfo);
-      if ( !ret ) ret = -1;
-    }
+    ret = (int)CreateDialogIndirectParamW(psInfo->ppshheader.hInstance,
+                                          (LPDLGTEMPLATEW) temp,
+                                          psInfo->ppshheader.hwndParent,
+                                          PROPSHEET_DialogProc,
+                                          (LPARAM)psInfo);
+    if ( !ret ) ret = -1;
   }
   else
   {
-    if (!(psInfo->ppshheader.dwFlags & PSH_MODELESS))
-      ret = DialogBoxIndirectParamA(psInfo->ppshheader.hInstance,
-                                    (LPDLGTEMPLATEA) temp,
-                                    psInfo->ppshheader.hwndParent,
-                                    PROPSHEET_DialogProc,
-                                    (LPARAM)psInfo);
-    else
-    {
-      ret = (int)CreateDialogIndirectParamA(psInfo->ppshheader.hInstance,
-                                            (LPDLGTEMPLATEA) temp,
-                                            psInfo->ppshheader.hwndParent,
-                                            PROPSHEET_DialogProc,
-                                            (LPARAM)psInfo);
-      if ( !ret ) ret = -1;
-    }
+    ret = (int)CreateDialogIndirectParamA(psInfo->ppshheader.hInstance,
+                                          (LPDLGTEMPLATEA) temp,
+                                          psInfo->ppshheader.hwndParent,
+                                          PROPSHEET_DialogProc,
+                                          (LPARAM)psInfo);
+    if ( !ret ) ret = -1;
   }
 
   Free(temp);
@@ -1757,7 +1740,7 @@ static BOOL PROPSHEET_Finish(HWND hwndDl
   if (psInfo->isModeless)
     psInfo->activeValid = FALSE;
   else
-    EndDialog(hwndDlg, TRUE);
+    psInfo->ended = TRUE;
 
   return TRUE;
 }
@@ -1870,7 +1853,7 @@ static void PROPSHEET_Cancel(HWND hwndDl
      psInfo->activeValid = FALSE;
   }
   else
-    EndDialog(hwndDlg, FALSE);
+    psInfo->ended = TRUE;
 }
 
 /******************************************************************************
@@ -2396,7 +2379,7 @@ static BOOL PROPSHEET_RemovePage(HWND hw
       psInfo->active_page = -1;
       if (!psInfo->isModeless)
       {
-         EndDialog(hwndDlg, FALSE);
+         psInfo->ended = TRUE;
          return TRUE;
       }
     }
@@ -2737,6 +2720,34 @@ static void PROPSHEET_CleanUp(HWND hwndD
   GlobalFree((HGLOBAL)psInfo);
 }
 
+static INT do_loop(PropSheetInfo *psInfo)
+{
+    MSG msg;
+    INT ret = -1;
+    HWND hwnd = psInfo->hwnd;
+
+    while(IsWindow(hwnd) && !psInfo->ended && (ret = GetMessageW(&msg, NULL, 0, 0)))
+    {
+        if(ret == -1)
+            break;
+
+        if(!IsDialogMessageW(hwnd, &msg))
+        {
+            TranslateMessage(&msg);
+            DispatchMessageW(&msg);
+        }
+    }
+
+    if(ret == 0)
+    {
+        PostQuitMessage(msg.wParam);
+        ret = -1;
+    }
+
+    DestroyWindow(hwnd);
+    return ret;
+}
+
 /******************************************************************************
  *            PropertySheet    (COMCTL32.@)
  *            PropertySheetA   (COMCTL32.@)
@@ -2787,7 +2798,11 @@ INT WINAPI PropertySheetA(LPCPROPSHEETHE
   }
 
   psInfo->unicode = FALSE;
+  psInfo->ended = FALSE;
+
   bRet = PROPSHEET_CreateDialog(psInfo);
+  if(!psInfo->isModeless)
+      bRet = do_loop(psInfo);
 
   return bRet;
 }
@@ -2834,7 +2849,11 @@ INT WINAPI PropertySheetW(LPCPROPSHEETHE
   }
 
   psInfo->unicode = TRUE;
+  psInfo->ended = FALSE;
+
   bRet = PROPSHEET_CreateDialog(psInfo);
+  if(!psInfo->isModeless)
+      bRet = do_loop(psInfo);
 
   return bRet;
 }
@@ -3039,7 +3058,7 @@ static BOOL PROPSHEET_DoCommand(HWND hwn
 		    if (psInfo->isModeless)
 			psInfo->activeValid = FALSE;
 		    else
-			EndDialog(hwnd, result);
+                        psInfo->ended = TRUE;
 		}
 	    else
 		EnableWindow(hwndApplyBtn, FALSE);
@@ -3423,6 +3442,17 @@ PROPSHEET_DialogProc(HWND hwnd, UINT uMs
           }
       }
       return TRUE;
+
+    case WM_SYSCOMMAND:
+      switch(wParam & 0xfff0)
+      {
+        case SC_CLOSE:
+          PROPSHEET_Cancel(hwnd, 1);
+          return TRUE;
+
+        default:
+          return FALSE;
+      }
 
     case WM_NOTIFY:
     {



More information about the wine-patches mailing list