]> git.saurik.com Git - wxWidgets.git/blame - src/msw/utils.cpp
fixed the vsprintf() problem once and for all
[wxWidgets.git] / src / msw / utils.cpp
CommitLineData
2bda0e17
KB
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
743e0a66 9// Licence: wxWindows license
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
a3b46648 13// #pragma implementation "utils.h" // Note: this is done in utilscmn.cpp now.
2bda0e17
KB
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"
743e0a66 28#endif //WX_PRECOMP
2bda0e17
KB
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>
743e0a66 38#endif //GNUWIN32
2bda0e17
KB
39
40#ifdef __GNUWIN32__
41#include <sys/unistd.h>
42#include <sys/stat.h>
743e0a66
VZ
43#endif //GNUWIN32
44
45#include "wx/log.h"
2bda0e17
KB
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
72static const char WX_SECTION[] = "wxWindows";
73static const char eHOSTNAME[] = "HostName";
74static const char eUSERID[] = "UserId";
75static const char eUSERNAME[] = "UserName";
76
2bda0e17
KB
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)
83bool 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
102bool 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 ...
743e0a66
VZ
158 if ( (user = getenv("USER")) == NULL &&
159 (user = getenv("LOGNAME")) == NULL ) {
2bda0e17
KB
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
169bool 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
47d67540 186#if !defined(__WATCOMC__) && !defined(__GNUWIN32__) && wxUSE_PENWINDOWS
81d66cf3
JS
187 extern HANDLE g_hPenWin; // PenWindows Running?
188 if (g_hPenWin)
2bda0e17
KB
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
2bda0e17
KB
206int wxKill(long pid, int sig)
207{
208 return 0;
209}
210
211//
212// Execute a program in an Interactive Shell
213//
214bool
215wxShell(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)
231long 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.
244static bool inTimer = FALSE;
245class wxSleepTimer: public wxTimer
246{
247 public:
248 inline void Notify(void)
249 {
250 inTimer = FALSE;
251 Stop();
252 }
253};
254
255static wxTimer *wxTheSleepTimer = NULL;
256
257void 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
279void wxFlushEvents(void)
280{
281// wxYield();
282}
283
284// Output a debug mess., in a system dependent fashion.
285void 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
302void 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
311void 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
318void wxBell(void)
319{
320#ifdef __WIN32__
743e0a66 321 Beep(1000,1000) ; // 1kHz during 1 sec.
2bda0e17
KB
322#else
323 MessageBeep(-1) ;
324#endif
325}
326
6f65e337
JS
327// Chris Breeze 27/5/98: revised WIN32 code to
328// detect WindowsNT correctly
2bda0e17
KB
329int wxGetOsVersion(int *majorVsn, int *minorVsn)
330{
331 extern char *wxOsVersion;
6f65e337
JS
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)
743e0a66
VZ
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;
6f65e337 354 }
743e0a66
VZ
355 }
356 return wxWINDOWS; // error if we get here, return generic value
6f65e337
JS
357#else
358 // Win16 code...
2bda0e17 359 int retValue ;
6f65e337 360# ifdef __WINDOWS_386__
2bda0e17 361 retValue = wxWIN386;
6f65e337 362# else
47d67540 363# if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
81d66cf3
JS
364 extern HANDLE g_hPenWin;
365 retValue = g_hPenWin ? wxPENWINDOWS : wxWINDOWS ;
6f65e337
JS
366# endif
367# endif
2bda0e17
KB
368 // @@@@ To be completed. I don't have the manual here...
369 if (majorVsn) *majorVsn = 3 ;
370 if (minorVsn) *minorVsn = 1 ;
371 return retValue ;
6f65e337 372#endif
2bda0e17
KB
373}
374
375// Reading and writing resources (eg WIN.INI, .Xdefaults)
47d67540 376#if wxUSE_RESOURCES
2bda0e17
KB
377bool 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
385bool 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
392bool 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
399bool 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
406bool 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
428bool 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
441bool 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
454bool 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}
47d67540 466#endif // wxUSE_RESOURCES
2bda0e17
KB
467
468// Old cursor
469static HCURSOR wxBusyCursorOld = 0;
470static int wxBusyCursorCount = 0;
471
472// Set the cursor to the busy cursor for all windows
473void 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
487void 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
501bool wxIsBusy(void)
502{
503 return (wxBusyCursorCount > 0);
504}
505
184b5d99 506const char* wxGetHomeDir(wxString *pstr)
743e0a66
VZ
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
2bda0e17
KB
564// Hack for MS-DOS
565char *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
743e0a66
VZ
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 : "\\";
2bda0e17 579 }
743e0a66
VZ
580 if (Stricmp(tmp, WXSTRINGCAST user1) == 0)
581 user1 = "";
2bda0e17
KB
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.
596bool wxCheckForInterrupt(wxWindow *wnd)
597{
743e0a66
VZ
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 }
2bda0e17
KB
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
2049ba38 616#ifdef __WXMSW__
2bda0e17
KB
617char *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
653void 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
662bool 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
676int 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
687void 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
7f555861
JS
694bool 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
1c4a764c
VZ
728wxString 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
7f555861
JS
738#if 0
739//------------------------------------------------------------------------
740// wild character routines
741//------------------------------------------------------------------------
742
743bool 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
760bool 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