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"
43 #include <sys/unistd.h>
49 #ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
50 // this (3.1 I believe) and how to test for it.
51 // If this works for Borland 4.0 as well, then no worries.
67 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
73 //// BEGIN for console support: VC++ only
75 #if defined(__WXDEBUG__) && defined(_MSC_VER) && !defined(__NO_VC_CRTDBG__)
76 #define wxUSE_VC_CRTDBG
78 #undef wxUSE_VC_CRTDBG
81 #ifdef wxUSE_VC_CRTDBG
82 // VC++ uses this macro as debug/release mode indicator
90 // N.B. BC++ doesn't have istream.h, ostream.h
91 # include <iostream.h>
104 /* Need to undef new if including crtdbg.h */
111 # if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS && wxUSE_DEBUG_NEW_ALWAYS
112 # define new new(__FILE__,__LINE__)
117 /// END for console support
119 // In the WIN.INI file
120 static const char WX_SECTION
[] = "wxWindows";
121 static const char eHOSTNAME
[] = "HostName";
122 static const char eUSERID
[] = "UserId";
123 static const char eUSERNAME
[] = "UserName";
125 // For the following functions we SHOULD fill in support
126 // for Windows-NT (which I don't know) as I assume it begin
127 // a POSIX Unix (so claims MS) that it has some special
128 // functions beyond those provided by WinSock
130 // Get full hostname (eg. DoDo.BSn-Germany.crg.de)
131 bool wxGetHostName(char *buf
, int maxSize
)
134 DWORD nSize
= maxSize
;
135 return (::GetComputerName(buf
, &nSize
) != 0);
138 const char *default_host
= "noname";
140 if ((sysname
= getenv("SYSTEM_NAME")) == NULL
) {
141 GetProfileString(WX_SECTION
, eHOSTNAME
, default_host
, buf
, maxSize
- 1);
143 strncpy(buf
, sysname
, maxSize
- 1);
145 return *buf
? TRUE
: FALSE
;
149 // Get user ID e.g. jacs
150 bool wxGetUserId(char *buf
, int maxSize
)
152 #if defined(__WIN32__) && !defined(__win32s__) && 0
153 // Gets the current user's full name according to the MS article PSS ID
155 // Seems to be the same as the login name for me?
156 char *UserName
= new char[256];
157 char *Domain
= new char[256];
158 DWORD maxCharacters
= 255;
159 GetUserName( UserName
, &maxCharacters
);
160 GetComputerName( Domain
, &maxCharacters
);
162 WCHAR wszUserName
[256]; // Unicode user name
163 WCHAR wszDomain
[256];
166 struct _SERVER_INFO_100
*si100
; // Server structure
167 struct _USER_INFO_2
*ui
; // User structure
169 // Convert ASCII user name and domain to Unicode.
171 MultiByteToWideChar( CP_ACP
, 0, UserName
,
172 strlen(UserName
)+1, wszUserName
, sizeof(wszUserName
) );
173 MultiByteToWideChar( CP_ACP
, 0, Domain
,
174 strlen(Domain
)+1, wszDomain
, sizeof(wszDomain
) );
176 // Get the computer name of a DC for the specified domain.
177 // >If you get a link error on this, include netapi32.lib<
179 NetGetDCName( NULL
, wszDomain
, &ComputerName
);
181 // Look up the user on the DC.
183 if(NetUserGetInfo( (LPWSTR
) ComputerName
,
184 (LPWSTR
) &wszUserName
, 2, (LPBYTE
*) &ui
))
186 printf( "Error getting user information.\n" );
190 // Convert the Unicode full name to ASCII.
192 WideCharToMultiByte( CP_ACP
, 0, ui
->usri2_full_name
,
193 -1, buf
, 256, NULL
, NULL
);
197 DWORD nSize = maxSize;
198 return ::GetUserName(buf, &nSize);
202 const char *default_id
= "anonymous";
204 // Can't assume we have NIS (PC-NFS) or some other ID daemon
206 if ( (user
= getenv("USER")) == NULL
&&
207 (user
= getenv("LOGNAME")) == NULL
) {
208 // Use wxWindows configuration data (comming soon)
209 GetProfileString(WX_SECTION
, eUSERID
, default_id
, buf
, maxSize
- 1);
211 strncpy(buf
, user
, maxSize
- 1);
212 return *buf
? TRUE
: FALSE
;
216 // Get user name e.g. Julian Smart
217 bool wxGetUserName(char *buf
, int maxSize
)
219 const char *default_name
= "Unknown User";
220 #if defined(__WIN32__)
222 DWORD nSize = maxSize;
223 In VC++ 4.0, results in unresolved symbol __imp__GetUserNameA
224 if (GetUserName(buf, &nSize))
228 // Could use NIS, MS-Mail or other site specific programs
229 // Use wxWindows configuration data
230 GetProfileString(WX_SECTION
, eUSERNAME
, default_name
, buf
, maxSize
- 1);
231 return *buf
? TRUE
: FALSE
;
234 #if !defined(__WATCOMC__) && !defined(__GNUWIN32__) && wxUSE_PENWINDOWS
235 extern HANDLE g_hPenWin
; // PenWindows Running?
238 // PenWindows Does have a user concept!
239 // Get the current owner of the recognizer
240 GetPrivateProfileString("Current", "User", default_name
, wxBuffer
, maxSize
- 1, "PENWIN.INI");
241 strncpy(buf
, wxBuffer
, maxSize
- 1);
246 // Could use NIS, MS-Mail or other site specific programs
247 // Use wxWindows configuration data
248 GetProfileString(WX_SECTION
, eUSERNAME
, default_name
, buf
, maxSize
- 1);
250 return *buf
? TRUE
: FALSE
;
254 int wxKill(long pid
, int sig
)
260 // Execute a program in an Interactive Shell
263 wxShell(const wxString
& command
)
266 if ((shell
= getenv("COMSPEC")) == NULL
)
267 shell
= "\\COMMAND.COM";
271 sprintf(tmp
, "%s /c %s", shell
, WXSTRINGCAST command
);
275 return (wxExecute((char *)tmp
, FALSE
) != 0);
278 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
279 long wxGetFreeMemory(void)
281 #if defined(__WIN32__) && !defined(__BORLANDC__)
282 MEMORYSTATUS memStatus
;
283 memStatus
.dwLength
= sizeof(MEMORYSTATUS
);
284 GlobalMemoryStatus(&memStatus
);
285 return memStatus
.dwAvailPhys
;
287 return (long)GetFreeSpace(0);
291 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
292 static bool inTimer
= FALSE
;
293 class wxSleepTimer
: public wxTimer
296 inline void Notify(void)
303 static wxTimer
*wxTheSleepTimer
= NULL
;
305 void wxSleep(int nSecs
)
307 #if 0 // WIN32 hangs app
313 wxTheSleepTimer
= new wxSleepTimer
;
315 wxTheSleepTimer
->Start(nSecs
*1000);
318 if (wxTheApp
->Pending())
319 wxTheApp
->Dispatch();
321 delete wxTheSleepTimer
;
322 wxTheSleepTimer
= NULL
;
326 // Consume all events until no more left
327 void wxFlushEvents(void)
332 // Output a debug mess., in a system dependent fashion.
333 void wxDebugMsg(const char *fmt
...)
336 static char buffer
[512];
338 if (!wxTheApp
->GetWantDebugOutput())
343 wvsprintf(buffer
,fmt
,ap
) ;
344 OutputDebugString((LPCSTR
)buffer
) ;
349 // Non-fatal error: pop up message box and (possibly) continue
350 void wxError(const wxString
& msg
, const wxString
& title
)
352 sprintf(wxBuffer
, "%s\nContinue?", WXSTRINGCAST msg
);
353 if (MessageBox(NULL
, (LPCSTR
)wxBuffer
, (LPCSTR
)WXSTRINGCAST title
,
354 MB_ICONSTOP
| MB_YESNO
) == IDNO
)
358 // Fatal error: pop up message box and abort
359 void wxFatalError(const wxString
& msg
, const wxString
& title
)
361 sprintf(wxBuffer
, "%s: %s", WXSTRINGCAST title
, WXSTRINGCAST msg
);
362 FatalAppExit(0, (LPCSTR
)wxBuffer
);
368 // Removed by RD because IHMO syncronous sound is a Bad Thing. MessageBeep
369 // will do a similar thing anyway if there is no sound card...
371 // Beep(1000,1000) ; // 1kHz during 1 sec.
373 MessageBeep((UINT
)-1) ;
377 // Chris Breeze 27/5/98: revised WIN32 code to
378 // detect WindowsNT correctly
379 int wxGetOsVersion(int *majorVsn
, int *minorVsn
)
381 extern char *wxOsVersion
;
382 if (majorVsn
) *majorVsn
= 0;
383 if (minorVsn
) *minorVsn
= 0;
387 memset(&info
, 0, sizeof(OSVERSIONINFO
));
388 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
389 if (GetVersionEx(&info
))
391 if (majorVsn
) *majorVsn
= info
.dwMajorVersion
;
392 if (minorVsn
) *minorVsn
= info
.dwMinorVersion
;
393 switch (info
.dwPlatformId
)
395 case VER_PLATFORM_WIN32s
:
398 case VER_PLATFORM_WIN32_WINDOWS
:
401 case VER_PLATFORM_WIN32_NT
:
406 return wxWINDOWS
; // error if we get here, return generic value
410 # ifdef __WINDOWS_386__
413 # if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
414 extern HANDLE g_hPenWin
;
415 retValue
= g_hPenWin
? wxPENWINDOWS
: wxWINDOWS
;
418 // @@@@ To be completed. I don't have the manual here...
419 if (majorVsn
) *majorVsn
= 3 ;
420 if (minorVsn
) *minorVsn
= 1 ;
425 // Reading and writing resources (eg WIN.INI, .Xdefaults)
427 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
)
430 return (WritePrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)value
, (LPCSTR
)WXSTRINGCAST file
) != 0);
432 return (WriteProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)WXSTRINGCAST value
) != 0);
435 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
)
438 sprintf(buf
, "%.4f", value
);
439 return wxWriteResource(section
, entry
, buf
, file
);
442 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
)
445 sprintf(buf
, "%ld", value
);
446 return wxWriteResource(section
, entry
, buf
, file
);
449 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
)
452 sprintf(buf
, "%d", value
);
453 return wxWriteResource(section
, entry
, buf
, file
);
456 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
)
458 static const char defunkt
[] = "$$default";
461 int n
= GetPrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
462 (LPSTR
)wxBuffer
, 1000, (LPCSTR
)WXSTRINGCAST file
);
463 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
468 int n
= GetProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
469 (LPSTR
)wxBuffer
, 1000);
470 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
473 if (*value
) delete[] (*value
);
474 *value
= copystring(wxBuffer
);
478 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
)
481 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
484 *value
= (float)strtod(s
, NULL
);
491 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
)
494 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
497 *value
= strtol(s
, NULL
, 10);
504 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
)
507 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
510 *value
= (int)strtol(s
, NULL
, 10);
516 #endif // wxUSE_RESOURCES
519 static HCURSOR wxBusyCursorOld
= 0;
520 static int wxBusyCursorCount
= 0;
522 // Set the cursor to the busy cursor for all windows
523 void wxBeginBusyCursor(wxCursor
*cursor
)
525 wxBusyCursorCount
++;
526 if (wxBusyCursorCount
== 1)
528 wxBusyCursorOld
= ::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
532 (void)::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
536 // Restore cursor to normal
537 void wxEndBusyCursor(void)
539 if (wxBusyCursorCount
== 0)
542 wxBusyCursorCount
--;
543 if (wxBusyCursorCount
== 0)
545 ::SetCursor(wxBusyCursorOld
);
550 // TRUE if we're between the above two calls
553 return (wxBusyCursorCount
> 0);
556 const char* wxGetHomeDir(wxString
*pstr
)
558 wxString
& strDir
= *pstr
;
561 const char *szHome
= getenv("HOME");
562 if ( szHome
== NULL
) {
564 wxLogWarning(_("can't find user's HOME, using current directory."));
570 // add a trailing slash if needed
571 if ( strDir
.Last() != '/' )
575 const char *szHome
= getenv("HOMEDRIVE");
576 if ( szHome
!= NULL
)
578 szHome
= getenv("HOMEPATH");
579 if ( szHome
!= NULL
) {
582 // the idea is that under NT these variables have default values
583 // of "%systemdrive%:" and "\\". As we don't want to create our
584 // config files in the root directory of the system drive, we will
585 // create it in our program's dir. However, if the user took care
586 // to set HOMEPATH to something other than "\\", we suppose that he
587 // knows what he is doing and use the supplied value.
588 if ( strcmp(szHome
, "\\") != 0 )
589 return strDir
.c_str();
593 // Win16 has no idea about home, so use the working directory instead
596 // 260 was taken from windef.h
602 ::GetModuleFileName(::GetModuleHandle(NULL
),
603 strPath
.GetWriteBuf(MAX_PATH
), MAX_PATH
);
604 strPath
.UngetWriteBuf();
606 // extract the dir name
607 wxSplitPath(strPath
, &strDir
, NULL
, NULL
);
611 return strDir
.c_str();
615 char *wxGetUserHome (const wxString
& user
)
618 wxString
user1(user
);
622 if (wxGetUserId(tmp
, sizeof(tmp
)/sizeof(char))) {
623 // Guests belong in the temp dir
624 if (Stricmp(tmp
, "annonymous") == 0) {
625 if ((home
= getenv("TMP")) != NULL
||
626 (home
= getenv("TMPDIR")) != NULL
||
627 (home
= getenv("TEMP")) != NULL
)
628 return *home
? home
: "\\";
630 if (Stricmp(tmp
, WXSTRINGCAST user1
) == 0)
635 if ((home
= getenv("HOME")) != NULL
)
637 strcpy(wxBuffer
, home
);
638 Unix2DosFilename(wxBuffer
);
641 return NULL
; // No home known!
644 // Check whether this window wants to process messages, e.g. Stop button
645 // in long calculations.
646 bool wxCheckForInterrupt(wxWindow
*wnd
)
650 HWND win
= (HWND
) wnd
->GetHWND();
651 while(PeekMessage(&msg
,win
,0,0,PM_REMOVE
)){
652 TranslateMessage(&msg
);
653 DispatchMessage(&msg
);
655 return TRUE
;//*** temporary?
658 wxError("wnd==NULL !!!");
659 return FALSE
;//*** temporary?
663 // MSW only: get user-defined resource from the .res file.
664 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
667 char *wxLoadUserResource(const wxString
& resourceName
, const wxString
& resourceType
)
671 HRSRC hResource
= ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
674 HRSRC hResource
= ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
676 HRSRC hResource
= ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
682 HGLOBAL hData
= ::LoadResource(wxGetInstance(), hResource
);
685 char *theText
= (char *)LockResource(hData
);
689 s
= copystring(theText
);
693 UnlockResource(hData
);
697 // GlobalFree(hData);
703 void wxGetMousePosition( int* x
, int* y
)
706 GetCursorPos( & pt
);
711 // Return TRUE if we have a colour display
712 bool wxColourDisplay(void)
714 HDC dc
= ::GetDC(NULL
);
716 int noCols
= GetDeviceCaps(dc
, NUMCOLORS
);
717 if ((noCols
== -1) || (noCols
> 2))
725 // Returns depth of screen
726 int wxDisplayDepth(void)
728 HDC dc
= ::GetDC(NULL
);
729 int planes
= GetDeviceCaps(dc
, PLANES
);
730 int bitsPerPixel
= GetDeviceCaps(dc
, BITSPIXEL
);
731 int depth
= planes
*bitsPerPixel
;
736 // Get size of display
737 void wxDisplaySize(int *width
, int *height
)
739 HDC dc
= ::GetDC(NULL
);
740 *width
= GetDeviceCaps(dc
, HORZRES
); *height
= GetDeviceCaps(dc
, VERTRES
);
744 bool wxDirExists(const wxString
& dir
)
746 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
747 #if defined(__WIN32__)
748 WIN32_FIND_DATA fileInfo
;
751 struct ffblk fileInfo
;
753 struct find_t fileInfo
;
757 #if defined(__WIN32__)
758 HANDLE h
= FindFirstFile((LPTSTR
) WXSTRINGCAST dir
,(LPWIN32_FIND_DATA
)&fileInfo
);
760 if (h
==INVALID_HANDLE_VALUE
)
764 return ((fileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) == FILE_ATTRIBUTE_DIRECTORY
);
767 // In Borland findfirst has a different argument
768 // ordering from _dos_findfirst. But _dos_findfirst
769 // _should_ be ok in both MS and Borland... why not?
771 return ((findfirst(WXSTRINGCAST dir
, &fileInfo
, _A_SUBDIR
) == 0 && (fileInfo
.ff_attrib
& _A_SUBDIR
) != 0));
773 return (((_dos_findfirst(WXSTRINGCAST dir
, _A_SUBDIR
, &fileInfo
) == 0) && (fileInfo
.attrib
& _A_SUBDIR
)) != 0);
778 wxString WXDLLEXPORT
wxGetWindowText(WXHWND hWnd
)
781 int len
= GetWindowTextLength((HWND
)hWnd
) + 1;
782 GetWindowText((HWND
)hWnd
, str
.GetWriteBuf(len
), len
);
789 //------------------------------------------------------------------------
790 // wild character routines
791 //------------------------------------------------------------------------
793 bool wxIsWild( const wxString
& pattern
)
795 wxString tmp
= pattern
;
796 char *pat
= WXSTRINGCAST(tmp
);
799 case '?': case '*': case '[': case '{':
810 bool wxMatchWild( const wxString
& pat
, const wxString
& text
, bool dot_special
)
813 char *pattern
= WXSTRINGCAST(tmp1
);
814 wxString tmp2
= text
;
815 char *str
= WXSTRINGCAST(tmp2
);
818 bool done
= FALSE
, ret_code
, ok
;
819 // Below is for vi fans
820 const char OB
= '{', CB
= '}';
822 // dot_special means '.' only matches '.'
823 if (dot_special
&& *str
== '.' && *pattern
!= *str
)
826 while ((*pattern
!= '\0') && (!done
)
827 && (((*str
=='\0')&&((*pattern
==OB
)||(*pattern
=='*')))||(*str
!='\0'))) {
831 if (*pattern
!= '\0')
838 && (!(ret_code
=wxMatchWild(pattern
, str
++, FALSE
))))
843 while (*pattern
!= '\0')
850 if ((*pattern
== '\0') || (*pattern
== ']')) {
854 if (*pattern
== '\\') {
856 if (*pattern
== '\0') {
861 if (*(pattern
+ 1) == '-') {
864 if (*pattern
== ']') {
868 if (*pattern
== '\\') {
870 if (*pattern
== '\0') {
875 if ((*str
< c
) || (*str
> *pattern
)) {
879 } else if (*pattern
!= *str
) {
884 while ((*pattern
!= ']') && (*pattern
!= '\0')) {
885 if ((*pattern
== '\\') && (*(pattern
+ 1) != '\0'))
889 if (*pattern
!= '\0') {
899 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
902 while (ok
&& (*cp
!= '\0') && (*pattern
!= '\0')
903 && (*pattern
!= ',') && (*pattern
!= CB
)) {
904 if (*pattern
== '\\')
906 ok
= (*pattern
++ == *cp
++);
908 if (*pattern
== '\0') {
914 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
915 if (*++pattern
== '\\') {
916 if (*++pattern
== CB
)
921 while (*pattern
!=CB
&& *pattern
!=',' && *pattern
!='\0') {
922 if (*++pattern
== '\\') {
923 if (*++pattern
== CB
|| *pattern
== ',')
928 if (*pattern
!= '\0')
933 if (*str
== *pattern
) {
940 while (*pattern
== '*')
942 return ((*str
== '\0') && (*pattern
== '\0'));
947 #if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
950 When I started programming with Visual C++ v4.0, I missed one of my favorite
951 tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
952 on MSDN was a step in the right direction, but it is a console application
953 and thus has limited features and extensibility. DBWIN32 is my creation
954 to solve this problem.
956 The code is essentially a merging of a stripped down version of the DBWIN code
957 from VC 1.5 and DBMON.C with a few 32 bit changes.
959 As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
960 built into the operating system and works just by running DBWIN32. The Win95
961 team decided not to support this hook, so I have provided code that will do
962 this for you. See the file WIN95.TXT for instructions on installing this.
964 If you have questions, problems or suggestions about DBWIN32, I welcome your
965 feedback and plan to actively maintain the code.
970 To download dbwin32, see e.g.:
972 http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
977 void OutputDebugStringW95(const char* lpOutputString
, ...)
979 HANDLE heventDBWIN
; /* DBWIN32 synchronization object */
980 HANDLE heventData
; /* data passing synch object */
981 HANDLE hSharedFile
; /* memory mapped file shared data */
985 /* create the output buffer */
987 va_start(args
, lpOutputString
);
988 vsprintf(achBuffer
, lpOutputString
, args
);
992 Do a regular OutputDebugString so that the output is
993 still seen in the debugger window if it exists.
995 This ifdef is necessary to avoid infinite recursion
996 from the inclusion of W95TRACE.H
999 ::OutputDebugStringW(achBuffer
);
1001 ::OutputDebugStringA(achBuffer
);
1004 /* bail if it's not Win95 */
1006 OSVERSIONINFO VerInfo
;
1007 VerInfo
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
1008 GetVersionEx(&VerInfo
);
1009 if ( VerInfo
.dwPlatformId
!= VER_PLATFORM_WIN32_WINDOWS
)
1013 /* make sure DBWIN is open and waiting */
1014 heventDBWIN
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_BUFFER_READY");
1017 //MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
1021 /* get a handle to the data synch object */
1022 heventData
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_DATA_READY");
1025 // MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
1026 CloseHandle(heventDBWIN
);
1030 hSharedFile
= CreateFileMapping((HANDLE
)-1, NULL
, PAGE_READWRITE
, 0, 4096, "DBWIN_BUFFER");
1033 //MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
1034 CloseHandle(heventDBWIN
);
1035 CloseHandle(heventData
);
1039 lpszSharedMem
= (LPSTR
)MapViewOfFile(hSharedFile
, FILE_MAP_WRITE
, 0, 0, 512);
1042 //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
1043 CloseHandle(heventDBWIN
);
1044 CloseHandle(heventData
);
1048 /* wait for buffer event */
1049 WaitForSingleObject(heventDBWIN
, INFINITE
);
1051 /* write it to the shared memory */
1053 *((LPDWORD
)lpszSharedMem
) = getpid();
1055 *((LPDWORD
)lpszSharedMem
) = _getpid();
1058 wsprintf(lpszSharedMem
+ sizeof(DWORD
), "%s", achBuffer
);
1060 /* signal data ready event */
1061 SetEvent(heventData
);
1063 /* clean up handles */
1064 CloseHandle(hSharedFile
);
1065 CloseHandle(heventData
);
1066 CloseHandle(heventDBWIN
);
1075 #ifdef wxUSE_VC_CRTDBG
1077 // maximum mumber of lines the output console should have
1078 static const WORD MAX_CONSOLE_LINES
= 500;
1080 BOOL WINAPI
MyConsoleHandler( DWORD dwCtrlType
) { // control signal type
1085 void wxRedirectIOToConsole()
1089 CONSOLE_SCREEN_BUFFER_INFO coninfo
;
1092 // allocate a console for this app
1095 // set the screen buffer to be big enough to let us scroll text
1096 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE
),
1098 coninfo
.dwSize
.Y
= MAX_CONSOLE_LINES
;
1099 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE
),
1102 // redirect unbuffered STDOUT to the console
1103 lStdHandle
= (long)GetStdHandle(STD_OUTPUT_HANDLE
);
1104 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1105 if(hConHandle
<= 0) return;
1106 fp
= _fdopen( hConHandle
, "w" );
1108 setvbuf( stdout
, NULL
, _IONBF
, 0 );
1110 // redirect unbuffered STDIN to the console
1111 lStdHandle
= (long)GetStdHandle(STD_INPUT_HANDLE
);
1112 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1113 if(hConHandle
<= 0) return;
1114 fp
= _fdopen( hConHandle
, "r" );
1116 setvbuf( stdin
, NULL
, _IONBF
, 0 );
1118 // redirect unbuffered STDERR to the console
1119 lStdHandle
= (long)GetStdHandle(STD_ERROR_HANDLE
);
1120 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1121 if(hConHandle
<= 0) return;
1122 fp
= _fdopen( hConHandle
, "w" );
1124 setvbuf( stderr
, NULL
, _IONBF
, 0 );
1126 // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
1127 // point to console as well
1128 ios::sync_with_stdio();
1130 SetConsoleCtrlHandler(MyConsoleHandler
, TRUE
);
1135 void wxRedirectIOToConsole()