]> git.saurik.com Git - wxWidgets.git/blame - src/msw/filedlg.cpp
Forgot header with OSX prefix
[wxWidgets.git] / src / msw / filedlg.cpp
CommitLineData
2bda0e17 1/////////////////////////////////////////////////////////////////////////////
f6bcfd97 2// Name: src/msw/filedlg.cpp
2bda0e17
KB
3// Purpose: wxFileDialog
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
6c9a19aa 8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
f6bcfd97
BP
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
2bda0e17
KB
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
ba681060 24 #pragma hdrstop
2bda0e17
KB
25#endif
26
3180bc0e 27#if wxUSE_FILEDLG && !(defined(__SMARTPHONE__) && defined(__WXWINCE__))
1e6feb95 28
949c9f74
WS
29#include "wx/filedlg.h"
30
2bda0e17 31#ifndef WX_PRECOMP
57bd4c60
WS
32 #include "wx/msw/wrapcdlg.h"
33 #include "wx/msw/missing.h"
ba681060
VZ
34 #include "wx/utils.h"
35 #include "wx/msgdlg.h"
2b5f62a0 36 #include "wx/filefn.h"
ba681060 37 #include "wx/intl.h"
2662e49e 38 #include "wx/log.h"
f6bcfd97 39 #include "wx/app.h"
18680f86 40 #include "wx/math.h"
8f177c8e 41#endif
2bda0e17 42
2bda0e17
KB
43#include <stdlib.h>
44#include <string.h>
45
8ad9ca97 46#include "wx/filename.h"
8f177c8e
VZ
47#include "wx/tokenzr.h"
48
f6bcfd97
BP
49// ----------------------------------------------------------------------------
50// constants
51// ----------------------------------------------------------------------------
52
53#ifdef __WIN32__
2b5f62a0 54# define wxMAXPATH 65534
f6bcfd97
BP
55#else
56# define wxMAXPATH 1024
57#endif
58
59# define wxMAXFILE 1024
60
61# define wxMAXEXT 5
62
0b11099d
VZ
63// ----------------------------------------------------------------------------
64// globals
65// ----------------------------------------------------------------------------
66
0a7b0229
VZ
67// standard dialog size for the old Windows systems where the dialog wasn't
68// resizeable
0b11099d
VZ
69static wxRect gs_rectDialog(0, 0, 428, 266);
70
f6bcfd97
BP
71// ============================================================================
72// implementation
73// ============================================================================
74
f74172ab 75IMPLEMENT_CLASS(wxFileDialog, wxFileDialogBase)
2bda0e17 76
0b11099d
VZ
77// ----------------------------------------------------------------------------
78// hook function for moving the dialog
79// ----------------------------------------------------------------------------
80
106d80ad 81UINT_PTR APIENTRY
0b11099d
VZ
82wxFileDialogHookFunction(HWND hDlg,
83 UINT iMsg,
84 WPARAM WXUNUSED(wParam),
85 LPARAM lParam)
86{
cb80db46 87 switch ( iMsg )
0b11099d 88 {
6fa6d659
VZ
89 case WM_INITDIALOG:
90 {
91 OPENFILENAME* ofn = reinterpret_cast<OPENFILENAME *>(lParam);
92 reinterpret_cast<wxFileDialog *>(ofn->lCustData)
93 ->MSWOnInitDialogHook((WXHWND)hDlg);
94 }
95 break;
96
0b11099d
VZ
97 case WM_NOTIFY:
98 {
5c33522f 99 OFNOTIFY *pNotifyCode = reinterpret_cast<OFNOTIFY *>(lParam);
cb80db46 100 if ( pNotifyCode->hdr.code == CDN_INITDONE )
0b11099d 101 {
5c33522f 102 reinterpret_cast<wxFileDialog *>(
0a7b0229
VZ
103 pNotifyCode->lpOFN->lCustData)
104 ->MSWOnInitDone((WXHWND)hDlg);
0b11099d
VZ
105 }
106 }
107 break;
cb80db46
VZ
108
109 case WM_DESTROY:
110 // reuse the position used for the dialog the next time by default
111 //
112 // NB: at least under Windows 2003 this is useless as after the
113 // first time it's shown the dialog always remembers its size
114 // and position itself and ignores any later SetWindowPos calls
115 wxCopyRECTToRect(wxGetWindowRect(::GetParent(hDlg)), gs_rectDialog);
116 break;
0b11099d
VZ
117 }
118
119 // do the default processing
120 return 0;
121}
122
f6bcfd97 123// ----------------------------------------------------------------------------
b600ed13 124// wxFileDialog
f6bcfd97
BP
125// ----------------------------------------------------------------------------
126
2b5f62a0
VZ
127wxFileDialog::wxFileDialog(wxWindow *parent,
128 const wxString& message,
129 const wxString& defaultDir,
130 const wxString& defaultFileName,
131 const wxString& wildCard,
132 long style,
ff3e84ff
VZ
133 const wxPoint& pos,
134 const wxSize& sz,
135 const wxString& name)
0b11099d 136 : wxFileDialogBase(parent, message, defaultDir, defaultFileName,
ff3e84ff 137 wildCard, style, pos, sz, name)
f74172ab 138
2bda0e17 139{
556151f5 140 // NB: all style checks are done by wxFileDialogBase::Create
2bda0e17 141
0b11099d 142 m_bMovedWindow = false;
0a7b0229 143 m_centreDir = 0;
0b11099d
VZ
144
145 // Must set to zero, otherwise the wx routines won't size the window
146 // the second time you call the file dialog, because it thinks it is
147 // already at the requested size.. (when centering)
148 gs_rectDialog.x =
149 gs_rectDialog.y = 0;
0b11099d 150}
0a7b0229 151
c61f4f6d
VZ
152void wxFileDialog::GetPaths(wxArrayString& paths) const
153{
154 paths.Empty();
155
156 wxString dir(m_dir);
157 if ( m_dir.Last() != _T('\\') )
158 dir += _T('\\');
159
160 size_t count = m_fileNames.GetCount();
161 for ( size_t n = 0; n < count; n++ )
162 {
8ad9ca97
JS
163 if (wxFileName(m_fileNames[n]).IsAbsolute())
164 paths.Add(m_fileNames[n]);
165 else
166 paths.Add(dir + m_fileNames[n]);
c61f4f6d
VZ
167 }
168}
169
89654c9a
VZ
170void wxFileDialog::GetFilenames(wxArrayString& files) const
171{
172 files = m_fileNames;
173}
174
2b5f62a0
VZ
175void wxFileDialog::SetPath(const wxString& path)
176{
177 wxString ext;
bd365871 178 wxFileName::SplitPath(path, &m_dir, &m_fileName, &ext);
2b5f62a0
VZ
179 if ( !ext.empty() )
180 m_fileName << _T('.') << ext;
181}
182
cb80db46 183void wxFileDialog::DoGetPosition(int *x, int *y) const
0b11099d 184{
cb80db46
VZ
185 if ( x )
186 *x = gs_rectDialog.x;
187 if ( y )
188 *y = gs_rectDialog.y;
0b11099d
VZ
189}
190
0b11099d
VZ
191void wxFileDialog::DoGetSize(int *width, int *height) const
192{
cb80db46
VZ
193 if ( width )
194 *width = gs_rectDialog.width;
195 if ( height )
196 *height = gs_rectDialog.height;
0b11099d
VZ
197}
198
cb80db46 199void wxFileDialog::DoMoveWindow(int x, int y, int WXUNUSED(w), int WXUNUSED(h))
0b11099d 200{
0b11099d
VZ
201 gs_rectDialog.x = x;
202 gs_rectDialog.y = y;
203
0a7b0229
VZ
204 // our HWND is only set when we're called from MSWOnInitDone(), test if
205 // this is the case
206 HWND hwnd = GetHwnd();
207 if ( hwnd )
208 {
209 // size of the dialog can't be changed because the controls are not
210 // laid out correctly then
211 ::SetWindowPos(hwnd, HWND_TOP, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
212 }
213 else // just remember that we were requested to move the window
214 {
215 m_bMovedWindow = true;
216
217 // if Centre() had been called before, it shouldn't be taken into
218 // account now
219 m_centreDir = 0;
220 }
221}
222
223void wxFileDialog::DoCentre(int dir)
224{
225 m_centreDir = dir;
226 m_bMovedWindow = true;
227
228 // it's unnecessary to do anything else at this stage as we'll redo it in
229 // MSWOnInitDone() anyhow
230}
231
232void wxFileDialog::MSWOnInitDone(WXHWND hDlg)
233{
234 // note the the dialog is the parent window: hDlg is a child of it when
235 // OFN_EXPLORER is used
236 HWND hFileDlg = ::GetParent((HWND)hDlg);
237
238 // set HWND so that our DoMoveWindow() works correctly
239 SetHWND((WXHWND)hFileDlg);
240
241 if ( m_centreDir )
242 {
243 // now we have the real dialog size, remember it
244 RECT rect;
245 GetWindowRect(hFileDlg, &rect);
246 gs_rectDialog = wxRectFromRECT(rect);
247
248 // and position the window correctly: notice that we must use the base
249 // class version as our own doesn't do anything except setting flags
250 wxFileDialogBase::DoCentre(m_centreDir);
251 }
252 else // need to just move it to the correct place
253 {
254 SetPosition(gs_rectDialog.GetPosition());
255 }
256
257 // we shouldn't destroy this HWND
258 SetHWND(NULL);
0b11099d
VZ
259}
260
fe048d77
VZ
261// helper used below in ShowCommFileDialog(): style is used to determine
262// whether to show the "Save file" dialog (if it contains wxFD_SAVE bit) or
263// "Open file" one; returns true on success or false on failure in which case
264// err is filled with the CDERR_XXX constant
c46c1fb8
VZ
265static bool DoShowCommFileDialog(OPENFILENAME *of, long style, DWORD *err)
266{
e031f1df 267 if ( style & wxFD_SAVE ? GetSaveFileName(of) : GetOpenFileName(of) )
c46c1fb8
VZ
268 return true;
269
270 if ( err )
271 {
272#ifdef __WXWINCE__
273 // according to MSDN, CommDlgExtendedError() should work under CE as
274 // well but apparently in practice it doesn't (anybody has more
275 // details?)
276 *err = GetLastError();
277#else
278 *err = CommDlgExtendedError();
279#endif
280 }
281
282 return false;
283}
284
04227efc
VZ
285// We want to use OPENFILENAME struct version 5 (Windows 2000/XP) but we don't
286// know if the OPENFILENAME declared in the currently used headers is a V5 or
287// V4 (smaller) one so we try to manually extend the struct in case it is the
288// old one.
5bb37216 289//
04227efc
VZ
290// We don't do this on Windows CE nor under Win64, however, as there are no
291// compilers with old headers for these architectures
292#if defined(__WXWINCE__) || defined(__WIN64__)
5bb37216
VZ
293 typedef OPENFILENAME wxOPENFILENAME;
294
04227efc
VZ
295 static const DWORD gs_ofStructSize = sizeof(OPENFILENAME);
296#else // !__WXWINCE__ || __WIN64__
297 #define wxTRY_SMALLER_OPENFILENAME
298
5bb37216
VZ
299 struct wxOPENFILENAME : public OPENFILENAME
300 {
301 // fields added in Windows 2000/XP comdlg32.dll version
302 void *pVoid;
303 DWORD dw1;
304 DWORD dw2;
305 };
306
307 // hardcoded sizeof(OPENFILENAME) in the Platform SDK: we have to do it
308 // because sizeof(OPENFILENAME) in the headers we use when compiling the
309 // library could be less if _WIN32_WINNT is not >= 0x500
310 static const DWORD wxOPENFILENAME_V5_SIZE = 88;
311
312 // this is hardcoded sizeof(OPENFILENAME_NT4) from Platform SDK
313 static const DWORD wxOPENFILENAME_V4_SIZE = 76;
5bb37216 314
04227efc
VZ
315 // always try the new one first
316 static DWORD gs_ofStructSize = wxOPENFILENAME_V5_SIZE;
317#endif // __WXWINCE__ || __WIN64__/!...
5bb37216 318
fe048d77
VZ
319static bool ShowCommFileDialog(OPENFILENAME *of, long style)
320{
321 DWORD errCode;
322 bool success = DoShowCommFileDialog(of, style, &errCode);
323
324#ifdef wxTRY_SMALLER_OPENFILENAME
325 // the system might be too old to support the new version file dialog
326 // boxes, try with the old size
327 if ( !success && errCode == CDERR_STRUCTSIZE &&
328 of->lStructSize != wxOPENFILENAME_V4_SIZE )
329 {
330 of->lStructSize = wxOPENFILENAME_V4_SIZE;
331
332 success = DoShowCommFileDialog(of, style, &errCode);
333
334 if ( success || !errCode )
335 {
336 // use this struct size for subsequent dialogs
337 gs_ofStructSize = of->lStructSize;
338 }
339 }
340#endif // wxTRY_SMALLER_OPENFILENAME
341
d4380371
VZ
342 if ( !success &&
343 // FNERR_INVALIDFILENAME is not defined under CE (besides we don't
344 // use CommDlgExtendedError() there anyhow)
345#ifndef __WXWINCE__
346 errCode == FNERR_INVALIDFILENAME &&
347#endif // !__WXWINCE__
348 of->lpstrFile[0] )
fe048d77
VZ
349 {
350 // this can happen if the default file name is invalid, try without it
351 // now
352 of->lpstrFile[0] = _T('\0');
353 success = DoShowCommFileDialog(of, style, &errCode);
354 }
355
356 if ( !success )
357 {
358 // common dialog failed - why?
359 if ( errCode != 0 )
360 {
361 wxLogError(_("File dialog failed with error code %0lx."), errCode);
362 }
363 //else: it was just cancelled
364
365 return false;
366 }
367
368 return true;
369}
370
6fa6d659
VZ
371void wxFileDialog::MSWOnInitDialogHook(WXHWND hwnd)
372{
373 SetHWND(hwnd);
374
375 CreateExtraControl();
376
377 SetHWND(NULL);
378}
379
c61f4f6d 380int wxFileDialog::ShowModal()
2bda0e17 381{
1f2f0331
VZ
382 HWND hWnd = 0;
383 if (m_parent) hWnd = (HWND) m_parent->GetHWND();
f6bcfd97
BP
384 if (!hWnd && wxTheApp->GetTopWindow())
385 hWnd = (HWND) wxTheApp->GetTopWindow()->GetHWND();
2bda0e17 386
f6bcfd97
BP
387 static wxChar fileNameBuffer [ wxMAXPATH ]; // the file-name
388 wxChar titleBuffer [ wxMAXFILE+1+wxMAXEXT ]; // the file-name, without path
2bda0e17 389
223d09f6
KB
390 *fileNameBuffer = wxT('\0');
391 *titleBuffer = wxT('\0');
2bda0e17 392
21416306 393 long msw_flags = OFN_HIDEREADONLY;
21416306 394
b014db05 395 if ( HasFdFlag(wxFD_FILE_MUST_EXIST) )
1f2f0331 396 msw_flags |= OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
0b11099d
VZ
397 /*
398 If the window has been moved the programmer is probably
399 trying to center or position it. Thus we set the callback
400 or hook function so that we can actually adjust the position.
401 Without moving or centering the dlg, it will just stay
402 in the upper left of the frame, it does not center
5bb37216 403 automatically.
0b11099d 404 */
6fa6d659 405 if (m_bMovedWindow || HasExtraControlCreator()) // we need these flags.
503528dc
JS
406 {
407 msw_flags |= OFN_EXPLORER|OFN_ENABLEHOOK;
408#ifndef __WXWINCE__
409 msw_flags |= OFN_ENABLESIZING;
410#endif
411 }
6e8aa701 412
b014db05 413 if ( HasFdFlag(wxFD_MULTIPLE) )
6e8aa701
VZ
414 {
415 // OFN_EXPLORER must always be specified with OFN_ALLOWMULTISELECT
416 msw_flags |= OFN_EXPLORER | OFN_ALLOWMULTISELECT;
417 }
418
e031f1df 419 // if wxFD_CHANGE_DIR flag is not given we shouldn't change the CWD which the
af1f0a76
VZ
420 // standard dialog does by default (notice that under NT it does it anyhow,
421 // OFN_NOCHANGEDIR or not, see below)
b014db05 422 if ( !HasFdFlag(wxFD_CHANGE_DIR) )
6e8aa701
VZ
423 {
424 msw_flags |= OFN_NOCHANGEDIR;
425 }
ac95e671 426
b014db05 427 if ( HasFdFlag(wxFD_OVERWRITE_PROMPT) )
99d1b93d
VZ
428 {
429 msw_flags |= OFN_OVERWRITEPROMPT;
430 }
ac95e671 431
5bb37216 432 wxOPENFILENAME of;
f6bcfd97
BP
433 wxZeroMemory(of);
434
5bb37216 435 of.lStructSize = gs_ofStructSize;
e15e548b 436 of.hwndOwner = hWnd;
e0a050e3 437 of.lpstrTitle = m_message.wx_str();
e15e548b 438 of.lpstrFileTitle = titleBuffer;
5bb37216 439 of.nMaxFileTitle = wxMAXFILE + 1 + wxMAXEXT;
2bda0e17 440
6fa6d659
VZ
441#ifndef __WXWINCE__
442 GlobalPtr hgbl;
443 if ( HasExtraControlCreator() )
444 {
445 msw_flags |= OFN_ENABLETEMPLATEHANDLE;
446
447 hgbl.Init(256, GMEM_ZEROINIT);
448 GlobalPtrLock hgblLock(hgbl);
449 LPDLGTEMPLATE lpdt = static_cast<LPDLGTEMPLATE>(hgblLock.Get());
450
451 // Define a dialog box.
452
453 lpdt->style = DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS;
454 lpdt->cdit = 0; // Number of controls
455 lpdt->x = 0;
456 lpdt->y = 0;
457
458 wxSize extra_size = GetExtraControlSize();
459 // setting cx doesn't change the width of the dialog
460 lpdt->cx = extra_size.GetWidth();
461 // Dividing by 2 gives expected height on WinXP and Wine.
462 // I don't know why (MW).
463 lpdt->cy = extra_size.GetHeight() / 2;
464
465 // after the DLGTEMPLATE there are 3 additional WORDs for dialog menu,
466 // class and title, all three set to zeros.
467
468 of.hInstance = (HINSTANCE)lpdt;
469 }
470#endif // __WXWINCE__
471
0bc9b25e 472 // Convert forward slashes to backslashes (file selector doesn't like
99d1b93d
VZ
473 // forward slashes) and also squeeze multiple consecutive slashes into one
474 // as it doesn't like two backslashes in a row neither
0627d091 475
cbe874bd
WS
476 wxString dir;
477 size_t i, len = m_dir.length();
99d1b93d 478 dir.reserve(len);
0627d091 479 for ( i = 0; i < len; i++ )
99d1b93d
VZ
480 {
481 wxChar ch = m_dir[i];
482 switch ( ch )
483 {
484 case _T('/'):
485 // convert to backslash
486 ch = _T('\\');
487
488 // fall through
0bc9b25e 489
99d1b93d
VZ
490 case _T('\\'):
491 while ( i < len - 1 )
492 {
493 wxChar chNext = m_dir[i + 1];
494 if ( chNext != _T('\\') && chNext != _T('/') )
495 break;
496
04d93c3a
CE
497 // ignore the next one, unless it is at the start of a UNC path
498 if (i > 0)
499 i++;
500 else
0b11099d 501 break;
99d1b93d
VZ
502 }
503 // fall through
504
505 default:
506 // normal char
507 dir += ch;
508 }
509 }
510
511 of.lpstrInitialDir = dir.c_str();
2bda0e17 512
e15e548b 513 of.Flags = msw_flags;
0b11099d 514 of.lpfnHook = wxFileDialogHookFunction;
0a7b0229 515 of.lCustData = (LPARAM)this;
2bda0e17 516
daf32463 517 wxArrayString wildDescriptions, wildFilters;
2bda0e17 518
daf32463 519 size_t items = wxParseCommonDialogsFilter(m_wildCard, wildDescriptions, wildFilters);
2bda0e17 520
daf32463 521 wxASSERT_MSG( items > 0 , _T("empty wildcard list") );
2bda0e17 522
1f2f0331 523 wxString filterBuffer;
2bda0e17 524
daf32463
WS
525 for (i = 0; i < items ; i++)
526 {
527 filterBuffer += wildDescriptions[i];
528 filterBuffer += wxT("|");
529 filterBuffer += wildFilters[i];
530 filterBuffer += wxT("|");
574c0bbf
JS
531 }
532
574c0bbf 533 // Replace | with \0
e031f1df 534 for (i = 0; i < filterBuffer.length(); i++ ) {
223d09f6
KB
535 if ( filterBuffer.GetChar(i) == wxT('|') ) {
536 filterBuffer[i] = wxT('\0');
e15e548b
VZ
537 }
538 }
2bda0e17 539
c9f78968 540 of.lpstrFilter = (LPTSTR)filterBuffer.wx_str();
cc42eb7a 541 of.nFilterIndex = m_filterIndex + 1;
2bda0e17
KB
542
543 //=== Setting defaultFileName >>=========================================
544
64accea5 545 wxStrlcpy(fileNameBuffer, m_fileName.c_str(), WXSIZEOF(fileNameBuffer));
2bda0e17 546
e15e548b 547 of.lpstrFile = fileNameBuffer; // holds returned filename
f6bcfd97 548 of.nMaxFile = wxMAXPATH;
2bda0e17 549
90bddb85 550 // we must set the default extension because otherwise Windows would check
e031f1df 551 // for the existing of a wrong file with wxFD_OVERWRITE_PROMPT (i.e. if the
90bddb85
VZ
552 // user types "foo" and the default extension is ".bar" we should force it
553 // to check for "foo.bar" existence and not "foo")
554 wxString defextBuffer; // we need it to be alive until GetSaveFileName()!
b014db05 555 if (HasFdFlag(wxFD_SAVE))
90bddb85 556 {
e0a050e3 557 const wxChar* extension = filterBuffer.wx_str();
90bddb85
VZ
558 int maxFilter = (int)(of.nFilterIndex*2L) - 1;
559
560 for( int i = 0; i < maxFilter; i++ ) // get extension
561 extension = extension + wxStrlen( extension ) + 1;
562
563 // use dummy name a to avoid assert in AppendExtension
564 defextBuffer = AppendExtension(wxT("a"), extension);
565 if (defextBuffer.StartsWith(wxT("a.")))
566 {
026ff75b 567 defextBuffer = defextBuffer.Mid(2); // remove "a."
90bddb85
VZ
568 of.lpstrDefExt = defextBuffer.c_str();
569 }
570 }
0b11099d 571
af1f0a76
VZ
572 // store off before the standard windows dialog can possibly change it
573 const wxString cwdOrig = wxGetCwd();
574
2bda0e17
KB
575 //== Execute FileDialog >>=================================================
576
fe048d77
VZ
577 if ( !ShowCommFileDialog(&of, m_windowStyle) )
578 return wxID_CANCEL;
2bda0e17 579
fe048d77
VZ
580 // GetOpenFileName will always change the current working directory on
581 // (according to MSDN) "Windows NT 4.0/2000/XP" because the flag
582 // OFN_NOCHANGEDIR has no effect. If the user did not specify
583 // wxFD_CHANGE_DIR let's restore the current working directory to what it
584 // was before the dialog was shown.
585 if ( msw_flags & OFN_NOCHANGEDIR )
f6bcfd97 586 {
fe048d77 587 wxSetWorkingDirectory(cwdOrig);
f6bcfd97 588 }
c46c1fb8 589
fe048d77 590 m_fileNames.Empty();
c61f4f6d 591
fe048d77 592 if ( ( HasFdFlag(wxFD_MULTIPLE) ) &&
c61f4f6d 593#if defined(OFN_EXPLORER)
fe048d77 594 ( fileNameBuffer[of.nFileOffset-1] == wxT('\0') )
c61f4f6d 595#else
fe048d77 596 ( fileNameBuffer[of.nFileOffset-1] == wxT(' ') )
c61f4f6d 597#endif // OFN_EXPLORER
fe048d77
VZ
598 )
599 {
c61f4f6d 600#if defined(OFN_EXPLORER)
fe048d77
VZ
601 m_dir = fileNameBuffer;
602 i = of.nFileOffset;
603 m_fileName = &fileNameBuffer[i];
604 m_fileNames.Add(m_fileName);
605 i += m_fileName.length() + 1;
c61f4f6d 606
fe048d77
VZ
607 while (fileNameBuffer[i] != wxT('\0'))
608 {
609 m_fileNames.Add(&fileNameBuffer[i]);
610 i += wxStrlen(&fileNameBuffer[i]) + 1;
611 }
c61f4f6d 612#else
fe048d77
VZ
613 wxStringTokenizer toke(fileNameBuffer, _T(" \t\r\n"));
614 m_dir = toke.GetNextToken();
615 m_fileName = toke.GetNextToken();
616 m_fileNames.Add(m_fileName);
c61f4f6d 617
fe048d77
VZ
618 while (toke.HasMoreTokens())
619 m_fileNames.Add(toke.GetNextToken());
c61f4f6d
VZ
620#endif // OFN_EXPLORER
621
fe048d77
VZ
622 wxString dir(m_dir);
623 if ( m_dir.Last() != _T('\\') )
624 dir += _T('\\');
2bda0e17 625
fe048d77
VZ
626 m_path = dir + m_fileName;
627 m_filterIndex = (int)of.nFilterIndex - 1;
628 }
629 else
630 {
631 //=== Adding the correct extension >>=================================
2bda0e17 632
fe048d77 633 m_filterIndex = (int)of.nFilterIndex - 1;
2bda0e17 634
fe048d77
VZ
635 if ( !of.nFileExtension ||
636 (of.nFileExtension && fileNameBuffer[of.nFileExtension] == wxT('\0')) )
637 {
638 // User has typed a filename without an extension:
639 const wxChar* extension = filterBuffer.wx_str();
640 int maxFilter = (int)(of.nFilterIndex*2L) - 1;
a039ccbf 641
fe048d77
VZ
642 for( int i = 0; i < maxFilter; i++ ) // get extension
643 extension = extension + wxStrlen( extension ) + 1;
2bda0e17 644
fe048d77 645 m_fileName = AppendExtension(fileNameBuffer, extension);
e408bf52 646 wxStrlcpy(fileNameBuffer, m_fileName.c_str(), WXSIZEOF(fileNameBuffer));
c61f4f6d 647 }
fe048d77
VZ
648
649 m_path = fileNameBuffer;
650 m_fileName = wxFileNameFromPath(fileNameBuffer);
651 m_fileNames.Add(m_fileName);
652 m_dir = wxPathOnly(fileNameBuffer);
7cc98b3e 653 }
2bda0e17 654
fe048d77 655 return wxID_OK;
2bda0e17
KB
656
657}
658
3180bc0e 659#endif // wxUSE_FILEDLG && !(__SMARTPHONE__ && __WXWINCE__)