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__)
156 // VZ: why should it be so complicated??
158 // Gets the current user's full name according to the MS article PSS ID
160 // Seems to be the same as the login name for me?
161 char *UserName
= new char[256];
162 char *Domain
= new char[256];
163 DWORD maxCharacters
= 255;
164 GetUserName( UserName
, &maxCharacters
);
165 GetComputerName( Domain
, &maxCharacters
);
167 WCHAR wszUserName
[256]; // Unicode user name
168 WCHAR wszDomain
[256];
171 struct _SERVER_INFO_100
*si100
; // Server structure
172 struct _USER_INFO_2
*ui
; // User structure
174 // Convert ASCII user name and domain to Unicode.
176 MultiByteToWideChar( CP_ACP
, 0, UserName
,
177 strlen(UserName
)+1, wszUserName
, sizeof(wszUserName
) );
178 MultiByteToWideChar( CP_ACP
, 0, Domain
,
179 strlen(Domain
)+1, wszDomain
, sizeof(wszDomain
) );
181 // Get the computer name of a DC for the specified domain.
182 // >If you get a link error on this, include netapi32.lib<
184 NetGetDCName( NULL
, wszDomain
, &ComputerName
);
186 // Look up the user on the DC.
188 if(NetUserGetInfo( (LPWSTR
) ComputerName
,
189 (LPWSTR
) &wszUserName
, 2, (LPBYTE
*) &ui
))
191 printf( "Error getting user information.\n" );
195 // Convert the Unicode full name to ASCII.
197 WideCharToMultiByte( CP_ACP
, 0, ui
->usri2_full_name
,
198 -1, buf
, 256, NULL
, NULL
);
202 DWORD nSize
= maxSize
;
203 if ( ::GetUserName(buf
, &nSize
) == 0 )
205 wxLogSysError("Can not get user name");
213 #else // Win16 or Win32s
215 const char *default_id
= "anonymous";
217 // Can't assume we have NIS (PC-NFS) or some other ID daemon
219 if ( (user
= getenv("USER")) == NULL
&&
220 (user
= getenv("LOGNAME")) == NULL
) {
221 // Use wxWindows configuration data (comming soon)
222 GetProfileString(WX_SECTION
, eUSERID
, default_id
, buf
, maxSize
- 1);
224 strncpy(buf
, user
, maxSize
- 1);
225 return *buf
? TRUE
: FALSE
;
229 // Get user name e.g. Julian Smart
230 bool wxGetUserName(char *buf
, int maxSize
)
232 #if wxUSE_PENWINDOWS && !defined(__WATCOMC__) && !defined(__GNUWIN32__)
233 extern HANDLE g_hPenWin
; // PenWindows Running?
236 // PenWindows Does have a user concept!
237 // Get the current owner of the recognizer
238 GetPrivateProfileString("Current", "User", default_name
, wxBuffer
, maxSize
- 1, "PENWIN.INI");
239 strncpy(buf
, wxBuffer
, maxSize
- 1);
244 // Could use NIS, MS-Mail or other site specific programs
245 // Use wxWindows configuration data
246 bool ok
= GetProfileString(WX_SECTION
, eUSERNAME
, "", buf
, maxSize
- 1) != 0;
249 ok
= wxGetUserId(buf
, maxSize
);
254 strncpy(buf
, "Unknown User", maxSize
);
261 int wxKill(long pid
, int sig
)
267 // Execute a program in an Interactive Shell
270 wxShell(const wxString
& command
)
273 if ((shell
= getenv("COMSPEC")) == NULL
)
274 shell
= "\\COMMAND.COM";
278 sprintf(tmp
, "%s /c %s", shell
, WXSTRINGCAST command
);
282 return (wxExecute((char *)tmp
, FALSE
) != 0);
285 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
286 long wxGetFreeMemory(void)
288 #if defined(__WIN32__) && !defined(__BORLANDC__)
289 MEMORYSTATUS memStatus
;
290 memStatus
.dwLength
= sizeof(MEMORYSTATUS
);
291 GlobalMemoryStatus(&memStatus
);
292 return memStatus
.dwAvailPhys
;
294 return (long)GetFreeSpace(0);
298 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
299 static bool inTimer
= FALSE
;
300 class wxSleepTimer
: public wxTimer
303 inline void Notify(void)
310 static wxTimer
*wxTheSleepTimer
= NULL
;
312 void wxSleep(int nSecs
)
314 #if 0 // WIN32 hangs app
320 wxTheSleepTimer
= new wxSleepTimer
;
322 wxTheSleepTimer
->Start(nSecs
*1000);
325 if (wxTheApp
->Pending())
326 wxTheApp
->Dispatch();
328 delete wxTheSleepTimer
;
329 wxTheSleepTimer
= NULL
;
333 // Consume all events until no more left
334 void wxFlushEvents(void)
339 // Output a debug mess., in a system dependent fashion.
340 void wxDebugMsg(const char *fmt
...)
343 static char buffer
[512];
345 if (!wxTheApp
->GetWantDebugOutput())
350 wvsprintf(buffer
,fmt
,ap
) ;
351 OutputDebugString((LPCSTR
)buffer
) ;
356 // Non-fatal error: pop up message box and (possibly) continue
357 void wxError(const wxString
& msg
, const wxString
& title
)
359 sprintf(wxBuffer
, "%s\nContinue?", WXSTRINGCAST msg
);
360 if (MessageBox(NULL
, (LPCSTR
)wxBuffer
, (LPCSTR
)WXSTRINGCAST title
,
361 MB_ICONSTOP
| MB_YESNO
) == IDNO
)
365 // Fatal error: pop up message box and abort
366 void wxFatalError(const wxString
& msg
, const wxString
& title
)
368 sprintf(wxBuffer
, "%s: %s", WXSTRINGCAST title
, WXSTRINGCAST msg
);
369 FatalAppExit(0, (LPCSTR
)wxBuffer
);
375 // Removed by RD because IHMO syncronous sound is a Bad Thing. MessageBeep
376 // will do a similar thing anyway if there is no sound card...
378 // Beep(1000,1000) ; // 1kHz during 1 sec.
380 MessageBeep((UINT
)-1) ;
384 // Chris Breeze 27/5/98: revised WIN32 code to
385 // detect WindowsNT correctly
386 int wxGetOsVersion(int *majorVsn
, int *minorVsn
)
388 extern char *wxOsVersion
;
389 if (majorVsn
) *majorVsn
= 0;
390 if (minorVsn
) *minorVsn
= 0;
394 memset(&info
, 0, sizeof(OSVERSIONINFO
));
395 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
396 if (GetVersionEx(&info
))
398 if (majorVsn
) *majorVsn
= info
.dwMajorVersion
;
399 if (minorVsn
) *minorVsn
= info
.dwMinorVersion
;
400 switch (info
.dwPlatformId
)
402 case VER_PLATFORM_WIN32s
:
405 case VER_PLATFORM_WIN32_WINDOWS
:
408 case VER_PLATFORM_WIN32_NT
:
413 return wxWINDOWS
; // error if we get here, return generic value
417 # ifdef __WINDOWS_386__
420 # if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
421 extern HANDLE g_hPenWin
;
422 retValue
= g_hPenWin
? wxPENWINDOWS
: wxWINDOWS
;
425 // @@@@ To be completed. I don't have the manual here...
426 if (majorVsn
) *majorVsn
= 3 ;
427 if (minorVsn
) *minorVsn
= 1 ;
432 // Reading and writing resources (eg WIN.INI, .Xdefaults)
434 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
)
437 return (WritePrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)value
, (LPCSTR
)WXSTRINGCAST file
) != 0);
439 return (WriteProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)WXSTRINGCAST value
) != 0);
442 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
)
445 sprintf(buf
, "%.4f", value
);
446 return wxWriteResource(section
, entry
, buf
, file
);
449 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
)
452 sprintf(buf
, "%ld", value
);
453 return wxWriteResource(section
, entry
, buf
, file
);
456 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
)
459 sprintf(buf
, "%d", value
);
460 return wxWriteResource(section
, entry
, buf
, file
);
463 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
)
465 static const char defunkt
[] = "$$default";
468 int n
= GetPrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
469 (LPSTR
)wxBuffer
, 1000, (LPCSTR
)WXSTRINGCAST file
);
470 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
475 int n
= GetProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
476 (LPSTR
)wxBuffer
, 1000);
477 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
480 if (*value
) delete[] (*value
);
481 *value
= copystring(wxBuffer
);
485 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
)
488 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
491 *value
= (float)strtod(s
, NULL
);
498 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
)
501 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
504 *value
= strtol(s
, NULL
, 10);
511 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
)
514 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
517 *value
= (int)strtol(s
, NULL
, 10);
523 #endif // wxUSE_RESOURCES
526 static HCURSOR wxBusyCursorOld
= 0;
527 static int wxBusyCursorCount
= 0;
529 // Set the cursor to the busy cursor for all windows
530 void wxBeginBusyCursor(wxCursor
*cursor
)
532 wxBusyCursorCount
++;
533 if (wxBusyCursorCount
== 1)
535 wxBusyCursorOld
= ::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
539 (void)::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
543 // Restore cursor to normal
544 void wxEndBusyCursor(void)
546 if (wxBusyCursorCount
== 0)
549 wxBusyCursorCount
--;
550 if (wxBusyCursorCount
== 0)
552 ::SetCursor(wxBusyCursorOld
);
557 // TRUE if we're between the above two calls
560 return (wxBusyCursorCount
> 0);
563 const char* wxGetHomeDir(wxString
*pstr
)
565 wxString
& strDir
= *pstr
;
568 const char *szHome
= getenv("HOME");
569 if ( szHome
== NULL
) {
571 wxLogWarning(_("can't find user's HOME, using current directory."));
577 // add a trailing slash if needed
578 if ( strDir
.Last() != '/' )
582 const char *szHome
= getenv("HOMEDRIVE");
583 if ( szHome
!= NULL
)
585 szHome
= getenv("HOMEPATH");
586 if ( szHome
!= NULL
) {
589 // the idea is that under NT these variables have default values
590 // of "%systemdrive%:" and "\\". As we don't want to create our
591 // config files in the root directory of the system drive, we will
592 // create it in our program's dir. However, if the user took care
593 // to set HOMEPATH to something other than "\\", we suppose that he
594 // knows what he is doing and use the supplied value.
595 if ( strcmp(szHome
, "\\") != 0 )
596 return strDir
.c_str();
600 // Win16 has no idea about home, so use the working directory instead
603 // 260 was taken from windef.h
609 ::GetModuleFileName(::GetModuleHandle(NULL
),
610 strPath
.GetWriteBuf(MAX_PATH
), MAX_PATH
);
611 strPath
.UngetWriteBuf();
613 // extract the dir name
614 wxSplitPath(strPath
, &strDir
, NULL
, NULL
);
618 return strDir
.c_str();
622 char *wxGetUserHome (const wxString
& user
)
625 wxString
user1(user
);
629 if (wxGetUserId(tmp
, sizeof(tmp
)/sizeof(char))) {
630 // Guests belong in the temp dir
631 if (Stricmp(tmp
, "annonymous") == 0) {
632 if ((home
= getenv("TMP")) != NULL
||
633 (home
= getenv("TMPDIR")) != NULL
||
634 (home
= getenv("TEMP")) != NULL
)
635 return *home
? home
: "\\";
637 if (Stricmp(tmp
, WXSTRINGCAST user1
) == 0)
642 if ((home
= getenv("HOME")) != NULL
)
644 strcpy(wxBuffer
, home
);
645 Unix2DosFilename(wxBuffer
);
648 return NULL
; // No home known!
651 // Check whether this window wants to process messages, e.g. Stop button
652 // in long calculations.
653 bool wxCheckForInterrupt(wxWindow
*wnd
)
657 HWND win
= (HWND
) wnd
->GetHWND();
658 while(PeekMessage(&msg
,win
,0,0,PM_REMOVE
)){
659 TranslateMessage(&msg
);
660 DispatchMessage(&msg
);
662 return TRUE
;//*** temporary?
665 wxError("wnd==NULL !!!");
666 return FALSE
;//*** temporary?
670 // MSW only: get user-defined resource from the .res file.
671 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
674 char *wxLoadUserResource(const wxString
& resourceName
, const wxString
& resourceType
)
678 HRSRC hResource
= ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
681 HRSRC hResource
= ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
683 HRSRC hResource
= ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
689 HGLOBAL hData
= ::LoadResource(wxGetInstance(), hResource
);
692 char *theText
= (char *)LockResource(hData
);
696 s
= copystring(theText
);
700 UnlockResource(hData
);
704 // GlobalFree(hData);
710 void wxGetMousePosition( int* x
, int* y
)
713 GetCursorPos( & pt
);
718 // Return TRUE if we have a colour display
719 bool wxColourDisplay(void)
721 HDC dc
= ::GetDC(NULL
);
723 int noCols
= GetDeviceCaps(dc
, NUMCOLORS
);
724 if ((noCols
== -1) || (noCols
> 2))
732 // Returns depth of screen
733 int wxDisplayDepth(void)
735 HDC dc
= ::GetDC(NULL
);
736 int planes
= GetDeviceCaps(dc
, PLANES
);
737 int bitsPerPixel
= GetDeviceCaps(dc
, BITSPIXEL
);
738 int depth
= planes
*bitsPerPixel
;
743 // Get size of display
744 void wxDisplaySize(int *width
, int *height
)
746 HDC dc
= ::GetDC(NULL
);
747 *width
= GetDeviceCaps(dc
, HORZRES
); *height
= GetDeviceCaps(dc
, VERTRES
);
751 bool wxDirExists(const wxString
& dir
)
753 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
754 #if defined(__WIN32__)
755 WIN32_FIND_DATA fileInfo
;
758 struct ffblk fileInfo
;
760 struct find_t fileInfo
;
764 #if defined(__WIN32__)
765 HANDLE h
= FindFirstFile((LPTSTR
) WXSTRINGCAST dir
,(LPWIN32_FIND_DATA
)&fileInfo
);
767 if (h
==INVALID_HANDLE_VALUE
)
771 return ((fileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) == FILE_ATTRIBUTE_DIRECTORY
);
774 // In Borland findfirst has a different argument
775 // ordering from _dos_findfirst. But _dos_findfirst
776 // _should_ be ok in both MS and Borland... why not?
778 return ((findfirst(WXSTRINGCAST dir
, &fileInfo
, _A_SUBDIR
) == 0 && (fileInfo
.ff_attrib
& _A_SUBDIR
) != 0));
780 return (((_dos_findfirst(WXSTRINGCAST dir
, _A_SUBDIR
, &fileInfo
) == 0) && (fileInfo
.attrib
& _A_SUBDIR
)) != 0);
785 wxString WXDLLEXPORT
wxGetWindowText(WXHWND hWnd
)
788 int len
= GetWindowTextLength((HWND
)hWnd
) + 1;
789 GetWindowText((HWND
)hWnd
, str
.GetWriteBuf(len
), len
);
796 //------------------------------------------------------------------------
797 // wild character routines
798 //------------------------------------------------------------------------
800 bool wxIsWild( const wxString
& pattern
)
802 wxString tmp
= pattern
;
803 char *pat
= WXSTRINGCAST(tmp
);
806 case '?': case '*': case '[': case '{':
817 bool wxMatchWild( const wxString
& pat
, const wxString
& text
, bool dot_special
)
820 char *pattern
= WXSTRINGCAST(tmp1
);
821 wxString tmp2
= text
;
822 char *str
= WXSTRINGCAST(tmp2
);
825 bool done
= FALSE
, ret_code
, ok
;
826 // Below is for vi fans
827 const char OB
= '{', CB
= '}';
829 // dot_special means '.' only matches '.'
830 if (dot_special
&& *str
== '.' && *pattern
!= *str
)
833 while ((*pattern
!= '\0') && (!done
)
834 && (((*str
=='\0')&&((*pattern
==OB
)||(*pattern
=='*')))||(*str
!='\0'))) {
838 if (*pattern
!= '\0')
845 && (!(ret_code
=wxMatchWild(pattern
, str
++, FALSE
))))
850 while (*pattern
!= '\0')
857 if ((*pattern
== '\0') || (*pattern
== ']')) {
861 if (*pattern
== '\\') {
863 if (*pattern
== '\0') {
868 if (*(pattern
+ 1) == '-') {
871 if (*pattern
== ']') {
875 if (*pattern
== '\\') {
877 if (*pattern
== '\0') {
882 if ((*str
< c
) || (*str
> *pattern
)) {
886 } else if (*pattern
!= *str
) {
891 while ((*pattern
!= ']') && (*pattern
!= '\0')) {
892 if ((*pattern
== '\\') && (*(pattern
+ 1) != '\0'))
896 if (*pattern
!= '\0') {
906 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
909 while (ok
&& (*cp
!= '\0') && (*pattern
!= '\0')
910 && (*pattern
!= ',') && (*pattern
!= CB
)) {
911 if (*pattern
== '\\')
913 ok
= (*pattern
++ == *cp
++);
915 if (*pattern
== '\0') {
921 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
922 if (*++pattern
== '\\') {
923 if (*++pattern
== CB
)
928 while (*pattern
!=CB
&& *pattern
!=',' && *pattern
!='\0') {
929 if (*++pattern
== '\\') {
930 if (*++pattern
== CB
|| *pattern
== ',')
935 if (*pattern
!= '\0')
940 if (*str
== *pattern
) {
947 while (*pattern
== '*')
949 return ((*str
== '\0') && (*pattern
== '\0'));
954 #if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
957 When I started programming with Visual C++ v4.0, I missed one of my favorite
958 tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
959 on MSDN was a step in the right direction, but it is a console application
960 and thus has limited features and extensibility. DBWIN32 is my creation
961 to solve this problem.
963 The code is essentially a merging of a stripped down version of the DBWIN code
964 from VC 1.5 and DBMON.C with a few 32 bit changes.
966 As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
967 built into the operating system and works just by running DBWIN32. The Win95
968 team decided not to support this hook, so I have provided code that will do
969 this for you. See the file WIN95.TXT for instructions on installing this.
971 If you have questions, problems or suggestions about DBWIN32, I welcome your
972 feedback and plan to actively maintain the code.
977 To download dbwin32, see e.g.:
979 http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
984 void OutputDebugStringW95(const char* lpOutputString
, ...)
986 HANDLE heventDBWIN
; /* DBWIN32 synchronization object */
987 HANDLE heventData
; /* data passing synch object */
988 HANDLE hSharedFile
; /* memory mapped file shared data */
992 /* create the output buffer */
994 va_start(args
, lpOutputString
);
995 vsprintf(achBuffer
, lpOutputString
, args
);
999 Do a regular OutputDebugString so that the output is
1000 still seen in the debugger window if it exists.
1002 This ifdef is necessary to avoid infinite recursion
1003 from the inclusion of W95TRACE.H
1006 ::OutputDebugStringW(achBuffer
);
1008 ::OutputDebugStringA(achBuffer
);
1011 /* bail if it's not Win95 */
1013 OSVERSIONINFO VerInfo
;
1014 VerInfo
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
1015 GetVersionEx(&VerInfo
);
1016 if ( VerInfo
.dwPlatformId
!= VER_PLATFORM_WIN32_WINDOWS
)
1020 /* make sure DBWIN is open and waiting */
1021 heventDBWIN
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_BUFFER_READY");
1024 //MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
1028 /* get a handle to the data synch object */
1029 heventData
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_DATA_READY");
1032 // MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
1033 CloseHandle(heventDBWIN
);
1037 hSharedFile
= CreateFileMapping((HANDLE
)-1, NULL
, PAGE_READWRITE
, 0, 4096, "DBWIN_BUFFER");
1040 //MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
1041 CloseHandle(heventDBWIN
);
1042 CloseHandle(heventData
);
1046 lpszSharedMem
= (LPSTR
)MapViewOfFile(hSharedFile
, FILE_MAP_WRITE
, 0, 0, 512);
1049 //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
1050 CloseHandle(heventDBWIN
);
1051 CloseHandle(heventData
);
1055 /* wait for buffer event */
1056 WaitForSingleObject(heventDBWIN
, INFINITE
);
1058 /* write it to the shared memory */
1060 *((LPDWORD
)lpszSharedMem
) = getpid();
1062 *((LPDWORD
)lpszSharedMem
) = _getpid();
1065 wsprintf(lpszSharedMem
+ sizeof(DWORD
), "%s", achBuffer
);
1067 /* signal data ready event */
1068 SetEvent(heventData
);
1070 /* clean up handles */
1071 CloseHandle(hSharedFile
);
1072 CloseHandle(heventData
);
1073 CloseHandle(heventDBWIN
);
1082 #ifdef wxUSE_VC_CRTDBG
1084 // maximum mumber of lines the output console should have
1085 static const WORD MAX_CONSOLE_LINES
= 500;
1087 BOOL WINAPI
MyConsoleHandler( DWORD dwCtrlType
) { // control signal type
1092 void wxRedirectIOToConsole()
1096 CONSOLE_SCREEN_BUFFER_INFO coninfo
;
1099 // allocate a console for this app
1102 // set the screen buffer to be big enough to let us scroll text
1103 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE
),
1105 coninfo
.dwSize
.Y
= MAX_CONSOLE_LINES
;
1106 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE
),
1109 // redirect unbuffered STDOUT to the console
1110 lStdHandle
= (long)GetStdHandle(STD_OUTPUT_HANDLE
);
1111 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1112 if(hConHandle
<= 0) return;
1113 fp
= _fdopen( hConHandle
, "w" );
1115 setvbuf( stdout
, NULL
, _IONBF
, 0 );
1117 // redirect unbuffered STDIN to the console
1118 lStdHandle
= (long)GetStdHandle(STD_INPUT_HANDLE
);
1119 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1120 if(hConHandle
<= 0) return;
1121 fp
= _fdopen( hConHandle
, "r" );
1123 setvbuf( stdin
, NULL
, _IONBF
, 0 );
1125 // redirect unbuffered STDERR to the console
1126 lStdHandle
= (long)GetStdHandle(STD_ERROR_HANDLE
);
1127 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1128 if(hConHandle
<= 0) return;
1129 fp
= _fdopen( hConHandle
, "w" );
1131 setvbuf( stderr
, NULL
, _IONBF
, 0 );
1133 // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
1134 // point to console as well
1135 ios::sync_with_stdio();
1137 SetConsoleCtrlHandler(MyConsoleHandler
, TRUE
);
1142 void wxRedirectIOToConsole()