Re: CFileDialog failure
Hi,
you may want to try this code.
I've tested that and it seems running fine:
The OnBnClickedButton1 is an handler associated to a button I put in a
dialog box (CTestDlg class), and it is the place when the text happens.
If you want to simulate the "too many files" error, uncomment the following
line in OnBnClickedButton1 body:
// const int MaxFileBuffer = 30; // TEST for small buffer
(and comment the line above).
Note that I put comments in source code, so you can read them.
<code>
//------------------------------------------------------------------
// Given the file list from Open file dialog in multi-select mode,
// parses it and prints its content to the user.
//------------------------------------------------------------------
void CTestDlg::ProcessFileList( LPCTSTR fileList )
{
ASSERT( fileList != NULL );
//
// Parse file list from CFileDialog,
// and build a string list from it
//
LPCTSTR pstr = fileList;
std::vector< CString > strings;
while ( true )
{
if ( *pstr == _T('\0') && *(pstr+1) == _T('\0') )
{
break;
}
// Ciao 0
// 1234 5
// *
// 0123 4
strings.push_back( CString(pstr) );
pstr += (_tcslen(pstr) + 1);
}
//
// Build a message with the file names
//
CString msg;
msg = _T("*** Selected files ***\n\n");
msg += _T("Path : ") + strings.at(0); // First string is path name
msg += _T("\n\n");
for ( size_t i = 1; i < strings.size(); i++ )
{
msg += strings.at(i);
msg += _T("\n");
}
AfxMessageBox( msg );
}
//------------------------------------------------------------------
// Tests Open file dialog in multi-select mode.
//------------------------------------------------------------------
void CTestDlg::OnBnClickedButton1()
{
// Max files in list (including folder path)
const int MaxFileCount = 50;
// Max TCHARs per file
const int MaxFilePath = MAX_PATH;
// Calculate approx size for the given number of max files.
// The "+1" is for the terminating NUL (_T('\0')) character.
const int MaxFileBuffer = MaxFileCount * MaxFilePath + 1;
// const int MaxFileBuffer = 30; // TEST for small buffer
// Buffer for file names
std::vector< TCHAR > fileNamesBuffer(MaxFileBuffer);
// File dialog object, dynamically allocated
// at each loop iteration
CFileDialog * fileDlg = NULL;
while ( true )
{
// Allocate a new file dialog object
ASSERT( fileDlg == NULL );
fileDlg = new CFileDialog(
TRUE, // Open file dialog
NULL, // No default extension
NULL, // Initial file name
OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT,
_T("All files (*.*)|*.*||"), // Filter
this // Parent
);
// Hook our buffer to file dialog structure
fileDlg->GetOFN().lpstrFile = &(fileNamesBuffer[0]);
fileDlg->GetOFN().nMaxFile = (DWORD) fileNamesBuffer.size();
// Clear buffer content, so we don't see garbage
// from the previous iteration
// (if the previous iteration failed).
::ZeroMemory( &(fileNamesBuffer[0]),
fileNamesBuffer.size() * sizeof(TCHAR) );
// Run the dialog-box
INT_PTR result = fileDlg->DoModal();
// Avoid memory leaks
delete fileDlg;
fileDlg = NULL;
// Check result
if ( result == IDCANCEL )
{
// Failure or user pressed Cancel?
DWORD dw = ::CommDlgExtendedError();
if ( dw & FNERR_BUFFERTOOSMALL )
{
// Failure due to few buffer memory;
// tell that to the user
AfxMessageBox( _T("Too many files selected.") );
// Do another iteration
continue;
}
// User pressed cancel, or other error.
// Quit loop.
break;
}
// User pressed OK:
// Show selected files and quit loop.
ProcessFileList( &(fileNamesBuffer[0]) );
break;
}
}
</code>
Giovanni
--------
"Raj" <rajaramank@msn.com> ha scritto nel messaggio
news:%23e8CXGUEIHA.1208@TK2MSFTNGP05.phx.gbl...
#define MAX_FILE_COUNT 1 //define it to 1. It make it easy to
reproduce this error
CString strFilesSelected;
CFileDialog *pFileDialog=NULL;
while(1) {
pFileDialog = new CFileDialog(TRUE, 0,
"C:\\",OFN_ALLOWMULTISELECT, "All Files (*.*)|*.*||",
CWnd::FromHandle(hStatusWnd));
pFileDialog->GetOFN().lpstrFile =
strFilesSelected.GetBuffer((_MAX_PATH + 1) * MAX_FILE_COUNT + 1);
pFileDialog->GetOFN().nMaxFile = (_MAX_PATH + 1) *
MAX_FILE_COUNT + 1;
nResult = pFileDialog->DoModal();
strFilesSelected.ReleaseBuffer();
if(IDOK != nResult) {
delete pFileDialog;
DWORD dwCommDlgFailure = CommDlgExtendedError();
if(FNERR_BUFFERTOOSMALL & dwCommDlgFailure) {
AfxMessageBox("Too many files selected.");
continue;
}
break;
}
break;
}
This is what I expect to happen
1. First time when the File Selection dialog appears, select a large
number of files to fail the selection
2. "Too many files selected" message appear
3. After pressing <OK> button I expect the File selection dialog to
appear
What is happening is after the first "Too many files selected" failure
DoModal() never successfully brings up the file selection dialog and
returns last error code, hence gets into endless loop.