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 wxSleep(int nSecs
)
304 #if 0 // WIN32 hangs app
310 wxTheSleepTimer
= new wxSleepTimer
;
312 wxTheSleepTimer
->Start(nSecs
*1000);
315 if (wxTheApp
->Pending())
316 wxTheApp
->Dispatch();
318 delete wxTheSleepTimer
;
319 wxTheSleepTimer
= NULL
;
323 // Consume all events until no more left
329 // Output a debug mess., in a system dependent fashion.
330 void wxDebugMsg(const char *fmt
...)
333 static char buffer
[512];
335 if (!wxTheApp
->GetWantDebugOutput())
340 wvsprintf(buffer
,fmt
,ap
) ;
341 OutputDebugString((LPCSTR
)buffer
) ;
346 // Non-fatal error: pop up message box and (possibly) continue
347 void wxError(const wxString
& msg
, const wxString
& title
)
349 sprintf(wxBuffer
, "%s\nContinue?", WXSTRINGCAST msg
);
350 if (MessageBox(NULL
, (LPCSTR
)wxBuffer
, (LPCSTR
)WXSTRINGCAST title
,
351 MB_ICONSTOP
| MB_YESNO
) == IDNO
)
355 // Fatal error: pop up message box and abort
356 void wxFatalError(const wxString
& msg
, const wxString
& title
)
358 sprintf(wxBuffer
, "%s: %s", WXSTRINGCAST title
, WXSTRINGCAST msg
);
359 FatalAppExit(0, (LPCSTR
)wxBuffer
);
365 // Removed by RD because IHMO syncronous sound is a Bad Thing. MessageBeep
366 // will do a similar thing anyway if there is no sound card...
368 // Beep(1000,1000) ; // 1kHz during 1 sec.
370 MessageBeep((UINT
)-1) ;
374 // Chris Breeze 27/5/98: revised WIN32 code to
375 // detect WindowsNT correctly
376 int wxGetOsVersion(int *majorVsn
, int *minorVsn
)
378 extern char *wxOsVersion
;
379 if (majorVsn
) *majorVsn
= 0;
380 if (minorVsn
) *minorVsn
= 0;
382 #if defined(__WIN32__) && !defined(__SC__)
384 memset(&info
, 0, sizeof(OSVERSIONINFO
));
385 info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
386 if (GetVersionEx(&info
))
388 if (majorVsn
) *majorVsn
= info
.dwMajorVersion
;
389 if (minorVsn
) *minorVsn
= info
.dwMinorVersion
;
390 switch (info
.dwPlatformId
)
392 case VER_PLATFORM_WIN32s
:
395 case VER_PLATFORM_WIN32_WINDOWS
:
398 case VER_PLATFORM_WIN32_NT
:
403 return wxWINDOWS
; // error if we get here, return generic value
407 # ifdef __WINDOWS_386__
410 # if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
411 extern HANDLE g_hPenWin
;
412 retValue
= g_hPenWin
? wxPENWINDOWS
: wxWINDOWS
;
415 // @@@@ To be completed. I don't have the manual here...
416 if (majorVsn
) *majorVsn
= 3 ;
417 if (minorVsn
) *minorVsn
= 1 ;
422 // Reading and writing resources (eg WIN.INI, .Xdefaults)
424 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
)
427 return (WritePrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)value
, (LPCSTR
)WXSTRINGCAST file
) != 0);
429 return (WriteProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)WXSTRINGCAST value
) != 0);
432 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
)
435 sprintf(buf
, "%.4f", value
);
436 return wxWriteResource(section
, entry
, buf
, file
);
439 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
)
442 sprintf(buf
, "%ld", value
);
443 return wxWriteResource(section
, entry
, buf
, file
);
446 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
)
449 sprintf(buf
, "%d", value
);
450 return wxWriteResource(section
, entry
, buf
, file
);
453 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
)
455 static const char defunkt
[] = "$$default";
458 int n
= GetPrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
459 (LPSTR
)wxBuffer
, 1000, (LPCSTR
)WXSTRINGCAST file
);
460 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
465 int n
= GetProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
466 (LPSTR
)wxBuffer
, 1000);
467 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
470 if (*value
) delete[] (*value
);
471 *value
= copystring(wxBuffer
);
475 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
)
478 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
481 *value
= (float)strtod(s
, NULL
);
488 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
)
491 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
494 *value
= strtol(s
, NULL
, 10);
501 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
)
504 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
507 *value
= (int)strtol(s
, NULL
, 10);
513 #endif // wxUSE_RESOURCES
515 // ---------------------------------------------------------------------------
516 // helper functiosn for showing a "busy" cursor
517 // ---------------------------------------------------------------------------
519 extern HCURSOR gs_wxBusyCursor
= 0; // new, busy cursor
520 static HCURSOR gs_wxBusyCursorOld
= 0; // old cursor
521 static int gs_wxBusyCursorCount
= 0;
523 // Set the cursor to the busy cursor for all windows
524 void wxBeginBusyCursor(wxCursor
*cursor
)
526 if ( gs_wxBusyCursorCount
++ == 0 )
528 gs_wxBusyCursor
= (HCURSOR
)cursor
->GetHCURSOR();
529 gs_wxBusyCursorOld
= ::SetCursor(gs_wxBusyCursor
);
531 //else: nothing to do, already set
534 // Restore cursor to normal
535 void wxEndBusyCursor()
537 wxCHECK_RET( gs_wxBusyCursorCount
> 0,
538 "no matching wxBeginBusyCursor() for wxEndBusyCursor()" );
540 gs_wxBusyCursorCount
--;
541 if ( --gs_wxBusyCursorCount
== 0 )
543 ::SetCursor(gs_wxBusyCursorOld
);
545 gs_wxBusyCursorOld
= 0;
549 // TRUE if we're between the above two calls
552 return (gs_wxBusyCursorCount
> 0);
555 // ---------------------------------------------------------------------------
556 const char* wxGetHomeDir(wxString
*pstr
)
558 wxString
& strDir
= *pstr
;
560 #if defined(__UNIX__) && !defined(__TWIN32__)
561 const char *szHome
= getenv("HOME");
562 if ( szHome
== NULL
) {
564 wxLogWarning(_("can't find user's HOME, using current directory."));
570 // add a trailing slash if needed
571 if ( strDir
.Last() != '/' )
575 const char *szHome
= getenv("HOMEDRIVE");
576 if ( szHome
!= NULL
)
578 szHome
= getenv("HOMEPATH");
579 if ( szHome
!= NULL
) {
582 // the idea is that under NT these variables have default values
583 // of "%systemdrive%:" and "\\". As we don't want to create our
584 // config files in the root directory of the system drive, we will
585 // create it in our program's dir. However, if the user took care
586 // to set HOMEPATH to something other than "\\", we suppose that he
587 // knows what he is doing and use the supplied value.
588 if ( strcmp(szHome
, "\\") != 0 )
589 return strDir
.c_str();
593 // Win16 has no idea about home, so use the working directory instead
596 // 260 was taken from windef.h
602 ::GetModuleFileName(::GetModuleHandle(NULL
),
603 strPath
.GetWriteBuf(MAX_PATH
), MAX_PATH
);
604 strPath
.UngetWriteBuf();
606 // extract the dir name
607 wxSplitPath(strPath
, &strDir
, NULL
, NULL
);
611 return strDir
.c_str();
615 char *wxGetUserHome (const wxString
& user
)
618 wxString
user1(user
);
622 if (wxGetUserId(tmp
, sizeof(tmp
)/sizeof(char))) {
623 // Guests belong in the temp dir
624 if (Stricmp(tmp
, "annonymous") == 0) {
625 if ((home
= getenv("TMP")) != NULL
||
626 (home
= getenv("TMPDIR")) != NULL
||
627 (home
= getenv("TEMP")) != NULL
)
628 return *home
? home
: "\\";
630 if (Stricmp(tmp
, WXSTRINGCAST user1
) == 0)
635 if ((home
= getenv("HOME")) != NULL
)
637 strcpy(wxBuffer
, home
);
638 Unix2DosFilename(wxBuffer
);
641 return NULL
; // No home known!
644 // Check whether this window wants to process messages, e.g. Stop button
645 // in long calculations.
646 bool wxCheckForInterrupt(wxWindow
*wnd
)
650 HWND win
= (HWND
) wnd
->GetHWND();
651 while(PeekMessage(&msg
,win
,0,0,PM_REMOVE
)){
652 TranslateMessage(&msg
);
653 DispatchMessage(&msg
);
655 return TRUE
;//*** temporary?
658 wxFAIL_MSG("wnd==NULL !!!");
660 return FALSE
;//*** temporary?
664 // MSW only: get user-defined resource from the .res file.
665 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
668 char *wxLoadUserResource(const wxString
& resourceName
, const wxString
& resourceType
)
671 #if !defined(__WIN32__) || defined(__TWIN32__)
672 HRSRC hResource
= ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
675 HRSRC hResource
= ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
677 HRSRC hResource
= ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
683 HGLOBAL hData
= ::LoadResource(wxGetInstance(), hResource
);
686 char *theText
= (char *)LockResource(hData
);
690 s
= copystring(theText
);
694 UnlockResource(hData
);
698 // GlobalFree(hData);
704 void wxGetMousePosition( int* x
, int* y
)
707 GetCursorPos( & pt
);
712 // Return TRUE if we have a colour display
713 bool wxColourDisplay()
715 HDC dc
= ::GetDC((HWND
) NULL
);
717 int noCols
= GetDeviceCaps(dc
, NUMCOLORS
);
718 if ((noCols
== -1) || (noCols
> 2))
722 ReleaseDC((HWND
) NULL
, dc
);
726 // Returns depth of screen
729 HDC dc
= ::GetDC((HWND
) NULL
);
730 int planes
= GetDeviceCaps(dc
, PLANES
);
731 int bitsPerPixel
= GetDeviceCaps(dc
, BITSPIXEL
);
732 int depth
= planes
*bitsPerPixel
;
733 ReleaseDC((HWND
) NULL
, dc
);
737 // Get size of display
738 void wxDisplaySize(int *width
, int *height
)
740 HDC dc
= ::GetDC((HWND
) NULL
);
741 *width
= GetDeviceCaps(dc
, HORZRES
); *height
= GetDeviceCaps(dc
, VERTRES
);
742 ReleaseDC((HWND
) NULL
, dc
);
745 bool wxDirExists(const wxString
& dir
)
747 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
748 #if defined(__WIN32__)
749 WIN32_FIND_DATA fileInfo
;
752 struct ffblk fileInfo
;
754 struct find_t fileInfo
;
758 #if defined(__WIN32__)
759 HANDLE h
= FindFirstFile((LPTSTR
) WXSTRINGCAST dir
,(LPWIN32_FIND_DATA
)&fileInfo
);
761 if (h
==INVALID_HANDLE_VALUE
)
765 return ((fileInfo
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) == FILE_ATTRIBUTE_DIRECTORY
);
768 // In Borland findfirst has a different argument
769 // ordering from _dos_findfirst. But _dos_findfirst
770 // _should_ be ok in both MS and Borland... why not?
772 return ((findfirst(WXSTRINGCAST dir
, &fileInfo
, _A_SUBDIR
) == 0 && (fileInfo
.ff_attrib
& _A_SUBDIR
) != 0));
774 return (((_dos_findfirst(WXSTRINGCAST dir
, _A_SUBDIR
, &fileInfo
) == 0) && (fileInfo
.attrib
& _A_SUBDIR
)) != 0);
779 wxString WXDLLEXPORT
wxGetWindowText(WXHWND hWnd
)
782 int len
= GetWindowTextLength((HWND
)hWnd
) + 1;
783 GetWindowText((HWND
)hWnd
, str
.GetWriteBuf(len
), len
);
790 //------------------------------------------------------------------------
791 // wild character routines
792 //------------------------------------------------------------------------
794 bool wxIsWild( const wxString
& pattern
)
796 wxString tmp
= pattern
;
797 char *pat
= WXSTRINGCAST(tmp
);
800 case '?': case '*': case '[': case '{':
811 bool wxMatchWild( const wxString
& pat
, const wxString
& text
, bool dot_special
)
814 char *pattern
= WXSTRINGCAST(tmp1
);
815 wxString tmp2
= text
;
816 char *str
= WXSTRINGCAST(tmp2
);
819 bool done
= FALSE
, ret_code
, ok
;
820 // Below is for vi fans
821 const char OB
= '{', CB
= '}';
823 // dot_special means '.' only matches '.'
824 if (dot_special
&& *str
== '.' && *pattern
!= *str
)
827 while ((*pattern
!= '\0') && (!done
)
828 && (((*str
=='\0')&&((*pattern
==OB
)||(*pattern
=='*')))||(*str
!='\0'))) {
832 if (*pattern
!= '\0')
839 && (!(ret_code
=wxMatchWild(pattern
, str
++, FALSE
))))
844 while (*pattern
!= '\0')
851 if ((*pattern
== '\0') || (*pattern
== ']')) {
855 if (*pattern
== '\\') {
857 if (*pattern
== '\0') {
862 if (*(pattern
+ 1) == '-') {
865 if (*pattern
== ']') {
869 if (*pattern
== '\\') {
871 if (*pattern
== '\0') {
876 if ((*str
< c
) || (*str
> *pattern
)) {
880 } else if (*pattern
!= *str
) {
885 while ((*pattern
!= ']') && (*pattern
!= '\0')) {
886 if ((*pattern
== '\\') && (*(pattern
+ 1) != '\0'))
890 if (*pattern
!= '\0') {
900 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
903 while (ok
&& (*cp
!= '\0') && (*pattern
!= '\0')
904 && (*pattern
!= ',') && (*pattern
!= CB
)) {
905 if (*pattern
== '\\')
907 ok
= (*pattern
++ == *cp
++);
909 if (*pattern
== '\0') {
915 while ((*pattern
!= CB
) && (*pattern
!= '\0')) {
916 if (*++pattern
== '\\') {
917 if (*++pattern
== CB
)
922 while (*pattern
!=CB
&& *pattern
!=',' && *pattern
!='\0') {
923 if (*++pattern
== '\\') {
924 if (*++pattern
== CB
|| *pattern
== ',')
929 if (*pattern
!= '\0')
934 if (*str
== *pattern
) {
941 while (*pattern
== '*')
943 return ((*str
== '\0') && (*pattern
== '\0'));
948 #if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
951 When I started programming with Visual C++ v4.0, I missed one of my favorite
952 tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
953 on MSDN was a step in the right direction, but it is a console application
954 and thus has limited features and extensibility. DBWIN32 is my creation
955 to solve this problem.
957 The code is essentially a merging of a stripped down version of the DBWIN code
958 from VC 1.5 and DBMON.C with a few 32 bit changes.
960 As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
961 built into the operating system and works just by running DBWIN32. The Win95
962 team decided not to support this hook, so I have provided code that will do
963 this for you. See the file WIN95.TXT for instructions on installing this.
965 If you have questions, problems or suggestions about DBWIN32, I welcome your
966 feedback and plan to actively maintain the code.
971 To download dbwin32, see e.g.:
973 http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
976 #if !defined(__MWERKS__) && !defined(__SALFORDC__) && !defined(__TWIN32__)
980 void OutputDebugStringW95(const char* lpOutputString
, ...)
982 HANDLE heventDBWIN
; /* DBWIN32 synchronization object */
983 HANDLE heventData
; /* data passing synch object */
984 HANDLE hSharedFile
; /* memory mapped file shared data */
988 /* create the output buffer */
990 va_start(args
, lpOutputString
);
991 vsprintf(achBuffer
, lpOutputString
, args
);
995 Do a regular OutputDebugString so that the output is
996 still seen in the debugger window if it exists.
998 This ifdef is necessary to avoid infinite recursion
999 from the inclusion of W95TRACE.H
1002 ::OutputDebugStringW(achBuffer
);
1005 ::OutputDebugString(achBuffer
);
1007 ::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 */
1059 #if defined( __BORLANDC__ ) || defined( __MWERKS__ ) || defined(__SALFORDC__)
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
);
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
);
1141 void wxRedirectIOToConsole()