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"
37 #if !defined(__GNUWIN32__) && !defined(__SALFORDC__)
46 #include <sys/unistd.h>
52 #ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
53 // this (3.1 I believe) and how to test for it.
54 // If this works for Borland 4.0 as well, then no worries.
70 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
76 //// BEGIN for console support: VC++ only
78 #if defined(__WXDEBUG__) && !defined(__WIN16__) && defined(_MSC_VER) && !defined(__NO_VC_CRTDBG__)
79 #define wxUSE_VC_CRTDBG
81 #undef wxUSE_VC_CRTDBG
84 #ifdef wxUSE_VC_CRTDBG
85 // VC++ uses this macro as debug/release mode indicator
93 // N.B. BC++ doesn't have istream.h, ostream.h
94 # include <iostream.h>
107 /* Need to undef new if including crtdbg.h */
116 # if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS && wxUSE_DEBUG_NEW_ALWAYS
117 # define new new(__FILE__,__LINE__)
122 /// END for console support
124 // In the WIN.INI file
125 static const char WX_SECTION
[] = "wxWindows";
126 static const char eHOSTNAME
[] = "HostName";
127 static const char eUSERID
[] = "UserId";
128 static const char eUSERNAME
[] = "UserName";
130 // For the following functions we SHOULD fill in support
131 // for Windows-NT (which I don't know) as I assume it begin
132 // a POSIX Unix (so claims MS) that it has some special
133 // functions beyond those provided by WinSock
135 // Get full hostname (eg. DoDo.BSn-Germany.crg.de)
136 bool wxGetHostName(char *buf
, int maxSize
)
139 DWORD nSize
= maxSize
;
140 return (::GetComputerName(buf
, &nSize
) != 0);
143 const char *default_host
= "noname";
145 if ((sysname
= getenv("SYSTEM_NAME")) == NULL
) {
146 GetProfileString(WX_SECTION
, eHOSTNAME
, default_host
, buf
, maxSize
- 1);
148 strncpy(buf
, sysname
, maxSize
- 1);
150 return *buf
? TRUE
: FALSE
;
154 // Get user ID e.g. jacs
155 bool wxGetUserId(char *buf
, int maxSize
)
157 #if defined(__WIN32__) && !defined(__win32s__)
159 // VZ: why should it be so complicated??
161 // Gets the current user's full name according to the MS article PSS ID
163 // Seems to be the same as the login name for me?
164 char *UserName
= new char[256];
165 char *Domain
= new char[256];
166 DWORD maxCharacters
= 255;
167 GetUserName( UserName
, &maxCharacters
);
168 GetComputerName( Domain
, &maxCharacters
);
170 WCHAR wszUserName
[256]; // Unicode user name
171 WCHAR wszDomain
[256];
174 struct _SERVER_INFO_100
*si100
; // Server structure
175 struct _USER_INFO_2
*ui
; // User structure
177 // Convert ASCII user name and domain to Unicode.
179 MultiByteToWideChar( CP_ACP
, 0, UserName
,
180 strlen(UserName
)+1, wszUserName
, sizeof(wszUserName
) );
181 MultiByteToWideChar( CP_ACP
, 0, Domain
,
182 strlen(Domain
)+1, wszDomain
, sizeof(wszDomain
) );
184 // Get the computer name of a DC for the specified domain.
185 // >If you get a link error on this, include netapi32.lib<
187 NetGetDCName( NULL
, wszDomain
, &ComputerName
);
189 // Look up the user on the DC.
191 if(NetUserGetInfo( (LPWSTR
) ComputerName
,
192 (LPWSTR
) &wszUserName
, 2, (LPBYTE
*) &ui
))
194 printf( "Error getting user information.\n" );
198 // Convert the Unicode full name to ASCII.
200 WideCharToMultiByte( CP_ACP
, 0, ui
->usri2_full_name
,
201 -1, buf
, 256, NULL
, NULL
);
205 DWORD nSize
= maxSize
;
206 if ( ::GetUserName(buf
, &nSize
) == 0 )
208 wxLogSysError("Can not get user name");
216 #else // Win16 or Win32s
218 const char *default_id
= "anonymous";
220 // Can't assume we have NIS (PC-NFS) or some other ID daemon
222 if ( (user
= getenv("USER")) == NULL
&&
223 (user
= getenv("LOGNAME")) == NULL
) {
224 // Use wxWindows configuration data (comming soon)
225 GetProfileString(WX_SECTION
, eUSERID
, default_id
, buf
, maxSize
- 1);
227 strncpy(buf
, user
, maxSize
- 1);
228 return *buf
? TRUE
: FALSE
;
232 // Get user name e.g. Julian Smart
233 bool wxGetUserName(char *buf
, int maxSize
)
235 #if wxUSE_PENWINDOWS && !defined(__WATCOMC__) && !defined(__GNUWIN32__)
236 extern HANDLE g_hPenWin
; // PenWindows Running?
239 // PenWindows Does have a user concept!
240 // Get the current owner of the recognizer
241 GetPrivateProfileString("Current", "User", default_name
, wxBuffer
, maxSize
- 1, "PENWIN.INI");
242 strncpy(buf
, wxBuffer
, maxSize
- 1);
247 // Could use NIS, MS-Mail or other site specific programs
248 // Use wxWindows configuration data
249 bool ok
= GetProfileString(WX_SECTION
, eUSERNAME
, "", buf
, maxSize
- 1) != 0;
252 ok
= wxGetUserId(buf
, maxSize
);
257 strncpy(buf
, "Unknown User", maxSize
);
264 int wxKill(long pid
, int sig
)
270 // Execute a program in an Interactive Shell
273 wxShell(const wxString
& command
)
276 if ((shell
= getenv("COMSPEC")) == NULL
)
277 shell
= "\\COMMAND.COM";
281 sprintf(tmp
, "%s /c %s", shell
, WXSTRINGCAST command
);
285 return (wxExecute((char *)tmp
, FALSE
) != 0);
288 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
289 long wxGetFreeMemory(void)
291 #if defined(__WIN32__) && !defined(__BORLANDC__)
292 MEMORYSTATUS memStatus
;
293 memStatus
.dwLength
= sizeof(MEMORYSTATUS
);
294 GlobalMemoryStatus(&memStatus
);
295 return memStatus
.dwAvailPhys
;
297 return (long)GetFreeSpace(0);
301 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
302 static bool inTimer
= FALSE
;
303 class wxSleepTimer
: public wxTimer
306 inline void Notify(void)
313 static wxTimer
*wxTheSleepTimer
= NULL
;
315 void wxSleep(int nSecs
)
317 #if 0 // WIN32 hangs app
323 wxTheSleepTimer
= new wxSleepTimer
;
325 wxTheSleepTimer
->Start(nSecs
*1000);
328 if (wxTheApp
->Pending())
329 wxTheApp
->Dispatch();
331 delete wxTheSleepTimer
;
332 wxTheSleepTimer
= NULL
;
336 // Consume all events until no more left
337 void wxFlushEvents(void)
342 // Output a debug mess., in a system dependent fashion.
343 void wxDebugMsg(const char *fmt
...)
346 static char buffer
[512];
348 if (!wxTheApp
->GetWantDebugOutput())
353 wvsprintf(buffer
,fmt
,ap
) ;
354 OutputDebugString((LPCSTR
)buffer
) ;
359 // Non-fatal error: pop up message box and (possibly) continue
360 void wxError(const wxString
& msg
, const wxString
& title
)
362 sprintf(wxBuffer
, "%s\nContinue?", WXSTRINGCAST msg
);
363 if (MessageBox(NULL
, (LPCSTR
)wxBuffer
, (LPCSTR
)WXSTRINGCAST title
,
364 MB_ICONSTOP
| MB_YESNO
) == IDNO
)
368 // Fatal error: pop up message box and abort
369 void wxFatalError(const wxString
& msg
, const wxString
& title
)
371 sprintf(wxBuffer
, "%s: %s", WXSTRINGCAST title
, WXSTRINGCAST msg
);
372 FatalAppExit(0, (LPCSTR
)wxBuffer
);
378 // Removed by RD because IHMO syncronous sound is a Bad Thing. MessageBeep
379 // will do a similar thing anyway if there is no sound card...
381 // Beep(1000,1000) ; // 1kHz during 1 sec.
383 MessageBeep((UINT
)-1) ;
387 // Chris Breeze 27/5/98: revised WIN32 code to
388 // detect WindowsNT correctly
389 int wxGetOsVersion(int *majorVsn
, int *minorVsn
)
391 extern char *wxOsVersion
;
392 if (majorVsn
) *majorVsn
= 0;
393 if (minorVsn
) *minorVsn
= 0;
395 #if defined(__WIN32__) && !defined(__SC__)
397 memset(&info
, 0, sizeof(OSVERSIONINFO
));
398 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
399 if (GetVersionEx(&info
))
401 if (majorVsn
) *majorVsn
= info
.dwMajorVersion
;
402 if (minorVsn
) *minorVsn
= info
.dwMinorVersion
;
403 switch (info
.dwPlatformId
)
405 case VER_PLATFORM_WIN32s
:
408 case VER_PLATFORM_WIN32_WINDOWS
:
411 case VER_PLATFORM_WIN32_NT
:
416 return wxWINDOWS
; // error if we get here, return generic value
420 # ifdef __WINDOWS_386__
423 # if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
424 extern HANDLE g_hPenWin
;
425 retValue
= g_hPenWin
? wxPENWINDOWS
: wxWINDOWS
;
428 // @@@@ To be completed. I don't have the manual here...
429 if (majorVsn
) *majorVsn
= 3 ;
430 if (minorVsn
) *minorVsn
= 1 ;
435 // Reading and writing resources (eg WIN.INI, .Xdefaults)
437 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
)
440 return (WritePrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)value
, (LPCSTR
)WXSTRINGCAST file
) != 0);
442 return (WriteProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)WXSTRINGCAST value
) != 0);
445 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
)
448 sprintf(buf
, "%.4f", value
);
449 return wxWriteResource(section
, entry
, buf
, file
);
452 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
)
455 sprintf(buf
, "%ld", value
);
456 return wxWriteResource(section
, entry
, buf
, file
);
459 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
)
462 sprintf(buf
, "%d", value
);
463 return wxWriteResource(section
, entry
, buf
, file
);
466 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
)
468 static const char defunkt
[] = "$$default";
471 int n
= GetPrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
472 (LPSTR
)wxBuffer
, 1000, (LPCSTR
)WXSTRINGCAST file
);
473 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
478 int n
= GetProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
479 (LPSTR
)wxBuffer
, 1000);
480 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
483 if (*value
) delete[] (*value
);
484 *value
= copystring(wxBuffer
);
488 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
)
491 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
494 *value
= (float)strtod(s
, NULL
);
501 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
)
504 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
507 *value
= strtol(s
, NULL
, 10);
514 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
)
517 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
520 *value
= (int)strtol(s
, NULL
, 10);
526 #endif // wxUSE_RESOURCES
529 static HCURSOR wxBusyCursorOld
= 0;
530 static int wxBusyCursorCount
= 0;
532 // Set the cursor to the busy cursor for all windows
533 void wxBeginBusyCursor(wxCursor
*cursor
)
535 wxBusyCursorCount
++;
536 if (wxBusyCursorCount
== 1)
538 wxBusyCursorOld
= ::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
542 (void)::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
546 // Restore cursor to normal
547 void wxEndBusyCursor(void)
549 if (wxBusyCursorCount
== 0)
552 wxBusyCursorCount
--;
553 if (wxBusyCursorCount
== 0)
555 ::SetCursor(wxBusyCursorOld
);
560 // TRUE if we're between the above two calls
563 return (wxBusyCursorCount
> 0);
566 const char* wxGetHomeDir(wxString
*pstr
)
568 wxString
& strDir
= *pstr
;
571 const char *szHome
= getenv("HOME");
572 if ( szHome
== NULL
) {
574 wxLogWarning(_("can't find user's HOME, using current directory."));
580 // add a trailing slash if needed
581 if ( strDir
.Last() != '/' )
585 const char *szHome
= getenv("HOMEDRIVE");
586 if ( szHome
!= NULL
)
588 szHome
= getenv("HOMEPATH");
589 if ( szHome
!= NULL
) {
592 // the idea is that under NT these variables have default values
593 // of "%systemdrive%:" and "\\". As we don't want to create our
594 // config files in the root directory of the system drive, we will
595 // create it in our program's dir. However, if the user took care
596 // to set HOMEPATH to something other than "\\", we suppose that he
597 // knows what he is doing and use the supplied value.
598 if ( strcmp(szHome
, "\\") != 0 )
599 return strDir
.c_str();
603 // Win16 has no idea about home, so use the working directory instead
606 // 260 was taken from windef.h
612 ::GetModuleFileName(::GetModuleHandle(NULL
),
613 strPath
.GetWriteBuf(MAX_PATH
), MAX_PATH
);
614 strPath
.UngetWriteBuf();
616 // extract the dir name
617 wxSplitPath(strPath
, &strDir
, NULL
, NULL
);
621 return strDir
.c_str();
625 char *wxGetUserHome (const wxString
& user
)
628 wxString
user1(user
);
632 if (wxGetUserId(tmp
, sizeof(tmp
)/sizeof(char))) {
633 // Guests belong in the temp dir
634 if (Stricmp(tmp
, "annonymous") == 0) {
635 if ((home
= getenv("TMP")) != NULL
||
636 (home
= getenv("TMPDIR")) != NULL
||
637 (home
= getenv("TEMP")) != NULL
)
638 return *home
? home
: "\\";
640 if (Stricmp(tmp
, WXSTRINGCAST user1
) == 0)
645 if ((home
= getenv("HOME")) != NULL
)
647 strcpy(wxBuffer
, home
);
648 Unix2DosFilename(wxBuffer
);
651 return NULL
; // No home known!
654 // Check whether this window wants to process messages, e.g. Stop button
655 // in long calculations.
656 bool wxCheckForInterrupt(wxWindow
*wnd
)
660 HWND win
= (HWND
) wnd
->GetHWND();
661 while(PeekMessage(&msg
,win
,0,0,PM_REMOVE
)){
662 TranslateMessage(&msg
);
663 DispatchMessage(&msg
);
665 return TRUE
;//*** temporary?
668 wxError("wnd==NULL !!!");
669 return FALSE
;//*** temporary?
673 // MSW only: get user-defined resource from the .res file.
674 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
677 char *wxLoadUserResource(const wxString
& resourceName
, const wxString
& resourceType
)
681 HRSRC hResource
= ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
684 HRSRC hResource
= ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
686 HRSRC hResource
= ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
692 HGLOBAL hData
= ::LoadResource(wxGetInstance(), hResource
);
695 char *theText
= (char *)LockResource(hData
);
699 s
= copystring(theText
);
703 UnlockResource(hData
);
707 // GlobalFree(hData);
713 void wxGetMousePosition( int* x
, int* y
)
716 GetCursorPos( & pt
);
721 // Return TRUE if we have a colour display
722 bool wxColourDisplay(void)
724 HDC dc
= ::GetDC(NULL
);
726 int noCols
= GetDeviceCaps(dc
, NUMCOLORS
);
727 if ((noCols
== -1) || (noCols
> 2))
735 // Returns depth of screen
736 int wxDisplayDepth(void)
738 HDC dc
= ::GetDC(NULL
);
739 int planes
= GetDeviceCaps(dc
, PLANES
);
740 int bitsPerPixel
= GetDeviceCaps(dc
, BITSPIXEL
);
741 int depth
= planes
*bitsPerPixel
;
746 // Get size of display
747 void wxDisplaySize(int *width
, int *height
)
749 HDC dc
= ::GetDC(NULL
);
750 *width
= GetDeviceCaps(dc
, HORZRES
); *height
= GetDeviceCaps(dc
, VERTRES
);
754 bool wxDirExists(const wxString
& dir
)
756 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
757 #if defined(__WIN32__)
758 WIN32_FIND_DATA fileInfo
;
761 struct ffblk fileInfo
;
763 struct find_t fileInfo
;
767 #if defined(__WIN32__)
768 HANDLE h
= FindFirstFile((LPTSTR
) WXSTRINGCAST dir
,(LPWIN32_FIND_DATA
)&fileInfo
);
770 if (h
==INVALID_HANDLE_VALUE
)
774 return ((fileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) == FILE_ATTRIBUTE_DIRECTORY
);
777 // In Borland findfirst has a different argument
778 // ordering from _dos_findfirst. But _dos_findfirst
779 // _should_ be ok in both MS and Borland... why not?
781 return ((findfirst(WXSTRINGCAST dir
, &fileInfo
, _A_SUBDIR
) == 0 && (fileInfo
.ff_attrib
& _A_SUBDIR
) != 0));
783 return (((_dos_findfirst(WXSTRINGCAST dir
, _A_SUBDIR
, &fileInfo
) == 0) && (fileInfo
.attrib
& _A_SUBDIR
)) != 0);
788 wxString WXDLLEXPORT
wxGetWindowText(WXHWND hWnd
)
791 int len
= GetWindowTextLength((HWND
)hWnd
) + 1;
792 GetWindowText((HWND
)hWnd
, str
.GetWriteBuf(len
), len
);
799 //------------------------------------------------------------------------
800 // wild character routines
801 //------------------------------------------------------------------------
803 bool wxIsWild( const wxString
& pattern
)
805 wxString tmp
= pattern
;
806 char *pat
= WXSTRINGCAST(tmp
);
809 case '?': case '*': case '[': case '{':
820 bool wxMatchWild( const wxString
& pat
, const wxString
& text
, bool dot_special
)
823 char *pattern
= WXSTRINGCAST(tmp1
);
824 wxString tmp2
= text
;
825 char *str
= WXSTRINGCAST(tmp2
);
828 bool done
= FALSE
, ret_code
, ok
;
829 // Below is for vi fans
830 const char OB
= '{', CB
= '}';
832 // dot_special means '.' only matches '.'
833 if (dot_special
&& *str
== '.' && *pattern
!= *str
)
836 while ((*pattern
!= '\0') && (!done
)
837 && (((*str
=='\0')&&((*pattern
==OB
)||(*pattern
=='*')))||(*str
!='\0'))) {
841 if (*pattern
!= '\0')
848 && (!(ret_code
=wxMatchWild(pattern
, str
++, FALSE
))))
853 while (*pattern
!= '\0')
860 if ((*pattern
== '\0') || (*pattern
== ']')) {
864 if (*pattern
== '\\') {
866 if (*pattern
== '\0') {
871 if (*(pattern
+ 1) == '-') {
874 if (*pattern
== ']') {
878 if (*pattern
== '\\') {
880 if (*pattern
== '\0') {
885 if ((*str
< c
) || (*str
> *pattern
)) {
889 } else if (*pattern
!= *str
) {
894 while ((*pattern
!= ']') && (*pattern
!= '\0')) {
895 if ((*pattern
== '\\') && (*(pattern
+ 1) != '\0'))
899 if (*pattern
!= '\0') {
909 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
912 while (ok
&& (*cp
!= '\0') && (*pattern
!= '\0')
913 && (*pattern
!= ',') && (*pattern
!= CB
)) {
914 if (*pattern
== '\\')
916 ok
= (*pattern
++ == *cp
++);
918 if (*pattern
== '\0') {
924 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
925 if (*++pattern
== '\\') {
926 if (*++pattern
== CB
)
931 while (*pattern
!=CB
&& *pattern
!=',' && *pattern
!='\0') {
932 if (*++pattern
== '\\') {
933 if (*++pattern
== CB
|| *pattern
== ',')
938 if (*pattern
!= '\0')
943 if (*str
== *pattern
) {
950 while (*pattern
== '*')
952 return ((*str
== '\0') && (*pattern
== '\0'));
957 #if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
960 When I started programming with Visual C++ v4.0, I missed one of my favorite
961 tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
962 on MSDN was a step in the right direction, but it is a console application
963 and thus has limited features and extensibility. DBWIN32 is my creation
964 to solve this problem.
966 The code is essentially a merging of a stripped down version of the DBWIN code
967 from VC 1.5 and DBMON.C with a few 32 bit changes.
969 As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
970 built into the operating system and works just by running DBWIN32. The Win95
971 team decided not to support this hook, so I have provided code that will do
972 this for you. See the file WIN95.TXT for instructions on installing this.
974 If you have questions, problems or suggestions about DBWIN32, I welcome your
975 feedback and plan to actively maintain the code.
980 To download dbwin32, see e.g.:
982 http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
985 #if !defined(__MWERKS__) && !defined(__SALFORDC__)
989 void OutputDebugStringW95(const char* lpOutputString
, ...)
991 HANDLE heventDBWIN
; /* DBWIN32 synchronization object */
992 HANDLE heventData
; /* data passing synch object */
993 HANDLE hSharedFile
; /* memory mapped file shared data */
997 /* create the output buffer */
999 va_start(args
, lpOutputString
);
1000 vsprintf(achBuffer
, lpOutputString
, args
);
1004 Do a regular OutputDebugString so that the output is
1005 still seen in the debugger window if it exists.
1007 This ifdef is necessary to avoid infinite recursion
1008 from the inclusion of W95TRACE.H
1011 ::OutputDebugStringW(achBuffer
);
1013 ::OutputDebugStringA(achBuffer
);
1016 /* bail if it's not Win95 */
1018 OSVERSIONINFO VerInfo
;
1019 VerInfo
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
1020 GetVersionEx(&VerInfo
);
1021 if ( VerInfo
.dwPlatformId
!= VER_PLATFORM_WIN32_WINDOWS
)
1025 /* make sure DBWIN is open and waiting */
1026 heventDBWIN
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_BUFFER_READY");
1029 //MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
1033 /* get a handle to the data synch object */
1034 heventData
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_DATA_READY");
1037 // MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
1038 CloseHandle(heventDBWIN
);
1042 hSharedFile
= CreateFileMapping((HANDLE
)-1, NULL
, PAGE_READWRITE
, 0, 4096, "DBWIN_BUFFER");
1045 //MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
1046 CloseHandle(heventDBWIN
);
1047 CloseHandle(heventData
);
1051 lpszSharedMem
= (LPSTR
)MapViewOfFile(hSharedFile
, FILE_MAP_WRITE
, 0, 0, 512);
1054 //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
1055 CloseHandle(heventDBWIN
);
1056 CloseHandle(heventData
);
1060 /* wait for buffer event */
1061 WaitForSingleObject(heventDBWIN
, INFINITE
);
1063 /* write it to the shared memory */
1064 #if defined( __BORLANDC__ ) || defined( __MWERKS__ ) || defined(__SALFORDC__)
1065 *((LPDWORD
)lpszSharedMem
) = getpid();
1067 *((LPDWORD
)lpszSharedMem
) = _getpid();
1070 wsprintf(lpszSharedMem
+ sizeof(DWORD
), "%s", achBuffer
);
1072 /* signal data ready event */
1073 SetEvent(heventData
);
1075 /* clean up handles */
1076 CloseHandle(hSharedFile
);
1077 CloseHandle(heventData
);
1078 CloseHandle(heventDBWIN
);
1087 #ifdef wxUSE_VC_CRTDBG
1089 // maximum mumber of lines the output console should have
1090 static const WORD MAX_CONSOLE_LINES
= 500;
1092 BOOL WINAPI
MyConsoleHandler( DWORD dwCtrlType
) { // control signal type
1097 void wxRedirectIOToConsole()
1101 CONSOLE_SCREEN_BUFFER_INFO coninfo
;
1104 // allocate a console for this app
1107 // set the screen buffer to be big enough to let us scroll text
1108 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE
),
1110 coninfo
.dwSize
.Y
= MAX_CONSOLE_LINES
;
1111 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE
),
1114 // redirect unbuffered STDOUT to the console
1115 lStdHandle
= (long)GetStdHandle(STD_OUTPUT_HANDLE
);
1116 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1117 if(hConHandle
<= 0) return;
1118 fp
= _fdopen( hConHandle
, "w" );
1120 setvbuf( stdout
, NULL
, _IONBF
, 0 );
1122 // redirect unbuffered STDIN to the console
1123 lStdHandle
= (long)GetStdHandle(STD_INPUT_HANDLE
);
1124 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1125 if(hConHandle
<= 0) return;
1126 fp
= _fdopen( hConHandle
, "r" );
1128 setvbuf( stdin
, NULL
, _IONBF
, 0 );
1130 // redirect unbuffered STDERR to the console
1131 lStdHandle
= (long)GetStdHandle(STD_ERROR_HANDLE
);
1132 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1133 if(hConHandle
<= 0) return;
1134 fp
= _fdopen( hConHandle
, "w" );
1136 setvbuf( stderr
, NULL
, _IONBF
, 0 );
1138 // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
1139 // point to console as well
1140 ios::sync_with_stdio();
1142 SetConsoleCtrlHandler(MyConsoleHandler
, TRUE
);
1147 void wxRedirectIOToConsole()