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