/////////////////////////////////////////////////////////////////////////////// // iFileNameDialog.cpp // // C++ class for handling the Win32 API functions GetSafeFileName and // // GetOpenFileName in a much nicer and easier fashion. // // // // Copyright (c) Smartsoft, LLC, 2002. All Rights Reserved. // // Written by Jan Knepper // // // // Redistribution and use in source and binary forms, with or without // // modification, are permitted provided that the following conditions // // are met: // // 1. Redistributions of source code must retain the above copyright // // notice, this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // // notice, this list of conditions and the following disclaimer in the // // documentation and/or other materials provided with the distribution. // // 3. The name of the author may not be used to endorse or promote products // // derived from this software without specific prior written permission. // // // // THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND // // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE // // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF // // THE POSSIBILITY OF SUCH DAMAGE. // /////////////////////////////////////////////////////////////////////////////// #include #include "FileNameDialog.hpp" iFileNameDialog :: iFileNameDialog ( HWND hwnd, LPCTSTR _filter, LPCTSTR _customfilter, DWORD _filterindex, LPCTSTR _file, LPCTSTR _filetitle, LPCTSTR _initialdir, LPCTSTR _title, DWORD _flags, LPCTSTR _defaultextension ) { memset ( &openfilename, 0, sizeof ( OPENFILENAME ) ); if ( _customfilter != 0 ) { maxcustomfilter = strlen ( _customfilter ) * 2; customfilter = new TCHAR [ maxcustomfilter ]; _tcscpy ( customfilter, _customfilter ); } else { maxcustomfilter = 0; customfilter = 0; } file = new TCHAR [ FILENAME_MAX ]; if ( _file != 0 ) _tcscpy ( file, _file ); else _tcsnset2 ( file, _T ( '\0' ), FILENAME_MAX ); if ( _filetitle != 0 ) { maxfiletitle = FILENAME_MAX; filetitle = new TCHAR [ FILENAME_MAX ]; _tcscpy ( filetitle, _filetitle ); } else { maxfiletitle = 0; filetitle = 0; } openfilename.lStructSize = sizeof ( OPENFILENAME ); openfilename.hwndOwner = hwnd; openfilename.lpstrFilter = _filter; openfilename.lpstrCustomFilter = customfilter; openfilename.nMaxCustFilter = maxcustomfilter; openfilename.nFilterIndex = _filterindex; openfilename.lpstrFile = file; openfilename.nMaxFile = FILENAME_MAX; openfilename.lpstrFileTitle = filetitle; openfilename.nMaxFileTitle = maxfiletitle; openfilename.lpstrInitialDir = _initialdir; openfilename.lpstrTitle = _title; openfilename.Flags = _flags; openfilename.lpstrDefExt = _defaultextension; // If no filterindex has been defined, there is no customfilter and a file // has been defined, try to find the filterindex for the extension of that // file. if ( ( _filterindex == 0 ) && ( customfilter == 0 ) && ( _file != 0 ) && ( _filter != 0 ) ) openfilename.nFilterIndex = FilterIndex ( file ) + 1; } iFileNameDialog :: ~iFileNameDialog () { delete [] filetitle; delete [] file; delete [] customfilter; } int iFileNameDialog :: FilterIndex ( LPCTSTR file ) const { if ( openfilename.lpstrFilter == 0 ) return ( -1 ); LPCTSTR extension = _tcsrchr ( file, _T ( '.' ) ); if ( ( extension != 0 ) && ( _tcsstr ( extension, "/\\" ) == 0 ) ) { size_t EXTENSION = _tcslen ( extension ); int index = 0; if ( *extension != _T ( '\0' ) ) { LPCTSTR ptr = openfilename.lpstrFilter; LPCTSTR str; while ( *ptr != '\0' ) { while ( *ptr != '\0' ) // Skip the description. ptr++; ptr++; // Skip over the '\0'. if ( *ptr != _T ( '\0' ) ) { if ( ( ( str = _tcsistr ( ptr, extension ) ) != 0 ) && ( ( *( str + EXTENSION ) == _T ( ';' ) ) || ( *( str + EXTENSION ) == _T ( '\0' ) ) ) ) { return ( index ); break; } while ( *ptr != '\0' ) // Skip the filter. ptr++; ptr++; // Skip over the '\0'. } else break; index++; } } } return ( -1 ); } iString iFileNameDialog :: FilterExtension ( int index ) const { int i = -1; LPCTSTR ptr = openfilename.lpstrFilter; iString str; if ( openfilename.lpstrFilter == 0 ) return ( str ); while ( ( i < index ) && ( *ptr != '\0' ) ) { while ( *ptr != _T ( '\0' ) ) // Skip the description. ptr++; ptr++; // Skip over the '\0'. if ( *ptr == _T ( '\0' ) ) break; if ( ++i == index ) { if ( *ptr == '*' ) { ptr++; if ( *ptr == '.' ) { ptr++; LPCTSTR extension = ptr; while ( ( *ptr != ';' ) && ( *ptr != '\0' ) ) ptr++; str.Copy ( extension, ptr - extension ); return ( str ); } } } while ( *ptr != _T ( '\0' ) ) // Skip the filter. ptr++; ptr++; // Skip over the '\0'. } return ( str ); } BOOL iFileNameDialog :: Open () { return ( GetOpenFileName ( &openfilename ) ); } BOOL iFileNameDialog :: Save () { return ( GetSaveFileName ( &openfilename ) ); } void iFileNameDialog :: SetExtension () { int filterindex = FilterIndex () - 1; // .nFileExtension is 0 when the user typed a '.' as the last character in // the file name! if ( openfilename.nFileExtension == 0 ) { *( file + ( openfilename.nFileExtension = _tcslen ( file ) ) ) = '.'; openfilename.nFileExtension++; } _tcscpy ( file + openfilename.nFileExtension, FilterExtension ( filterindex ) ); }