comdlg32: Fix a problem with the returned value of a CDN_FILEOK notification.
Rein Klazes
wijn at online.nl
Tue Jun 30 01:41:10 CDT 2009
fixes bug #19079
The application of this bug report subclasses the window proc of the file
dialog. It does not return the result in the DWLP_MSGRESULT dialog
property but the return code of the window proc. Tests are provided to
show correct behaviour in all cases, subclassed or not.
---
dlls/comdlg32/filedlg.c | 8 ++--
dlls/comdlg32/tests/filedlg.c | 112 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 116 insertions(+), 4 deletions(-)
diff --git a/dlls/comdlg32/filedlg.c b/dlls/comdlg32/filedlg.c
index 6e7f985..6f89697 100644
--- a/dlls/comdlg32/filedlg.c
+++ b/dlls/comdlg32/filedlg.c
@@ -1760,19 +1760,19 @@ static BOOL FILEDLG95_SendFileOK( HWND hwnd, FileOpenDlgInfos *fodInfos )
/* First send CDN_FILEOK as MSDN doc says */
if(fodInfos->ofnInfos->Flags & OFN_EXPLORER)
retval = SendCustomDlgNotificationMessage(hwnd,CDN_FILEOK);
- if (GetWindowLongPtrW(fodInfos->DlgInfos.hwndCustomDlg, DWLP_MSGRESULT))
+ if( retval)
{
TRACE("canceled\n");
- return (retval == 0);
+ return FALSE;
}
/* fodInfos->ofnInfos points to an ASCII or UNICODE structure as appropriate */
retval = SendMessageW(fodInfos->DlgInfos.hwndCustomDlg,
fodInfos->HookMsg.fileokstring, 0, (LPARAM)fodInfos->ofnInfos);
- if (GetWindowLongPtrW(fodInfos->DlgInfos.hwndCustomDlg, DWLP_MSGRESULT))
+ if( retval)
{
TRACE("canceled\n");
- return (retval == 0);
+ return FALSE;
}
}
return TRUE;
diff --git a/dlls/comdlg32/tests/filedlg.c b/dlls/comdlg32/tests/filedlg.c
index 0cd1e63..0b1561e 100644
--- a/dlls/comdlg32/tests/filedlg.c
+++ b/dlls/comdlg32/tests/filedlg.c
@@ -399,10 +399,122 @@ static void test_resize(void)
}
}
+/* test cases for control message IDOK */
+/* Show case for bug #19079 */
+static struct {
+ int retval; /* return code of the message handler */
+ BOOL setmsgresult; /* set the result in the DWLP_MSGRESULT */
+ BOOL usemsgokstr; /* use the FILEOKSTRING message instead of WM_NOTIFY:CDN_FILEOK */
+ BOOL do_subclass; /* subclass the dialog hook procedure */
+ BOOL expclose; /* is the dialog expected to close ? */
+ BOOL actclose; /* has the dialog actually closed ? */
+} ok_testcases[] = {
+ { 0, FALSE, FALSE, FALSE, TRUE},
+ { 0, TRUE, FALSE, FALSE, TRUE},
+ { 0, FALSE, FALSE, TRUE, TRUE},
+ { 0, TRUE, FALSE, TRUE, TRUE},
+ { 1, FALSE, FALSE, FALSE, TRUE},
+ { 1, TRUE, FALSE, FALSE, FALSE},
+ { 1, FALSE, FALSE, TRUE, FALSE},
+ { 1, TRUE, FALSE, TRUE, FALSE},
+ /* FILEOKSTRING tests */
+ { 1, TRUE, TRUE, FALSE, FALSE},
+ { 1, FALSE, TRUE, TRUE, FALSE},
+ /* mark the end */
+ { -1 }
+};
+
+/* test_ok_wndproc can be used as hook procedure or a subclass
+ * window proc for the file dialog */
+static LONG_PTR WINAPI test_ok_wndproc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ HWND parent = GetParent( dlg);
+ static int index;
+ static UINT msgFILEOKSTRING;
+ if (msg == WM_INITDIALOG)
+ {
+ index = ((OPENFILENAME*)lParam)->lCustData;
+ ok_testcases[index].actclose = TRUE;
+ msgFILEOKSTRING = RegisterWindowMessageA( FILEOKSTRING);
+ }
+ if( msg == WM_NOTIFY) {
+ if(((LPNMHDR)lParam)->code == CDN_INITDONE) {
+ SetTimer( dlg, 0, 100, 0);
+ PostMessage( parent, WM_COMMAND, IDOK, 0);
+ return FALSE;
+ } else if(((LPNMHDR)lParam)->code == CDN_FILEOK) {
+ if( ok_testcases[index].usemsgokstr)
+ return FALSE;
+ if( ok_testcases[index].setmsgresult)
+ SetWindowLongPtrA( dlg, DWLP_MSGRESULT, ok_testcases[index].retval);
+ return ok_testcases[index].retval;
+ }
+ }
+ if( msg == msgFILEOKSTRING) {
+ if( !ok_testcases[index].usemsgokstr)
+ return FALSE;
+ if( ok_testcases[index].setmsgresult)
+ SetWindowLongPtrA( dlg, DWLP_MSGRESULT, ok_testcases[index].retval);
+ return ok_testcases[index].retval;
+ }
+ if( msg == WM_TIMER) {
+ /* the dialog did not close automatically */
+ ok_testcases[index].actclose = FALSE;
+ KillTimer( dlg, 0);
+ PostMessage( parent, WM_COMMAND, IDCANCEL, 0);
+ return FALSE;
+ }
+ if( ok_testcases[index].do_subclass)
+ return DefWindowProc( dlg, msg, wParam, lParam);
+ return FALSE;
+}
+
+static LONG_PTR WINAPI ok_template_hook(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if (msg == WM_SETFONT)
+ SetWindowLongPtrA( dlg, GWLP_WNDPROC, (LONG_PTR) test_ok_wndproc);
+ return FALSE;
+}
+
+static void test_ok(void)
+{
+ OPENFILENAME ofn = { sizeof(OPENFILENAME)};
+ char filename[1024] = {0};
+ char tmpfilename[ MAX_PATH];
+ int i;
+ DWORD ret;
+
+ if (!GetTempFileNameA(".", "tmp", 0, tmpfilename)) {
+ skip("Failed to create a temporary file name\n");
+ return;
+ }
+ ofn.lpstrFile = filename;
+ ofn.nMaxFile = 1024;
+ ofn.hInstance = GetModuleHandle(NULL);
+ ofn.lpTemplateName = "template1";
+ ofn.Flags = OFN_ENABLEHOOK | OFN_EXPLORER| OFN_ENABLETEMPLATE ;
+ for( i = 0; ok_testcases[i].retval != -1; i++) {
+ strcpy( filename, tmpfilename);
+ ofn.lCustData = i;
+ ofn.lpfnHook = ok_testcases[i].do_subclass
+ ? (LPOFNHOOKPROC) ok_template_hook
+ : (LPOFNHOOKPROC) test_ok_wndproc;
+ ret = GetOpenFileNameA(&ofn);
+ ok( ok_testcases[i].expclose == ok_testcases[i].actclose,
+ "Open File dialog should %shave closed.\n",
+ ok_testcases[i].expclose ? "" : "NOT ");
+ ok(ret == ok_testcases[i].expclose, "GetOpenFileName returned %#x\n", ret);
+ ret = CommDlgExtendedError();
+ ok(!ret, "CommDlgExtendedError returned %#x\n", ret);
+ }
+ ok( DeleteFileA( tmpfilename), "Failed to delete temporary file\n");
+}
+
START_TEST(filedlg)
{
test_DialogCancel();
test_create_view_window2();
test_create_view_template();
test_resize();
+ test_ok();
}
--
1.6.3.1
More information about the wine-patches
mailing list