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