X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/41b8fe99b470616fb58690c27ae6f91e2060a371..68df211faedeabdf4259858109d1bd7385fdccf5:/src/msw/filedlg.cpp diff --git a/src/msw/filedlg.cpp b/src/msw/filedlg.cpp index 7e59525d7b..f71cfb69c8 100644 --- a/src/msw/filedlg.cpp +++ b/src/msw/filedlg.cpp @@ -17,10 +17,6 @@ // 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" @@ -28,7 +24,7 @@ #pragma hdrstop #endif -#if wxUSE_FILEDLG && !defined(__SMARTPHONE__) +#if wxUSE_FILEDLG && !(defined(__SMARTPHONE__) && defined(__WXWINCE__)) #ifndef WX_PRECOMP #include "wx/utils.h" @@ -40,18 +36,14 @@ #include "wx/app.h" #endif -#include "wx/msw/private.h" - -#if !defined(__WIN32__) || defined(__WXWINCE__) - #include -#endif +#include "wx/msw/wrapcdlg.h" -#include #include #include #include "wx/filename.h" #include "wx/tokenzr.h" +#include "wx/math.h" #include "wx/msw/missing.h" @@ -86,7 +78,7 @@ IMPLEMENT_CLASS(wxFileDialog, wxFileDialogBase) // hook function for moving the dialog // ---------------------------------------------------------------------------- -UINT APIENTRY +UINT_PTR APIENTRY wxFileDialogHookFunction(HWND hDlg, UINT iMsg, WPARAM WXUNUSED(wParam), @@ -214,6 +206,30 @@ void wxFileDialog::DoMoveWindow(int x, int y, int WXUNUSED(width), int WXUNUSED( */ } +// 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; @@ -265,7 +281,8 @@ int wxFileDialog::ShowModal() } // 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; @@ -283,7 +300,7 @@ int wxFileDialog::ShowModal() // 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 @@ -299,8 +316,8 @@ int wxFileDialog::ShowModal() // forward slashes) and also squeeze multiple consecutive slashes into one // as it doesn't like two backslashes in a row neither - wxString dir; - size_t i, len = m_dir.length(); + wxString dir; + size_t i, len = m_dir.length(); dir.reserve(len); for ( i = 0; i < len; i++ ) { @@ -395,37 +412,45 @@ int wxFileDialog::ShowModal() } } - //== 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 ) && @@ -492,24 +517,23 @@ int wxFileDialog::ShowModal() 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; } -#endif // wxUSE_FILEDLG +#endif // wxUSE_FILEDLG && !(__SMARTPHONE__ && __WXWINCE__)