]> git.saurik.com Git - wxWidgets.git/blob - src/msw/utils.cpp
* Fixed a bug in notebook.tex
[wxWidgets.git] / src / msw / utils.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: utils.cpp
3 // Purpose: Various utilities
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 // Note: this is done in utilscmn.cpp now.
14 // #pragma implementation
15 // #pragma implementation "utils.h"
16 #endif
17
18 // For compilers that support precompilation, includes "wx.h".
19 #include "wx/wxprec.h"
20
21 #ifdef __BORLANDC__
22 #pragma hdrstop
23 #endif
24
25 #ifndef WX_PRECOMP
26 #include "wx/setup.h"
27 #include "wx/utils.h"
28 #include "wx/app.h"
29 #include "wx/cursor.h"
30 #endif //WX_PRECOMP
31
32 #include "wx/msw/private.h"
33 #include "wx/timer.h"
34
35 #include <ctype.h>
36
37 #ifndef __GNUWIN32__
38 #include <direct.h>
39 #include <dos.h>
40 #endif //GNUWIN32
41
42 #ifdef __GNUWIN32__
43 #include <sys/unistd.h>
44 #include <sys/stat.h>
45 #ifndef __MINGW32__
46 #include <std.h>
47 #endif //MINGW32
48
49 #endif //GNUWIN32
50
51 #include "wx/log.h"
52
53 #ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
54 // this (3.1 I believe) and how to test for it.
55 // If this works for Borland 4.0 as well, then no worries.
56 #include <dir.h>
57 #endif
58
59 #ifdef __WIN32__
60 #include <io.h>
61
62 #ifndef __GNUWIN32__
63 #include <shellapi.h>
64 #endif
65 #endif
66
67 #include <stdio.h>
68 #include <stdlib.h>
69 #include <string.h>
70 #ifndef __WATCOMC__
71 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
72 #include <errno.h>
73 #endif
74 #endif
75 #include <stdarg.h>
76
77 // In the WIN.INI file
78 static const char WX_SECTION[] = "wxWindows";
79 static const char eHOSTNAME[] = "HostName";
80 static const char eUSERID[] = "UserId";
81 static const char eUSERNAME[] = "UserName";
82
83 // For the following functions we SHOULD fill in support
84 // for Windows-NT (which I don't know) as I assume it begin
85 // a POSIX Unix (so claims MS) that it has some special
86 // functions beyond those provided by WinSock
87
88 // Get full hostname (eg. DoDo.BSn-Germany.crg.de)
89 bool wxGetHostName(char *buf, int maxSize)
90 {
91 #ifdef __WIN32__
92 DWORD nSize = maxSize;
93 return (::GetComputerName(buf, &nSize) != 0);
94 #else
95 char *sysname;
96 const char *default_host = "noname";
97
98 if ((sysname = getenv("SYSTEM_NAME")) == NULL) {
99 GetProfileString(WX_SECTION, eHOSTNAME, default_host, buf, maxSize - 1);
100 } else
101 strncpy(buf, sysname, maxSize - 1);
102 buf[maxSize] = '\0';
103 return *buf ? TRUE : FALSE;
104 #endif
105 }
106
107 // Get user ID e.g. jacs
108 bool wxGetUserId(char *buf, int maxSize)
109 {
110 #if defined(__WIN32__) && !defined(__win32s__) && 0
111 // Gets the current user's full name according to the MS article PSS ID
112 // Number: Q119670
113 // Seems to be the same as the login name for me?
114 char *UserName = new char[256];
115 char *Domain = new char[256];
116 DWORD maxCharacters = 255;
117 GetUserName( UserName, &maxCharacters );
118 GetComputerName( Domain, &maxCharacters );
119
120 WCHAR wszUserName[256]; // Unicode user name
121 WCHAR wszDomain[256];
122 LPBYTE ComputerName;
123
124 struct _SERVER_INFO_100 *si100; // Server structure
125 struct _USER_INFO_2 *ui; // User structure
126
127 // Convert ASCII user name and domain to Unicode.
128
129 MultiByteToWideChar( CP_ACP, 0, UserName,
130 strlen(UserName)+1, wszUserName, sizeof(wszUserName) );
131 MultiByteToWideChar( CP_ACP, 0, Domain,
132 strlen(Domain)+1, wszDomain, sizeof(wszDomain) );
133
134 // Get the computer name of a DC for the specified domain.
135 // >If you get a link error on this, include netapi32.lib<
136
137 NetGetDCName( NULL, wszDomain, &ComputerName );
138
139 // Look up the user on the DC.
140
141 if(NetUserGetInfo( (LPWSTR) ComputerName,
142 (LPWSTR) &wszUserName, 2, (LPBYTE *) &ui))
143 {
144 printf( "Error getting user information.\n" );
145 return( FALSE );
146 }
147
148 // Convert the Unicode full name to ASCII.
149
150 WideCharToMultiByte( CP_ACP, 0, ui->usri2_full_name,
151 -1, buf, 256, NULL, NULL );
152 }
153 return( TRUE );
154 /*
155 DWORD nSize = maxSize;
156 return ::GetUserName(buf, &nSize);
157 */
158 #else
159 char *user;
160 const char *default_id = "anonymous";
161
162 // Can't assume we have NIS (PC-NFS) or some other ID daemon
163 // So we ...
164 if ( (user = getenv("USER")) == NULL &&
165 (user = getenv("LOGNAME")) == NULL ) {
166 // Use wxWindows configuration data (comming soon)
167 GetProfileString(WX_SECTION, eUSERID, default_id, buf, maxSize - 1);
168 } else
169 strncpy(buf, user, maxSize - 1);
170 return *buf ? TRUE : FALSE;
171 #endif
172 }
173
174 // Get user name e.g. Julian Smart
175 bool wxGetUserName(char *buf, int maxSize)
176 {
177 const char *default_name = "Unknown User";
178 #if defined(__WIN32__)
179 /*
180 DWORD nSize = maxSize;
181 In VC++ 4.0, results in unresolved symbol __imp__GetUserNameA
182 if (GetUserName(buf, &nSize))
183 return TRUE;
184 else
185 */
186 // Could use NIS, MS-Mail or other site specific programs
187 // Use wxWindows configuration data
188 GetProfileString(WX_SECTION, eUSERNAME, default_name, buf, maxSize - 1);
189 return *buf ? TRUE : FALSE;
190 // }
191 #else
192 #if !defined(__WATCOMC__) && !defined(__GNUWIN32__) && USE_PENWINDOWS
193 extern HANDLE g_hPenWin; // PenWindows Running?
194 if (g_hPenWin)
195 {
196 // PenWindows Does have a user concept!
197 // Get the current owner of the recognizer
198 GetPrivateProfileString("Current", "User", default_name, wxBuffer, maxSize - 1, "PENWIN.INI");
199 strncpy(buf, wxBuffer, maxSize - 1);
200 }
201 else
202 #endif
203 {
204 // Could use NIS, MS-Mail or other site specific programs
205 // Use wxWindows configuration data
206 GetProfileString(WX_SECTION, eUSERNAME, default_name, buf, maxSize - 1);
207 }
208 return *buf ? TRUE : FALSE;
209 #endif
210 }
211
212 int wxKill(long pid, int sig)
213 {
214 return 0;
215 }
216
217 //
218 // Execute a program in an Interactive Shell
219 //
220 bool
221 wxShell(const wxString& command)
222 {
223 char *shell;
224 if ((shell = getenv("COMSPEC")) == NULL)
225 shell = "\\COMMAND.COM";
226
227 char tmp[255];
228 if (command != "")
229 sprintf(tmp, "%s /c %s", shell, WXSTRINGCAST command);
230 else
231 strcpy(tmp, shell);
232
233 return (wxExecute((char *)tmp, FALSE) != 0);
234 }
235
236 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
237 long wxGetFreeMemory(void)
238 {
239 #if defined(__WIN32__) && !defined(__BORLANDC__)
240 MEMORYSTATUS memStatus;
241 memStatus.dwLength = sizeof(MEMORYSTATUS);
242 GlobalMemoryStatus(&memStatus);
243 return memStatus.dwAvailPhys;
244 #else
245 return (long)GetFreeSpace(0);
246 #endif
247 }
248
249 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
250 static bool inTimer = FALSE;
251 class wxSleepTimer: public wxTimer
252 {
253 public:
254 inline void Notify(void)
255 {
256 inTimer = FALSE;
257 Stop();
258 }
259 };
260
261 static wxTimer *wxTheSleepTimer = NULL;
262
263 void wxSleep(int nSecs)
264 {
265 #if 0 // WIN32 hangs app
266 Sleep( 1000*nSecs );
267 #else
268 if (inTimer)
269 return;
270
271 wxTheSleepTimer = new wxSleepTimer;
272 inTimer = TRUE;
273 wxTheSleepTimer->Start(nSecs*1000);
274 while (inTimer)
275 {
276 if (wxTheApp->Pending())
277 wxTheApp->Dispatch();
278 }
279 delete wxTheSleepTimer;
280 wxTheSleepTimer = NULL;
281 #endif
282 }
283
284 // Consume all events until no more left
285 void wxFlushEvents(void)
286 {
287 // wxYield();
288 }
289
290 // Output a debug mess., in a system dependent fashion.
291 void wxDebugMsg(const char *fmt ...)
292 {
293 va_list ap;
294 static char buffer[512];
295
296 if (!wxTheApp->GetWantDebugOutput())
297 return ;
298
299 va_start(ap, fmt);
300
301 wvsprintf(buffer,fmt,ap) ;
302 OutputDebugString((LPCSTR)buffer) ;
303
304 va_end(ap);
305 }
306
307 // Non-fatal error: pop up message box and (possibly) continue
308 void wxError(const wxString& msg, const wxString& title)
309 {
310 sprintf(wxBuffer, "%s\nContinue?", WXSTRINGCAST msg);
311 if (MessageBox(NULL, (LPCSTR)wxBuffer, (LPCSTR)WXSTRINGCAST title,
312 MB_ICONSTOP | MB_YESNO) == IDNO)
313 wxExit();
314 }
315
316 // Fatal error: pop up message box and abort
317 void wxFatalError(const wxString& msg, const wxString& title)
318 {
319 sprintf(wxBuffer, "%s: %s", WXSTRINGCAST title, WXSTRINGCAST msg);
320 FatalAppExit(0, (LPCSTR)wxBuffer);
321 }
322
323 // Emit a beeeeeep
324 void wxBell(void)
325 {
326 #ifdef __WIN32__
327 Beep(1000,1000) ; // 1kHz during 1 sec.
328 #else
329 MessageBeep(-1) ;
330 #endif
331 }
332
333 // Chris Breeze 27/5/98: revised WIN32 code to
334 // detect WindowsNT correctly
335 int wxGetOsVersion(int *majorVsn, int *minorVsn)
336 {
337 extern char *wxOsVersion;
338 if (majorVsn) *majorVsn = 0;
339 if (minorVsn) *minorVsn = 0;
340
341 #ifdef WIN32
342 OSVERSIONINFO info;
343 memset(&info, 0, sizeof(OSVERSIONINFO));
344 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
345 if (GetVersionEx(&info))
346 {
347 if (majorVsn) *majorVsn = info.dwMajorVersion;
348 if (minorVsn) *minorVsn = info.dwMinorVersion;
349 switch (info.dwPlatformId)
350 {
351 case VER_PLATFORM_WIN32s:
352 return wxWIN32S;
353 break;
354 case VER_PLATFORM_WIN32_WINDOWS:
355 return wxWIN95;
356 break;
357 case VER_PLATFORM_WIN32_NT:
358 return wxWINDOWS_NT;
359 break;
360 }
361 }
362 return wxWINDOWS; // error if we get here, return generic value
363 #else
364 // Win16 code...
365 int retValue ;
366 # ifdef __WINDOWS_386__
367 retValue = wxWIN386;
368 # else
369 # if !defined(__WATCOMC__) && !defined(GNUWIN32) && USE_PENWINDOWS
370 extern HANDLE g_hPenWin;
371 retValue = g_hPenWin ? wxPENWINDOWS : wxWINDOWS ;
372 # endif
373 # endif
374 // @@@@ To be completed. I don't have the manual here...
375 if (majorVsn) *majorVsn = 3 ;
376 if (minorVsn) *minorVsn = 1 ;
377 return retValue ;
378 #endif
379 }
380
381 // Reading and writing resources (eg WIN.INI, .Xdefaults)
382 #if USE_RESOURCES
383 bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
384 {
385 if (file != "")
386 return (WritePrivateProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)value, (LPCSTR)WXSTRINGCAST file) != 0);
387 else
388 return (WriteProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)WXSTRINGCAST value) != 0);
389 }
390
391 bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
392 {
393 char buf[50];
394 sprintf(buf, "%.4f", value);
395 return wxWriteResource(section, entry, buf, file);
396 }
397
398 bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
399 {
400 char buf[50];
401 sprintf(buf, "%ld", value);
402 return wxWriteResource(section, entry, buf, file);
403 }
404
405 bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
406 {
407 char buf[50];
408 sprintf(buf, "%d", value);
409 return wxWriteResource(section, entry, buf, file);
410 }
411
412 bool wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file)
413 {
414 static const char defunkt[] = "$$default";
415 if (file != "")
416 {
417 int n = GetPrivateProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)defunkt,
418 (LPSTR)wxBuffer, 1000, (LPCSTR)WXSTRINGCAST file);
419 if (n == 0 || strcmp(wxBuffer, defunkt) == 0)
420 return FALSE;
421 }
422 else
423 {
424 int n = GetProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)defunkt,
425 (LPSTR)wxBuffer, 1000);
426 if (n == 0 || strcmp(wxBuffer, defunkt) == 0)
427 return FALSE;
428 }
429 if (*value) delete[] (*value);
430 *value = copystring(wxBuffer);
431 return TRUE;
432 }
433
434 bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
435 {
436 char *s = NULL;
437 bool succ = wxGetResource(section, entry, (char **)&s, file);
438 if (succ)
439 {
440 *value = (float)strtod(s, NULL);
441 delete[] s;
442 return TRUE;
443 }
444 else return FALSE;
445 }
446
447 bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file)
448 {
449 char *s = NULL;
450 bool succ = wxGetResource(section, entry, (char **)&s, file);
451 if (succ)
452 {
453 *value = strtol(s, NULL, 10);
454 delete[] s;
455 return TRUE;
456 }
457 else return FALSE;
458 }
459
460 bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file)
461 {
462 char *s = NULL;
463 bool succ = wxGetResource(section, entry, (char **)&s, file);
464 if (succ)
465 {
466 *value = (int)strtol(s, NULL, 10);
467 delete[] s;
468 return TRUE;
469 }
470 else return FALSE;
471 }
472 #endif // USE_RESOURCES
473
474 // Old cursor
475 static HCURSOR wxBusyCursorOld = 0;
476 static int wxBusyCursorCount = 0;
477
478 // Set the cursor to the busy cursor for all windows
479 void wxBeginBusyCursor(wxCursor *cursor)
480 {
481 wxBusyCursorCount ++;
482 if (wxBusyCursorCount == 1)
483 {
484 wxBusyCursorOld = ::SetCursor((HCURSOR) cursor->GetHCURSOR());
485 }
486 else
487 {
488 (void)::SetCursor((HCURSOR) cursor->GetHCURSOR());
489 }
490 }
491
492 // Restore cursor to normal
493 void wxEndBusyCursor(void)
494 {
495 if (wxBusyCursorCount == 0)
496 return;
497
498 wxBusyCursorCount --;
499 if (wxBusyCursorCount == 0)
500 {
501 ::SetCursor(wxBusyCursorOld);
502 wxBusyCursorOld = 0;
503 }
504 }
505
506 // TRUE if we're between the above two calls
507 bool wxIsBusy(void)
508 {
509 return (wxBusyCursorCount > 0);
510 }
511
512 const char* WXDLLEXPORT wxGetHomeDir(wxString *pstr)
513 {
514 wxString& strDir = *pstr;
515
516 #ifdef __UNIX__
517 const char *szHome = getenv("HOME");
518 if ( szHome == NULL ) {
519 // we're homeless...
520 wxLogWarning(_("can't find user's HOME, using current directory."));
521 strDir = ".";
522 }
523 else
524 strDir = szHome;
525
526 // add a trailing slash if needed
527 if ( strDir.Last() != '/' )
528 strDir << '/';
529 #else // Windows
530 #ifdef __WIN32__
531 const char *szHome = getenv("HOMEDRIVE");
532 if ( szHome != NULL )
533 strDir << szHome;
534 szHome = getenv("HOMEPATH");
535 if ( szHome != NULL ) {
536 strDir << szHome;
537
538 // the idea is that under NT these variables have default values
539 // of "%systemdrive%:" and "\\". As we don't want to create our
540 // config files in the root directory of the system drive, we will
541 // create it in our program's dir. However, if the user took care
542 // to set HOMEPATH to something other than "\\", we suppose that he
543 // knows what he is doing and use the supplied value.
544 if ( strcmp(szHome, "\\") != 0 )
545 return strDir.c_str();
546 }
547
548 #else // Win16
549 // Win16 has no idea about home, so use the working directory instead
550 #endif // WIN16/32
551
552 // 260 was taken from windef.h
553 #ifndef MAX_PATH
554 #define MAX_PATH 260
555 #endif
556
557 wxString strPath;
558 ::GetModuleFileName(::GetModuleHandle(NULL),
559 strPath.GetWriteBuf(MAX_PATH), MAX_PATH);
560 strPath.UngetWriteBuf();
561
562 // extract the dir name
563 wxSplitPath(strPath, &strDir, NULL, NULL);
564
565 #endif // UNIX/Win
566
567 return strDir.c_str();
568 }
569
570 // Hack for MS-DOS
571 char *wxGetUserHome (const wxString& user)
572 {
573 char *home;
574 wxString user1(user);
575
576 if (user1 != "") {
577 char tmp[64];
578 if (wxGetUserId(tmp, sizeof(tmp)/sizeof(char))) {
579 // Guests belong in the temp dir
580 if (Stricmp(tmp, "annonymous") == 0) {
581 if ((home = getenv("TMP")) != NULL ||
582 (home = getenv("TMPDIR")) != NULL ||
583 (home = getenv("TEMP")) != NULL)
584 return *home ? home : "\\";
585 }
586 if (Stricmp(tmp, WXSTRINGCAST user1) == 0)
587 user1 = "";
588 }
589 }
590 if (user1 == "")
591 if ((home = getenv("HOME")) != NULL)
592 {
593 strcpy(wxBuffer, home);
594 Unix2DosFilename(wxBuffer);
595 return wxBuffer;
596 }
597 return NULL; // No home known!
598 }
599
600 // Check whether this window wants to process messages, e.g. Stop button
601 // in long calculations.
602 bool wxCheckForInterrupt(wxWindow *wnd)
603 {
604 if(wnd){
605 MSG msg;
606 HWND win= (HWND) wnd->GetHWND();
607 while(PeekMessage(&msg,win,0,0,PM_REMOVE)){
608 TranslateMessage(&msg);
609 DispatchMessage(&msg);
610 }
611 return TRUE;//*** temporary?
612 }
613 else{
614 wxError("wnd==NULL !!!");
615 return FALSE;//*** temporary?
616 }
617 }
618
619 // MSW only: get user-defined resource from the .res file.
620 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
621
622 #ifdef __WXMSW__
623 char *wxLoadUserResource(const wxString& resourceName, const wxString& resourceType)
624 {
625 char *s = NULL;
626 #ifndef __WIN32__
627 HRSRC hResource = ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
628 #else
629 #ifdef UNICODE
630 HRSRC hResource = ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
631 #else
632 HRSRC hResource = ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
633 #endif
634 #endif
635
636 if (hResource == 0)
637 return NULL;
638 HGLOBAL hData = ::LoadResource(wxGetInstance(), hResource);
639 if (hData == 0)
640 return NULL;
641 char *theText = (char *)LockResource(hData);
642 if (!theText)
643 return NULL;
644
645 s = copystring(theText);
646
647 // Obsolete in WIN32
648 #ifndef __WIN32__
649 UnlockResource(hData);
650 #endif
651
652 // No need??
653 // GlobalFree(hData);
654
655 return s;
656 }
657 #endif
658
659 void wxGetMousePosition( int* x, int* y )
660 {
661 POINT pt;
662 GetCursorPos( & pt );
663 *x = pt.x;
664 *y = pt.y;
665 };
666
667 // Return TRUE if we have a colour display
668 bool wxColourDisplay(void)
669 {
670 HDC dc = ::GetDC(NULL);
671 bool flag;
672 int noCols = GetDeviceCaps(dc, NUMCOLORS);
673 if ((noCols == -1) || (noCols > 2))
674 flag = TRUE;
675 else
676 flag = FALSE;
677 ReleaseDC(NULL, dc);
678 return flag;
679 }
680
681 // Returns depth of screen
682 int wxDisplayDepth(void)
683 {
684 HDC dc = ::GetDC(NULL);
685 int planes = GetDeviceCaps(dc, PLANES);
686 int bitsPerPixel = GetDeviceCaps(dc, BITSPIXEL);
687 int depth = planes*bitsPerPixel;
688 ReleaseDC(NULL, dc);
689 return depth;
690 }
691
692 // Get size of display
693 void wxDisplaySize(int *width, int *height)
694 {
695 HDC dc = ::GetDC(NULL);
696 *width = GetDeviceCaps(dc, HORZRES); *height = GetDeviceCaps(dc, VERTRES);
697 ReleaseDC(NULL, dc);
698 }
699
700 bool wxDirExists(const wxString& dir)
701 {
702 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
703 #if defined(__WIN32__)
704 WIN32_FIND_DATA fileInfo;
705 #else
706 #ifdef __BORLANDC__
707 struct ffblk fileInfo;
708 #else
709 struct find_t fileInfo;
710 #endif
711 #endif
712
713 #if defined(__WIN32__)
714 HANDLE h = FindFirstFile((LPTSTR) WXSTRINGCAST dir,(LPWIN32_FIND_DATA)&fileInfo);
715
716 if (h==INVALID_HANDLE_VALUE)
717 return FALSE;
718 else {
719 FindClose(h);
720 return ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
721 }
722 #else
723 // In Borland findfirst has a different argument
724 // ordering from _dos_findfirst. But _dos_findfirst
725 // _should_ be ok in both MS and Borland... why not?
726 #ifdef __BORLANDC__
727 return ((findfirst(WXSTRINGCAST dir, &fileInfo, _A_SUBDIR) == 0 && (fileInfo.ff_attrib & _A_SUBDIR) != 0));
728 #else
729 return (((_dos_findfirst(WXSTRINGCAST dir, _A_SUBDIR, &fileInfo) == 0) && (fileInfo.attrib & _A_SUBDIR)) != 0);
730 #endif
731 #endif
732 }
733
734 #if 0
735 //------------------------------------------------------------------------
736 // wild character routines
737 //------------------------------------------------------------------------
738
739 bool wxIsWild( const wxString& pattern )
740 {
741 wxString tmp = pattern;
742 char *pat = WXSTRINGCAST(tmp);
743 while (*pat) {
744 switch (*pat++) {
745 case '?': case '*': case '[': case '{':
746 return TRUE;
747 case '\\':
748 if (!*pat++)
749 return FALSE;
750 }
751 }
752 return FALSE;
753 };
754
755
756 bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
757 {
758 wxString tmp1 = pat;
759 char *pattern = WXSTRINGCAST(tmp1);
760 wxString tmp2 = text;
761 char *str = WXSTRINGCAST(tmp2);
762 char c;
763 char *cp;
764 bool done = FALSE, ret_code, ok;
765 // Below is for vi fans
766 const char OB = '{', CB = '}';
767
768 // dot_special means '.' only matches '.'
769 if (dot_special && *str == '.' && *pattern != *str)
770 return FALSE;
771
772 while ((*pattern != '\0') && (!done)
773 && (((*str=='\0')&&((*pattern==OB)||(*pattern=='*')))||(*str!='\0'))) {
774 switch (*pattern) {
775 case '\\':
776 pattern++;
777 if (*pattern != '\0')
778 pattern++;
779 break;
780 case '*':
781 pattern++;
782 ret_code = FALSE;
783 while ((*str!='\0')
784 && (!(ret_code=wxMatchWild(pattern, str++, FALSE))))
785 /*loop*/;
786 if (ret_code) {
787 while (*str != '\0')
788 str++;
789 while (*pattern != '\0')
790 pattern++;
791 }
792 break;
793 case '[':
794 pattern++;
795 repeat:
796 if ((*pattern == '\0') || (*pattern == ']')) {
797 done = TRUE;
798 break;
799 }
800 if (*pattern == '\\') {
801 pattern++;
802 if (*pattern == '\0') {
803 done = TRUE;
804 break;
805 }
806 }
807 if (*(pattern + 1) == '-') {
808 c = *pattern;
809 pattern += 2;
810 if (*pattern == ']') {
811 done = TRUE;
812 break;
813 }
814 if (*pattern == '\\') {
815 pattern++;
816 if (*pattern == '\0') {
817 done = TRUE;
818 break;
819 }
820 }
821 if ((*str < c) || (*str > *pattern)) {
822 pattern++;
823 goto repeat;
824 }
825 } else if (*pattern != *str) {
826 pattern++;
827 goto repeat;
828 }
829 pattern++;
830 while ((*pattern != ']') && (*pattern != '\0')) {
831 if ((*pattern == '\\') && (*(pattern + 1) != '\0'))
832 pattern++;
833 pattern++;
834 }
835 if (*pattern != '\0') {
836 pattern++, str++;
837 }
838 break;
839 case '?':
840 pattern++;
841 str++;
842 break;
843 case OB:
844 pattern++;
845 while ((*pattern != CB) && (*pattern != '\0')) {
846 cp = str;
847 ok = TRUE;
848 while (ok && (*cp != '\0') && (*pattern != '\0')
849 && (*pattern != ',') && (*pattern != CB)) {
850 if (*pattern == '\\')
851 pattern++;
852 ok = (*pattern++ == *cp++);
853 }
854 if (*pattern == '\0') {
855 ok = FALSE;
856 done = TRUE;
857 break;
858 } else if (ok) {
859 str = cp;
860 while ((*pattern != CB) && (*pattern != '\0')) {
861 if (*++pattern == '\\') {
862 if (*++pattern == CB)
863 pattern++;
864 }
865 }
866 } else {
867 while (*pattern!=CB && *pattern!=',' && *pattern!='\0') {
868 if (*++pattern == '\\') {
869 if (*++pattern == CB || *pattern == ',')
870 pattern++;
871 }
872 }
873 }
874 if (*pattern != '\0')
875 pattern++;
876 }
877 break;
878 default:
879 if (*str == *pattern) {
880 str++, pattern++;
881 } else {
882 done = TRUE;
883 }
884 }
885 }
886 while (*pattern == '*')
887 pattern++;
888 return ((*str == '\0') && (*pattern == '\0'));
889 };
890
891 #endif
892