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 #include "wx/msw/msvcrt.h"
83 #include "wx/ioswrap.h"
86 // N.B. BC++ doesn't have istream.h, ostream.h
93 /* Need to undef new if including crtdbg.h */
102 # if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS && wxUSE_DEBUG_NEW_ALWAYS
103 # define new new(__FILE__,__LINE__)
106 /// END for console support
108 // In the WIN.INI file
109 static const char WX_SECTION
[] = "wxWindows";
110 static const char eHOSTNAME
[] = "HostName";
111 static const char eUSERID
[] = "UserId";
112 static const char eUSERNAME
[] = "UserName";
114 // For the following functions we SHOULD fill in support
115 // for Windows-NT (which I don't know) as I assume it begin
116 // a POSIX Unix (so claims MS) that it has some special
117 // functions beyond those provided by WinSock
119 // Get full hostname (eg. DoDo.BSn-Germany.crg.de)
120 bool wxGetHostName(char *buf
, int maxSize
)
122 #if defined(__WIN32__) && !defined(__TWIN32__)
123 DWORD nSize
= maxSize
;
124 return (::GetComputerName(buf
, &nSize
) != 0);
127 const char *default_host
= "noname";
129 if ((sysname
= getenv("SYSTEM_NAME")) == NULL
) {
130 GetProfileString(WX_SECTION
, eHOSTNAME
, default_host
, buf
, maxSize
- 1);
132 strncpy(buf
, sysname
, maxSize
- 1);
134 return *buf
? TRUE
: FALSE
;
138 // Get user ID e.g. jacs
139 bool wxGetUserId(char *buf
, int maxSize
)
141 #if defined(__WIN32__) && !defined(__win32s__) && !defined(__TWIN32__)
143 // VZ: why should it be so complicated??
145 // Gets the current user's full name according to the MS article PSS ID
147 // Seems to be the same as the login name for me?
148 char *UserName
= new char[256];
149 char *Domain
= new char[256];
150 DWORD maxCharacters
= 255;
151 GetUserName( UserName
, &maxCharacters
);
152 GetComputerName( Domain
, &maxCharacters
);
154 WCHAR wszUserName
[256]; // Unicode user name
155 WCHAR wszDomain
[256];
158 struct _SERVER_INFO_100
*si100
; // Server structure
159 struct _USER_INFO_2
*ui
; // User structure
161 // Convert ASCII user name and domain to Unicode.
163 MultiByteToWideChar( CP_ACP
, 0, UserName
,
164 strlen(UserName
)+1, wszUserName
, sizeof(wszUserName
) );
165 MultiByteToWideChar( CP_ACP
, 0, Domain
,
166 strlen(Domain
)+1, wszDomain
, sizeof(wszDomain
) );
168 // Get the computer name of a DC for the specified domain.
169 // >If you get a link error on this, include netapi32.lib<
171 NetGetDCName( NULL
, wszDomain
, &ComputerName
);
173 // Look up the user on the DC.
175 if(NetUserGetInfo( (LPWSTR
) ComputerName
,
176 (LPWSTR
) &wszUserName
, 2, (LPBYTE
*) &ui
))
178 printf( "Error getting user information.\n" );
182 // Convert the Unicode full name to ASCII.
184 WideCharToMultiByte( CP_ACP
, 0, ui
->usri2_full_name
,
185 -1, buf
, 256, NULL
, NULL
);
189 DWORD nSize
= maxSize
;
190 if ( ::GetUserName(buf
, &nSize
) == 0 )
192 wxLogSysError("Can not get user name");
200 #else // Win16 or Win32s
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 #if wxUSE_PENWINDOWS && !defined(__WATCOMC__) && !defined(__GNUWIN32__)
220 extern HANDLE g_hPenWin
; // PenWindows Running?
223 // PenWindows Does have a user concept!
224 // Get the current owner of the recognizer
225 GetPrivateProfileString("Current", "User", default_name
, wxBuffer
, maxSize
- 1, "PENWIN.INI");
226 strncpy(buf
, wxBuffer
, maxSize
- 1);
231 // Could use NIS, MS-Mail or other site specific programs
232 // Use wxWindows configuration data
233 bool ok
= GetProfileString(WX_SECTION
, eUSERNAME
, "", buf
, maxSize
- 1) != 0;
236 ok
= wxGetUserId(buf
, maxSize
);
241 strncpy(buf
, "Unknown User", maxSize
);
248 int wxKill(long pid
, int sig
)
254 // Execute a program in an Interactive Shell
257 wxShell(const wxString
& command
)
260 if ((shell
= getenv("COMSPEC")) == NULL
)
261 shell
= "\\COMMAND.COM";
265 sprintf(tmp
, "%s /c %s", shell
, WXSTRINGCAST command
);
269 return (wxExecute((char *)tmp
, FALSE
) != 0);
272 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
273 long wxGetFreeMemory(void)
275 #if defined(__WIN32__) && !defined(__BORLANDC__) && !defined(__TWIN32__)
276 MEMORYSTATUS memStatus
;
277 memStatus
.dwLength
= sizeof(MEMORYSTATUS
);
278 GlobalMemoryStatus(&memStatus
);
279 return memStatus
.dwAvailPhys
;
281 return (long)GetFreeSpace(0);
285 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
286 static bool inTimer
= FALSE
;
287 class wxSleepTimer
: public wxTimer
290 inline void Notify(void)
297 static wxTimer
*wxTheSleepTimer
= NULL
;
299 void wxSleep(int nSecs
)
301 #if 0 // WIN32 hangs app
307 wxTheSleepTimer
= new wxSleepTimer
;
309 wxTheSleepTimer
->Start(nSecs
*1000);
312 if (wxTheApp
->Pending())
313 wxTheApp
->Dispatch();
315 delete wxTheSleepTimer
;
316 wxTheSleepTimer
= NULL
;
320 // Consume all events until no more left
321 void wxFlushEvents(void)
326 // Output a debug mess., in a system dependent fashion.
327 void wxDebugMsg(const char *fmt
...)
330 static char buffer
[512];
332 if (!wxTheApp
->GetWantDebugOutput())
337 wvsprintf(buffer
,fmt
,ap
) ;
338 OutputDebugString((LPCSTR
)buffer
) ;
343 // Non-fatal error: pop up message box and (possibly) continue
344 void wxError(const wxString
& msg
, const wxString
& title
)
346 sprintf(wxBuffer
, "%s\nContinue?", WXSTRINGCAST msg
);
347 if (MessageBox(NULL
, (LPCSTR
)wxBuffer
, (LPCSTR
)WXSTRINGCAST title
,
348 MB_ICONSTOP
| MB_YESNO
) == IDNO
)
352 // Fatal error: pop up message box and abort
353 void wxFatalError(const wxString
& msg
, const wxString
& title
)
355 sprintf(wxBuffer
, "%s: %s", WXSTRINGCAST title
, WXSTRINGCAST msg
);
356 FatalAppExit(0, (LPCSTR
)wxBuffer
);
362 // Removed by RD because IHMO syncronous sound is a Bad Thing. MessageBeep
363 // will do a similar thing anyway if there is no sound card...
365 // Beep(1000,1000) ; // 1kHz during 1 sec.
367 MessageBeep((UINT
)-1) ;
371 // Chris Breeze 27/5/98: revised WIN32 code to
372 // detect WindowsNT correctly
373 int wxGetOsVersion(int *majorVsn
, int *minorVsn
)
375 extern char *wxOsVersion
;
376 if (majorVsn
) *majorVsn
= 0;
377 if (minorVsn
) *minorVsn
= 0;
379 #if defined(__WIN32__) && !defined(__SC__)
381 memset(&info
, 0, sizeof(OSVERSIONINFO
));
382 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
383 if (GetVersionEx(&info
))
385 if (majorVsn
) *majorVsn
= info
.dwMajorVersion
;
386 if (minorVsn
) *minorVsn
= info
.dwMinorVersion
;
387 switch (info
.dwPlatformId
)
389 case VER_PLATFORM_WIN32s
:
392 case VER_PLATFORM_WIN32_WINDOWS
:
395 case VER_PLATFORM_WIN32_NT
:
400 return wxWINDOWS
; // error if we get here, return generic value
404 # ifdef __WINDOWS_386__
407 # if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
408 extern HANDLE g_hPenWin
;
409 retValue
= g_hPenWin
? wxPENWINDOWS
: wxWINDOWS
;
412 // @@@@ To be completed. I don't have the manual here...
413 if (majorVsn
) *majorVsn
= 3 ;
414 if (minorVsn
) *minorVsn
= 1 ;
419 // Reading and writing resources (eg WIN.INI, .Xdefaults)
421 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
)
424 return (WritePrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)value
, (LPCSTR
)WXSTRINGCAST file
) != 0);
426 return (WriteProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)WXSTRINGCAST value
) != 0);
429 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
)
432 sprintf(buf
, "%.4f", value
);
433 return wxWriteResource(section
, entry
, buf
, file
);
436 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
)
439 sprintf(buf
, "%ld", value
);
440 return wxWriteResource(section
, entry
, buf
, file
);
443 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
)
446 sprintf(buf
, "%d", value
);
447 return wxWriteResource(section
, entry
, buf
, file
);
450 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
)
452 static const char defunkt
[] = "$$default";
455 int n
= GetPrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
456 (LPSTR
)wxBuffer
, 1000, (LPCSTR
)WXSTRINGCAST file
);
457 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
462 int n
= GetProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
463 (LPSTR
)wxBuffer
, 1000);
464 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
467 if (*value
) delete[] (*value
);
468 *value
= copystring(wxBuffer
);
472 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
)
475 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
478 *value
= (float)strtod(s
, NULL
);
485 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
)
488 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
491 *value
= strtol(s
, NULL
, 10);
498 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
)
501 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
504 *value
= (int)strtol(s
, NULL
, 10);
510 #endif // wxUSE_RESOURCES
513 static HCURSOR wxBusyCursorOld
= 0;
514 static int wxBusyCursorCount
= 0;
516 // Set the cursor to the busy cursor for all windows
517 void wxBeginBusyCursor(wxCursor
*cursor
)
519 wxBusyCursorCount
++;
520 if (wxBusyCursorCount
== 1)
522 wxBusyCursorOld
= ::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
526 (void)::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
530 // Restore cursor to normal
531 void wxEndBusyCursor(void)
533 if (wxBusyCursorCount
== 0)
536 wxBusyCursorCount
--;
537 if (wxBusyCursorCount
== 0)
539 ::SetCursor(wxBusyCursorOld
);
544 // TRUE if we're between the above two calls
547 return (wxBusyCursorCount
> 0);
550 const char* wxGetHomeDir(wxString
*pstr
)
552 wxString
& strDir
= *pstr
;
554 #if defined(__UNIX__) && !defined(__TWIN32__)
555 const char *szHome
= getenv("HOME");
556 if ( szHome
== NULL
) {
558 wxLogWarning(_("can't find user's HOME, using current directory."));
564 // add a trailing slash if needed
565 if ( strDir
.Last() != '/' )
569 const char *szHome
= getenv("HOMEDRIVE");
570 if ( szHome
!= NULL
)
572 szHome
= getenv("HOMEPATH");
573 if ( szHome
!= NULL
) {
576 // the idea is that under NT these variables have default values
577 // of "%systemdrive%:" and "\\". As we don't want to create our
578 // config files in the root directory of the system drive, we will
579 // create it in our program's dir. However, if the user took care
580 // to set HOMEPATH to something other than "\\", we suppose that he
581 // knows what he is doing and use the supplied value.
582 if ( strcmp(szHome
, "\\") != 0 )
583 return strDir
.c_str();
587 // Win16 has no idea about home, so use the working directory instead
590 // 260 was taken from windef.h
596 ::GetModuleFileName(::GetModuleHandle(NULL
),
597 strPath
.GetWriteBuf(MAX_PATH
), MAX_PATH
);
598 strPath
.UngetWriteBuf();
600 // extract the dir name
601 wxSplitPath(strPath
, &strDir
, NULL
, NULL
);
605 return strDir
.c_str();
609 char *wxGetUserHome (const wxString
& user
)
612 wxString
user1(user
);
616 if (wxGetUserId(tmp
, sizeof(tmp
)/sizeof(char))) {
617 // Guests belong in the temp dir
618 if (Stricmp(tmp
, "annonymous") == 0) {
619 if ((home
= getenv("TMP")) != NULL
||
620 (home
= getenv("TMPDIR")) != NULL
||
621 (home
= getenv("TEMP")) != NULL
)
622 return *home
? home
: "\\";
624 if (Stricmp(tmp
, WXSTRINGCAST user1
) == 0)
629 if ((home
= getenv("HOME")) != NULL
)
631 strcpy(wxBuffer
, home
);
632 Unix2DosFilename(wxBuffer
);
635 return NULL
; // No home known!
638 // Check whether this window wants to process messages, e.g. Stop button
639 // in long calculations.
640 bool wxCheckForInterrupt(wxWindow
*wnd
)
644 HWND win
= (HWND
) wnd
->GetHWND();
645 while(PeekMessage(&msg
,win
,0,0,PM_REMOVE
)){
646 TranslateMessage(&msg
);
647 DispatchMessage(&msg
);
649 return TRUE
;//*** temporary?
652 wxError("wnd==NULL !!!");
653 return FALSE
;//*** temporary?
657 // MSW only: get user-defined resource from the .res file.
658 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
661 char *wxLoadUserResource(const wxString
& resourceName
, const wxString
& resourceType
)
664 #if !defined(__WIN32__) || defined(__TWIN32__)
665 HRSRC hResource
= ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
668 HRSRC hResource
= ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
670 HRSRC hResource
= ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
676 HGLOBAL hData
= ::LoadResource(wxGetInstance(), hResource
);
679 char *theText
= (char *)LockResource(hData
);
683 s
= copystring(theText
);
687 UnlockResource(hData
);
691 // GlobalFree(hData);
697 void wxGetMousePosition( int* x
, int* y
)
700 GetCursorPos( & pt
);
705 // Return TRUE if we have a colour display
706 bool wxColourDisplay(void)
708 HDC dc
= ::GetDC((HWND
) NULL
);
710 int noCols
= GetDeviceCaps(dc
, NUMCOLORS
);
711 if ((noCols
== -1) || (noCols
> 2))
715 ReleaseDC((HWND
) NULL
, dc
);
719 // Returns depth of screen
720 int wxDisplayDepth(void)
722 HDC dc
= ::GetDC((HWND
) NULL
);
723 int planes
= GetDeviceCaps(dc
, PLANES
);
724 int bitsPerPixel
= GetDeviceCaps(dc
, BITSPIXEL
);
725 int depth
= planes
*bitsPerPixel
;
726 ReleaseDC((HWND
) NULL
, dc
);
730 // Get size of display
731 void wxDisplaySize(int *width
, int *height
)
733 HDC dc
= ::GetDC((HWND
) NULL
);
734 *width
= GetDeviceCaps(dc
, HORZRES
); *height
= GetDeviceCaps(dc
, VERTRES
);
735 ReleaseDC((HWND
) NULL
, dc
);
738 bool wxDirExists(const wxString
& dir
)
740 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
741 #if defined(__WIN32__)
742 WIN32_FIND_DATA fileInfo
;
745 struct ffblk fileInfo
;
747 struct find_t fileInfo
;
751 #if defined(__WIN32__)
752 HANDLE h
= FindFirstFile((LPTSTR
) WXSTRINGCAST dir
,(LPWIN32_FIND_DATA
)&fileInfo
);
754 if (h
==INVALID_HANDLE_VALUE
)
758 return ((fileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) == FILE_ATTRIBUTE_DIRECTORY
);
761 // In Borland findfirst has a different argument
762 // ordering from _dos_findfirst. But _dos_findfirst
763 // _should_ be ok in both MS and Borland... why not?
765 return ((findfirst(WXSTRINGCAST dir
, &fileInfo
, _A_SUBDIR
) == 0 && (fileInfo
.ff_attrib
& _A_SUBDIR
) != 0));
767 return (((_dos_findfirst(WXSTRINGCAST dir
, _A_SUBDIR
, &fileInfo
) == 0) && (fileInfo
.attrib
& _A_SUBDIR
)) != 0);
772 wxString WXDLLEXPORT
wxGetWindowText(WXHWND hWnd
)
775 int len
= GetWindowTextLength((HWND
)hWnd
) + 1;
776 GetWindowText((HWND
)hWnd
, str
.GetWriteBuf(len
), len
);
783 //------------------------------------------------------------------------
784 // wild character routines
785 //------------------------------------------------------------------------
787 bool wxIsWild( const wxString
& pattern
)
789 wxString tmp
= pattern
;
790 char *pat
= WXSTRINGCAST(tmp
);
793 case '?': case '*': case '[': case '{':
804 bool wxMatchWild( const wxString
& pat
, const wxString
& text
, bool dot_special
)
807 char *pattern
= WXSTRINGCAST(tmp1
);
808 wxString tmp2
= text
;
809 char *str
= WXSTRINGCAST(tmp2
);
812 bool done
= FALSE
, ret_code
, ok
;
813 // Below is for vi fans
814 const char OB
= '{', CB
= '}';
816 // dot_special means '.' only matches '.'
817 if (dot_special
&& *str
== '.' && *pattern
!= *str
)
820 while ((*pattern
!= '\0') && (!done
)
821 && (((*str
=='\0')&&((*pattern
==OB
)||(*pattern
=='*')))||(*str
!='\0'))) {
825 if (*pattern
!= '\0')
832 && (!(ret_code
=wxMatchWild(pattern
, str
++, FALSE
))))
837 while (*pattern
!= '\0')
844 if ((*pattern
== '\0') || (*pattern
== ']')) {
848 if (*pattern
== '\\') {
850 if (*pattern
== '\0') {
855 if (*(pattern
+ 1) == '-') {
858 if (*pattern
== ']') {
862 if (*pattern
== '\\') {
864 if (*pattern
== '\0') {
869 if ((*str
< c
) || (*str
> *pattern
)) {
873 } else if (*pattern
!= *str
) {
878 while ((*pattern
!= ']') && (*pattern
!= '\0')) {
879 if ((*pattern
== '\\') && (*(pattern
+ 1) != '\0'))
883 if (*pattern
!= '\0') {
893 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
896 while (ok
&& (*cp
!= '\0') && (*pattern
!= '\0')
897 && (*pattern
!= ',') && (*pattern
!= CB
)) {
898 if (*pattern
== '\\')
900 ok
= (*pattern
++ == *cp
++);
902 if (*pattern
== '\0') {
908 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
909 if (*++pattern
== '\\') {
910 if (*++pattern
== CB
)
915 while (*pattern
!=CB
&& *pattern
!=',' && *pattern
!='\0') {
916 if (*++pattern
== '\\') {
917 if (*++pattern
== CB
|| *pattern
== ',')
922 if (*pattern
!= '\0')
927 if (*str
== *pattern
) {
934 while (*pattern
== '*')
936 return ((*str
== '\0') && (*pattern
== '\0'));
941 #if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
944 When I started programming with Visual C++ v4.0, I missed one of my favorite
945 tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
946 on MSDN was a step in the right direction, but it is a console application
947 and thus has limited features and extensibility. DBWIN32 is my creation
948 to solve this problem.
950 The code is essentially a merging of a stripped down version of the DBWIN code
951 from VC 1.5 and DBMON.C with a few 32 bit changes.
953 As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
954 built into the operating system and works just by running DBWIN32. The Win95
955 team decided not to support this hook, so I have provided code that will do
956 this for you. See the file WIN95.TXT for instructions on installing this.
958 If you have questions, problems or suggestions about DBWIN32, I welcome your
959 feedback and plan to actively maintain the code.
964 To download dbwin32, see e.g.:
966 http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
969 #if !defined(__MWERKS__) && !defined(__SALFORDC__) && !defined(__TWIN32__)
973 void OutputDebugStringW95(const char* lpOutputString
, ...)
975 HANDLE heventDBWIN
; /* DBWIN32 synchronization object */
976 HANDLE heventData
; /* data passing synch object */
977 HANDLE hSharedFile
; /* memory mapped file shared data */
981 /* create the output buffer */
983 va_start(args
, lpOutputString
);
984 vsprintf(achBuffer
, lpOutputString
, args
);
988 Do a regular OutputDebugString so that the output is
989 still seen in the debugger window if it exists.
991 This ifdef is necessary to avoid infinite recursion
992 from the inclusion of W95TRACE.H
995 ::OutputDebugStringW(achBuffer
);
998 ::OutputDebugString(achBuffer
);
1000 ::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 */
1052 #if defined( __BORLANDC__ ) || defined( __MWERKS__ ) || defined(__SALFORDC__)
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
);
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
);
1134 void wxRedirectIOToConsole()