// headers
// ----------------------------------------------------------------------------
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
- #pragma implementation "filedlg.h"
-#endif
-
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#include "wx/app.h"
#endif
-#include "wx/msw/private.h"
-
-#if !defined(__WIN32__) || defined(__WXWINCE__)
- #include <commdlg.h>
-#endif
+#include "wx/msw/wrapcdlg.h"
-#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "wx/filename.h"
#include "wx/tokenzr.h"
+#include "wx/math.h"
#include "wx/msw/missing.h"
// hook function for moving the dialog
// ----------------------------------------------------------------------------
-UINT APIENTRY
+UINT_PTR APIENTRY
wxFileDialogHookFunction(HWND hDlg,
UINT iMsg,
WPARAM WXUNUSED(wParam),
*/
}
+// helper used below in ShowModal(): style is used to determine whether to show
+// the "Save file" dialog (if it contains wxSAVE bit) or "Open file" one;
+// returns true on success or false on failure in which case err is filled with
+// the CDERR_XXX constant
+static bool DoShowCommFileDialog(OPENFILENAME *of, long style, DWORD *err)
+{
+ if ( style & wxSAVE ? GetSaveFileName(of) : GetOpenFileName(of) )
+ return true;
+
+ if ( err )
+ {
+#ifdef __WXWINCE__
+ // according to MSDN, CommDlgExtendedError() should work under CE as
+ // well but apparently in practice it doesn't (anybody has more
+ // details?)
+ *err = GetLastError();
+#else
+ *err = CommDlgExtendedError();
+#endif
+ }
+
+ return false;
+}
+
int wxFileDialog::ShowModal()
{
HWND hWnd = 0;
}
// if wxCHANGE_DIR flag is not given we shouldn't change the CWD which the
- // standard dialog does by default
+ // standard dialog does by default (notice that under NT it does it anyhow,
+ // OFN_NOCHANGEDIR or not, see below)
if ( !(m_dialogStyle & wxCHANGE_DIR) )
{
msw_flags |= OFN_NOCHANGEDIR;
// comcdlg32.dll, but as we don't use the extended fields anyhow, set
// the struct size to the old value - otherwise, the programs compiled
// with new headers will not work with the old libraries
-#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0500)
+#if !defined(__WXWINCE__) && defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0500)
of.lStructSize = sizeof(OPENFILENAME) -
(sizeof(void *) + 2*sizeof(DWORD));
#else // old headers
}
}
- //== Execute FileDialog >>=================================================
+ // store off before the standard windows dialog can possibly change it
+ const wxString cwdOrig = wxGetCwd();
//== Execute FileDialog >>=================================================
- bool success = (m_dialogStyle & wxSAVE ? GetSaveFileName(&of)
- : GetOpenFileName(&of)) != 0;
-
- DWORD errCode = CommDlgExtendedError();
+ DWORD errCode;
+ bool success = DoShowCommFileDialog(&of, m_dialogStyle, &errCode);
-#ifdef __WIN32__
- if (!success && (errCode == CDERR_STRUCTSIZE))
+ // sometimes we may have a mismatch between the headers used to compile the
+ // library and the run-time version of comdlg32.dll, try to account for it
+#ifndef __WXWINCE__
+ if ( !success && errCode == CDERR_STRUCTSIZE )
{
// The struct size has changed so try a smaller or bigger size
+ const int oldStructSize = of.lStructSize;
+ of.lStructSize = oldStructSize - (sizeof(void *) + 2*sizeof(DWORD));
+ success = DoShowCommFileDialog(&of, m_dialogStyle, &errCode);
- int oldStructSize = of.lStructSize;
- of.lStructSize = oldStructSize - (sizeof(void *) + 2*sizeof(DWORD));
- success = (m_dialogStyle & wxSAVE) ? (GetSaveFileName(&of) != 0)
- : (GetOpenFileName(&of) != 0);
- errCode = CommDlgExtendedError();
-
- if (!success && (errCode == CDERR_STRUCTSIZE))
+ if ( !success && (errCode == CDERR_STRUCTSIZE) )
{
- of.lStructSize = oldStructSize + (sizeof(void *) + 2*sizeof(DWORD));
- success = (m_dialogStyle & wxSAVE) ? (GetSaveFileName(&of) != 0)
- : (GetOpenFileName(&of) != 0);
+ // try to adjust in the other direction
+ of.lStructSize = oldStructSize + (sizeof(void *) + 2*sizeof(DWORD));
+ success = DoShowCommFileDialog(&of, m_dialogStyle, &errCode);
}
}
-#endif // __WIN32__
+#endif // !__WXWINCE__
if ( success )
{
+ // GetOpenFileName will always change the current working directory on
+ // (according to MSDN) "Windows NT 4.0/2000/XP" because the flag
+ // OFN_NOCHANGEDIR has no effect. If the user did not specify
+ // wxCHANGE_DIR let's restore the current working directory to what it
+ // was before the dialog was shown.
+ if ( msw_flags & OFN_NOCHANGEDIR )
+ {
+ wxSetWorkingDirectory(cwdOrig);
+ }
+
m_fileNames.Empty();
if ( ( m_dialogStyle & wxMULTIPLE ) &&
m_dir = wxPathOnly(fileNameBuffer);
}
}
+#ifdef __WXDEBUG__
else
{
// common dialog failed - why?
-#ifdef __WXDEBUG__
- DWORD dwErr = CommDlgExtendedError();
- if ( dwErr != 0 )
+ if ( errCode != 0 )
{
- // this msg is only for developers
+ // this msg is only for developers so don't translate it
wxLogError(wxT("Common dialog failed with error code %0lx."),
- dwErr);
+ errCode);
}
//else: it was just cancelled
-#endif
}
+#endif // __WXDEBUG__
return success ? wxID_OK : wxID_CANCEL;