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"
45 #include <sys/unistd.h>
51 #ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
52 // this (3.1 I believe) and how to test for it.
53 // If this works for Borland 4.0 as well, then no worries.
69 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
75 //// BEGIN for console support: VC++ only
77 #if defined(__WXDEBUG__) && !defined(__WIN16__) && defined(_MSC_VER) && !defined(__NO_VC_CRTDBG__)
78 #define wxUSE_VC_CRTDBG
80 #undef wxUSE_VC_CRTDBG
83 #ifdef wxUSE_VC_CRTDBG
84 // VC++ uses this macro as debug/release mode indicator
92 // N.B. BC++ doesn't have istream.h, ostream.h
93 # include <iostream.h>
106 /* Need to undef new if including crtdbg.h */
115 # if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS && wxUSE_DEBUG_NEW_ALWAYS
116 # define new new(__FILE__,__LINE__)
121 /// END for console support
123 // In the WIN.INI file
124 static const char WX_SECTION
[] = "wxWindows";
125 static const char eHOSTNAME
[] = "HostName";
126 static const char eUSERID
[] = "UserId";
127 static const char eUSERNAME
[] = "UserName";
129 // For the following functions we SHOULD fill in support
130 // for Windows-NT (which I don't know) as I assume it begin
131 // a POSIX Unix (so claims MS) that it has some special
132 // functions beyond those provided by WinSock
134 // Get full hostname (eg. DoDo.BSn-Germany.crg.de)
135 bool wxGetHostName(char *buf
, int maxSize
)
138 DWORD nSize
= maxSize
;
139 return (::GetComputerName(buf
, &nSize
) != 0);
142 const char *default_host
= "noname";
144 if ((sysname
= getenv("SYSTEM_NAME")) == NULL
) {
145 GetProfileString(WX_SECTION
, eHOSTNAME
, default_host
, buf
, maxSize
- 1);
147 strncpy(buf
, sysname
, maxSize
- 1);
149 return *buf
? TRUE
: FALSE
;
153 // Get user ID e.g. jacs
154 bool wxGetUserId(char *buf
, int maxSize
)
156 #if defined(__WIN32__) && !defined(__win32s__)
158 // VZ: why should it be so complicated??
160 // Gets the current user's full name according to the MS article PSS ID
162 // Seems to be the same as the login name for me?
163 char *UserName
= new char[256];
164 char *Domain
= new char[256];
165 DWORD maxCharacters
= 255;
166 GetUserName( UserName
, &maxCharacters
);
167 GetComputerName( Domain
, &maxCharacters
);
169 WCHAR wszUserName
[256]; // Unicode user name
170 WCHAR wszDomain
[256];
173 struct _SERVER_INFO_100
*si100
; // Server structure
174 struct _USER_INFO_2
*ui
; // User structure
176 // Convert ASCII user name and domain to Unicode.
178 MultiByteToWideChar( CP_ACP
, 0, UserName
,
179 strlen(UserName
)+1, wszUserName
, sizeof(wszUserName
) );
180 MultiByteToWideChar( CP_ACP
, 0, Domain
,
181 strlen(Domain
)+1, wszDomain
, sizeof(wszDomain
) );
183 // Get the computer name of a DC for the specified domain.
184 // >If you get a link error on this, include netapi32.lib<
186 NetGetDCName( NULL
, wszDomain
, &ComputerName
);
188 // Look up the user on the DC.
190 if(NetUserGetInfo( (LPWSTR
) ComputerName
,
191 (LPWSTR
) &wszUserName
, 2, (LPBYTE
*) &ui
))
193 printf( "Error getting user information.\n" );
197 // Convert the Unicode full name to ASCII.
199 WideCharToMultiByte( CP_ACP
, 0, ui
->usri2_full_name
,
200 -1, buf
, 256, NULL
, NULL
);
204 DWORD nSize
= maxSize
;
205 if ( ::GetUserName(buf
, &nSize
) == 0 )
207 wxLogSysError("Can not get user name");
215 #else // Win16 or Win32s
217 const char *default_id
= "anonymous";
219 // Can't assume we have NIS (PC-NFS) or some other ID daemon
221 if ( (user
= getenv("USER")) == NULL
&&
222 (user
= getenv("LOGNAME")) == NULL
) {
223 // Use wxWindows configuration data (comming soon)
224 GetProfileString(WX_SECTION
, eUSERID
, default_id
, buf
, maxSize
- 1);
226 strncpy(buf
, user
, maxSize
- 1);
227 return *buf
? TRUE
: FALSE
;
231 // Get user name e.g. Julian Smart
232 bool wxGetUserName(char *buf
, int maxSize
)
234 #if wxUSE_PENWINDOWS && !defined(__WATCOMC__) && !defined(__GNUWIN32__)
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 bool ok
= GetProfileString(WX_SECTION
, eUSERNAME
, "", buf
, maxSize
- 1) != 0;
251 ok
= wxGetUserId(buf
, maxSize
);
256 strncpy(buf
, "Unknown User", maxSize
);
263 int wxKill(long pid
, int sig
)
269 // Execute a program in an Interactive Shell
272 wxShell(const wxString
& command
)
275 if ((shell
= getenv("COMSPEC")) == NULL
)
276 shell
= "\\COMMAND.COM";
280 sprintf(tmp
, "%s /c %s", shell
, WXSTRINGCAST command
);
284 return (wxExecute((char *)tmp
, FALSE
) != 0);
287 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
288 long wxGetFreeMemory(void)
290 #if defined(__WIN32__) && !defined(__BORLANDC__)
291 MEMORYSTATUS memStatus
;
292 memStatus
.dwLength
= sizeof(MEMORYSTATUS
);
293 GlobalMemoryStatus(&memStatus
);
294 return memStatus
.dwAvailPhys
;
296 return (long)GetFreeSpace(0);
300 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
301 static bool inTimer
= FALSE
;
302 class wxSleepTimer
: public wxTimer
305 inline void Notify(void)
312 static wxTimer
*wxTheSleepTimer
= NULL
;
314 void wxSleep(int nSecs
)
316 #if 0 // WIN32 hangs app
322 wxTheSleepTimer
= new wxSleepTimer
;
324 wxTheSleepTimer
->Start(nSecs
*1000);
327 if (wxTheApp
->Pending())
328 wxTheApp
->Dispatch();
330 delete wxTheSleepTimer
;
331 wxTheSleepTimer
= NULL
;
335 // Consume all events until no more left
336 void wxFlushEvents(void)
341 // Output a debug mess., in a system dependent fashion.
342 void wxDebugMsg(const char *fmt
...)
345 static char buffer
[512];
347 if (!wxTheApp
->GetWantDebugOutput())
352 wvsprintf(buffer
,fmt
,ap
) ;
353 OutputDebugString((LPCSTR
)buffer
) ;
358 // Non-fatal error: pop up message box and (possibly) continue
359 void wxError(const wxString
& msg
, const wxString
& title
)
361 sprintf(wxBuffer
, "%s\nContinue?", WXSTRINGCAST msg
);
362 if (MessageBox(NULL
, (LPCSTR
)wxBuffer
, (LPCSTR
)WXSTRINGCAST title
,
363 MB_ICONSTOP
| MB_YESNO
) == IDNO
)
367 // Fatal error: pop up message box and abort
368 void wxFatalError(const wxString
& msg
, const wxString
& title
)
370 sprintf(wxBuffer
, "%s: %s", WXSTRINGCAST title
, WXSTRINGCAST msg
);
371 FatalAppExit(0, (LPCSTR
)wxBuffer
);
377 // Removed by RD because IHMO syncronous sound is a Bad Thing. MessageBeep
378 // will do a similar thing anyway if there is no sound card...
380 // Beep(1000,1000) ; // 1kHz during 1 sec.
382 MessageBeep((UINT
)-1) ;
386 // Chris Breeze 27/5/98: revised WIN32 code to
387 // detect WindowsNT correctly
388 int wxGetOsVersion(int *majorVsn
, int *minorVsn
)
390 extern char *wxOsVersion
;
391 if (majorVsn
) *majorVsn
= 0;
392 if (minorVsn
) *minorVsn
= 0;
394 #if defined(__WIN32__) && !defined(__SC__)
396 memset(&info
, 0, sizeof(OSVERSIONINFO
));
397 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
398 if (GetVersionEx(&info
))
400 if (majorVsn
) *majorVsn
= info
.dwMajorVersion
;
401 if (minorVsn
) *minorVsn
= info
.dwMinorVersion
;
402 switch (info
.dwPlatformId
)
404 case VER_PLATFORM_WIN32s
:
407 case VER_PLATFORM_WIN32_WINDOWS
:
410 case VER_PLATFORM_WIN32_NT
:
415 return wxWINDOWS
; // error if we get here, return generic value
419 # ifdef __WINDOWS_386__
422 # if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
423 extern HANDLE g_hPenWin
;
424 retValue
= g_hPenWin
? wxPENWINDOWS
: wxWINDOWS
;
427 // @@@@ To be completed. I don't have the manual here...
428 if (majorVsn
) *majorVsn
= 3 ;
429 if (minorVsn
) *minorVsn
= 1 ;
434 // Reading and writing resources (eg WIN.INI, .Xdefaults)
436 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
)
439 return (WritePrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)value
, (LPCSTR
)WXSTRINGCAST file
) != 0);
441 return (WriteProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)WXSTRINGCAST value
) != 0);
444 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
)
447 sprintf(buf
, "%.4f", value
);
448 return wxWriteResource(section
, entry
, buf
, file
);
451 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
)
454 sprintf(buf
, "%ld", value
);
455 return wxWriteResource(section
, entry
, buf
, file
);
458 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
)
461 sprintf(buf
, "%d", value
);
462 return wxWriteResource(section
, entry
, buf
, file
);
465 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
)
467 static const char defunkt
[] = "$$default";
470 int n
= GetPrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
471 (LPSTR
)wxBuffer
, 1000, (LPCSTR
)WXSTRINGCAST file
);
472 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
477 int n
= GetProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
478 (LPSTR
)wxBuffer
, 1000);
479 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
482 if (*value
) delete[] (*value
);
483 *value
= copystring(wxBuffer
);
487 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
)
490 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
493 *value
= (float)strtod(s
, NULL
);
500 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
)
503 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
506 *value
= strtol(s
, NULL
, 10);
513 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
)
516 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
519 *value
= (int)strtol(s
, NULL
, 10);
525 #endif // wxUSE_RESOURCES
528 static HCURSOR wxBusyCursorOld
= 0;
529 static int wxBusyCursorCount
= 0;
531 // Set the cursor to the busy cursor for all windows
532 void wxBeginBusyCursor(wxCursor
*cursor
)
534 wxBusyCursorCount
++;
535 if (wxBusyCursorCount
== 1)
537 wxBusyCursorOld
= ::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
541 (void)::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
545 // Restore cursor to normal
546 void wxEndBusyCursor(void)
548 if (wxBusyCursorCount
== 0)
551 wxBusyCursorCount
--;
552 if (wxBusyCursorCount
== 0)
554 ::SetCursor(wxBusyCursorOld
);
559 // TRUE if we're between the above two calls
562 return (wxBusyCursorCount
> 0);
565 const char* wxGetHomeDir(wxString
*pstr
)
567 wxString
& strDir
= *pstr
;
570 const char *szHome
= getenv("HOME");
571 if ( szHome
== NULL
) {
573 wxLogWarning(_("can't find user's HOME, using current directory."));
579 // add a trailing slash if needed
580 if ( strDir
.Last() != '/' )
584 const char *szHome
= getenv("HOMEDRIVE");
585 if ( szHome
!= NULL
)
587 szHome
= getenv("HOMEPATH");
588 if ( szHome
!= NULL
) {
591 // the idea is that under NT these variables have default values
592 // of "%systemdrive%:" and "\\". As we don't want to create our
593 // config files in the root directory of the system drive, we will
594 // create it in our program's dir. However, if the user took care
595 // to set HOMEPATH to something other than "\\", we suppose that he
596 // knows what he is doing and use the supplied value.
597 if ( strcmp(szHome
, "\\") != 0 )
598 return strDir
.c_str();
602 // Win16 has no idea about home, so use the working directory instead
605 // 260 was taken from windef.h
611 ::GetModuleFileName(::GetModuleHandle(NULL
),
612 strPath
.GetWriteBuf(MAX_PATH
), MAX_PATH
);
613 strPath
.UngetWriteBuf();
615 // extract the dir name
616 wxSplitPath(strPath
, &strDir
, NULL
, NULL
);
620 return strDir
.c_str();
624 char *wxGetUserHome (const wxString
& user
)
627 wxString
user1(user
);
631 if (wxGetUserId(tmp
, sizeof(tmp
)/sizeof(char))) {
632 // Guests belong in the temp dir
633 if (Stricmp(tmp
, "annonymous") == 0) {
634 if ((home
= getenv("TMP")) != NULL
||
635 (home
= getenv("TMPDIR")) != NULL
||
636 (home
= getenv("TEMP")) != NULL
)
637 return *home
? home
: "\\";
639 if (Stricmp(tmp
, WXSTRINGCAST user1
) == 0)
644 if ((home
= getenv("HOME")) != NULL
)
646 strcpy(wxBuffer
, home
);
647 Unix2DosFilename(wxBuffer
);
650 return NULL
; // No home known!
653 // Check whether this window wants to process messages, e.g. Stop button
654 // in long calculations.
655 bool wxCheckForInterrupt(wxWindow
*wnd
)
659 HWND win
= (HWND
) wnd
->GetHWND();
660 while(PeekMessage(&msg
,win
,0,0,PM_REMOVE
)){
661 TranslateMessage(&msg
);
662 DispatchMessage(&msg
);
664 return TRUE
;//*** temporary?
667 wxError("wnd==NULL !!!");
668 return FALSE
;//*** temporary?
672 // MSW only: get user-defined resource from the .res file.
673 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
676 char *wxLoadUserResource(const wxString
& resourceName
, const wxString
& resourceType
)
680 HRSRC hResource
= ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
683 HRSRC hResource
= ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
685 HRSRC hResource
= ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
691 HGLOBAL hData
= ::LoadResource(wxGetInstance(), hResource
);
694 char *theText
= (char *)LockResource(hData
);
698 s
= copystring(theText
);
702 UnlockResource(hData
);
706 // GlobalFree(hData);
712 void wxGetMousePosition( int* x
, int* y
)
715 GetCursorPos( & pt
);
720 // Return TRUE if we have a colour display
721 bool wxColourDisplay(void)
723 HDC dc
= ::GetDC(NULL
);
725 int noCols
= GetDeviceCaps(dc
, NUMCOLORS
);
726 if ((noCols
== -1) || (noCols
> 2))
734 // Returns depth of screen
735 int wxDisplayDepth(void)
737 HDC dc
= ::GetDC(NULL
);
738 int planes
= GetDeviceCaps(dc
, PLANES
);
739 int bitsPerPixel
= GetDeviceCaps(dc
, BITSPIXEL
);
740 int depth
= planes
*bitsPerPixel
;
745 // Get size of display
746 void wxDisplaySize(int *width
, int *height
)
748 HDC dc
= ::GetDC(NULL
);
749 *width
= GetDeviceCaps(dc
, HORZRES
); *height
= GetDeviceCaps(dc
, VERTRES
);
753 bool wxDirExists(const wxString
& dir
)
755 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
756 #if defined(__WIN32__)
757 WIN32_FIND_DATA fileInfo
;
760 struct ffblk fileInfo
;
762 struct find_t fileInfo
;
766 #if defined(__WIN32__)
767 HANDLE h
= FindFirstFile((LPTSTR
) WXSTRINGCAST dir
,(LPWIN32_FIND_DATA
)&fileInfo
);
769 if (h
==INVALID_HANDLE_VALUE
)
773 return ((fileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) == FILE_ATTRIBUTE_DIRECTORY
);
776 // In Borland findfirst has a different argument
777 // ordering from _dos_findfirst. But _dos_findfirst
778 // _should_ be ok in both MS and Borland... why not?
780 return ((findfirst(WXSTRINGCAST dir
, &fileInfo
, _A_SUBDIR
) == 0 && (fileInfo
.ff_attrib
& _A_SUBDIR
) != 0));
782 return (((_dos_findfirst(WXSTRINGCAST dir
, _A_SUBDIR
, &fileInfo
) == 0) && (fileInfo
.attrib
& _A_SUBDIR
)) != 0);
787 wxString WXDLLEXPORT
wxGetWindowText(WXHWND hWnd
)
790 int len
= GetWindowTextLength((HWND
)hWnd
) + 1;
791 GetWindowText((HWND
)hWnd
, str
.GetWriteBuf(len
), len
);
798 //------------------------------------------------------------------------
799 // wild character routines
800 //------------------------------------------------------------------------
802 bool wxIsWild( const wxString
& pattern
)
804 wxString tmp
= pattern
;
805 char *pat
= WXSTRINGCAST(tmp
);
808 case '?': case '*': case '[': case '{':
819 bool wxMatchWild( const wxString
& pat
, const wxString
& text
, bool dot_special
)
822 char *pattern
= WXSTRINGCAST(tmp1
);
823 wxString tmp2
= text
;
824 char *str
= WXSTRINGCAST(tmp2
);
827 bool done
= FALSE
, ret_code
, ok
;
828 // Below is for vi fans
829 const char OB
= '{', CB
= '}';
831 // dot_special means '.' only matches '.'
832 if (dot_special
&& *str
== '.' && *pattern
!= *str
)
835 while ((*pattern
!= '\0') && (!done
)
836 && (((*str
=='\0')&&((*pattern
==OB
)||(*pattern
=='*')))||(*str
!='\0'))) {
840 if (*pattern
!= '\0')
847 && (!(ret_code
=wxMatchWild(pattern
, str
++, FALSE
))))
852 while (*pattern
!= '\0')
859 if ((*pattern
== '\0') || (*pattern
== ']')) {
863 if (*pattern
== '\\') {
865 if (*pattern
== '\0') {
870 if (*(pattern
+ 1) == '-') {
873 if (*pattern
== ']') {
877 if (*pattern
== '\\') {
879 if (*pattern
== '\0') {
884 if ((*str
< c
) || (*str
> *pattern
)) {
888 } else if (*pattern
!= *str
) {
893 while ((*pattern
!= ']') && (*pattern
!= '\0')) {
894 if ((*pattern
== '\\') && (*(pattern
+ 1) != '\0'))
898 if (*pattern
!= '\0') {
908 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
911 while (ok
&& (*cp
!= '\0') && (*pattern
!= '\0')
912 && (*pattern
!= ',') && (*pattern
!= CB
)) {
913 if (*pattern
== '\\')
915 ok
= (*pattern
++ == *cp
++);
917 if (*pattern
== '\0') {
923 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
924 if (*++pattern
== '\\') {
925 if (*++pattern
== CB
)
930 while (*pattern
!=CB
&& *pattern
!=',' && *pattern
!='\0') {
931 if (*++pattern
== '\\') {
932 if (*++pattern
== CB
|| *pattern
== ',')
937 if (*pattern
!= '\0')
942 if (*str
== *pattern
) {
949 while (*pattern
== '*')
951 return ((*str
== '\0') && (*pattern
== '\0'));
956 #if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
959 When I started programming with Visual C++ v4.0, I missed one of my favorite
960 tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
961 on MSDN was a step in the right direction, but it is a console application
962 and thus has limited features and extensibility. DBWIN32 is my creation
963 to solve this problem.
965 The code is essentially a merging of a stripped down version of the DBWIN code
966 from VC 1.5 and DBMON.C with a few 32 bit changes.
968 As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
969 built into the operating system and works just by running DBWIN32. The Win95
970 team decided not to support this hook, so I have provided code that will do
971 this for you. See the file WIN95.TXT for instructions on installing this.
973 If you have questions, problems or suggestions about DBWIN32, I welcome your
974 feedback and plan to actively maintain the code.
979 To download dbwin32, see e.g.:
981 http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
988 void OutputDebugStringW95(const char* lpOutputString
, ...)
990 HANDLE heventDBWIN
; /* DBWIN32 synchronization object */
991 HANDLE heventData
; /* data passing synch object */
992 HANDLE hSharedFile
; /* memory mapped file shared data */
996 /* create the output buffer */
998 va_start(args
, lpOutputString
);
999 vsprintf(achBuffer
, lpOutputString
, args
);
1003 Do a regular OutputDebugString so that the output is
1004 still seen in the debugger window if it exists.
1006 This ifdef is necessary to avoid infinite recursion
1007 from the inclusion of W95TRACE.H
1010 ::OutputDebugStringW(achBuffer
);
1012 ::OutputDebugStringA(achBuffer
);
1015 /* bail if it's not Win95 */
1017 OSVERSIONINFO VerInfo
;
1018 VerInfo
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
1019 GetVersionEx(&VerInfo
);
1020 if ( VerInfo
.dwPlatformId
!= VER_PLATFORM_WIN32_WINDOWS
)
1024 /* make sure DBWIN is open and waiting */
1025 heventDBWIN
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_BUFFER_READY");
1028 //MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
1032 /* get a handle to the data synch object */
1033 heventData
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_DATA_READY");
1036 // MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
1037 CloseHandle(heventDBWIN
);
1041 hSharedFile
= CreateFileMapping((HANDLE
)-1, NULL
, PAGE_READWRITE
, 0, 4096, "DBWIN_BUFFER");
1044 //MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
1045 CloseHandle(heventDBWIN
);
1046 CloseHandle(heventData
);
1050 lpszSharedMem
= (LPSTR
)MapViewOfFile(hSharedFile
, FILE_MAP_WRITE
, 0, 0, 512);
1053 //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
1054 CloseHandle(heventDBWIN
);
1055 CloseHandle(heventData
);
1059 /* wait for buffer event */
1060 WaitForSingleObject(heventDBWIN
, INFINITE
);
1062 /* write it to the shared memory */
1063 #if defined( __BORLANDC__ ) || defined( __MWERKS__ )
1064 *((LPDWORD
)lpszSharedMem
) = getpid();
1066 *((LPDWORD
)lpszSharedMem
) = _getpid();
1069 wsprintf(lpszSharedMem
+ sizeof(DWORD
), "%s", achBuffer
);
1071 /* signal data ready event */
1072 SetEvent(heventData
);
1074 /* clean up handles */
1075 CloseHandle(hSharedFile
);
1076 CloseHandle(heventData
);
1077 CloseHandle(heventDBWIN
);
1086 #ifdef wxUSE_VC_CRTDBG
1088 // maximum mumber of lines the output console should have
1089 static const WORD MAX_CONSOLE_LINES
= 500;
1091 BOOL WINAPI
MyConsoleHandler( DWORD dwCtrlType
) { // control signal type
1096 void wxRedirectIOToConsole()
1100 CONSOLE_SCREEN_BUFFER_INFO coninfo
;
1103 // allocate a console for this app
1106 // set the screen buffer to be big enough to let us scroll text
1107 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE
),
1109 coninfo
.dwSize
.Y
= MAX_CONSOLE_LINES
;
1110 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE
),
1113 // redirect unbuffered STDOUT to the console
1114 lStdHandle
= (long)GetStdHandle(STD_OUTPUT_HANDLE
);
1115 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1116 if(hConHandle
<= 0) return;
1117 fp
= _fdopen( hConHandle
, "w" );
1119 setvbuf( stdout
, NULL
, _IONBF
, 0 );
1121 // redirect unbuffered STDIN to the console
1122 lStdHandle
= (long)GetStdHandle(STD_INPUT_HANDLE
);
1123 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1124 if(hConHandle
<= 0) return;
1125 fp
= _fdopen( hConHandle
, "r" );
1127 setvbuf( stdin
, NULL
, _IONBF
, 0 );
1129 // redirect unbuffered STDERR to the console
1130 lStdHandle
= (long)GetStdHandle(STD_ERROR_HANDLE
);
1131 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1132 if(hConHandle
<= 0) return;
1133 fp
= _fdopen( hConHandle
, "w" );
1135 setvbuf( stderr
, NULL
, _IONBF
, 0 );
1137 // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
1138 // point to console as well
1139 ios::sync_with_stdio();
1141 SetConsoleCtrlHandler(MyConsoleHandler
, TRUE
);
1146 void wxRedirectIOToConsole()