]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/filedlg.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/filedlg.cpp 
   3 // Purpose:     wxFileDialog 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  21     #pragma implementation "filedlg.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  31 #if wxUSE_FILEDLG && !wxUSE_SMARTPHONE 
  35     #include "wx/msgdlg.h" 
  36     #include "wx/filedlg.h" 
  37     #include "wx/filefn.h" 
  43 #include "wx/msw/private.h" 
  45 #if !defined(__WIN32__) || defined(__WXWINCE__) 
  53 #include "wx/filename.h" 
  54 #include "wx/tokenzr.h" 
  57     #define OFN_EXPLORER 0x00080000 
  60 // ---------------------------------------------------------------------------- 
  62 // ---------------------------------------------------------------------------- 
  65 # define wxMAXPATH   65534 
  67 # define wxMAXPATH   1024 
  70 # define wxMAXFILE   1024 
  74 // ============================================================================ 
  76 // ============================================================================ 
  78 IMPLEMENT_CLASS(wxFileDialog
, wxFileDialogBase
) 
  80 // ---------------------------------------------------------------------------- 
  82 // ---------------------------------------------------------------------------- 
  84 wxFileDialog::wxFileDialog(wxWindow 
*parent
, 
  85                            const wxString
& message
, 
  86                            const wxString
& defaultDir
, 
  87                            const wxString
& defaultFileName
, 
  88                            const wxString
& wildCard
, 
  91              :wxFileDialogBase(parent
, message
, defaultDir
, defaultFileName
, wildCard
, style
, pos
) 
  94     if ( ( m_dialogStyle 
& wxMULTIPLE 
) && ( m_dialogStyle 
& wxSAVE 
) ) 
  95         m_dialogStyle 
&= ~wxMULTIPLE
; 
  98 void wxFileDialog::GetPaths(wxArrayString
& paths
) const 
 103     if ( m_dir
.Last() != _T('\\') ) 
 106     size_t count 
= m_fileNames
.GetCount(); 
 107     for ( size_t n 
= 0; n 
< count
; n
++ ) 
 109         if (wxFileName(m_fileNames
[n
]).IsAbsolute()) 
 110             paths
.Add(m_fileNames
[n
]); 
 112             paths
.Add(dir 
+ m_fileNames
[n
]); 
 116 void wxFileDialog::GetFilenames(wxArrayString
& files
) const 
 121 void wxFileDialog::SetPath(const wxString
& path
) 
 124     wxSplitPath(path
, &m_dir
, &m_fileName
, &ext
); 
 126         m_fileName 
<< _T('.') << ext
; 
 129 int wxFileDialog::ShowModal() 
 132     if (m_parent
) hWnd 
= (HWND
) m_parent
->GetHWND(); 
 133     if (!hWnd 
&& wxTheApp
->GetTopWindow()) 
 134         hWnd 
= (HWND
) wxTheApp
->GetTopWindow()->GetHWND(); 
 136     static wxChar fileNameBuffer 
[ wxMAXPATH 
];           // the file-name 
 137     wxChar        titleBuffer    
[ wxMAXFILE
+1+wxMAXEXT 
];  // the file-name, without path 
 139     *fileNameBuffer 
= wxT('\0'); 
 140     *titleBuffer    
= wxT('\0'); 
 143     if ( (m_dialogStyle 
& wxHIDE_READONLY
) || (m_dialogStyle 
& wxSAVE
) ) 
 144         msw_flags 
|= OFN_HIDEREADONLY
; 
 145     if ( m_dialogStyle 
& wxFILE_MUST_EXIST 
) 
 146         msw_flags 
|= OFN_PATHMUSTEXIST 
| OFN_FILEMUSTEXIST
; 
 148     if (m_dialogStyle 
& wxMULTIPLE 
) 
 150         // OFN_EXPLORER must always be specified with OFN_ALLOWMULTISELECT 
 151         msw_flags 
|= OFN_EXPLORER 
| OFN_ALLOWMULTISELECT
; 
 154     // if wxCHANGE_DIR flag is not given we shouldn't change the CWD which the 
 155     // standard dialog does by default 
 156     if ( !(m_dialogStyle 
& wxCHANGE_DIR
) ) 
 158         msw_flags 
|= OFN_NOCHANGEDIR
; 
 161     if ( m_dialogStyle 
& wxOVERWRITE_PROMPT 
) 
 163         msw_flags 
|= OFN_OVERWRITEPROMPT
; 
 169     // the OPENFILENAME struct has been extended in newer version of 
 170     // comcdlg32.dll, but as we don't use the extended fields anyhow, set 
 171     // the struct size to the old value - otherwise, the programs compiled 
 172     // with new headers will not work with the old libraries 
 173 #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0500) 
 174     of
.lStructSize       
= sizeof(OPENFILENAME
) - 
 175                            (sizeof(void *) + 2*sizeof(DWORD
)); 
 177     of
.lStructSize       
= sizeof(OPENFILENAME
); 
 181     of
.lpstrTitle        
= WXSTRINGCAST m_message
; 
 182     of
.lpstrFileTitle    
= titleBuffer
; 
 183     of
.nMaxFileTitle     
= wxMAXFILE 
+ 1 + wxMAXEXT
;    // Windows 3.0 and 3.1 
 185     // Convert forward slashes to backslashes (file selector doesn't like 
 186     // forward slashes) and also squeeze multiple consecutive slashes into one 
 187     // as it doesn't like two backslashes in a row neither 
 190     size_t      i
, len 
= m_dir
.length(); 
 192     for ( i 
= 0; i 
< len
; i
++ ) 
 194         wxChar ch 
= m_dir
[i
]; 
 198                 // convert to backslash 
 204                 while ( i 
< len 
- 1 ) 
 206                     wxChar chNext 
= m_dir
[i 
+ 1]; 
 207                     if ( chNext 
!= _T('\\') && chNext 
!= _T('/') ) 
 210                     // ignore the next one, unless it is at the start of a UNC path 
 224     of
.lpstrInitialDir   
= dir
.c_str(); 
 226     of
.Flags             
= msw_flags
; 
 229     //=== Like Alejandro Sierra's wildcard modification >>=================== 
 231        In wxFileSelector you can put, instead of a single wild_card, 
 232        pairs of strings separated by '|'. 
 233        The first string is a description, and the 
 234        second is the wild card. You can put any number of pairs. 
 236        eg.  "description1 (*.ex1)|*.ex1|description2 (*.ex2)|*.ex2" 
 238        If you put a single wild card, it works as before the modification. 
 240     //======================================================================= 
 243     if ( wxStrlen(m_wildCard
) == 0 ) 
 244         theFilter 
= wxString(wxT("*.*")); 
 246         theFilter 
= m_wildCard 
; 
 247     wxString filterBuffer
; 
 249     if ( !wxStrchr( theFilter
, wxT('|') ) ) {    // only one filter ==> default text 
 250         filterBuffer
.Printf(_("Files (%s)|%s"), 
 251                             theFilter
.c_str(), theFilter
.c_str()); 
 253     else {                                // more then one filter 
 254         filterBuffer 
= theFilter
; 
 258     filterBuffer 
+= wxT("|"); 
 260     for (i 
= 0; i 
< filterBuffer
.Len(); i
++ ) { 
 261         if ( filterBuffer
.GetChar(i
) == wxT('|') ) { 
 262             filterBuffer
[i
] = wxT('\0'); 
 266     of
.lpstrFilter  
= (LPTSTR
)(const wxChar 
*)filterBuffer
; 
 267     of
.nFilterIndex 
= m_filterIndex 
+ 1; 
 269     //=== Setting defaultFileName >>========================================= 
 271     wxStrncpy( fileNameBuffer
, (const wxChar 
*)m_fileName
, wxMAXPATH
-1 ); 
 272     fileNameBuffer
[ wxMAXPATH
-1 ] = wxT('\0'); 
 274     of
.lpstrFile 
= fileNameBuffer
;  // holds returned filename 
 275     of
.nMaxFile  
= wxMAXPATH
; 
 277     //== Execute FileDialog >>================================================= 
 279     bool success 
= (m_dialogStyle 
& wxSAVE 
? GetSaveFileName(&of
) 
 280                                            : GetOpenFileName(&of
)) != 0; 
 282     DWORD errCode 
= CommDlgExtendedError(); 
 285     if (!success 
&& (errCode 
== CDERR_STRUCTSIZE
)) 
 287         // The struct size has changed so try a smaller or bigger size 
 289         int oldStructSize 
= of
.lStructSize
; 
 290         of
.lStructSize       
= oldStructSize 
- (sizeof(void *) + 2*sizeof(DWORD
)); 
 291         success 
= (m_dialogStyle 
& wxSAVE
) ? (GetSaveFileName(&of
) != 0) 
 292                                             : (GetOpenFileName(&of
) != 0); 
 293         errCode 
= CommDlgExtendedError(); 
 295         if (!success 
&& (errCode 
== CDERR_STRUCTSIZE
)) 
 297             of
.lStructSize       
= oldStructSize 
+ (sizeof(void *) + 2*sizeof(DWORD
)); 
 298             success 
= (m_dialogStyle 
& wxSAVE
) ? (GetSaveFileName(&of
) != 0) 
 299                                             : (GetOpenFileName(&of
) != 0); 
 308         if ( ( m_dialogStyle 
& wxMULTIPLE 
) && 
 309 #if defined(OFN_EXPLORER) 
 310              ( fileNameBuffer
[of
.nFileOffset
-1] == wxT('\0') ) 
 312              ( fileNameBuffer
[of
.nFileOffset
-1] == wxT(' ') ) 
 313 #endif // OFN_EXPLORER 
 316 #if defined(OFN_EXPLORER) 
 317             m_dir 
= fileNameBuffer
; 
 319             m_fileName 
= &fileNameBuffer
[i
]; 
 320             m_fileNames
.Add(m_fileName
); 
 321             i 
+= m_fileName
.Len() + 1; 
 323             while (fileNameBuffer
[i
] != wxT('\0')) 
 325                 m_fileNames
.Add(&fileNameBuffer
[i
]); 
 326                 i 
+= wxStrlen(&fileNameBuffer
[i
]) + 1; 
 329             wxStringTokenizer 
toke(fileNameBuffer
, _T(" \t\r\n")); 
 330             m_dir 
= toke
.GetNextToken(); 
 331             m_fileName 
= toke
.GetNextToken(); 
 332             m_fileNames
.Add(m_fileName
); 
 334             while (toke
.HasMoreTokens()) 
 335                 m_fileNames
.Add(toke
.GetNextToken()); 
 336 #endif // OFN_EXPLORER 
 339             if ( m_dir
.Last() != _T('\\') ) 
 342             m_path 
= dir 
+ m_fileName
; 
 343             m_filterIndex 
= (int)of
.nFilterIndex 
- 1; 
 347             //=== Adding the correct extension >>================================= 
 349             m_filterIndex 
= (int)of
.nFilterIndex 
- 1; 
 351             if ( !of
.nFileExtension 
||  
 352                  (of
.nFileExtension 
&& fileNameBuffer
[of
.nFileExtension
] == wxT('\0')) ) 
 354                 // User has typed a filename without an extension: 
 355                 const wxChar
* extension 
= filterBuffer
; 
 356                 int   maxFilter 
= (int)(of
.nFilterIndex
*2L) - 1; 
 358                 for( int i 
= 0; i 
< maxFilter
; i
++ )           // get extension 
 359                     extension 
= extension 
+ wxStrlen( extension 
) + 1; 
 361                 m_fileName 
= AppendExtension(fileNameBuffer
, extension
); 
 362                 wxStrncpy(fileNameBuffer
, m_fileName
.c_str(), wxMin(m_fileName
.Len(), wxMAXPATH
-1)); 
 363                 fileNameBuffer
[wxMin(m_fileName
.Len(), wxMAXPATH
-1)] = wxT('\0'); 
 366             m_path 
= fileNameBuffer
; 
 367             m_fileName 
= wxFileNameFromPath(fileNameBuffer
); 
 368             m_fileNames
.Add(m_fileName
); 
 369             m_dir 
= wxPathOnly(fileNameBuffer
); 
 374         // common dialog failed - why? 
 376         DWORD dwErr 
= CommDlgExtendedError(); 
 379             // this msg is only for developers 
 380             wxLogError(wxT("Common dialog failed with error code %0lx."), 
 383         //else: it was just cancelled 
 387     return success 
? wxID_OK 
: wxID_CANCEL
; 
 391 #endif // wxUSE_FILEDLG