handle FNERR_INVALIDFILENAME which happens if an invalid file name is passed to wxFileDialog (#9688)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@54479 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -250,10 +250,10 @@ void wxFileDialog::MSWOnInitDone(WXHWND hDlg)
|
|||||||
SetHWND(NULL);
|
SetHWND(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper used below in ShowModal(): style is used to determine whether to show
|
// helper used below in ShowCommFileDialog(): style is used to determine
|
||||||
// the "Save file" dialog (if it contains wxFD_SAVE bit) or "Open file" one;
|
// whether to show the "Save file" dialog (if it contains wxFD_SAVE bit) or
|
||||||
// returns true on success or false on failure in which case err is filled with
|
// "Open file" one; returns true on success or false on failure in which case
|
||||||
// the CDERR_XXX constant
|
// err is filled with the CDERR_XXX constant
|
||||||
static bool DoShowCommFileDialog(OPENFILENAME *of, long style, DWORD *err)
|
static bool DoShowCommFileDialog(OPENFILENAME *of, long style, DWORD *err)
|
||||||
{
|
{
|
||||||
if ( style & wxFD_SAVE ? GetSaveFileName(of) : GetOpenFileName(of) )
|
if ( style & wxFD_SAVE ? GetSaveFileName(of) : GetOpenFileName(of) )
|
||||||
@@ -308,6 +308,52 @@ static bool DoShowCommFileDialog(OPENFILENAME *of, long style, DWORD *err)
|
|||||||
static DWORD gs_ofStructSize = wxOPENFILENAME_V5_SIZE;
|
static DWORD gs_ofStructSize = wxOPENFILENAME_V5_SIZE;
|
||||||
#endif // __WXWINCE__ || __WIN64__/!...
|
#endif // __WXWINCE__ || __WIN64__/!...
|
||||||
|
|
||||||
|
static bool ShowCommFileDialog(OPENFILENAME *of, long style)
|
||||||
|
{
|
||||||
|
DWORD errCode;
|
||||||
|
bool success = DoShowCommFileDialog(of, style, &errCode);
|
||||||
|
|
||||||
|
#ifdef wxTRY_SMALLER_OPENFILENAME
|
||||||
|
// the system might be too old to support the new version file dialog
|
||||||
|
// boxes, try with the old size
|
||||||
|
if ( !success && errCode == CDERR_STRUCTSIZE &&
|
||||||
|
of->lStructSize != wxOPENFILENAME_V4_SIZE )
|
||||||
|
{
|
||||||
|
of->lStructSize = wxOPENFILENAME_V4_SIZE;
|
||||||
|
|
||||||
|
success = DoShowCommFileDialog(of, style, &errCode);
|
||||||
|
|
||||||
|
if ( success || !errCode )
|
||||||
|
{
|
||||||
|
// use this struct size for subsequent dialogs
|
||||||
|
gs_ofStructSize = of->lStructSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // wxTRY_SMALLER_OPENFILENAME
|
||||||
|
|
||||||
|
if ( !success && errCode == FNERR_INVALIDFILENAME && of->lpstrFile[0] )
|
||||||
|
{
|
||||||
|
// this can happen if the default file name is invalid, try without it
|
||||||
|
// now
|
||||||
|
of->lpstrFile[0] = _T('\0');
|
||||||
|
success = DoShowCommFileDialog(of, style, &errCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !success )
|
||||||
|
{
|
||||||
|
// common dialog failed - why?
|
||||||
|
if ( errCode != 0 )
|
||||||
|
{
|
||||||
|
wxLogError(_("File dialog failed with error code %0lx."), errCode);
|
||||||
|
}
|
||||||
|
//else: it was just cancelled
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int wxFileDialog::ShowModal()
|
int wxFileDialog::ShowModal()
|
||||||
{
|
{
|
||||||
HWND hWnd = 0;
|
HWND hWnd = 0;
|
||||||
@@ -475,120 +521,86 @@ int wxFileDialog::ShowModal()
|
|||||||
|
|
||||||
//== Execute FileDialog >>=================================================
|
//== Execute FileDialog >>=================================================
|
||||||
|
|
||||||
DWORD errCode;
|
if ( !ShowCommFileDialog(&of, m_windowStyle) )
|
||||||
bool success = DoShowCommFileDialog(&of, m_windowStyle, &errCode);
|
return wxID_CANCEL;
|
||||||
|
|
||||||
#ifdef wxTRY_SMALLER_OPENFILENAME
|
// GetOpenFileName will always change the current working directory on
|
||||||
// the system might be too old to support the new version file dialog
|
// (according to MSDN) "Windows NT 4.0/2000/XP" because the flag
|
||||||
// boxes, try with the old size
|
// OFN_NOCHANGEDIR has no effect. If the user did not specify
|
||||||
if ( !success && errCode == CDERR_STRUCTSIZE &&
|
// wxFD_CHANGE_DIR let's restore the current working directory to what it
|
||||||
of.lStructSize != wxOPENFILENAME_V4_SIZE )
|
// was before the dialog was shown.
|
||||||
|
if ( msw_flags & OFN_NOCHANGEDIR )
|
||||||
{
|
{
|
||||||
of.lStructSize = wxOPENFILENAME_V4_SIZE;
|
wxSetWorkingDirectory(cwdOrig);
|
||||||
|
|
||||||
success = DoShowCommFileDialog(&of, m_windowStyle, &errCode);
|
|
||||||
|
|
||||||
if ( success || !errCode )
|
|
||||||
{
|
|
||||||
// use this struct size for subsequent dialogs
|
|
||||||
gs_ofStructSize = of.lStructSize;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif // wxTRY_SMALLER_OPENFILENAME
|
|
||||||
|
|
||||||
if ( success )
|
m_fileNames.Empty();
|
||||||
{
|
|
||||||
// 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
|
|
||||||
// wxFD_CHANGE_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 ( ( HasFdFlag(wxFD_MULTIPLE) ) &&
|
||||||
|
|
||||||
if ( ( HasFdFlag(wxFD_MULTIPLE) ) &&
|
|
||||||
#if defined(OFN_EXPLORER)
|
#if defined(OFN_EXPLORER)
|
||||||
( fileNameBuffer[of.nFileOffset-1] == wxT('\0') )
|
( fileNameBuffer[of.nFileOffset-1] == wxT('\0') )
|
||||||
#else
|
#else
|
||||||
( fileNameBuffer[of.nFileOffset-1] == wxT(' ') )
|
( fileNameBuffer[of.nFileOffset-1] == wxT(' ') )
|
||||||
#endif // OFN_EXPLORER
|
#endif // OFN_EXPLORER
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#if defined(OFN_EXPLORER)
|
#if defined(OFN_EXPLORER)
|
||||||
m_dir = fileNameBuffer;
|
m_dir = fileNameBuffer;
|
||||||
i = of.nFileOffset;
|
i = of.nFileOffset;
|
||||||
m_fileName = &fileNameBuffer[i];
|
m_fileName = &fileNameBuffer[i];
|
||||||
m_fileNames.Add(m_fileName);
|
m_fileNames.Add(m_fileName);
|
||||||
i += m_fileName.length() + 1;
|
i += m_fileName.length() + 1;
|
||||||
|
|
||||||
while (fileNameBuffer[i] != wxT('\0'))
|
while (fileNameBuffer[i] != wxT('\0'))
|
||||||
{
|
{
|
||||||
m_fileNames.Add(&fileNameBuffer[i]);
|
m_fileNames.Add(&fileNameBuffer[i]);
|
||||||
i += wxStrlen(&fileNameBuffer[i]) + 1;
|
i += wxStrlen(&fileNameBuffer[i]) + 1;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
wxStringTokenizer toke(fileNameBuffer, _T(" \t\r\n"));
|
wxStringTokenizer toke(fileNameBuffer, _T(" \t\r\n"));
|
||||||
m_dir = toke.GetNextToken();
|
m_dir = toke.GetNextToken();
|
||||||
m_fileName = toke.GetNextToken();
|
m_fileName = toke.GetNextToken();
|
||||||
m_fileNames.Add(m_fileName);
|
m_fileNames.Add(m_fileName);
|
||||||
|
|
||||||
while (toke.HasMoreTokens())
|
while (toke.HasMoreTokens())
|
||||||
m_fileNames.Add(toke.GetNextToken());
|
m_fileNames.Add(toke.GetNextToken());
|
||||||
#endif // OFN_EXPLORER
|
#endif // OFN_EXPLORER
|
||||||
|
|
||||||
wxString dir(m_dir);
|
wxString dir(m_dir);
|
||||||
if ( m_dir.Last() != _T('\\') )
|
if ( m_dir.Last() != _T('\\') )
|
||||||
dir += _T('\\');
|
dir += _T('\\');
|
||||||
|
|
||||||
m_path = dir + m_fileName;
|
m_path = dir + m_fileName;
|
||||||
m_filterIndex = (int)of.nFilterIndex - 1;
|
m_filterIndex = (int)of.nFilterIndex - 1;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//=== Adding the correct extension >>=================================
|
|
||||||
|
|
||||||
m_filterIndex = (int)of.nFilterIndex - 1;
|
|
||||||
|
|
||||||
if ( !of.nFileExtension ||
|
|
||||||
(of.nFileExtension && fileNameBuffer[of.nFileExtension] == wxT('\0')) )
|
|
||||||
{
|
|
||||||
// User has typed a filename without an extension:
|
|
||||||
const wxChar* extension = filterBuffer.wx_str();
|
|
||||||
int maxFilter = (int)(of.nFilterIndex*2L) - 1;
|
|
||||||
|
|
||||||
for( int i = 0; i < maxFilter; i++ ) // get extension
|
|
||||||
extension = extension + wxStrlen( extension ) + 1;
|
|
||||||
|
|
||||||
m_fileName = AppendExtension(fileNameBuffer, extension);
|
|
||||||
wxStrncpy(fileNameBuffer, m_fileName.c_str(), wxMin(m_fileName.length(), wxMAXPATH-1));
|
|
||||||
fileNameBuffer[wxMin(m_fileName.length(), wxMAXPATH-1)] = wxT('\0');
|
|
||||||
}
|
|
||||||
|
|
||||||
m_path = fileNameBuffer;
|
|
||||||
m_fileName = wxFileNameFromPath(fileNameBuffer);
|
|
||||||
m_fileNames.Add(m_fileName);
|
|
||||||
m_dir = wxPathOnly(fileNameBuffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#ifdef __WXDEBUG__
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// common dialog failed - why?
|
//=== Adding the correct extension >>=================================
|
||||||
if ( errCode != 0 )
|
|
||||||
{
|
|
||||||
// this msg is only for developers so don't translate it
|
|
||||||
wxLogError(wxT("Common dialog failed with error code %0lx."),
|
|
||||||
errCode);
|
|
||||||
}
|
|
||||||
//else: it was just cancelled
|
|
||||||
}
|
|
||||||
#endif // __WXDEBUG__
|
|
||||||
|
|
||||||
return success ? wxID_OK : wxID_CANCEL;
|
m_filterIndex = (int)of.nFilterIndex - 1;
|
||||||
|
|
||||||
|
if ( !of.nFileExtension ||
|
||||||
|
(of.nFileExtension && fileNameBuffer[of.nFileExtension] == wxT('\0')) )
|
||||||
|
{
|
||||||
|
// User has typed a filename without an extension:
|
||||||
|
const wxChar* extension = filterBuffer.wx_str();
|
||||||
|
int maxFilter = (int)(of.nFilterIndex*2L) - 1;
|
||||||
|
|
||||||
|
for( int i = 0; i < maxFilter; i++ ) // get extension
|
||||||
|
extension = extension + wxStrlen( extension ) + 1;
|
||||||
|
|
||||||
|
m_fileName = AppendExtension(fileNameBuffer, extension);
|
||||||
|
wxStrncpy(fileNameBuffer, m_fileName.c_str(), wxMin(m_fileName.length(), wxMAXPATH-1));
|
||||||
|
fileNameBuffer[wxMin(m_fileName.length(), wxMAXPATH-1)] = wxT('\0');
|
||||||
|
}
|
||||||
|
|
||||||
|
m_path = fileNameBuffer;
|
||||||
|
m_fileName = wxFileNameFromPath(fileNameBuffer);
|
||||||
|
m_fileNames.Add(m_fileName);
|
||||||
|
m_dir = wxPathOnly(fileNameBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxID_OK;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user