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
80 #include "wx/msw/msvcrt.h"
84 #include "wx/ioswrap.h"
87 // N.B. BC++ doesn't have istream.h, ostream.h
94 /* Need to undef new if including crtdbg.h */
103 # if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS && wxUSE_DEBUG_NEW_ALWAYS
104 # define new new(__FILE__,__LINE__)
109 /// END for console support
111 // In the WIN.INI file
112 static const char WX_SECTION
[] = "wxWindows";
113 static const char eHOSTNAME
[] = "HostName";
114 static const char eUSERID
[] = "UserId";
115 static const char eUSERNAME
[] = "UserName";
117 // For the following functions we SHOULD fill in support
118 // for Windows-NT (which I don't know) as I assume it begin
119 // a POSIX Unix (so claims MS) that it has some special
120 // functions beyond those provided by WinSock
122 // Get full hostname (eg. DoDo.BSn-Germany.crg.de)
123 bool wxGetHostName(char *buf
, int maxSize
)
125 #if defined(__WIN32__) && !defined(__TWIN32__)
126 DWORD nSize
= maxSize
;
127 return (::GetComputerName(buf
, &nSize
) != 0);
130 const char *default_host
= "noname";
132 if ((sysname
= getenv("SYSTEM_NAME")) == NULL
) {
133 GetProfileString(WX_SECTION
, eHOSTNAME
, default_host
, buf
, maxSize
- 1);
135 strncpy(buf
, sysname
, maxSize
- 1);
137 return *buf
? TRUE
: FALSE
;
141 // Get user ID e.g. jacs
142 bool wxGetUserId(char *buf
, int maxSize
)
144 #if defined(__WIN32__) && !defined(__win32s__) && !defined(__TWIN32__)
146 // VZ: why should it be so complicated??
148 // Gets the current user's full name according to the MS article PSS ID
150 // Seems to be the same as the login name for me?
151 char *UserName
= new char[256];
152 char *Domain
= new char[256];
153 DWORD maxCharacters
= 255;
154 GetUserName( UserName
, &maxCharacters
);
155 GetComputerName( Domain
, &maxCharacters
);
157 WCHAR wszUserName
[256]; // Unicode user name
158 WCHAR wszDomain
[256];
161 struct _SERVER_INFO_100
*si100
; // Server structure
162 struct _USER_INFO_2
*ui
; // User structure
164 // Convert ASCII user name and domain to Unicode.
166 MultiByteToWideChar( CP_ACP
, 0, UserName
,
167 strlen(UserName
)+1, wszUserName
, sizeof(wszUserName
) );
168 MultiByteToWideChar( CP_ACP
, 0, Domain
,
169 strlen(Domain
)+1, wszDomain
, sizeof(wszDomain
) );
171 // Get the computer name of a DC for the specified domain.
172 // >If you get a link error on this, include netapi32.lib<
174 NetGetDCName( NULL
, wszDomain
, &ComputerName
);
176 // Look up the user on the DC.
178 if(NetUserGetInfo( (LPWSTR
) ComputerName
,
179 (LPWSTR
) &wszUserName
, 2, (LPBYTE
*) &ui
))
181 printf( "Error getting user information.\n" );
185 // Convert the Unicode full name to ASCII.
187 WideCharToMultiByte( CP_ACP
, 0, ui
->usri2_full_name
,
188 -1, buf
, 256, NULL
, NULL
);
192 DWORD nSize
= maxSize
;
193 if ( ::GetUserName(buf
, &nSize
) == 0 )
195 wxLogSysError("Can not get user name");
203 #else // Win16 or Win32s
205 const char *default_id
= "anonymous";
207 // Can't assume we have NIS (PC-NFS) or some other ID daemon
209 if ( (user
= getenv("USER")) == NULL
&&
210 (user
= getenv("LOGNAME")) == NULL
) {
211 // Use wxWindows configuration data (comming soon)
212 GetProfileString(WX_SECTION
, eUSERID
, default_id
, buf
, maxSize
- 1);
214 strncpy(buf
, user
, maxSize
- 1);
215 return *buf
? TRUE
: FALSE
;
219 // Get user name e.g. Julian Smart
220 bool wxGetUserName(char *buf
, int maxSize
)
222 #if wxUSE_PENWINDOWS && !defined(__WATCOMC__) && !defined(__GNUWIN32__)
223 extern HANDLE g_hPenWin
; // PenWindows Running?
226 // PenWindows Does have a user concept!
227 // Get the current owner of the recognizer
228 GetPrivateProfileString("Current", "User", default_name
, wxBuffer
, maxSize
- 1, "PENWIN.INI");
229 strncpy(buf
, wxBuffer
, maxSize
- 1);
234 // Could use NIS, MS-Mail or other site specific programs
235 // Use wxWindows configuration data
236 bool ok
= GetProfileString(WX_SECTION
, eUSERNAME
, "", buf
, maxSize
- 1) != 0;
239 ok
= wxGetUserId(buf
, maxSize
);
244 strncpy(buf
, "Unknown User", maxSize
);
251 int wxKill(long pid
, int sig
)
257 // Execute a program in an Interactive Shell
260 wxShell(const wxString
& command
)
263 if ((shell
= getenv("COMSPEC")) == NULL
)
264 shell
= "\\COMMAND.COM";
268 sprintf(tmp
, "%s /c %s", shell
, WXSTRINGCAST command
);
272 return (wxExecute((char *)tmp
, FALSE
) != 0);
275 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
276 long wxGetFreeMemory()
278 #if defined(__WIN32__) && !defined(__BORLANDC__) && !defined(__TWIN32__)
279 MEMORYSTATUS memStatus
;
280 memStatus
.dwLength
= sizeof(MEMORYSTATUS
);
281 GlobalMemoryStatus(&memStatus
);
282 return memStatus
.dwAvailPhys
;
284 return (long)GetFreeSpace(0);
288 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
289 static bool inTimer
= FALSE
;
290 class wxSleepTimer
: public wxTimer
300 static wxTimer
*wxTheSleepTimer
= NULL
;
302 void wxUsleep(unsigned long milliseconds
)
304 ::Sleep(milliseconds
);
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
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;
387 #if defined(__WIN32__) && !defined(__SC__)
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
520 // ---------------------------------------------------------------------------
521 // helper functiosn for showing a "busy" cursor
522 // ---------------------------------------------------------------------------
524 extern HCURSOR gs_wxBusyCursor
= 0; // new, busy cursor
525 static HCURSOR gs_wxBusyCursorOld
= 0; // old cursor
526 static int gs_wxBusyCursorCount
= 0;
528 // Set the cursor to the busy cursor for all windows
529 void wxBeginBusyCursor(wxCursor
*cursor
)
531 if ( gs_wxBusyCursorCount
++ == 0 )
533 gs_wxBusyCursor
= (HCURSOR
)cursor
->GetHCURSOR();
534 gs_wxBusyCursorOld
= ::SetCursor(gs_wxBusyCursor
);
536 //else: nothing to do, already set
539 // Restore cursor to normal
540 void wxEndBusyCursor()
542 wxCHECK_RET( gs_wxBusyCursorCount
> 0,
543 "no matching wxBeginBusyCursor() for wxEndBusyCursor()" );
545 if ( --gs_wxBusyCursorCount
== 0 )
547 ::SetCursor(gs_wxBusyCursorOld
);
549 gs_wxBusyCursorOld
= 0;
553 // TRUE if we're between the above two calls
556 return (gs_wxBusyCursorCount
> 0);
559 // ---------------------------------------------------------------------------
560 const char* wxGetHomeDir(wxString
*pstr
)
562 wxString
& strDir
= *pstr
;
564 #if defined(__UNIX__) && !defined(__TWIN32__)
565 const char *szHome
= getenv("HOME");
566 if ( szHome
== NULL
) {
568 wxLogWarning(_("can't find user's HOME, using current directory."));
574 // add a trailing slash if needed
575 if ( strDir
.Last() != '/' )
579 const char *szHome
= getenv("HOMEDRIVE");
580 if ( szHome
!= NULL
)
582 szHome
= getenv("HOMEPATH");
583 if ( szHome
!= NULL
) {
586 // the idea is that under NT these variables have default values
587 // of "%systemdrive%:" and "\\". As we don't want to create our
588 // config files in the root directory of the system drive, we will
589 // create it in our program's dir. However, if the user took care
590 // to set HOMEPATH to something other than "\\", we suppose that he
591 // knows what he is doing and use the supplied value.
592 if ( strcmp(szHome
, "\\") != 0 )
593 return strDir
.c_str();
597 // Win16 has no idea about home, so use the working directory instead
600 // 260 was taken from windef.h
606 ::GetModuleFileName(::GetModuleHandle(NULL
),
607 strPath
.GetWriteBuf(MAX_PATH
), MAX_PATH
);
608 strPath
.UngetWriteBuf();
610 // extract the dir name
611 wxSplitPath(strPath
, &strDir
, NULL
, NULL
);
615 return strDir
.c_str();
619 char *wxGetUserHome (const wxString
& user
)
622 wxString
user1(user
);
626 if (wxGetUserId(tmp
, sizeof(tmp
)/sizeof(char))) {
627 // Guests belong in the temp dir
628 if (Stricmp(tmp
, "annonymous") == 0) {
629 if ((home
= getenv("TMP")) != NULL
||
630 (home
= getenv("TMPDIR")) != NULL
||
631 (home
= getenv("TEMP")) != NULL
)
632 return *home
? home
: "\\";
634 if (Stricmp(tmp
, WXSTRINGCAST user1
) == 0)
639 if ((home
= getenv("HOME")) != NULL
)
641 strcpy(wxBuffer
, home
);
642 Unix2DosFilename(wxBuffer
);
645 return NULL
; // No home known!
648 // Check whether this window wants to process messages, e.g. Stop button
649 // in long calculations.
650 bool wxCheckForInterrupt(wxWindow
*wnd
)
654 HWND win
= (HWND
) wnd
->GetHWND();
655 while(PeekMessage(&msg
,win
,0,0,PM_REMOVE
)){
656 TranslateMessage(&msg
);
657 DispatchMessage(&msg
);
659 return TRUE
;//*** temporary?
662 wxFAIL_MSG("wnd==NULL !!!");
664 return FALSE
;//*** temporary?
668 // MSW only: get user-defined resource from the .res file.
669 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
672 char *wxLoadUserResource(const wxString
& resourceName
, const wxString
& resourceType
)
675 #if !defined(__WIN32__) || defined(__TWIN32__)
676 HRSRC hResource
= ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
679 HRSRC hResource
= ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
681 HRSRC hResource
= ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
687 HGLOBAL hData
= ::LoadResource(wxGetInstance(), hResource
);
690 char *theText
= (char *)LockResource(hData
);
694 s
= copystring(theText
);
698 UnlockResource(hData
);
702 // GlobalFree(hData);
708 void wxGetMousePosition( int* x
, int* y
)
711 GetCursorPos( & pt
);
716 // Return TRUE if we have a colour display
717 bool wxColourDisplay()
719 HDC dc
= ::GetDC((HWND
) NULL
);
721 int noCols
= GetDeviceCaps(dc
, NUMCOLORS
);
722 if ((noCols
== -1) || (noCols
> 2))
726 ReleaseDC((HWND
) NULL
, dc
);
730 // Returns depth of screen
733 HDC dc
= ::GetDC((HWND
) NULL
);
734 int planes
= GetDeviceCaps(dc
, PLANES
);
735 int bitsPerPixel
= GetDeviceCaps(dc
, BITSPIXEL
);
736 int depth
= planes
*bitsPerPixel
;
737 ReleaseDC((HWND
) NULL
, dc
);
741 // Get size of display
742 void wxDisplaySize(int *width
, int *height
)
744 HDC dc
= ::GetDC((HWND
) NULL
);
745 *width
= GetDeviceCaps(dc
, HORZRES
); *height
= GetDeviceCaps(dc
, VERTRES
);
746 ReleaseDC((HWND
) NULL
, dc
);
749 bool wxDirExists(const wxString
& dir
)
751 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
752 #if defined(__WIN32__)
753 WIN32_FIND_DATA fileInfo
;
756 struct ffblk fileInfo
;
758 struct find_t fileInfo
;
762 #if defined(__WIN32__)
763 HANDLE h
= FindFirstFile((LPTSTR
) WXSTRINGCAST dir
,(LPWIN32_FIND_DATA
)&fileInfo
);
765 if (h
==INVALID_HANDLE_VALUE
)
769 return ((fileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) == FILE_ATTRIBUTE_DIRECTORY
);
772 // In Borland findfirst has a different argument
773 // ordering from _dos_findfirst. But _dos_findfirst
774 // _should_ be ok in both MS and Borland... why not?
776 return ((findfirst(WXSTRINGCAST dir
, &fileInfo
, _A_SUBDIR
) == 0 && (fileInfo
.ff_attrib
& _A_SUBDIR
) != 0));
778 return (((_dos_findfirst(WXSTRINGCAST dir
, _A_SUBDIR
, &fileInfo
) == 0) && (fileInfo
.attrib
& _A_SUBDIR
)) != 0);
783 wxString WXDLLEXPORT
wxGetWindowText(WXHWND hWnd
)
786 int len
= GetWindowTextLength((HWND
)hWnd
) + 1;
787 GetWindowText((HWND
)hWnd
, str
.GetWriteBuf(len
), len
);
794 //------------------------------------------------------------------------
795 // wild character routines
796 //------------------------------------------------------------------------
798 bool wxIsWild( const wxString
& pattern
)
800 wxString tmp
= pattern
;
801 char *pat
= WXSTRINGCAST(tmp
);
804 case '?': case '*': case '[': case '{':
815 bool wxMatchWild( const wxString
& pat
, const wxString
& text
, bool dot_special
)
818 char *pattern
= WXSTRINGCAST(tmp1
);
819 wxString tmp2
= text
;
820 char *str
= WXSTRINGCAST(tmp2
);
823 bool done
= FALSE
, ret_code
, ok
;
824 // Below is for vi fans
825 const char OB
= '{', CB
= '}';
827 // dot_special means '.' only matches '.'
828 if (dot_special
&& *str
== '.' && *pattern
!= *str
)
831 while ((*pattern
!= '\0') && (!done
)
832 && (((*str
=='\0')&&((*pattern
==OB
)||(*pattern
=='*')))||(*str
!='\0'))) {
836 if (*pattern
!= '\0')
843 && (!(ret_code
=wxMatchWild(pattern
, str
++, FALSE
))))
848 while (*pattern
!= '\0')
855 if ((*pattern
== '\0') || (*pattern
== ']')) {
859 if (*pattern
== '\\') {
861 if (*pattern
== '\0') {
866 if (*(pattern
+ 1) == '-') {
869 if (*pattern
== ']') {
873 if (*pattern
== '\\') {
875 if (*pattern
== '\0') {
880 if ((*str
< c
) || (*str
> *pattern
)) {
884 } else if (*pattern
!= *str
) {
889 while ((*pattern
!= ']') && (*pattern
!= '\0')) {
890 if ((*pattern
== '\\') && (*(pattern
+ 1) != '\0'))
894 if (*pattern
!= '\0') {
904 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
907 while (ok
&& (*cp
!= '\0') && (*pattern
!= '\0')
908 && (*pattern
!= ',') && (*pattern
!= CB
)) {
909 if (*pattern
== '\\')
911 ok
= (*pattern
++ == *cp
++);
913 if (*pattern
== '\0') {
919 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
920 if (*++pattern
== '\\') {
921 if (*++pattern
== CB
)
926 while (*pattern
!=CB
&& *pattern
!=',' && *pattern
!='\0') {
927 if (*++pattern
== '\\') {
928 if (*++pattern
== CB
|| *pattern
== ',')
933 if (*pattern
!= '\0')
938 if (*str
== *pattern
) {
945 while (*pattern
== '*')
947 return ((*str
== '\0') && (*pattern
== '\0'));
952 #if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
955 When I started programming with Visual C++ v4.0, I missed one of my favorite
956 tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
957 on MSDN was a step in the right direction, but it is a console application
958 and thus has limited features and extensibility. DBWIN32 is my creation
959 to solve this problem.
961 The code is essentially a merging of a stripped down version of the DBWIN code
962 from VC 1.5 and DBMON.C with a few 32 bit changes.
964 As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
965 built into the operating system and works just by running DBWIN32. The Win95
966 team decided not to support this hook, so I have provided code that will do
967 this for you. See the file WIN95.TXT for instructions on installing this.
969 If you have questions, problems or suggestions about DBWIN32, I welcome your
970 feedback and plan to actively maintain the code.
975 To download dbwin32, see e.g.:
977 http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
980 #if !defined(__MWERKS__) && !defined(__SALFORDC__) && !defined(__TWIN32__)
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
);
1009 ::OutputDebugString(achBuffer
);
1011 ::OutputDebugStringA(achBuffer
);
1015 /* bail if it's not Win95 */
1017 OSVERSIONINFO VerInfo
;
1018 VerInfo
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
1019 GetVersionEx(&VerInfo
);
1020 if ( VerInfo
.dwPlatformId
!= VER_PLATFORM_WIN32_WINDOWS
)
1024 /* make sure DBWIN is open and waiting */
1025 heventDBWIN
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_BUFFER_READY");
1028 //MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
1032 /* get a handle to the data synch object */
1033 heventData
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, "DBWIN_DATA_READY");
1036 // MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
1037 CloseHandle(heventDBWIN
);
1041 hSharedFile
= CreateFileMapping((HANDLE
)-1, NULL
, PAGE_READWRITE
, 0, 4096, "DBWIN_BUFFER");
1044 //MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
1045 CloseHandle(heventDBWIN
);
1046 CloseHandle(heventData
);
1050 lpszSharedMem
= (LPSTR
)MapViewOfFile(hSharedFile
, FILE_MAP_WRITE
, 0, 0, 512);
1053 //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
1054 CloseHandle(heventDBWIN
);
1055 CloseHandle(heventData
);
1059 /* wait for buffer event */
1060 WaitForSingleObject(heventDBWIN
, INFINITE
);
1062 /* write it to the shared memory */
1063 #if defined( __BORLANDC__ ) || defined( __MWERKS__ ) || defined(__SALFORDC__)
1064 *((LPDWORD
)lpszSharedMem
) = getpid();
1066 *((LPDWORD
)lpszSharedMem
) = _getpid();
1069 wsprintf(lpszSharedMem
+ sizeof(DWORD
), "%s", achBuffer
);
1071 /* signal data ready event */
1072 SetEvent(heventData
);
1074 /* clean up handles */
1075 CloseHandle(hSharedFile
);
1076 CloseHandle(heventData
);
1077 CloseHandle(heventDBWIN
);
1088 // maximum mumber of lines the output console should have
1089 static const WORD MAX_CONSOLE_LINES
= 500;
1091 BOOL WINAPI
MyConsoleHandler( DWORD dwCtrlType
) { // control signal type
1096 void wxRedirectIOToConsole()
1100 CONSOLE_SCREEN_BUFFER_INFO coninfo
;
1103 // allocate a console for this app
1106 // set the screen buffer to be big enough to let us scroll text
1107 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE
),
1109 coninfo
.dwSize
.Y
= MAX_CONSOLE_LINES
;
1110 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE
),
1113 // redirect unbuffered STDOUT to the console
1114 lStdHandle
= (long)GetStdHandle(STD_OUTPUT_HANDLE
);
1115 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1116 if(hConHandle
<= 0) return;
1117 fp
= _fdopen( hConHandle
, "w" );
1119 setvbuf( stdout
, NULL
, _IONBF
, 0 );
1121 // redirect unbuffered STDIN to the console
1122 lStdHandle
= (long)GetStdHandle(STD_INPUT_HANDLE
);
1123 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1124 if(hConHandle
<= 0) return;
1125 fp
= _fdopen( hConHandle
, "r" );
1127 setvbuf( stdin
, NULL
, _IONBF
, 0 );
1129 // redirect unbuffered STDERR to the console
1130 lStdHandle
= (long)GetStdHandle(STD_ERROR_HANDLE
);
1131 hConHandle
= _open_osfhandle(lStdHandle
, _O_TEXT
);
1132 if(hConHandle
<= 0) return;
1133 fp
= _fdopen( hConHandle
, "w" );
1135 setvbuf( stderr
, NULL
, _IONBF
, 0 );
1137 // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
1138 // point to console as well
1139 ios::sync_with_stdio();
1141 SetConsoleCtrlHandler(MyConsoleHandler
, TRUE
);
1145 void wxRedirectIOToConsole()