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(__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.
71 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
77 //// BEGIN for console support: VC++ only
79 #if defined(__WXDEBUG__) && !defined(__WIN16__) && defined(_MSC_VER) && !defined(__NO_VC_CRTDBG__)
80 #define wxUSE_VC_CRTDBG
82 #undef wxUSE_VC_CRTDBG
85 #ifdef wxUSE_VC_CRTDBG
86 // VC++ uses this macro as debug/release mode indicator
94 // N.B. BC++ doesn't have istream.h, ostream.h
95 # include <iostream.h>
108 /* Need to undef new if including crtdbg.h */
117 # if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS && wxUSE_DEBUG_NEW_ALWAYS
118 # define new new(__FILE__,__LINE__)
123 /// END for console support
125 // In the WIN.INI file
126 static const char WX_SECTION
[] = "wxWindows";
127 static const char eHOSTNAME
[] = "HostName";
128 static const char eUSERID
[] = "UserId";
129 static const char eUSERNAME
[] = "UserName";
131 // For the following functions we SHOULD fill in support
132 // for Windows-NT (which I don't know) as I assume it begin
133 // a POSIX Unix (so claims MS) that it has some special
134 // functions beyond those provided by WinSock
136 // Get full hostname (eg. DoDo.BSn-Germany.crg.de)
137 bool wxGetHostName(char *buf
, int maxSize
)
139 #if defined(__WIN32__) && !defined(__TWIN32__)
140 DWORD nSize
= maxSize
;
141 return (::GetComputerName(buf
, &nSize
) != 0);
144 const char *default_host
= "noname";
146 if ((sysname
= getenv("SYSTEM_NAME")) == NULL
) {
147 GetProfileString(WX_SECTION
, eHOSTNAME
, default_host
, buf
, maxSize
- 1);
149 strncpy(buf
, sysname
, maxSize
- 1);
151 return *buf
? TRUE
: FALSE
;
155 // Get user ID e.g. jacs
156 bool wxGetUserId(char *buf
, int maxSize
)
158 #if defined(__WIN32__) && !defined(__win32s__) && !defined(__TWIN32__)
160 // VZ: why should it be so complicated??
162 // Gets the current user's full name according to the MS article PSS ID
164 // Seems to be the same as the login name for me?
165 char *UserName
= new char[256];
166 char *Domain
= new char[256];
167 DWORD maxCharacters
= 255;
168 GetUserName( UserName
, &maxCharacters
);
169 GetComputerName( Domain
, &maxCharacters
);
171 WCHAR wszUserName
[256]; // Unicode user name
172 WCHAR wszDomain
[256];
175 struct _SERVER_INFO_100
*si100
; // Server structure
176 struct _USER_INFO_2
*ui
; // User structure
178 // Convert ASCII user name and domain to Unicode.
180 MultiByteToWideChar( CP_ACP
, 0, UserName
,
181 strlen(UserName
)+1, wszUserName
, sizeof(wszUserName
) );
182 MultiByteToWideChar( CP_ACP
, 0, Domain
,
183 strlen(Domain
)+1, wszDomain
, sizeof(wszDomain
) );
185 // Get the computer name of a DC for the specified domain.
186 // >If you get a link error on this, include netapi32.lib<
188 NetGetDCName( NULL
, wszDomain
, &ComputerName
);
190 // Look up the user on the DC.
192 if(NetUserGetInfo( (LPWSTR
) ComputerName
,
193 (LPWSTR
) &wszUserName
, 2, (LPBYTE
*) &ui
))
195 printf( "Error getting user information.\n" );
199 // Convert the Unicode full name to ASCII.
201 WideCharToMultiByte( CP_ACP
, 0, ui
->usri2_full_name
,
202 -1, buf
, 256, NULL
, NULL
);
206 DWORD nSize
= maxSize
;
207 if ( ::GetUserName(buf
, &nSize
) == 0 )
209 wxLogSysError("Can not get user name");
217 #else // Win16 or Win32s
219 const char *default_id
= "anonymous";
221 // Can't assume we have NIS (PC-NFS) or some other ID daemon
223 if ( (user
= getenv("USER")) == NULL
&&
224 (user
= getenv("LOGNAME")) == NULL
) {
225 // Use wxWindows configuration data (comming soon)
226 GetProfileString(WX_SECTION
, eUSERID
, default_id
, buf
, maxSize
- 1);
228 strncpy(buf
, user
, maxSize
- 1);
229 return *buf
? TRUE
: FALSE
;
233 // Get user name e.g. Julian Smart
234 bool wxGetUserName(char *buf
, int maxSize
)
236 #if wxUSE_PENWINDOWS && !defined(__WATCOMC__) && !defined(__GNUWIN32__)
237 extern HANDLE g_hPenWin
; // PenWindows Running?
240 // PenWindows Does have a user concept!
241 // Get the current owner of the recognizer
242 GetPrivateProfileString("Current", "User", default_name
, wxBuffer
, maxSize
- 1, "PENWIN.INI");
243 strncpy(buf
, wxBuffer
, maxSize
- 1);
248 // Could use NIS, MS-Mail or other site specific programs
249 // Use wxWindows configuration data
250 bool ok
= GetProfileString(WX_SECTION
, eUSERNAME
, "", buf
, maxSize
- 1) != 0;
253 ok
= wxGetUserId(buf
, maxSize
);
258 strncpy(buf
, "Unknown User", maxSize
);
265 int wxKill(long pid
, int sig
)
271 // Execute a program in an Interactive Shell
274 wxShell(const wxString
& command
)
277 if ((shell
= getenv("COMSPEC")) == NULL
)
278 shell
= "\\COMMAND.COM";
282 sprintf(tmp
, "%s /c %s", shell
, WXSTRINGCAST command
);
286 return (wxExecute((char *)tmp
, FALSE
) != 0);
289 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
290 long wxGetFreeMemory(void)
292 #if defined(__WIN32__) && !defined(__BORLANDC__) && !defined(__TWIN32__)
293 MEMORYSTATUS memStatus
;
294 memStatus
.dwLength
= sizeof(MEMORYSTATUS
);
295 GlobalMemoryStatus(&memStatus
);
296 return memStatus
.dwAvailPhys
;
298 return (long)GetFreeSpace(0);
302 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
303 static bool inTimer
= FALSE
;
304 class wxSleepTimer
: public wxTimer
307 inline void Notify(void)
314 static wxTimer
*wxTheSleepTimer
= NULL
;
316 void wxSleep(int nSecs
)
318 #if 0 // WIN32 hangs app
324 wxTheSleepTimer
= new wxSleepTimer
;
326 wxTheSleepTimer
->Start(nSecs
*1000);
329 if (wxTheApp
->Pending())
330 wxTheApp
->Dispatch();
332 delete wxTheSleepTimer
;
333 wxTheSleepTimer
= NULL
;
337 // Consume all events until no more left
338 void wxFlushEvents(void)
343 // Output a debug mess., in a system dependent fashion.
344 void wxDebugMsg(const char *fmt
...)
347 static char buffer
[512];
349 if (!wxTheApp
->GetWantDebugOutput())
354 wvsprintf(buffer
,fmt
,ap
) ;
355 OutputDebugString((LPCSTR
)buffer
) ;
360 // Non-fatal error: pop up message box and (possibly) continue
361 void wxError(const wxString
& msg
, const wxString
& title
)
363 sprintf(wxBuffer
, "%s\nContinue?", WXSTRINGCAST msg
);
364 if (MessageBox(NULL
, (LPCSTR
)wxBuffer
, (LPCSTR
)WXSTRINGCAST title
,
365 MB_ICONSTOP
| MB_YESNO
) == IDNO
)
369 // Fatal error: pop up message box and abort
370 void wxFatalError(const wxString
& msg
, const wxString
& title
)
372 sprintf(wxBuffer
, "%s: %s", WXSTRINGCAST title
, WXSTRINGCAST msg
);
373 FatalAppExit(0, (LPCSTR
)wxBuffer
);
379 // Removed by RD because IHMO syncronous sound is a Bad Thing. MessageBeep
380 // will do a similar thing anyway if there is no sound card...
382 // Beep(1000,1000) ; // 1kHz during 1 sec.
384 MessageBeep((UINT
)-1) ;
388 // Chris Breeze 27/5/98: revised WIN32 code to
389 // detect WindowsNT correctly
390 int wxGetOsVersion(int *majorVsn
, int *minorVsn
)
392 extern char *wxOsVersion
;
393 if (majorVsn
) *majorVsn
= 0;
394 if (minorVsn
) *minorVsn
= 0;
396 #if defined(__WIN32__) && !defined(__SC__)
398 memset(&info
, 0, sizeof(OSVERSIONINFO
));
399 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
400 if (GetVersionEx(&info
))
402 if (majorVsn
) *majorVsn
= info
.dwMajorVersion
;
403 if (minorVsn
) *minorVsn
= info
.dwMinorVersion
;
404 switch (info
.dwPlatformId
)
406 case VER_PLATFORM_WIN32s
:
409 case VER_PLATFORM_WIN32_WINDOWS
:
412 case VER_PLATFORM_WIN32_NT
:
417 return wxWINDOWS
; // error if we get here, return generic value
421 # ifdef __WINDOWS_386__
424 # if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
425 extern HANDLE g_hPenWin
;
426 retValue
= g_hPenWin
? wxPENWINDOWS
: wxWINDOWS
;
429 // @@@@ To be completed. I don't have the manual here...
430 if (majorVsn
) *majorVsn
= 3 ;
431 if (minorVsn
) *minorVsn
= 1 ;
436 // Reading and writing resources (eg WIN.INI, .Xdefaults)
438 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
)
441 return (WritePrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)value
, (LPCSTR
)WXSTRINGCAST file
) != 0);
443 return (WriteProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)WXSTRINGCAST value
) != 0);
446 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
)
449 sprintf(buf
, "%.4f", value
);
450 return wxWriteResource(section
, entry
, buf
, file
);
453 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
)
456 sprintf(buf
, "%ld", value
);
457 return wxWriteResource(section
, entry
, buf
, file
);
460 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
)
463 sprintf(buf
, "%d", value
);
464 return wxWriteResource(section
, entry
, buf
, file
);
467 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
)
469 static const char defunkt
[] = "$$default";
472 int n
= GetPrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
473 (LPSTR
)wxBuffer
, 1000, (LPCSTR
)WXSTRINGCAST file
);
474 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
479 int n
= GetProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
480 (LPSTR
)wxBuffer
, 1000);
481 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
484 if (*value
) delete[] (*value
);
485 *value
= copystring(wxBuffer
);
489 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
)
492 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
495 *value
= (float)strtod(s
, NULL
);
502 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
)
505 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
508 *value
= strtol(s
, NULL
, 10);
515 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
)
518 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
521 *value
= (int)strtol(s
, NULL
, 10);
527 #endif // wxUSE_RESOURCES
530 static HCURSOR wxBusyCursorOld
= 0;
531 static int wxBusyCursorCount
= 0;
533 // Set the cursor to the busy cursor for all windows
534 void wxBeginBusyCursor(wxCursor
*cursor
)
536 wxBusyCursorCount
++;
537 if (wxBusyCursorCount
== 1)
539 wxBusyCursorOld
= ::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
543 (void)::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
547 // Restore cursor to normal
548 void wxEndBusyCursor(void)
550 if (wxBusyCursorCount
== 0)
553 wxBusyCursorCount
--;
554 if (wxBusyCursorCount
== 0)
556 ::SetCursor(wxBusyCursorOld
);
561 // TRUE if we're between the above two calls
564 return (wxBusyCursorCount
> 0);
567 const char* wxGetHomeDir(wxString
*pstr
)
569 wxString
& strDir
= *pstr
;
571 #if defined(__UNIX__) && !defined(__TWIN32__)
572 const char *szHome
= getenv("HOME");
573 if ( szHome
== NULL
) {
575 wxLogWarning(_("can't find user's HOME, using current directory."));
581 // add a trailing slash if needed
582 if ( strDir
.Last() != '/' )
586 const char *szHome
= getenv("HOMEDRIVE");
587 if ( szHome
!= NULL
)
589 szHome
= getenv("HOMEPATH");
590 if ( szHome
!= NULL
) {
593 // the idea is that under NT these variables have default values
594 // of "%systemdrive%:" and "\\". As we don't want to create our
595 // config files in the root directory of the system drive, we will
596 // create it in our program's dir. However, if the user took care
597 // to set HOMEPATH to something other than "\\", we suppose that he
598 // knows what he is doing and use the supplied value.
599 if ( strcmp(szHome
, "\\") != 0 )
600 return strDir
.c_str();
604 // Win16 has no idea about home, so use the working directory instead
607 // 260 was taken from windef.h
613 ::GetModuleFileName(::GetModuleHandle(NULL
),
614 strPath
.GetWriteBuf(MAX_PATH
), MAX_PATH
);
615 strPath
.UngetWriteBuf();
617 // extract the dir name
618 wxSplitPath(strPath
, &strDir
, NULL
, NULL
);
622 return strDir
.c_str();
626 char *wxGetUserHome (const wxString
& user
)
629 wxString
user1(user
);
633 if (wxGetUserId(tmp
, sizeof(tmp
)/sizeof(char))) {
634 // Guests belong in the temp dir
635 if (Stricmp(tmp
, "annonymous") == 0) {
636 if ((home
= getenv("TMP")) != NULL
||
637 (home
= getenv("TMPDIR")) != NULL
||
638 (home
= getenv("TEMP")) != NULL
)
639 return *home
? home
: "\\";
641 if (Stricmp(tmp
, WXSTRINGCAST user1
) == 0)
646 if ((home
= getenv("HOME")) != NULL
)
648 strcpy(wxBuffer
, home
);
649 Unix2DosFilename(wxBuffer
);
652 return NULL
; // No home known!
655 // Check whether this window wants to process messages, e.g. Stop button
656 // in long calculations.
657 bool wxCheckForInterrupt(wxWindow
*wnd
)
661 HWND win
= (HWND
) wnd
->GetHWND();
662 while(PeekMessage(&msg
,win
,0,0,PM_REMOVE
)){
663 TranslateMessage(&msg
);
664 DispatchMessage(&msg
);
666 return TRUE
;//*** temporary?
669 wxError("wnd==NULL !!!");
670 return FALSE
;//*** temporary?
674 // MSW only: get user-defined resource from the .res file.
675 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
678 char *wxLoadUserResource(const wxString
& resourceName
, const wxString
& resourceType
)
681 #if !defined(__WIN32__) || defined(__TWIN32__)
682 HRSRC hResource
= ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
685 HRSRC hResource
= ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
687 HRSRC hResource
= ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
693 HGLOBAL hData
= ::LoadResource(wxGetInstance(), hResource
);
696 char *theText
= (char *)LockResource(hData
);
700 s
= copystring(theText
);
704 UnlockResource(hData
);
708 // GlobalFree(hData);
714 void wxGetMousePosition( int* x
, int* y
)
717 GetCursorPos( & pt
);
722 // Return TRUE if we have a colour display
723 bool wxColourDisplay(void)
725 HDC dc
= ::GetDC((HWND
) NULL
);
727 int noCols
= GetDeviceCaps(dc
, NUMCOLORS
);
728 if ((noCols
== -1) || (noCols
> 2))
732 ReleaseDC((HWND
) NULL
, dc
);
736 // Returns depth of screen
737 int wxDisplayDepth(void)
739 HDC dc
= ::GetDC((HWND
) NULL
);
740 int planes
= GetDeviceCaps(dc
, PLANES
);
741 int bitsPerPixel
= GetDeviceCaps(dc
, BITSPIXEL
);
742 int depth
= planes
*bitsPerPixel
;
743 ReleaseDC((HWND
) NULL
, dc
);
747 // Get size of display
748 void wxDisplaySize(int *width
, int *height
)
750 HDC dc
= ::GetDC((HWND
) NULL
);
751 *width
= GetDeviceCaps(dc
, HORZRES
); *height
= GetDeviceCaps(dc
, VERTRES
);
752 ReleaseDC((HWND
) NULL
, dc
);
755 bool wxDirExists(const wxString
& dir
)
757 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
758 #if defined(__WIN32__)
759 WIN32_FIND_DATA fileInfo
;
762 struct ffblk fileInfo
;
764 struct find_t fileInfo
;
768 #if defined(__WIN32__)
769 HANDLE h
= FindFirstFile((LPTSTR
) WXSTRINGCAST dir
,(LPWIN32_FIND_DATA
)&fileInfo
);
771 if (h
==INVALID_HANDLE_VALUE
)
775 return ((fileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) == FILE_ATTRIBUTE_DIRECTORY
);
778 // In Borland findfirst has a different argument
779 // ordering from _dos_findfirst. But _dos_findfirst
780 // _should_ be ok in both MS and Borland... why not?
782 return ((findfirst(WXSTRINGCAST dir
, &fileInfo
, _A_SUBDIR
) == 0 && (fileInfo
.ff_attrib
& _A_SUBDIR
) != 0));
784 return (((_dos_findfirst(WXSTRINGCAST dir
, _A_SUBDIR
, &fileInfo
) == 0) && (fileInfo
.attrib
& _A_SUBDIR
)) != 0);
789 wxString WXDLLEXPORT
wxGetWindowText(WXHWND hWnd
)
792 int len
= GetWindowTextLength((HWND
)hWnd
) + 1;
793 GetWindowText((HWND
)hWnd
, str
.GetWriteBuf(len
), len
);
800 //------------------------------------------------------------------------
801 // wild character routines
802 //------------------------------------------------------------------------
804 bool wxIsWild( const wxString
& pattern
)
806 wxString tmp
= pattern
;
807 char *pat
= WXSTRINGCAST(tmp
);
810 case '?': case '*': case '[': case '{':
821 bool wxMatchWild( const wxString
& pat
, const wxString
& text
, bool dot_special
)
824 char *pattern
= WXSTRINGCAST(tmp1
);
825 wxString tmp2
= text
;
826 char *str
= WXSTRINGCAST(tmp2
);
829 bool done
= FALSE
, ret_code
, ok
;
830 // Below is for vi fans
831 const char OB
= '{', CB
= '}';
833 // dot_special means '.' only matches '.'
834 if (dot_special
&& *str
== '.' && *pattern
!= *str
)
837 while ((*pattern
!= '\0') && (!done
)
838 && (((*str
=='\0')&&((*pattern
==OB
)||(*pattern
=='*')))||(*str
!='\0'))) {
842 if (*pattern
!= '\0')
849 && (!(ret_code
=wxMatchWild(pattern
, str
++, FALSE
))))
854 while (*pattern
!= '\0')
861 if ((*pattern
== '\0') || (*pattern
== ']')) {
865 if (*pattern
== '\\') {
867 if (*pattern
== '\0') {
872 if (*(pattern
+ 1) == '-') {
875 if (*pattern
== ']') {
879 if (*pattern
== '\\') {
881 if (*pattern
== '\0') {
886 if ((*str
< c
) || (*str
> *pattern
)) {
890 } else if (*pattern
!= *str
) {
895 while ((*pattern
!= ']') && (*pattern
!= '\0')) {
896 if ((*pattern
== '\\') && (*(pattern
+ 1) != '\0'))
900 if (*pattern
!= '\0') {
910 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
913 while (ok
&& (*cp
!= '\0') && (*pattern
!= '\0')
914 && (*pattern
!= ',') && (*pattern
!= CB
)) {
915 if (*pattern
== '\\')
917 ok
= (*pattern
++ == *cp
++);
919 if (*pattern
== '\0') {
925 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
926 if (*++pattern
== '\\') {
927 if (*++pattern
== CB
)
932 while (*pattern
!=CB
&& *pattern
!=',' && *pattern
!='\0') {
933 if (*++pattern
== '\\') {
934 if (*++pattern
== CB
|| *pattern
== ',')
939 if (*pattern
!= '\0')
944 if (*str
== *pattern
) {
951 while (*pattern
== '*')
953 return ((*str
== '\0') && (*pattern
== '\0'));
958 #if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
961 When I started programming with Visual C++ v4.0, I missed one of my favorite
962 tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
963 on MSDN was a step in the right direction, but it is a console application
964 and thus has limited features and extensibility. DBWIN32 is my creation
965 to solve this problem.
967 The code is essentially a merging of a stripped down version of the DBWIN code
968 from VC 1.5 and DBMON.C with a few 32 bit changes.
970 As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
971 built into the operating system and works just by running DBWIN32. The Win95
972 team decided not to support this hook, so I have provided code that will do
973 this for you. See the file WIN95.TXT for instructions on installing this.
975 If you have questions, problems or suggestions about DBWIN32, I welcome your
976 feedback and plan to actively maintain the code.
981 To download dbwin32, see e.g.:
983 http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
986 #if !defined(__MWERKS__) && !defined(__SALFORDC__) && !defined(__TWIN32__)
990 void OutputDebugStringW95(const char* lpOutputString
, ...)
992 HANDLE heventDBWIN
; /* DBWIN32 synchronization object */
993 HANDLE heventData
; /* data passing synch object */
994 HANDLE hSharedFile
; /* memory mapped file shared data */
998 /* create the output buffer */
1000 va_start(args
, lpOutputString
);
1001 vsprintf(achBuffer
, lpOutputString
, args
);
1005 Do a regular OutputDebugString so that the output is
1006 still seen in the debugger window if it exists.
1008 This ifdef is necessary to avoid infinite recursion
1009 from the inclusion of W95TRACE.H
1012 ::OutputDebugStringW(achBuffer
);
1015 ::OutputDebugString(achBuffer
);
1017 ::OutputDebugStringA(achBuffer
);
1021 /* bail if it's not Win95 */
1023 OSVERSIONINFO VerInfo
;
1024 VerInfo
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
1025 GetVersionEx(&VerInfo
);
1026 if ( VerInfo
.dwPlatformId
!= VER_PLATFORM_WIN32_WINDOWS
)
1030 /* make sure DBWIN is open and waiting */
1031 heventDBWIN
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_BUFFER_READY");
1034 //MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
1038 /* get a handle to the data synch object */
1039 heventData
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_DATA_READY");
1042 // MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
1043 CloseHandle(heventDBWIN
);
1047 hSharedFile
= CreateFileMapping((HANDLE
)-1, NULL
, PAGE_READWRITE
, 0, 4096, "DBWIN_BUFFER");
1050 //MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
1051 CloseHandle(heventDBWIN
);
1052 CloseHandle(heventData
);
1056 lpszSharedMem
= (LPSTR
)MapViewOfFile(hSharedFile
, FILE_MAP_WRITE
, 0, 0, 512);
1059 //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
1060 CloseHandle(heventDBWIN
);
1061 CloseHandle(heventData
);
1065 /* wait for buffer event */
1066 WaitForSingleObject(heventDBWIN
, INFINITE
);
1068 /* write it to the shared memory */
1069 #if defined( __BORLANDC__ ) || defined( __MWERKS__ ) || defined(__SALFORDC__)
1070 *((LPDWORD
)lpszSharedMem
) = getpid();
1072 *((LPDWORD
)lpszSharedMem
) = _getpid();
1075 wsprintf(lpszSharedMem
+ sizeof(DWORD
), "%s", achBuffer
);
1077 /* signal data ready event */
1078 SetEvent(heventData
);
1080 /* clean up handles */
1081 CloseHandle(hSharedFile
);
1082 CloseHandle(heventData
);
1083 CloseHandle(heventDBWIN
);
1092 #ifdef wxUSE_VC_CRTDBG
1094 // maximum mumber of lines the output console should have
1095 static const WORD MAX_CONSOLE_LINES
= 500;
1097 BOOL WINAPI
MyConsoleHandler( DWORD dwCtrlType
) { // control signal type
1102 void wxRedirectIOToConsole()
1106 CONSOLE_SCREEN_BUFFER_INFO coninfo
;
1109 // allocate a console for this app
1112 // set the screen buffer to be big enough to let us scroll text
1113 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE
),
1115 coninfo
.dwSize
.Y
= MAX_CONSOLE_LINES
;
1116 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE
),
1119 // redirect unbuffered STDOUT to the console
1120 lStdHandle
= (long)GetStdHandle(STD_OUTPUT_HANDLE
);
1121 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1122 if(hConHandle
<= 0) return;
1123 fp
= _fdopen( hConHandle
, "w" );
1125 setvbuf( stdout
, NULL
, _IONBF
, 0 );
1127 // redirect unbuffered STDIN to the console
1128 lStdHandle
= (long)GetStdHandle(STD_INPUT_HANDLE
);
1129 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1130 if(hConHandle
<= 0) return;
1131 fp
= _fdopen( hConHandle
, "r" );
1133 setvbuf( stdin
, NULL
, _IONBF
, 0 );
1135 // redirect unbuffered STDERR to the console
1136 lStdHandle
= (long)GetStdHandle(STD_ERROR_HANDLE
);
1137 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1138 if(hConHandle
<= 0) return;
1139 fp
= _fdopen( hConHandle
, "w" );
1141 setvbuf( stderr
, NULL
, _IONBF
, 0 );
1143 // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
1144 // point to console as well
1145 ios::sync_with_stdio();
1147 SetConsoleCtrlHandler(MyConsoleHandler
, TRUE
);
1152 void wxRedirectIOToConsole()