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(__WIN16__) && 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 */
113 # if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS && wxUSE_DEBUG_NEW_ALWAYS
114 # define new new(__FILE__,__LINE__)
119 /// END for console support
121 // In the WIN.INI file
122 static const char WX_SECTION
[] = "wxWindows";
123 static const char eHOSTNAME
[] = "HostName";
124 static const char eUSERID
[] = "UserId";
125 static const char eUSERNAME
[] = "UserName";
127 // For the following functions we SHOULD fill in support
128 // for Windows-NT (which I don't know) as I assume it begin
129 // a POSIX Unix (so claims MS) that it has some special
130 // functions beyond those provided by WinSock
132 // Get full hostname (eg. DoDo.BSn-Germany.crg.de)
133 bool wxGetHostName(char *buf
, int maxSize
)
136 DWORD nSize
= maxSize
;
137 return (::GetComputerName(buf
, &nSize
) != 0);
140 const char *default_host
= "noname";
142 if ((sysname
= getenv("SYSTEM_NAME")) == NULL
) {
143 GetProfileString(WX_SECTION
, eHOSTNAME
, default_host
, buf
, maxSize
- 1);
145 strncpy(buf
, sysname
, maxSize
- 1);
147 return *buf
? TRUE
: FALSE
;
151 // Get user ID e.g. jacs
152 bool wxGetUserId(char *buf
, int maxSize
)
154 #if defined(__WIN32__) && !defined(__win32s__) && 0
155 // Gets the current user's full name according to the MS article PSS ID
157 // Seems to be the same as the login name for me?
158 char *UserName
= new char[256];
159 char *Domain
= new char[256];
160 DWORD maxCharacters
= 255;
161 GetUserName( UserName
, &maxCharacters
);
162 GetComputerName( Domain
, &maxCharacters
);
164 WCHAR wszUserName
[256]; // Unicode user name
165 WCHAR wszDomain
[256];
168 struct _SERVER_INFO_100
*si100
; // Server structure
169 struct _USER_INFO_2
*ui
; // User structure
171 // Convert ASCII user name and domain to Unicode.
173 MultiByteToWideChar( CP_ACP
, 0, UserName
,
174 strlen(UserName
)+1, wszUserName
, sizeof(wszUserName
) );
175 MultiByteToWideChar( CP_ACP
, 0, Domain
,
176 strlen(Domain
)+1, wszDomain
, sizeof(wszDomain
) );
178 // Get the computer name of a DC for the specified domain.
179 // >If you get a link error on this, include netapi32.lib<
181 NetGetDCName( NULL
, wszDomain
, &ComputerName
);
183 // Look up the user on the DC.
185 if(NetUserGetInfo( (LPWSTR
) ComputerName
,
186 (LPWSTR
) &wszUserName
, 2, (LPBYTE
*) &ui
))
188 printf( "Error getting user information.\n" );
192 // Convert the Unicode full name to ASCII.
194 WideCharToMultiByte( CP_ACP
, 0, ui
->usri2_full_name
,
195 -1, buf
, 256, NULL
, NULL
);
199 DWORD nSize = maxSize;
200 return ::GetUserName(buf, &nSize);
204 const char *default_id
= "anonymous";
206 // Can't assume we have NIS (PC-NFS) or some other ID daemon
208 if ( (user
= getenv("USER")) == NULL
&&
209 (user
= getenv("LOGNAME")) == NULL
) {
210 // Use wxWindows configuration data (comming soon)
211 GetProfileString(WX_SECTION
, eUSERID
, default_id
, buf
, maxSize
- 1);
213 strncpy(buf
, user
, maxSize
- 1);
214 return *buf
? TRUE
: FALSE
;
218 // Get user name e.g. Julian Smart
219 bool wxGetUserName(char *buf
, int maxSize
)
221 const char *default_name
= "Unknown User";
222 #if defined(__WIN32__)
224 DWORD nSize = maxSize;
225 In VC++ 4.0, results in unresolved symbol __imp__GetUserNameA
226 if (GetUserName(buf, &nSize))
230 // Could use NIS, MS-Mail or other site specific programs
231 // Use wxWindows configuration data
232 GetProfileString(WX_SECTION
, eUSERNAME
, default_name
, buf
, maxSize
- 1);
233 return *buf
? TRUE
: FALSE
;
236 #if !defined(__WATCOMC__) && !defined(__GNUWIN32__) && wxUSE_PENWINDOWS
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 GetProfileString(WX_SECTION
, eUSERNAME
, default_name
, buf
, maxSize
- 1);
252 return *buf
? TRUE
: FALSE
;
256 int wxKill(long pid
, int sig
)
262 // Execute a program in an Interactive Shell
265 wxShell(const wxString
& command
)
268 if ((shell
= getenv("COMSPEC")) == NULL
)
269 shell
= "\\COMMAND.COM";
273 sprintf(tmp
, "%s /c %s", shell
, WXSTRINGCAST command
);
277 return (wxExecute((char *)tmp
, FALSE
) != 0);
280 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
281 long wxGetFreeMemory(void)
283 #if defined(__WIN32__) && !defined(__BORLANDC__)
284 MEMORYSTATUS memStatus
;
285 memStatus
.dwLength
= sizeof(MEMORYSTATUS
);
286 GlobalMemoryStatus(&memStatus
);
287 return memStatus
.dwAvailPhys
;
289 return (long)GetFreeSpace(0);
293 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
294 static bool inTimer
= FALSE
;
295 class wxSleepTimer
: public wxTimer
298 inline void Notify(void)
305 static wxTimer
*wxTheSleepTimer
= NULL
;
307 void wxSleep(int nSecs
)
309 #if 0 // WIN32 hangs app
315 wxTheSleepTimer
= new wxSleepTimer
;
317 wxTheSleepTimer
->Start(nSecs
*1000);
320 if (wxTheApp
->Pending())
321 wxTheApp
->Dispatch();
323 delete wxTheSleepTimer
;
324 wxTheSleepTimer
= NULL
;
328 // Consume all events until no more left
329 void wxFlushEvents(void)
334 // Output a debug mess., in a system dependent fashion.
335 void wxDebugMsg(const char *fmt
...)
338 static char buffer
[512];
340 if (!wxTheApp
->GetWantDebugOutput())
345 wvsprintf(buffer
,fmt
,ap
) ;
346 OutputDebugString((LPCSTR
)buffer
) ;
351 // Non-fatal error: pop up message box and (possibly) continue
352 void wxError(const wxString
& msg
, const wxString
& title
)
354 sprintf(wxBuffer
, "%s\nContinue?", WXSTRINGCAST msg
);
355 if (MessageBox(NULL
, (LPCSTR
)wxBuffer
, (LPCSTR
)WXSTRINGCAST title
,
356 MB_ICONSTOP
| MB_YESNO
) == IDNO
)
360 // Fatal error: pop up message box and abort
361 void wxFatalError(const wxString
& msg
, const wxString
& title
)
363 sprintf(wxBuffer
, "%s: %s", WXSTRINGCAST title
, WXSTRINGCAST msg
);
364 FatalAppExit(0, (LPCSTR
)wxBuffer
);
370 // Removed by RD because IHMO syncronous sound is a Bad Thing. MessageBeep
371 // will do a similar thing anyway if there is no sound card...
373 // Beep(1000,1000) ; // 1kHz during 1 sec.
375 MessageBeep((UINT
)-1) ;
379 // Chris Breeze 27/5/98: revised WIN32 code to
380 // detect WindowsNT correctly
381 int wxGetOsVersion(int *majorVsn
, int *minorVsn
)
383 extern char *wxOsVersion
;
384 if (majorVsn
) *majorVsn
= 0;
385 if (minorVsn
) *minorVsn
= 0;
389 memset(&info
, 0, sizeof(OSVERSIONINFO
));
390 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
391 if (GetVersionEx(&info
))
393 if (majorVsn
) *majorVsn
= info
.dwMajorVersion
;
394 if (minorVsn
) *minorVsn
= info
.dwMinorVersion
;
395 switch (info
.dwPlatformId
)
397 case VER_PLATFORM_WIN32s
:
400 case VER_PLATFORM_WIN32_WINDOWS
:
403 case VER_PLATFORM_WIN32_NT
:
408 return wxWINDOWS
; // error if we get here, return generic value
412 # ifdef __WINDOWS_386__
415 # if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
416 extern HANDLE g_hPenWin
;
417 retValue
= g_hPenWin
? wxPENWINDOWS
: wxWINDOWS
;
420 // @@@@ To be completed. I don't have the manual here...
421 if (majorVsn
) *majorVsn
= 3 ;
422 if (minorVsn
) *minorVsn
= 1 ;
427 // Reading and writing resources (eg WIN.INI, .Xdefaults)
429 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
)
432 return (WritePrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)value
, (LPCSTR
)WXSTRINGCAST file
) != 0);
434 return (WriteProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)WXSTRINGCAST value
) != 0);
437 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
)
440 sprintf(buf
, "%.4f", value
);
441 return wxWriteResource(section
, entry
, buf
, file
);
444 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
)
447 sprintf(buf
, "%ld", value
);
448 return wxWriteResource(section
, entry
, buf
, file
);
451 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
)
454 sprintf(buf
, "%d", value
);
455 return wxWriteResource(section
, entry
, buf
, file
);
458 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
)
460 static const char defunkt
[] = "$$default";
463 int n
= GetPrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
464 (LPSTR
)wxBuffer
, 1000, (LPCSTR
)WXSTRINGCAST file
);
465 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
470 int n
= GetProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
471 (LPSTR
)wxBuffer
, 1000);
472 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
475 if (*value
) delete[] (*value
);
476 *value
= copystring(wxBuffer
);
480 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
)
483 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
486 *value
= (float)strtod(s
, NULL
);
493 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
)
496 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
499 *value
= strtol(s
, NULL
, 10);
506 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
)
509 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
512 *value
= (int)strtol(s
, NULL
, 10);
518 #endif // wxUSE_RESOURCES
521 static HCURSOR wxBusyCursorOld
= 0;
522 static int wxBusyCursorCount
= 0;
524 // Set the cursor to the busy cursor for all windows
525 void wxBeginBusyCursor(wxCursor
*cursor
)
527 wxBusyCursorCount
++;
528 if (wxBusyCursorCount
== 1)
530 wxBusyCursorOld
= ::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
534 (void)::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
538 // Restore cursor to normal
539 void wxEndBusyCursor(void)
541 if (wxBusyCursorCount
== 0)
544 wxBusyCursorCount
--;
545 if (wxBusyCursorCount
== 0)
547 ::SetCursor(wxBusyCursorOld
);
552 // TRUE if we're between the above two calls
555 return (wxBusyCursorCount
> 0);
558 const char* wxGetHomeDir(wxString
*pstr
)
560 wxString
& strDir
= *pstr
;
563 const char *szHome
= getenv("HOME");
564 if ( szHome
== NULL
) {
566 wxLogWarning(_("can't find user's HOME, using current directory."));
572 // add a trailing slash if needed
573 if ( strDir
.Last() != '/' )
577 const char *szHome
= getenv("HOMEDRIVE");
578 if ( szHome
!= NULL
)
580 szHome
= getenv("HOMEPATH");
581 if ( szHome
!= NULL
) {
584 // the idea is that under NT these variables have default values
585 // of "%systemdrive%:" and "\\". As we don't want to create our
586 // config files in the root directory of the system drive, we will
587 // create it in our program's dir. However, if the user took care
588 // to set HOMEPATH to something other than "\\", we suppose that he
589 // knows what he is doing and use the supplied value.
590 if ( strcmp(szHome
, "\\") != 0 )
591 return strDir
.c_str();
595 // Win16 has no idea about home, so use the working directory instead
598 // 260 was taken from windef.h
604 ::GetModuleFileName(::GetModuleHandle(NULL
),
605 strPath
.GetWriteBuf(MAX_PATH
), MAX_PATH
);
606 strPath
.UngetWriteBuf();
608 // extract the dir name
609 wxSplitPath(strPath
, &strDir
, NULL
, NULL
);
613 return strDir
.c_str();
617 char *wxGetUserHome (const wxString
& user
)
620 wxString
user1(user
);
624 if (wxGetUserId(tmp
, sizeof(tmp
)/sizeof(char))) {
625 // Guests belong in the temp dir
626 if (Stricmp(tmp
, "annonymous") == 0) {
627 if ((home
= getenv("TMP")) != NULL
||
628 (home
= getenv("TMPDIR")) != NULL
||
629 (home
= getenv("TEMP")) != NULL
)
630 return *home
? home
: "\\";
632 if (Stricmp(tmp
, WXSTRINGCAST user1
) == 0)
637 if ((home
= getenv("HOME")) != NULL
)
639 strcpy(wxBuffer
, home
);
640 Unix2DosFilename(wxBuffer
);
643 return NULL
; // No home known!
646 // Check whether this window wants to process messages, e.g. Stop button
647 // in long calculations.
648 bool wxCheckForInterrupt(wxWindow
*wnd
)
652 HWND win
= (HWND
) wnd
->GetHWND();
653 while(PeekMessage(&msg
,win
,0,0,PM_REMOVE
)){
654 TranslateMessage(&msg
);
655 DispatchMessage(&msg
);
657 return TRUE
;//*** temporary?
660 wxError("wnd==NULL !!!");
661 return FALSE
;//*** temporary?
665 // MSW only: get user-defined resource from the .res file.
666 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
669 char *wxLoadUserResource(const wxString
& resourceName
, const wxString
& resourceType
)
673 HRSRC hResource
= ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
676 HRSRC hResource
= ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
678 HRSRC hResource
= ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
684 HGLOBAL hData
= ::LoadResource(wxGetInstance(), hResource
);
687 char *theText
= (char *)LockResource(hData
);
691 s
= copystring(theText
);
695 UnlockResource(hData
);
699 // GlobalFree(hData);
705 void wxGetMousePosition( int* x
, int* y
)
708 GetCursorPos( & pt
);
713 // Return TRUE if we have a colour display
714 bool wxColourDisplay(void)
716 HDC dc
= ::GetDC(NULL
);
718 int noCols
= GetDeviceCaps(dc
, NUMCOLORS
);
719 if ((noCols
== -1) || (noCols
> 2))
727 // Returns depth of screen
728 int wxDisplayDepth(void)
730 HDC dc
= ::GetDC(NULL
);
731 int planes
= GetDeviceCaps(dc
, PLANES
);
732 int bitsPerPixel
= GetDeviceCaps(dc
, BITSPIXEL
);
733 int depth
= planes
*bitsPerPixel
;
738 // Get size of display
739 void wxDisplaySize(int *width
, int *height
)
741 HDC dc
= ::GetDC(NULL
);
742 *width
= GetDeviceCaps(dc
, HORZRES
); *height
= GetDeviceCaps(dc
, VERTRES
);
746 bool wxDirExists(const wxString
& dir
)
748 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
749 #if defined(__WIN32__)
750 WIN32_FIND_DATA fileInfo
;
753 struct ffblk fileInfo
;
755 struct find_t fileInfo
;
759 #if defined(__WIN32__)
760 HANDLE h
= FindFirstFile((LPTSTR
) WXSTRINGCAST dir
,(LPWIN32_FIND_DATA
)&fileInfo
);
762 if (h
==INVALID_HANDLE_VALUE
)
766 return ((fileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) == FILE_ATTRIBUTE_DIRECTORY
);
769 // In Borland findfirst has a different argument
770 // ordering from _dos_findfirst. But _dos_findfirst
771 // _should_ be ok in both MS and Borland... why not?
773 return ((findfirst(WXSTRINGCAST dir
, &fileInfo
, _A_SUBDIR
) == 0 && (fileInfo
.ff_attrib
& _A_SUBDIR
) != 0));
775 return (((_dos_findfirst(WXSTRINGCAST dir
, _A_SUBDIR
, &fileInfo
) == 0) && (fileInfo
.attrib
& _A_SUBDIR
)) != 0);
780 wxString WXDLLEXPORT
wxGetWindowText(WXHWND hWnd
)
783 int len
= GetWindowTextLength((HWND
)hWnd
) + 1;
784 GetWindowText((HWND
)hWnd
, str
.GetWriteBuf(len
), len
);
791 //------------------------------------------------------------------------
792 // wild character routines
793 //------------------------------------------------------------------------
795 bool wxIsWild( const wxString
& pattern
)
797 wxString tmp
= pattern
;
798 char *pat
= WXSTRINGCAST(tmp
);
801 case '?': case '*': case '[': case '{':
812 bool wxMatchWild( const wxString
& pat
, const wxString
& text
, bool dot_special
)
815 char *pattern
= WXSTRINGCAST(tmp1
);
816 wxString tmp2
= text
;
817 char *str
= WXSTRINGCAST(tmp2
);
820 bool done
= FALSE
, ret_code
, ok
;
821 // Below is for vi fans
822 const char OB
= '{', CB
= '}';
824 // dot_special means '.' only matches '.'
825 if (dot_special
&& *str
== '.' && *pattern
!= *str
)
828 while ((*pattern
!= '\0') && (!done
)
829 && (((*str
=='\0')&&((*pattern
==OB
)||(*pattern
=='*')))||(*str
!='\0'))) {
833 if (*pattern
!= '\0')
840 && (!(ret_code
=wxMatchWild(pattern
, str
++, FALSE
))))
845 while (*pattern
!= '\0')
852 if ((*pattern
== '\0') || (*pattern
== ']')) {
856 if (*pattern
== '\\') {
858 if (*pattern
== '\0') {
863 if (*(pattern
+ 1) == '-') {
866 if (*pattern
== ']') {
870 if (*pattern
== '\\') {
872 if (*pattern
== '\0') {
877 if ((*str
< c
) || (*str
> *pattern
)) {
881 } else if (*pattern
!= *str
) {
886 while ((*pattern
!= ']') && (*pattern
!= '\0')) {
887 if ((*pattern
== '\\') && (*(pattern
+ 1) != '\0'))
891 if (*pattern
!= '\0') {
901 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
904 while (ok
&& (*cp
!= '\0') && (*pattern
!= '\0')
905 && (*pattern
!= ',') && (*pattern
!= CB
)) {
906 if (*pattern
== '\\')
908 ok
= (*pattern
++ == *cp
++);
910 if (*pattern
== '\0') {
916 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
917 if (*++pattern
== '\\') {
918 if (*++pattern
== CB
)
923 while (*pattern
!=CB
&& *pattern
!=',' && *pattern
!='\0') {
924 if (*++pattern
== '\\') {
925 if (*++pattern
== CB
|| *pattern
== ',')
930 if (*pattern
!= '\0')
935 if (*str
== *pattern
) {
942 while (*pattern
== '*')
944 return ((*str
== '\0') && (*pattern
== '\0'));
949 #if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
952 When I started programming with Visual C++ v4.0, I missed one of my favorite
953 tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
954 on MSDN was a step in the right direction, but it is a console application
955 and thus has limited features and extensibility. DBWIN32 is my creation
956 to solve this problem.
958 The code is essentially a merging of a stripped down version of the DBWIN code
959 from VC 1.5 and DBMON.C with a few 32 bit changes.
961 As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
962 built into the operating system and works just by running DBWIN32. The Win95
963 team decided not to support this hook, so I have provided code that will do
964 this for you. See the file WIN95.TXT for instructions on installing this.
966 If you have questions, problems or suggestions about DBWIN32, I welcome your
967 feedback and plan to actively maintain the code.
972 To download dbwin32, see e.g.:
974 http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
979 void OutputDebugStringW95(const char* lpOutputString
, ...)
981 HANDLE heventDBWIN
; /* DBWIN32 synchronization object */
982 HANDLE heventData
; /* data passing synch object */
983 HANDLE hSharedFile
; /* memory mapped file shared data */
987 /* create the output buffer */
989 va_start(args
, lpOutputString
);
990 vsprintf(achBuffer
, lpOutputString
, args
);
994 Do a regular OutputDebugString so that the output is
995 still seen in the debugger window if it exists.
997 This ifdef is necessary to avoid infinite recursion
998 from the inclusion of W95TRACE.H
1001 ::OutputDebugStringW(achBuffer
);
1003 ::OutputDebugStringA(achBuffer
);
1006 /* bail if it's not Win95 */
1008 OSVERSIONINFO VerInfo
;
1009 VerInfo
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
1010 GetVersionEx(&VerInfo
);
1011 if ( VerInfo
.dwPlatformId
!= VER_PLATFORM_WIN32_WINDOWS
)
1015 /* make sure DBWIN is open and waiting */
1016 heventDBWIN
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_BUFFER_READY");
1019 //MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
1023 /* get a handle to the data synch object */
1024 heventData
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_DATA_READY");
1027 // MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
1028 CloseHandle(heventDBWIN
);
1032 hSharedFile
= CreateFileMapping((HANDLE
)-1, NULL
, PAGE_READWRITE
, 0, 4096, "DBWIN_BUFFER");
1035 //MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
1036 CloseHandle(heventDBWIN
);
1037 CloseHandle(heventData
);
1041 lpszSharedMem
= (LPSTR
)MapViewOfFile(hSharedFile
, FILE_MAP_WRITE
, 0, 0, 512);
1044 //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
1045 CloseHandle(heventDBWIN
);
1046 CloseHandle(heventData
);
1050 /* wait for buffer event */
1051 WaitForSingleObject(heventDBWIN
, INFINITE
);
1053 /* write it to the shared memory */
1055 *((LPDWORD
)lpszSharedMem
) = getpid();
1057 *((LPDWORD
)lpszSharedMem
) = _getpid();
1060 wsprintf(lpszSharedMem
+ sizeof(DWORD
), "%s", achBuffer
);
1062 /* signal data ready event */
1063 SetEvent(heventData
);
1065 /* clean up handles */
1066 CloseHandle(hSharedFile
);
1067 CloseHandle(heventData
);
1068 CloseHandle(heventDBWIN
);
1077 #ifdef wxUSE_VC_CRTDBG
1079 // maximum mumber of lines the output console should have
1080 static const WORD MAX_CONSOLE_LINES
= 500;
1082 BOOL WINAPI
MyConsoleHandler( DWORD dwCtrlType
) { // control signal type
1087 void wxRedirectIOToConsole()
1091 CONSOLE_SCREEN_BUFFER_INFO coninfo
;
1094 // allocate a console for this app
1097 // set the screen buffer to be big enough to let us scroll text
1098 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE
),
1100 coninfo
.dwSize
.Y
= MAX_CONSOLE_LINES
;
1101 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE
),
1104 // redirect unbuffered STDOUT to the console
1105 lStdHandle
= (long)GetStdHandle(STD_OUTPUT_HANDLE
);
1106 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1107 if(hConHandle
<= 0) return;
1108 fp
= _fdopen( hConHandle
, "w" );
1110 setvbuf( stdout
, NULL
, _IONBF
, 0 );
1112 // redirect unbuffered STDIN to the console
1113 lStdHandle
= (long)GetStdHandle(STD_INPUT_HANDLE
);
1114 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1115 if(hConHandle
<= 0) return;
1116 fp
= _fdopen( hConHandle
, "r" );
1118 setvbuf( stdin
, NULL
, _IONBF
, 0 );
1120 // redirect unbuffered STDERR to the console
1121 lStdHandle
= (long)GetStdHandle(STD_ERROR_HANDLE
);
1122 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1123 if(hConHandle
<= 0) return;
1124 fp
= _fdopen( hConHandle
, "w" );
1126 setvbuf( stderr
, NULL
, _IONBF
, 0 );
1128 // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
1129 // point to console as well
1130 ios::sync_with_stdio();
1132 SetConsoleCtrlHandler(MyConsoleHandler
, TRUE
);
1137 void wxRedirectIOToConsole()