]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/msw/dir.cpp
Corrected problem related to wxSIZE_ALLOW_MINUS_ONE
[wxWidgets.git] / src / msw / dir.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: msw/dir.cpp
3// Purpose: wxDir implementation for Win32
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 08.12.99
7// RCS-ID: $Id$
8// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#ifdef __GNUG__
21 #pragma implementation "dir.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#ifndef WX_PRECOMP
32 #include "wx/intl.h"
33 #include "wx/log.h"
34#endif // PCH
35
36#include "wx/dir.h"
37#include "wx/filefn.h" // for wxPathExists()
38
39// ----------------------------------------------------------------------------
40// define the types and functions used for file searching
41// ----------------------------------------------------------------------------
42
43// under Win16 use compiler-specific functions
44#ifdef __WIN16__
45 #ifdef __VISUALC__
46 #include <dos.h>
47 #include <errno.h>
48
49 typedef struct _find_t FIND_STRUCT;
50 #elif defined(__BORLANDC__)
51 #include <dir.h>
52
53 typedef struct ffblk FIND_STRUCT;
54 #else
55 #error "No directory searching functions for this compiler"
56 #endif
57
58 typedef FIND_STRUCT *FIND_DATA;
59 typedef char FIND_ATTR;
60
61 static inline FIND_DATA InitFindData() { return (FIND_DATA)NULL; }
62 static inline bool IsFindDataOk(FIND_DATA fd) { return fd != NULL; }
63 static inline void FreeFindData(FIND_DATA fd) { free(fd); }
64
65 static inline FIND_DATA FindFirst(const wxString& spec,
66 FIND_STRUCT * WXUNUSED(finddata))
67 {
68 // attribute to find all files
69 static const FIND_ATTR attr = 0x3F;
70
71 FIND_DATA fd = (FIND_DATA)malloc(sizeof(FIND_STRUCT));
72
73 if (
74 #ifdef __VISUALC__
75 _dos_findfirst(spec, attr, fd) == 0
76 #else // Borland
77 findfirst(spec, fd, attr) == 0
78 #endif
79 )
80 {
81 return fd;
82 }
83 else
84 {
85 free(fd);
86
87 return NULL;
88 }
89 }
90
91 static inline bool FindNext(FIND_DATA fd, FIND_STRUCT * WXUNUSED(finddata))
92 {
93 #ifdef __VISUALC__
94 return _dos_findnext(fd) == 0;
95 #else // Borland
96 return findnext(fd) == 0;
97 #endif
98 }
99
100 static const wxChar *GetNameFromFindData(FIND_STRUCT *finddata)
101 {
102 #ifdef __VISUALC__
103 return finddata->name;
104 #else // Borland
105 return finddata->ff_name;
106 #endif
107 }
108
109 static const FIND_ATTR GetAttrFromFindData(FIND_STRUCT *finddata)
110 {
111 #ifdef __VISUALC__
112 return finddata->attrib;
113 #else // Borland
114 return finddata->ff_attrib;
115 #endif
116 }
117
118 static inline bool IsDir(FIND_ATTR attr)
119 {
120 return (attr & _A_SUBDIR) != 0;
121 }
122
123 static inline bool IsHidden(FIND_ATTR attr)
124 {
125 return (attr & (_A_SYSTEM | _A_HIDDEN)) != 0;
126 }
127#else // Win32
128 #include <windows.h>
129
130 typedef WIN32_FIND_DATA FIND_STRUCT;
131 typedef HANDLE FIND_DATA;
132 typedef DWORD FIND_ATTR;
133
134 static inline FIND_DATA InitFindData() { return INVALID_HANDLE_VALUE; }
135
136 static inline bool IsFindDataOk(FIND_DATA fd)
137 {
138 return fd != INVALID_HANDLE_VALUE;
139 }
140
141 static inline void FreeFindData(FIND_DATA fd)
142 {
143 if ( !::FindClose(fd) )
144 {
145 wxLogLastError(_T("FindClose"));
146 }
147 }
148
149 static inline FIND_DATA FindFirst(const wxString& spec,
150 FIND_STRUCT *finddata)
151 {
152 return ::FindFirstFile(spec, finddata);
153 }
154
155 static inline bool FindNext(FIND_DATA fd, FIND_STRUCT *finddata)
156 {
157 return ::FindNextFile(fd, finddata) != 0;
158 }
159
160 static const wxChar *GetNameFromFindData(FIND_STRUCT *finddata)
161 {
162 return finddata->cFileName;
163 }
164
165 static const FIND_ATTR GetAttrFromFindData(FIND_STRUCT *finddata)
166 {
167 return finddata->dwFileAttributes;
168 }
169
170 static inline bool IsDir(FIND_ATTR attr)
171 {
172 return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
173 }
174
175 static inline bool IsHidden(FIND_ATTR attr)
176 {
177 return (attr & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) != 0;
178 }
179#endif // __WIN16__
180
181// ----------------------------------------------------------------------------
182// constants
183// ----------------------------------------------------------------------------
184
185#ifndef MAX_PATH
186 #define MAX_PATH 260 // from VC++ headers
187#endif
188
189// ----------------------------------------------------------------------------
190// macros
191// ----------------------------------------------------------------------------
192
193#define M_DIR ((wxDirData *)m_data)
194
195// ----------------------------------------------------------------------------
196// private classes
197// ----------------------------------------------------------------------------
198
199// this class stores everything we need to enumerate the files
200class wxDirData
201{
202public:
203 wxDirData(const wxString& dirname);
204 ~wxDirData();
205
206 void SetFileSpec(const wxString& filespec) { m_filespec = filespec; }
207 void SetFlags(int flags) { m_flags = flags; }
208
209 void Close();
210 void Rewind();
211 bool Read(wxString *filename);
212
213private:
214 FIND_DATA m_finddata;
215
216 wxString m_dirname;
217 wxString m_filespec;
218
219 int m_flags;
220};
221
222// ============================================================================
223// implementation
224// ============================================================================
225
226// ----------------------------------------------------------------------------
227// wxDirData
228// ----------------------------------------------------------------------------
229
230wxDirData::wxDirData(const wxString& dirname)
231 : m_dirname(dirname)
232{
233 m_finddata = InitFindData();
234}
235
236wxDirData::~wxDirData()
237{
238 Close();
239}
240
241void wxDirData::Close()
242{
243 if ( IsFindDataOk(m_finddata) )
244 {
245 FreeFindData(m_finddata);
246
247 m_finddata = InitFindData();
248 }
249}
250
251void wxDirData::Rewind()
252{
253 Close();
254}
255
256bool wxDirData::Read(wxString *filename)
257{
258 bool first = FALSE;
259
260#ifdef __WIN32__
261 WIN32_FIND_DATA finddata;
262 #define PTR_TO_FINDDATA (&finddata)
263#else // Win16
264 #define PTR_TO_FINDDATA (m_finddata)
265#endif
266
267 if ( !IsFindDataOk(m_finddata) )
268 {
269 // open first
270 wxString filespec = m_dirname;
271 if ( !wxEndsWithPathSeparator(filespec) )
272 {
273 filespec += _T('\\');
274 }
275 filespec += (!m_filespec ? _T("*.*") : m_filespec.c_str());
276
277 m_finddata = FindFirst(filespec, PTR_TO_FINDDATA);
278
279 first = TRUE;
280 }
281
282 if ( !IsFindDataOk(m_finddata) )
283 {
284#ifdef __WIN32__
285 DWORD err = ::GetLastError();
286
287 if ( err != ERROR_FILE_NOT_FOUND )
288 {
289 wxLogSysError(err, _("Can not enumerate files in directory '%s'"),
290 m_dirname.c_str());
291 }
292#endif // __WIN32__
293 //else: not an error, just no (such) files
294
295 return FALSE;
296 }
297
298 const wxChar *name;
299 FIND_ATTR attr;
300
301 for ( ;; )
302 {
303 if ( first )
304 {
305 first = FALSE;
306 }
307 else
308 {
309 if ( !FindNext(m_finddata, PTR_TO_FINDDATA) )
310 {
311#ifdef __WIN32__
312 DWORD err = ::GetLastError();
313
314 if ( err != ERROR_NO_MORE_FILES )
315 {
316 wxLogLastError(_T("FindNext"));
317 }
318#endif // __WIN32__
319 //else: not an error, just no more (such) files
320
321 return FALSE;
322 }
323 }
324
325 name = GetNameFromFindData(PTR_TO_FINDDATA);
326 attr = GetAttrFromFindData(PTR_TO_FINDDATA);
327
328 // don't return "." and ".." unless asked for
329 if ( name[0] == _T('.') &&
330 ((name[1] == _T('.') && name[2] == _T('\0')) ||
331 (name[1] == _T('\0'))) )
332 {
333 if ( !(m_flags & wxDIR_DOTDOT) )
334 continue;
335 }
336
337 // check the type now
338 if ( !(m_flags & wxDIR_FILES) && !IsDir(attr) )
339 {
340 // it's a file, but we don't want them
341 continue;
342 }
343 else if ( !(m_flags & wxDIR_DIRS) && IsDir(attr) )
344 {
345 // it's a dir, and we don't want it
346 continue;
347 }
348
349 // finally, check whether it's a hidden file
350 if ( !(m_flags & wxDIR_HIDDEN) )
351 {
352 if ( IsHidden(attr) )
353 {
354 // it's a hidden file, skip it
355 continue;
356 }
357 }
358
359 *filename = name;
360
361 break;
362 }
363
364 return TRUE;
365}
366
367// ----------------------------------------------------------------------------
368// wxDir helpers
369// ----------------------------------------------------------------------------
370
371/* static */
372bool wxDir::Exists(const wxString& dir)
373{
374 return wxPathExists(dir);
375}
376
377// ----------------------------------------------------------------------------
378// wxDir construction/destruction
379// ----------------------------------------------------------------------------
380
381wxDir::wxDir(const wxString& dirname)
382{
383 m_data = NULL;
384
385 (void)Open(dirname);
386}
387
388bool wxDir::Open(const wxString& dirname)
389{
390 delete M_DIR;
391 m_data = new wxDirData(dirname);
392
393 return TRUE;
394}
395
396bool wxDir::IsOpened() const
397{
398 return m_data != NULL;
399}
400
401wxDir::~wxDir()
402{
403 delete M_DIR;
404}
405
406// ----------------------------------------------------------------------------
407// wxDir enumerating
408// ----------------------------------------------------------------------------
409
410bool wxDir::GetFirst(wxString *filename,
411 const wxString& filespec,
412 int flags) const
413{
414 wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
415
416 M_DIR->Rewind();
417
418 M_DIR->SetFileSpec(filespec);
419 M_DIR->SetFlags(flags);
420
421 return GetNext(filename);
422}
423
424bool wxDir::GetNext(wxString *filename) const
425{
426 wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
427
428 wxCHECK_MSG( filename, FALSE, _T("bad pointer in wxDir::GetNext()") );
429
430 return M_DIR->Read(filename);
431}