1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Various utilities
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 // #pragma implementation "utils.h" // Note: this is done in utilscmn.cpp now.
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
27 #include "wx/cursor.h"
30 #include "wx/msw/private.h"
38 #if !defined(__GNUWIN32__) && !defined(__WXWINE__) && !defined(__SALFORDC__)
46 #if defined(__GNUWIN32__) && !defined(__TWIN32__)
47 #include <sys/unistd.h>
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.
59 // VZ: there is some code using NetXXX() functions to get the full user name:
60 // I don't think it's a good idea because they don't work under Win95 and
61 // seem to return the same as wxGetUserId() under NT. If you really want
62 // to use them, just #define USE_NET_API
69 #if defined(__WIN32__) && !defined(__WXWINE__)
81 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
87 //// BEGIN for console support: VC++ only
90 #include "wx/msw/msvcrt.h"
94 #include "wx/ioswrap.h"
97 // N.B. BC++ doesn't have istream.h, ostream.h
104 /* Need to undef new if including crtdbg.h */
113 # if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS && wxUSE_DEBUG_NEW_ALWAYS
114 # define new new(__FILE__,__LINE__)
119 /// END for console support
121 // In the WIN.INI file
122 static const wxChar WX_SECTION
[] = wxT("wxWindows");
123 static const wxChar eHOSTNAME
[] = wxT("HostName");
124 static const wxChar eUSERID
[] = wxT("UserId");
125 static const wxChar eUSERNAME
[] = wxT("UserName");
127 // For the following functions we SHOULD fill in support
128 // for Windows-NT (which I don't know) as I assume it begin
129 // a POSIX Unix (so claims MS) that it has some special
130 // functions beyond those provided by WinSock
132 // Get full hostname (eg. DoDo.BSn-Germany.crg.de)
133 bool wxGetHostName(wxChar
*buf
, int maxSize
)
135 #if defined(__WIN32__) && !defined(__TWIN32__)
136 DWORD nSize
= maxSize
;
137 return (::GetComputerName(buf
, &nSize
) != 0);
140 const wxChar
*default_host
= wxT("noname");
142 if ((sysname
= wxGetenv(wxT("SYSTEM_NAME"))) == NULL
) {
143 GetProfileString(WX_SECTION
, eHOSTNAME
, default_host
, buf
, maxSize
- 1);
145 wxStrncpy(buf
, sysname
, maxSize
- 1);
146 buf
[maxSize
] = wxT('\0');
147 return *buf
? TRUE
: FALSE
;
151 // Get user ID e.g. jacs
152 bool wxGetUserId(wxChar
*buf
, int maxSize
)
154 #if defined(__WIN32__) && !defined(__win32s__) && !defined(__TWIN32__)
155 DWORD nSize
= maxSize
;
156 if ( ::GetUserName(buf
, &nSize
) == 0 )
158 // actually, it does happen on Win9x if the user didn't log on
159 DWORD res
= ::GetEnvironmentVariable(wxT("username"), buf
, maxSize
);
168 #else // Win16 or Win32s
170 const wxChar
*default_id
= wxT("anonymous");
172 // Can't assume we have NIS (PC-NFS) or some other ID daemon
174 if ( (user
= wxGetenv(wxT("USER"))) == NULL
&&
175 (user
= wxGetenv(wxT("LOGNAME"))) == NULL
)
177 // Use wxWindows configuration data (comming soon)
178 GetProfileString(WX_SECTION
, eUSERID
, default_id
, buf
, maxSize
- 1);
182 wxStrncpy(buf
, user
, maxSize
- 1);
185 return *buf
? TRUE
: FALSE
;
189 // Get user name e.g. Julian Smart
190 bool wxGetUserName(wxChar
*buf
, int maxSize
)
192 #if wxUSE_PENWINDOWS && !defined(__WATCOMC__) && !defined(__GNUWIN32__)
193 extern HANDLE g_hPenWin
; // PenWindows Running?
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);
205 CHAR szUserName
[256];
206 if ( !wxGetUserId(szUserName
, WXSIZEOF(szUserName
)) )
209 // TODO how to get the domain name?
212 // the code is based on the MSDN example (also see KB article Q119670)
213 WCHAR wszUserName
[256]; // Unicode user name
214 WCHAR wszDomain
[256];
217 USER_INFO_2
*ui2
; // User structure
219 // Convert ANSI user name and domain to Unicode
220 MultiByteToWideChar( CP_ACP
, 0, szUserName
, strlen(szUserName
)+1,
221 wszUserName
, WXSIZEOF(wszUserName
) );
222 MultiByteToWideChar( CP_ACP
, 0, szDomain
, strlen(szDomain
)+1,
223 wszDomain
, WXSIZEOF(wszDomain
) );
225 // Get the computer name of a DC for the domain.
226 if ( NetGetDCName( NULL
, wszDomain
, &ComputerName
) != NERR_Success
)
228 wxLogError(wxT("Can not find domain controller"));
233 // Look up the user on the DC
234 NET_API_STATUS status
= NetUserGetInfo( (LPWSTR
)ComputerName
,
235 (LPWSTR
)&wszUserName
,
236 2, // level - we want USER_INFO_2
244 case NERR_InvalidComputer
:
245 wxLogError(wxT("Invalid domain controller name."));
249 case NERR_UserNotFound
:
250 wxLogError(wxT("Invalid user name '%s'."), szUserName
);
255 wxLogSysError(wxT("Can't get information about user"));
260 // Convert the Unicode full name to ANSI
261 WideCharToMultiByte( CP_ACP
, 0, ui2
->usri2_full_name
, -1,
262 buf
, maxSize
, NULL
, NULL
);
267 wxLogError(wxT("Couldn't look up full user name."));
270 #else // !USE_NET_API
271 // Could use NIS, MS-Mail or other site specific programs
272 // Use wxWindows configuration data
273 bool ok
= GetProfileString(WX_SECTION
, eUSERNAME
, wxT(""), buf
, maxSize
- 1) != 0;
276 ok
= wxGetUserId(buf
, maxSize
);
281 wxStrncpy(buf
, wxT("Unknown User"), maxSize
);
289 int wxKill(long pid
, int sig
)
295 // Execute a program in an Interactive Shell
298 wxShell(const wxString
& command
)
301 if ((shell
= wxGetenv(wxT("COMSPEC"))) == NULL
)
302 shell
= wxT("\\COMMAND.COM");
305 if (command
!= wxT(""))
306 wxSprintf(tmp
, wxT("%s /c %s"), shell
, WXSTRINGCAST command
);
308 wxStrcpy(tmp
, shell
);
310 return (wxExecute((wxChar
*)tmp
, FALSE
) != 0);
313 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
314 long wxGetFreeMemory()
316 #if defined(__WIN32__) && !defined(__BORLANDC__) && !defined(__TWIN32__)
317 MEMORYSTATUS memStatus
;
318 memStatus
.dwLength
= sizeof(MEMORYSTATUS
);
319 GlobalMemoryStatus(&memStatus
);
320 return memStatus
.dwAvailPhys
;
322 return (long)GetFreeSpace(0);
326 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
327 static bool inTimer
= FALSE
;
328 class wxSleepTimer
: public wxTimer
338 static wxTimer
*wxTheSleepTimer
= NULL
;
340 void wxUsleep(unsigned long milliseconds
)
343 ::Sleep(milliseconds
);
348 wxTheSleepTimer
= new wxSleepTimer
;
350 wxTheSleepTimer
->Start(milliseconds
);
353 if (wxTheApp
->Pending())
354 wxTheApp
->Dispatch();
356 delete wxTheSleepTimer
;
357 wxTheSleepTimer
= NULL
;
361 void wxSleep(int nSecs
)
363 #if 0 // WIN32 hangs app
369 wxTheSleepTimer
= new wxSleepTimer
;
371 wxTheSleepTimer
->Start(nSecs
*1000);
374 if (wxTheApp
->Pending())
375 wxTheApp
->Dispatch();
377 delete wxTheSleepTimer
;
378 wxTheSleepTimer
= NULL
;
382 // Consume all events until no more left
388 // Output a debug mess., in a system dependent fashion.
389 void wxDebugMsg(const wxChar
*fmt
...)
392 static wxChar buffer
[512];
394 if (!wxTheApp
->GetWantDebugOutput())
399 wvsprintf(buffer
,fmt
,ap
) ;
400 OutputDebugString((LPCTSTR
)buffer
) ;
405 // Non-fatal error: pop up message box and (possibly) continue
406 void wxError(const wxString
& msg
, const wxString
& title
)
408 wxSprintf(wxBuffer
, wxT("%s\nContinue?"), WXSTRINGCAST msg
);
409 if (MessageBox(NULL
, (LPCTSTR
)wxBuffer
, (LPCTSTR
)WXSTRINGCAST title
,
410 MB_ICONSTOP
| MB_YESNO
) == IDNO
)
414 // Fatal error: pop up message box and abort
415 void wxFatalError(const wxString
& msg
, const wxString
& title
)
417 wxSprintf(wxBuffer
, wxT("%s: %s"), WXSTRINGCAST title
, WXSTRINGCAST msg
);
418 FatalAppExit(0, (LPCTSTR
)wxBuffer
);
424 // Removed by RD because IHMO syncronous sound is a Bad Thing. MessageBeep
425 // will do a similar thing anyway if there is no sound card...
427 // Beep(1000,1000) ; // 1kHz during 1 sec.
429 MessageBeep((UINT
)-1) ;
433 // Chris Breeze 27/5/98: revised WIN32 code to
434 // detect WindowsNT correctly
435 int wxGetOsVersion(int *majorVsn
, int *minorVsn
)
437 if (majorVsn
) *majorVsn
= 0;
438 if (minorVsn
) *minorVsn
= 0;
440 #if defined(__WIN32__) && !defined(__SC__)
442 memset(&info
, 0, sizeof(OSVERSIONINFO
));
443 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
444 if (GetVersionEx(&info
))
446 if (majorVsn
) *majorVsn
= info
.dwMajorVersion
;
447 if (minorVsn
) *minorVsn
= info
.dwMinorVersion
;
448 switch (info
.dwPlatformId
)
450 case VER_PLATFORM_WIN32s
:
453 case VER_PLATFORM_WIN32_WINDOWS
:
456 case VER_PLATFORM_WIN32_NT
:
461 return wxWINDOWS
; // error if we get here, return generic value
465 # ifdef __WINDOWS_386__
468 # if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
469 extern HANDLE g_hPenWin
;
470 retValue
= g_hPenWin
? wxPENWINDOWS
: wxWINDOWS
;
473 // @@@@ To be completed. I don't have the manual here...
474 if (majorVsn
) *majorVsn
= 3 ;
475 if (minorVsn
) *minorVsn
= 1 ;
480 // Reading and writing resources (eg WIN.INI, .Xdefaults)
482 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
)
485 // Don't know what the correct cast should be, but it doesn't
486 // compile in BC++/16-bit without this cast.
487 #if !defined(__WIN32__)
488 return (WritePrivateProfileString((const char*) section
, (const char*) entry
, (const char*) value
, (const char*) file
) != 0);
490 return (WritePrivateProfileString((LPCTSTR
)WXSTRINGCAST section
, (LPCTSTR
)WXSTRINGCAST entry
, (LPCTSTR
)value
, (LPCTSTR
)WXSTRINGCAST file
) != 0);
493 return (WriteProfileString((LPCTSTR
)WXSTRINGCAST section
, (LPCTSTR
)WXSTRINGCAST entry
, (LPCTSTR
)WXSTRINGCAST value
) != 0);
496 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
)
499 wxSprintf(buf
, wxT("%.4f"), value
);
500 return wxWriteResource(section
, entry
, buf
, file
);
503 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
)
506 wxSprintf(buf
, wxT("%ld"), value
);
507 return wxWriteResource(section
, entry
, buf
, file
);
510 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
)
513 wxSprintf(buf
, wxT("%d"), value
);
514 return wxWriteResource(section
, entry
, buf
, file
);
517 bool wxGetResource(const wxString
& section
, const wxString
& entry
, wxChar
**value
, const wxString
& file
)
519 static const wxChar defunkt
[] = wxT("$$default");
522 int n
= GetPrivateProfileString((LPCTSTR
)WXSTRINGCAST section
, (LPCTSTR
)WXSTRINGCAST entry
, (LPCTSTR
)defunkt
,
523 (LPTSTR
)wxBuffer
, 1000, (LPCTSTR
)WXSTRINGCAST file
);
524 if (n
== 0 || wxStrcmp(wxBuffer
, defunkt
) == 0)
529 int n
= GetProfileString((LPCTSTR
)WXSTRINGCAST section
, (LPCTSTR
)WXSTRINGCAST entry
, (LPCTSTR
)defunkt
,
530 (LPTSTR
)wxBuffer
, 1000);
531 if (n
== 0 || wxStrcmp(wxBuffer
, defunkt
) == 0)
534 if (*value
) delete[] (*value
);
535 *value
= copystring(wxBuffer
);
539 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
)
542 bool succ
= wxGetResource(section
, entry
, (wxChar
**)&s
, file
);
545 *value
= (float)wxStrtod(s
, NULL
);
552 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
)
555 bool succ
= wxGetResource(section
, entry
, (wxChar
**)&s
, file
);
558 *value
= wxStrtol(s
, NULL
, 10);
565 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
)
568 bool succ
= wxGetResource(section
, entry
, (wxChar
**)&s
, file
);
571 *value
= (int)wxStrtol(s
, NULL
, 10);
577 #endif // wxUSE_RESOURCES
579 // ---------------------------------------------------------------------------
580 // helper functions for showing a "busy" cursor
581 // ---------------------------------------------------------------------------
583 HCURSOR gs_wxBusyCursor
= 0; // new, busy cursor
584 HCURSOR gs_wxBusyCursorOld
= 0; // old cursor
585 static int gs_wxBusyCursorCount
= 0;
587 // Set the cursor to the busy cursor for all windows
588 void wxBeginBusyCursor(wxCursor
*cursor
)
590 if ( gs_wxBusyCursorCount
++ == 0 )
592 gs_wxBusyCursor
= (HCURSOR
)cursor
->GetHCURSOR();
593 gs_wxBusyCursorOld
= ::SetCursor(gs_wxBusyCursor
);
595 //else: nothing to do, already set
598 // Restore cursor to normal
599 void wxEndBusyCursor()
601 wxCHECK_RET( gs_wxBusyCursorCount
> 0,
602 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
604 if ( --gs_wxBusyCursorCount
== 0 )
606 ::SetCursor(gs_wxBusyCursorOld
);
608 gs_wxBusyCursorOld
= 0;
612 // TRUE if we're between the above two calls
615 return (gs_wxBusyCursorCount
> 0);
618 // ---------------------------------------------------------------------------
619 const wxChar
* wxGetHomeDir(wxString
*pstr
)
621 wxString
& strDir
= *pstr
;
623 #if defined(__UNIX__) && !defined(__TWIN32__)
624 const wxChar
*szHome
= wxGetenv("HOME");
625 if ( szHome
== NULL
) {
627 wxLogWarning(_("can't find user's HOME, using current directory."));
633 // add a trailing slash if needed
634 if ( strDir
.Last() != wxT('/') )
638 const wxChar
*szHome
= wxGetenv(wxT("HOMEDRIVE"));
639 if ( szHome
!= NULL
)
641 szHome
= wxGetenv(wxT("HOMEPATH"));
642 if ( szHome
!= NULL
) {
645 // the idea is that under NT these variables have default values
646 // of "%systemdrive%:" and "\\". As we don't want to create our
647 // config files in the root directory of the system drive, we will
648 // create it in our program's dir. However, if the user took care
649 // to set HOMEPATH to something other than "\\", we suppose that he
650 // knows what he is doing and use the supplied value.
651 if ( wxStrcmp(szHome
, wxT("\\")) != 0 )
652 return strDir
.c_str();
656 // Win16 has no idea about home, so use the working directory instead
659 // 260 was taken from windef.h
665 ::GetModuleFileName(::GetModuleHandle(NULL
),
666 strPath
.GetWriteBuf(MAX_PATH
), MAX_PATH
);
667 strPath
.UngetWriteBuf();
669 // extract the dir name
670 wxSplitPath(strPath
, &strDir
, NULL
, NULL
);
674 return strDir
.c_str();
678 wxChar
*wxGetUserHome (const wxString
& user
)
681 wxString
user1(user
);
683 if (user1
!= wxT("")) {
685 if (wxGetUserId(tmp
, sizeof(tmp
)/sizeof(char))) {
686 // Guests belong in the temp dir
687 if (wxStricmp(tmp
, wxT("annonymous")) == 0) {
688 if ((home
= wxGetenv(wxT("TMP"))) != NULL
||
689 (home
= wxGetenv(wxT("TMPDIR"))) != NULL
||
690 (home
= wxGetenv(wxT("TEMP"))) != NULL
)
691 return *home
? home
: (wxChar
*)wxT("\\");
693 if (wxStricmp(tmp
, WXSTRINGCAST user1
) == 0)
697 if (user1
== wxT(""))
698 if ((home
= wxGetenv(wxT("HOME"))) != NULL
)
700 wxStrcpy(wxBuffer
, home
);
701 Unix2DosFilename(wxBuffer
);
704 return NULL
; // No home known!
707 // Check whether this window wants to process messages, e.g. Stop button
708 // in long calculations.
709 bool wxCheckForInterrupt(wxWindow
*wnd
)
713 HWND win
= (HWND
) wnd
->GetHWND();
714 while(PeekMessage(&msg
,win
,0,0,PM_REMOVE
)){
715 TranslateMessage(&msg
);
716 DispatchMessage(&msg
);
718 return TRUE
;//*** temporary?
721 wxFAIL_MSG(wxT("wnd==NULL !!!"));
723 return FALSE
;//*** temporary?
727 // MSW only: get user-defined resource from the .res file.
728 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
731 wxChar
*wxLoadUserResource(const wxString
& resourceName
, const wxString
& resourceType
)
734 #if !defined(__WIN32__) || defined(__TWIN32__)
735 HRSRC hResource
= ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
738 HRSRC hResource
= ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
740 HRSRC hResource
= ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
746 HGLOBAL hData
= ::LoadResource(wxGetInstance(), hResource
);
749 wxChar
*theText
= (wxChar
*)LockResource(hData
);
753 s
= copystring(theText
);
757 UnlockResource(hData
);
761 // GlobalFree(hData);
767 void wxGetMousePosition( int* x
, int* y
)
770 GetCursorPos( & pt
);
775 // Return TRUE if we have a colour display
776 bool wxColourDisplay()
778 HDC dc
= ::GetDC((HWND
) NULL
);
780 int noCols
= GetDeviceCaps(dc
, NUMCOLORS
);
781 if ((noCols
== -1) || (noCols
> 2))
785 ReleaseDC((HWND
) NULL
, dc
);
789 // Returns depth of screen
792 HDC dc
= ::GetDC((HWND
) NULL
);
793 int planes
= GetDeviceCaps(dc
, PLANES
);
794 int bitsPerPixel
= GetDeviceCaps(dc
, BITSPIXEL
);
795 int depth
= planes
*bitsPerPixel
;
796 ReleaseDC((HWND
) NULL
, dc
);
800 // Get size of display
801 void wxDisplaySize(int *width
, int *height
)
803 HDC dc
= ::GetDC((HWND
) NULL
);
804 *width
= GetDeviceCaps(dc
, HORZRES
); *height
= GetDeviceCaps(dc
, VERTRES
);
805 ReleaseDC((HWND
) NULL
, dc
);
808 bool wxDirExists(const wxString
& dir
)
810 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
811 #if defined(__WIN32__)
812 WIN32_FIND_DATA fileInfo
;
815 struct ffblk fileInfo
;
817 struct find_t fileInfo
;
821 #if defined(__WIN32__)
822 HANDLE h
= FindFirstFile((LPTSTR
) WXSTRINGCAST dir
,(LPWIN32_FIND_DATA
)&fileInfo
);
824 if (h
==INVALID_HANDLE_VALUE
)
828 return ((fileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) == FILE_ATTRIBUTE_DIRECTORY
);
831 // In Borland findfirst has a different argument
832 // ordering from _dos_findfirst. But _dos_findfirst
833 // _should_ be ok in both MS and Borland... why not?
835 return ((findfirst(WXSTRINGCAST dir
, &fileInfo
, _A_SUBDIR
) == 0 && (fileInfo
.ff_attrib
& _A_SUBDIR
) != 0));
837 return (((_dos_findfirst(WXSTRINGCAST dir
, _A_SUBDIR
, &fileInfo
) == 0) && (fileInfo
.attrib
& _A_SUBDIR
)) != 0);
842 // ---------------------------------------------------------------------------
843 // window information functions
844 // ---------------------------------------------------------------------------
846 wxString WXDLLEXPORT
wxGetWindowText(WXHWND hWnd
)
849 int len
= GetWindowTextLength((HWND
)hWnd
) + 1;
850 GetWindowText((HWND
)hWnd
, str
.GetWriteBuf(len
), len
);
856 wxString WXDLLEXPORT
wxGetWindowClass(WXHWND hWnd
)
860 int len
= 256; // some starting value
864 // as we've #undefined GetClassName we must now manually choose the
865 // right function to call
878 #endif // Twin32/!Twin32
879 #endif // Unicode/ANSI
881 ((HWND
)hWnd
, str
.GetWriteBuf(len
), len
);
886 // the class name might have been truncated, retry with larger
899 WXWORD WXDLLEXPORT
wxGetWindowId(WXHWND hWnd
)
902 return GetWindowWord((HWND
)hWnd
, GWW_ID
);
904 return GetWindowLong((HWND
)hWnd
, GWL_ID
);
909 //------------------------------------------------------------------------
910 // wild character routines
911 //------------------------------------------------------------------------
913 bool wxIsWild( const wxString
& pattern
)
915 wxString tmp
= pattern
;
916 char *pat
= WXSTRINGCAST(tmp
);
919 case '?': case '*': case '[': case '{':
930 bool wxMatchWild( const wxString
& pat
, const wxString
& text
, bool dot_special
)
933 char *pattern
= WXSTRINGCAST(tmp1
);
934 wxString tmp2
= text
;
935 char *str
= WXSTRINGCAST(tmp2
);
938 bool done
= FALSE
, ret_code
, ok
;
939 // Below is for vi fans
940 const char OB
= '{', CB
= '}';
942 // dot_special means '.' only matches '.'
943 if (dot_special
&& *str
== '.' && *pattern
!= *str
)
946 while ((*pattern
!= '\0') && (!done
)
947 && (((*str
=='\0')&&((*pattern
==OB
)||(*pattern
=='*')))||(*str
!='\0'))) {
951 if (*pattern
!= '\0')
958 && (!(ret_code
=wxMatchWild(pattern
, str
++, FALSE
))))
963 while (*pattern
!= '\0')
970 if ((*pattern
== '\0') || (*pattern
== ']')) {
974 if (*pattern
== '\\') {
976 if (*pattern
== '\0') {
981 if (*(pattern
+ 1) == '-') {
984 if (*pattern
== ']') {
988 if (*pattern
== '\\') {
990 if (*pattern
== '\0') {
995 if ((*str
< c
) || (*str
> *pattern
)) {
999 } else if (*pattern
!= *str
) {
1004 while ((*pattern
!= ']') && (*pattern
!= '\0')) {
1005 if ((*pattern
== '\\') && (*(pattern
+ 1) != '\0'))
1009 if (*pattern
!= '\0') {
1019 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
1022 while (ok
&& (*cp
!= '\0') && (*pattern
!= '\0')
1023 && (*pattern
!= ',') && (*pattern
!= CB
)) {
1024 if (*pattern
== '\\')
1026 ok
= (*pattern
++ == *cp
++);
1028 if (*pattern
== '\0') {
1034 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
1035 if (*++pattern
== '\\') {
1036 if (*++pattern
== CB
)
1041 while (*pattern
!=CB
&& *pattern
!=',' && *pattern
!='\0') {
1042 if (*++pattern
== '\\') {
1043 if (*++pattern
== CB
|| *pattern
== ',')
1048 if (*pattern
!= '\0')
1053 if (*str
== *pattern
) {
1060 while (*pattern
== '*')
1062 return ((*str
== '\0') && (*pattern
== '\0'));
1067 #if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
1070 When I started programming with Visual C++ v4.0, I missed one of my favorite
1071 tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
1072 on MSDN was a step in the right direction, but it is a console application
1073 and thus has limited features and extensibility. DBWIN32 is my creation
1074 to solve this problem.
1076 The code is essentially a merging of a stripped down version of the DBWIN code
1077 from VC 1.5 and DBMON.C with a few 32 bit changes.
1079 As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
1080 built into the operating system and works just by running DBWIN32. The Win95
1081 team decided not to support this hook, so I have provided code that will do
1082 this for you. See the file WIN95.TXT for instructions on installing this.
1084 If you have questions, problems or suggestions about DBWIN32, I welcome your
1085 feedback and plan to actively maintain the code.
1090 To download dbwin32, see e.g.:
1092 http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
1095 #if !defined(__MWERKS__) && !defined(__SALFORDC__) && !defined(__TWIN32__)
1096 #include <process.h>
1099 void OutputDebugStringW95(const wxChar
* lpOutputString
, ...)
1101 HANDLE heventDBWIN
; /* DBWIN32 synchronization object */
1102 HANDLE heventData
; /* data passing synch object */
1103 HANDLE hSharedFile
; /* memory mapped file shared data */
1104 LPSTR lpszSharedMem
;
1105 wxChar achBuffer
[500];
1107 /* create the output buffer */
1109 va_start(args
, lpOutputString
);
1110 wxVsprintf(achBuffer
, lpOutputString
, args
);
1114 Do a regular OutputDebugString so that the output is
1115 still seen in the debugger window if it exists.
1117 This ifdef is necessary to avoid infinite recursion
1118 from the inclusion of W95TRACE.H
1121 ::OutputDebugStringW(achBuffer
);
1124 ::OutputDebugString(achBuffer
);
1126 ::OutputDebugStringA(achBuffer
);
1130 /* bail if it's not Win95 */
1132 OSVERSIONINFO VerInfo
;
1133 VerInfo
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
1134 GetVersionEx(&VerInfo
);
1135 if ( VerInfo
.dwPlatformId
!= VER_PLATFORM_WIN32_WINDOWS
)
1139 /* make sure DBWIN is open and waiting */
1140 heventDBWIN
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, wxT("DBWIN_BUFFER_READY"));
1143 //MessageBox(NULL, wxT("DBWIN_BUFFER_READY nonexistent"), NULL, MB_OK);
1147 /* get a handle to the data synch object */
1148 heventData
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, wxT("DBWIN_DATA_READY"));
1151 // MessageBox(NULL, wxT("DBWIN_DATA_READY nonexistent"), NULL, MB_OK);
1152 CloseHandle(heventDBWIN
);
1156 hSharedFile
= CreateFileMapping((HANDLE
)-1, NULL
, PAGE_READWRITE
, 0, 4096, wxT("DBWIN_BUFFER"));
1159 //MessageBox(NULL, wxT("DebugTrace: Unable to create file mapping object DBWIN_BUFFER"), wxT("Error"), MB_OK);
1160 CloseHandle(heventDBWIN
);
1161 CloseHandle(heventData
);
1165 lpszSharedMem
= (LPSTR
)MapViewOfFile(hSharedFile
, FILE_MAP_WRITE
, 0, 0, 512);
1168 //MessageBox(NULL, wxT("DebugTrace: Unable to map shared memory"), wxT("Error"), MB_OK);
1169 CloseHandle(heventDBWIN
);
1170 CloseHandle(heventData
);
1174 /* wait for buffer event */
1175 WaitForSingleObject(heventDBWIN
, INFINITE
);
1177 /* write it to the shared memory */
1178 #if defined( __BORLANDC__ ) || defined( __MWERKS__ ) || defined(__SALFORDC__)
1179 *((LPDWORD
)lpszSharedMem
) = getpid();
1181 *((LPDWORD
)lpszSharedMem
) = _getpid();
1184 wsprintf((LPTSTR
)(lpszSharedMem
+ sizeof(DWORD
)), wxT("%s"), achBuffer
);
1186 /* signal data ready event */
1187 SetEvent(heventData
);
1189 /* clean up handles */
1190 CloseHandle(hSharedFile
);
1191 CloseHandle(heventData
);
1192 CloseHandle(heventDBWIN
);
1203 // maximum mumber of lines the output console should have
1204 static const WORD MAX_CONSOLE_LINES
= 500;
1206 BOOL WINAPI
MyConsoleHandler( DWORD dwCtrlType
) { // control signal type
1211 void wxRedirectIOToConsole()
1215 CONSOLE_SCREEN_BUFFER_INFO coninfo
;
1218 // allocate a console for this app
1221 // set the screen buffer to be big enough to let us scroll text
1222 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE
),
1224 coninfo
.dwSize
.Y
= MAX_CONSOLE_LINES
;
1225 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE
),
1228 // redirect unbuffered STDOUT to the console
1229 lStdHandle
= (long)GetStdHandle(STD_OUTPUT_HANDLE
);
1230 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1231 if(hConHandle
<= 0) return;
1232 fp
= _fdopen( hConHandle
, "w" );
1234 setvbuf( stdout
, NULL
, _IONBF
, 0 );
1236 // redirect unbuffered STDIN to the console
1237 lStdHandle
= (long)GetStdHandle(STD_INPUT_HANDLE
);
1238 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1239 if(hConHandle
<= 0) return;
1240 fp
= _fdopen( hConHandle
, "r" );
1242 setvbuf( stdin
, NULL
, _IONBF
, 0 );
1244 // redirect unbuffered STDERR to the console
1245 lStdHandle
= (long)GetStdHandle(STD_ERROR_HANDLE
);
1246 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1247 if(hConHandle
<= 0) return;
1248 fp
= _fdopen( hConHandle
, "w" );
1250 setvbuf( stderr
, NULL
, _IONBF
, 0 );
1252 // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
1253 // point to console as well
1254 ios::sync_with_stdio();
1256 SetConsoleCtrlHandler(MyConsoleHandler
, TRUE
);
1260 void wxRedirectIOToConsole()