]> git.saurik.com Git - wxWidgets.git/blame - src/msw/dir.cpp
Initial wxTLW::(Can)SetTransparent support for wxGTK. The return value of SetTranspar...
[wxWidgets.git] / src / msw / dir.cpp
CommitLineData
1944c6bd
VZ
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>
65571936 9// Licence: wxWindows licence
1944c6bd
VZ
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
1944c6bd
VZ
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#ifndef WX_PRECOMP
28 #include "wx/intl.h"
29 #include "wx/log.h"
30#endif // PCH
31
32#include "wx/dir.h"
da865fdd 33#include "wx/filefn.h" // for wxDirExists()
1944c6bd 34
532d575b 35#ifdef __WINDOWS__
4676948b
JS
36 #include "wx/msw/private.h"
37#endif
38
8f177c8e
VZ
39// ----------------------------------------------------------------------------
40// define the types and functions used for file searching
41// ----------------------------------------------------------------------------
42
3a5bcc4d
VZ
43typedef WIN32_FIND_DATA FIND_STRUCT;
44typedef HANDLE FIND_DATA;
45typedef DWORD FIND_ATTR;
8f177c8e 46
3a5bcc4d 47static inline FIND_DATA InitFindData() { return INVALID_HANDLE_VALUE; }
8f177c8e 48
3a5bcc4d
VZ
49static inline bool IsFindDataOk(FIND_DATA fd)
50{
8f177c8e 51 return fd != INVALID_HANDLE_VALUE;
3a5bcc4d 52}
8f177c8e 53
3a5bcc4d
VZ
54static inline void FreeFindData(FIND_DATA fd)
55{
8f177c8e
VZ
56 if ( !::FindClose(fd) )
57 {
58 wxLogLastError(_T("FindClose"));
59 }
3a5bcc4d 60}
8f177c8e 61
3a5bcc4d 62static inline FIND_DATA FindFirst(const wxString& spec,
8f177c8e 63 FIND_STRUCT *finddata)
3a5bcc4d 64{
c5a1681b 65 return ::FindFirstFile(spec, finddata);
3a5bcc4d 66}
8f177c8e 67
3a5bcc4d
VZ
68static inline bool FindNext(FIND_DATA fd, FIND_STRUCT *finddata)
69{
8f177c8e 70 return ::FindNextFile(fd, finddata) != 0;
3a5bcc4d 71}
8f177c8e 72
3a5bcc4d
VZ
73static const wxChar *GetNameFromFindData(FIND_STRUCT *finddata)
74{
8f177c8e 75 return finddata->cFileName;
3a5bcc4d 76}
8f177c8e 77
3a5bcc4d
VZ
78static const FIND_ATTR GetAttrFromFindData(FIND_STRUCT *finddata)
79{
8f177c8e 80 return finddata->dwFileAttributes;
3a5bcc4d 81}
8f177c8e 82
3a5bcc4d
VZ
83static inline bool IsDir(FIND_ATTR attr)
84{
8f177c8e 85 return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
3a5bcc4d 86}
8f177c8e 87
3a5bcc4d
VZ
88static inline bool IsHidden(FIND_ATTR attr)
89{
8f177c8e 90 return (attr & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) != 0;
3a5bcc4d 91}
1944c6bd
VZ
92
93// ----------------------------------------------------------------------------
94// constants
95// ----------------------------------------------------------------------------
96
97#ifndef MAX_PATH
98 #define MAX_PATH 260 // from VC++ headers
99#endif
100
101// ----------------------------------------------------------------------------
102// macros
103// ----------------------------------------------------------------------------
104
105#define M_DIR ((wxDirData *)m_data)
106
107// ----------------------------------------------------------------------------
108// private classes
109// ----------------------------------------------------------------------------
110
111// this class stores everything we need to enumerate the files
112class wxDirData
113{
114public:
115 wxDirData(const wxString& dirname);
116 ~wxDirData();
117
118 void SetFileSpec(const wxString& filespec) { m_filespec = filespec; }
119 void SetFlags(int flags) { m_flags = flags; }
120
121 void Close();
122 void Rewind();
123 bool Read(wxString *filename);
124
35332784
VZ
125 const wxString& GetName() const { return m_dirname; }
126
1944c6bd 127private:
8f177c8e 128 FIND_DATA m_finddata;
1944c6bd
VZ
129
130 wxString m_dirname;
131 wxString m_filespec;
132
133 int m_flags;
22f3361e
VZ
134
135 DECLARE_NO_COPY_CLASS(wxDirData)
1944c6bd
VZ
136};
137
138// ============================================================================
139// implementation
140// ============================================================================
141
142// ----------------------------------------------------------------------------
143// wxDirData
144// ----------------------------------------------------------------------------
145
146wxDirData::wxDirData(const wxString& dirname)
147 : m_dirname(dirname)
148{
8f177c8e 149 m_finddata = InitFindData();
1944c6bd
VZ
150}
151
152wxDirData::~wxDirData()
153{
154 Close();
155}
156
157void wxDirData::Close()
158{
8f177c8e 159 if ( IsFindDataOk(m_finddata) )
1944c6bd 160 {
8f177c8e 161 FreeFindData(m_finddata);
4afd7529 162
8f177c8e 163 m_finddata = InitFindData();
1944c6bd
VZ
164 }
165}
166
167void wxDirData::Rewind()
168{
169 Close();
170}
171
172bool wxDirData::Read(wxString *filename)
173{
d71cc120 174 bool first = false;
1944c6bd
VZ
175
176 WIN32_FIND_DATA finddata;
8f177c8e 177 #define PTR_TO_FINDDATA (&finddata)
8f177c8e
VZ
178
179 if ( !IsFindDataOk(m_finddata) )
1944c6bd
VZ
180 {
181 // open first
ad0dc53b
VZ
182 wxString filespec = m_dirname;
183 if ( !wxEndsWithPathSeparator(filespec) )
184 {
185 filespec += _T('\\');
186 }
187 filespec += (!m_filespec ? _T("*.*") : m_filespec.c_str());
4afd7529 188
8f177c8e 189 m_finddata = FindFirst(filespec, PTR_TO_FINDDATA);
1944c6bd 190
d71cc120 191 first = true;
1944c6bd
VZ
192 }
193
8f177c8e 194 if ( !IsFindDataOk(m_finddata) )
1944c6bd 195 {
8f177c8e 196#ifdef __WIN32__
1944c6bd
VZ
197 DWORD err = ::GetLastError();
198
5613bc20 199 if ( err != ERROR_FILE_NOT_FOUND && err != ERROR_NO_MORE_FILES )
1944c6bd
VZ
200 {
201 wxLogSysError(err, _("Can not enumerate files in directory '%s'"),
202 m_dirname.c_str());
203 }
8f177c8e 204#endif // __WIN32__
1944c6bd
VZ
205 //else: not an error, just no (such) files
206
d71cc120 207 return false;
1944c6bd
VZ
208 }
209
1944c6bd 210 const wxChar *name;
8f177c8e 211 FIND_ATTR attr;
1944c6bd 212
4afd7529 213 for ( ;; )
1944c6bd
VZ
214 {
215 if ( first )
216 {
d71cc120 217 first = false;
1944c6bd
VZ
218 }
219 else
220 {
8f177c8e 221 if ( !FindNext(m_finddata, PTR_TO_FINDDATA) )
1944c6bd 222 {
8f177c8e 223#ifdef __WIN32__
1944c6bd
VZ
224 DWORD err = ::GetLastError();
225
226 if ( err != ERROR_NO_MORE_FILES )
227 {
228 wxLogLastError(_T("FindNext"));
229 }
8f177c8e 230#endif // __WIN32__
1944c6bd
VZ
231 //else: not an error, just no more (such) files
232
d71cc120 233 return false;
1944c6bd
VZ
234 }
235 }
236
8f177c8e
VZ
237 name = GetNameFromFindData(PTR_TO_FINDDATA);
238 attr = GetAttrFromFindData(PTR_TO_FINDDATA);
1944c6bd
VZ
239
240 // don't return "." and ".." unless asked for
241 if ( name[0] == _T('.') &&
242 ((name[1] == _T('.') && name[2] == _T('\0')) ||
243 (name[1] == _T('\0'))) )
244 {
245 if ( !(m_flags & wxDIR_DOTDOT) )
246 continue;
247 }
248
249 // check the type now
8f177c8e 250 if ( !(m_flags & wxDIR_FILES) && !IsDir(attr) )
1944c6bd
VZ
251 {
252 // it's a file, but we don't want them
253 continue;
254 }
8f177c8e 255 else if ( !(m_flags & wxDIR_DIRS) && IsDir(attr) )
1944c6bd
VZ
256 {
257 // it's a dir, and we don't want it
258 continue;
259 }
260
261 // finally, check whether it's a hidden file
262 if ( !(m_flags & wxDIR_HIDDEN) )
263 {
8f177c8e 264 if ( IsHidden(attr) )
4afd7529
VZ
265 {
266 // it's a hidden file, skip it
267 continue;
268 }
1944c6bd 269 }
1944c6bd 270
4afd7529
VZ
271 *filename = name;
272
273 break;
274 }
1944c6bd 275
d71cc120 276 return true;
1944c6bd
VZ
277}
278
279// ----------------------------------------------------------------------------
280// wxDir helpers
281// ----------------------------------------------------------------------------
282
283/* static */
284bool wxDir::Exists(const wxString& dir)
285{
da865fdd 286 return wxDirExists(dir);
1944c6bd
VZ
287}
288
289// ----------------------------------------------------------------------------
290// wxDir construction/destruction
291// ----------------------------------------------------------------------------
292
293wxDir::wxDir(const wxString& dirname)
294{
295 m_data = NULL;
296
297 (void)Open(dirname);
298}
299
300bool wxDir::Open(const wxString& dirname)
301{
302 delete M_DIR;
303 m_data = new wxDirData(dirname);
304
d71cc120 305 return true;
1944c6bd
VZ
306}
307
308bool wxDir::IsOpened() const
309{
310 return m_data != NULL;
311}
312
35332784
VZ
313wxString wxDir::GetName() const
314{
315 wxString name;
316 if ( m_data )
317 {
318 name = M_DIR->GetName();
319 if ( !name.empty() )
320 {
321 // bring to canonical Windows form
322 name.Replace(_T("/"), _T("\\"));
323
324 if ( name.Last() == _T('\\') )
325 {
326 // chop off the last (back)slash
327 name.Truncate(name.length() - 1);
328 }
329 }
330 }
331
332 return name;
333}
334
1944c6bd
VZ
335wxDir::~wxDir()
336{
337 delete M_DIR;
338}
339
340// ----------------------------------------------------------------------------
341// wxDir enumerating
342// ----------------------------------------------------------------------------
343
344bool wxDir::GetFirst(wxString *filename,
345 const wxString& filespec,
346 int flags) const
347{
d71cc120 348 wxCHECK_MSG( IsOpened(), false, _T("must wxDir::Open() first") );
1944c6bd
VZ
349
350 M_DIR->Rewind();
351
352 M_DIR->SetFileSpec(filespec);
353 M_DIR->SetFlags(flags);
354
355 return GetNext(filename);
356}
357
358bool wxDir::GetNext(wxString *filename) const
359{
d71cc120 360 wxCHECK_MSG( IsOpened(), false, _T("must wxDir::Open() first") );
1944c6bd 361
d71cc120 362 wxCHECK_MSG( filename, false, _T("bad pointer in wxDir::GetNext()") );
1944c6bd
VZ
363
364 return M_DIR->Read(filename);
365}
2b5f62a0
VZ
366
367// ----------------------------------------------------------------------------
368// wxGetDirectoryTimes: used by wxFileName::GetTimes()
369// ----------------------------------------------------------------------------
370
371#ifdef __WIN32__
372
373extern bool
374wxGetDirectoryTimes(const wxString& dirname,
375 FILETIME *ftAccess, FILETIME *ftCreate, FILETIME *ftMod)
376{
377 // FindFirst() is going to fail
378 wxASSERT_MSG( !dirname.empty() && dirname.Last() != _T('\\'),
379 _T("incorrect directory name format in wxGetDirectoryTimes") );
380
381 FIND_STRUCT fs;
382 FIND_DATA fd = FindFirst(dirname, &fs);
383 if ( !IsFindDataOk(fd) )
384 {
d71cc120 385 return false;
2b5f62a0
VZ
386 }
387
388 *ftAccess = fs.ftLastAccessTime;
389 *ftCreate = fs.ftCreationTime;
390 *ftMod = fs.ftLastWriteTime;
391
392 FindClose(fd);
393
d71cc120 394 return true;
2b5f62a0
VZ
395}
396
397#endif // __WIN32__
398