]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/msw/utils.cpp
Fixes for WXWIN_COMPATIBILITY, and BC++ fix for event.cpp
[wxWidgets.git] / src / msw / utils.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: utils.cpp
3// Purpose: Various utilities
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13// #pragma implementation "utils.h" // Note: this is done in utilscmn.cpp now.
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include "wx/setup.h"
25#include "wx/utils.h"
26#include "wx/app.h"
27#include "wx/cursor.h"
28#endif //WX_PRECOMP
29
30#include "wx/msw/private.h"
31#include "wx/timer.h"
32
33#include <ctype.h>
34
35#ifndef __GNUWIN32__
36#include <direct.h>
37#include <dos.h>
38#endif //GNUWIN32
39
40#ifdef __GNUWIN32__
41#include <sys/unistd.h>
42#include <sys/stat.h>
43#endif //GNUWIN32
44
45#include "wx/log.h"
46
47#ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
48 // this (3.1 I believe) and how to test for it.
49 // If this works for Borland 4.0 as well, then no worries.
50#include <dir.h>
51#endif
52
53#ifdef __WIN32__
54#include <io.h>
55
56#ifndef __GNUWIN32__
57#include <shellapi.h>
58#endif
59#endif
60
61#include <stdio.h>
62#include <stdlib.h>
63#include <string.h>
64#ifndef __WATCOMC__
65#if !(defined(_MSC_VER) && (_MSC_VER > 800))
66#include <errno.h>
67#endif
68#endif
69#include <stdarg.h>
70
71// In the WIN.INI file
72static const char WX_SECTION[] = "wxWindows";
73static const char eHOSTNAME[] = "HostName";
74static const char eUSERID[] = "UserId";
75static const char eUSERNAME[] = "UserName";
76
77// For the following functions we SHOULD fill in support
78// for Windows-NT (which I don't know) as I assume it begin
79// a POSIX Unix (so claims MS) that it has some special
80// functions beyond those provided by WinSock
81
82// Get full hostname (eg. DoDo.BSn-Germany.crg.de)
83bool wxGetHostName(char *buf, int maxSize)
84{
85#ifdef __WIN32__
86 DWORD nSize = maxSize;
87 return (::GetComputerName(buf, &nSize) != 0);
88#else
89 char *sysname;
90 const char *default_host = "noname";
91
92 if ((sysname = getenv("SYSTEM_NAME")) == NULL) {
93 GetProfileString(WX_SECTION, eHOSTNAME, default_host, buf, maxSize - 1);
94 } else
95 strncpy(buf, sysname, maxSize - 1);
96 buf[maxSize] = '\0';
97 return *buf ? TRUE : FALSE;
98#endif
99}
100
101// Get user ID e.g. jacs
102bool wxGetUserId(char *buf, int maxSize)
103{
104#if defined(__WIN32__) && !defined(__win32s__) && 0
105 // Gets the current user's full name according to the MS article PSS ID
106 // Number: Q119670
107 // Seems to be the same as the login name for me?
108 char *UserName = new char[256];
109 char *Domain = new char[256];
110 DWORD maxCharacters = 255;
111 GetUserName( UserName, &maxCharacters );
112 GetComputerName( Domain, &maxCharacters );
113
114 WCHAR wszUserName[256]; // Unicode user name
115 WCHAR wszDomain[256];
116 LPBYTE ComputerName;
117
118 struct _SERVER_INFO_100 *si100; // Server structure
119 struct _USER_INFO_2 *ui; // User structure
120
121 // Convert ASCII user name and domain to Unicode.
122
123 MultiByteToWideChar( CP_ACP, 0, UserName,
124 strlen(UserName)+1, wszUserName, sizeof(wszUserName) );
125 MultiByteToWideChar( CP_ACP, 0, Domain,
126 strlen(Domain)+1, wszDomain, sizeof(wszDomain) );
127
128 // Get the computer name of a DC for the specified domain.
129 // >If you get a link error on this, include netapi32.lib<
130
131 NetGetDCName( NULL, wszDomain, &ComputerName );
132
133 // Look up the user on the DC.
134
135 if(NetUserGetInfo( (LPWSTR) ComputerName,
136 (LPWSTR) &wszUserName, 2, (LPBYTE *) &ui))
137 {
138 printf( "Error getting user information.\n" );
139 return( FALSE );
140 }
141
142 // Convert the Unicode full name to ASCII.
143
144 WideCharToMultiByte( CP_ACP, 0, ui->usri2_full_name,
145 -1, buf, 256, NULL, NULL );
146 }
147 return( TRUE );
148/*
149 DWORD nSize = maxSize;
150 return ::GetUserName(buf, &nSize);
151*/
152#else
153 char *user;
154 const char *default_id = "anonymous";
155
156 // Can't assume we have NIS (PC-NFS) or some other ID daemon
157 // So we ...
158 if ( (user = getenv("USER")) == NULL &&
159 (user = getenv("LOGNAME")) == NULL ) {
160 // Use wxWindows configuration data (comming soon)
161 GetProfileString(WX_SECTION, eUSERID, default_id, buf, maxSize - 1);
162 } else
163 strncpy(buf, user, maxSize - 1);
164 return *buf ? TRUE : FALSE;
165#endif
166}
167
168// Get user name e.g. Julian Smart
169bool wxGetUserName(char *buf, int maxSize)
170{
171 const char *default_name = "Unknown User";
172#if defined(__WIN32__)
173/*
174 DWORD nSize = maxSize;
175 In VC++ 4.0, results in unresolved symbol __imp__GetUserNameA
176 if (GetUserName(buf, &nSize))
177 return TRUE;
178 else
179*/
180 // Could use NIS, MS-Mail or other site specific programs
181 // Use wxWindows configuration data
182 GetProfileString(WX_SECTION, eUSERNAME, default_name, buf, maxSize - 1);
183 return *buf ? TRUE : FALSE;
184// }
185#else
186#if !defined(__WATCOMC__) && !defined(__GNUWIN32__) && wxUSE_PENWINDOWS
187 extern HANDLE g_hPenWin; // PenWindows Running?
188 if (g_hPenWin)
189 {
190 // PenWindows Does have a user concept!
191 // Get the current owner of the recognizer
192 GetPrivateProfileString("Current", "User", default_name, wxBuffer, maxSize - 1, "PENWIN.INI");
193 strncpy(buf, wxBuffer, maxSize - 1);
194 }
195 else
196#endif
197 {
198 // Could use NIS, MS-Mail or other site specific programs
199 // Use wxWindows configuration data
200 GetProfileString(WX_SECTION, eUSERNAME, default_name, buf, maxSize - 1);
201 }
202 return *buf ? TRUE : FALSE;
203#endif
204}
205
206int wxKill(long pid, int sig)
207{
208 return 0;
209}
210
211//
212// Execute a program in an Interactive Shell
213//
214bool
215wxShell(const wxString& command)
216{
217 char *shell;
218 if ((shell = getenv("COMSPEC")) == NULL)
219 shell = "\\COMMAND.COM";
220
221 char tmp[255];
222 if (command != "")
223 sprintf(tmp, "%s /c %s", shell, WXSTRINGCAST command);
224 else
225 strcpy(tmp, shell);
226
227 return (wxExecute((char *)tmp, FALSE) != 0);
228}
229
230// Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
231long wxGetFreeMemory(void)
232{
233#if defined(__WIN32__) && !defined(__BORLANDC__)
234 MEMORYSTATUS memStatus;
235 memStatus.dwLength = sizeof(MEMORYSTATUS);
236 GlobalMemoryStatus(&memStatus);
237 return memStatus.dwAvailPhys;
238#else
239 return (long)GetFreeSpace(0);
240#endif
241}
242
243// Sleep for nSecs seconds. Attempt a Windows implementation using timers.
244static bool inTimer = FALSE;
245class wxSleepTimer: public wxTimer
246{
247 public:
248 inline void Notify(void)
249 {
250 inTimer = FALSE;
251 Stop();
252 }
253};
254
255static wxTimer *wxTheSleepTimer = NULL;
256
257void wxSleep(int nSecs)
258{
259#if 0 // WIN32 hangs app
260 Sleep( 1000*nSecs );
261#else
262 if (inTimer)
263 return;
264
265 wxTheSleepTimer = new wxSleepTimer;
266 inTimer = TRUE;
267 wxTheSleepTimer->Start(nSecs*1000);
268 while (inTimer)
269 {
270 if (wxTheApp->Pending())
271 wxTheApp->Dispatch();
272 }
273 delete wxTheSleepTimer;
274 wxTheSleepTimer = NULL;
275#endif
276}
277
278// Consume all events until no more left
279void wxFlushEvents(void)
280{
281// wxYield();
282}
283
284// Output a debug mess., in a system dependent fashion.
285void wxDebugMsg(const char *fmt ...)
286{
287 va_list ap;
288 static char buffer[512];
289
290 if (!wxTheApp->GetWantDebugOutput())
291 return ;
292
293 va_start(ap, fmt);
294
295 wvsprintf(buffer,fmt,ap) ;
296 OutputDebugString((LPCSTR)buffer) ;
297
298 va_end(ap);
299}
300
301// Non-fatal error: pop up message box and (possibly) continue
302void wxError(const wxString& msg, const wxString& title)
303{
304 sprintf(wxBuffer, "%s\nContinue?", WXSTRINGCAST msg);
305 if (MessageBox(NULL, (LPCSTR)wxBuffer, (LPCSTR)WXSTRINGCAST title,
306 MB_ICONSTOP | MB_YESNO) == IDNO)
307 wxExit();
308}
309
310// Fatal error: pop up message box and abort
311void wxFatalError(const wxString& msg, const wxString& title)
312{
313 sprintf(wxBuffer, "%s: %s", WXSTRINGCAST title, WXSTRINGCAST msg);
314 FatalAppExit(0, (LPCSTR)wxBuffer);
315}
316
317// Emit a beeeeeep
318void wxBell(void)
319{
320 // Removed by RD because IHMO syncronous sound is a Bad Thing. MessageBeep
321 // will do a similar thing anyway if there is no sound card...
322//#ifdef __WIN32__
323// Beep(1000,1000) ; // 1kHz during 1 sec.
324//#else
325 MessageBeep(-1) ;
326//#endif
327}
328
329// Chris Breeze 27/5/98: revised WIN32 code to
330// detect WindowsNT correctly
331int wxGetOsVersion(int *majorVsn, int *minorVsn)
332{
333 extern char *wxOsVersion;
334 if (majorVsn) *majorVsn = 0;
335 if (minorVsn) *minorVsn = 0;
336
337#ifdef WIN32
338 OSVERSIONINFO info;
339 memset(&info, 0, sizeof(OSVERSIONINFO));
340 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
341 if (GetVersionEx(&info))
342 {
343 if (majorVsn) *majorVsn = info.dwMajorVersion;
344 if (minorVsn) *minorVsn = info.dwMinorVersion;
345 switch (info.dwPlatformId)
346 {
347 case VER_PLATFORM_WIN32s:
348 return wxWIN32S;
349 break;
350 case VER_PLATFORM_WIN32_WINDOWS:
351 return wxWIN95;
352 break;
353 case VER_PLATFORM_WIN32_NT:
354 return wxWINDOWS_NT;
355 break;
356 }
357 }
358 return wxWINDOWS; // error if we get here, return generic value
359#else
360 // Win16 code...
361 int retValue ;
362# ifdef __WINDOWS_386__
363 retValue = wxWIN386;
364# else
365# if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
366 extern HANDLE g_hPenWin;
367 retValue = g_hPenWin ? wxPENWINDOWS : wxWINDOWS ;
368# endif
369# endif
370 // @@@@ To be completed. I don't have the manual here...
371 if (majorVsn) *majorVsn = 3 ;
372 if (minorVsn) *minorVsn = 1 ;
373 return retValue ;
374#endif
375}
376
377// Reading and writing resources (eg WIN.INI, .Xdefaults)
378#if wxUSE_RESOURCES
379bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
380{
381 if (file != "")
382 return (WritePrivateProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)value, (LPCSTR)WXSTRINGCAST file) != 0);
383 else
384 return (WriteProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)WXSTRINGCAST value) != 0);
385}
386
387bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
388{
389 char buf[50];
390 sprintf(buf, "%.4f", value);
391 return wxWriteResource(section, entry, buf, file);
392}
393
394bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
395{
396 char buf[50];
397 sprintf(buf, "%ld", value);
398 return wxWriteResource(section, entry, buf, file);
399}
400
401bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
402{
403 char buf[50];
404 sprintf(buf, "%d", value);
405 return wxWriteResource(section, entry, buf, file);
406}
407
408bool wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file)
409{
410 static const char defunkt[] = "$$default";
411 if (file != "")
412 {
413 int n = GetPrivateProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)defunkt,
414 (LPSTR)wxBuffer, 1000, (LPCSTR)WXSTRINGCAST file);
415 if (n == 0 || strcmp(wxBuffer, defunkt) == 0)
416 return FALSE;
417 }
418 else
419 {
420 int n = GetProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)defunkt,
421 (LPSTR)wxBuffer, 1000);
422 if (n == 0 || strcmp(wxBuffer, defunkt) == 0)
423 return FALSE;
424 }
425 if (*value) delete[] (*value);
426 *value = copystring(wxBuffer);
427 return TRUE;
428 }
429
430bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
431{
432 char *s = NULL;
433 bool succ = wxGetResource(section, entry, (char **)&s, file);
434 if (succ)
435 {
436 *value = (float)strtod(s, NULL);
437 delete[] s;
438 return TRUE;
439 }
440 else return FALSE;
441}
442
443bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file)
444{
445 char *s = NULL;
446 bool succ = wxGetResource(section, entry, (char **)&s, file);
447 if (succ)
448 {
449 *value = strtol(s, NULL, 10);
450 delete[] s;
451 return TRUE;
452 }
453 else return FALSE;
454}
455
456bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file)
457{
458 char *s = NULL;
459 bool succ = wxGetResource(section, entry, (char **)&s, file);
460 if (succ)
461 {
462 *value = (int)strtol(s, NULL, 10);
463 delete[] s;
464 return TRUE;
465 }
466 else return FALSE;
467}
468#endif // wxUSE_RESOURCES
469
470// Old cursor
471static HCURSOR wxBusyCursorOld = 0;
472static int wxBusyCursorCount = 0;
473
474// Set the cursor to the busy cursor for all windows
475void wxBeginBusyCursor(wxCursor *cursor)
476{
477 wxBusyCursorCount ++;
478 if (wxBusyCursorCount == 1)
479 {
480 wxBusyCursorOld = ::SetCursor((HCURSOR) cursor->GetHCURSOR());
481 }
482 else
483 {
484 (void)::SetCursor((HCURSOR) cursor->GetHCURSOR());
485 }
486}
487
488// Restore cursor to normal
489void wxEndBusyCursor(void)
490{
491 if (wxBusyCursorCount == 0)
492 return;
493
494 wxBusyCursorCount --;
495 if (wxBusyCursorCount == 0)
496 {
497 ::SetCursor(wxBusyCursorOld);
498 wxBusyCursorOld = 0;
499 }
500}
501
502// TRUE if we're between the above two calls
503bool wxIsBusy(void)
504{
505 return (wxBusyCursorCount > 0);
506}
507
508const char* wxGetHomeDir(wxString *pstr)
509{
510 wxString& strDir = *pstr;
511
512 #ifdef __UNIX__
513 const char *szHome = getenv("HOME");
514 if ( szHome == NULL ) {
515 // we're homeless...
516 wxLogWarning(_("can't find user's HOME, using current directory."));
517 strDir = ".";
518 }
519 else
520 strDir = szHome;
521
522 // add a trailing slash if needed
523 if ( strDir.Last() != '/' )
524 strDir << '/';
525 #else // Windows
526 #ifdef __WIN32__
527 const char *szHome = getenv("HOMEDRIVE");
528 if ( szHome != NULL )
529 strDir << szHome;
530 szHome = getenv("HOMEPATH");
531 if ( szHome != NULL ) {
532 strDir << szHome;
533
534 // the idea is that under NT these variables have default values
535 // of "%systemdrive%:" and "\\". As we don't want to create our
536 // config files in the root directory of the system drive, we will
537 // create it in our program's dir. However, if the user took care
538 // to set HOMEPATH to something other than "\\", we suppose that he
539 // knows what he is doing and use the supplied value.
540 if ( strcmp(szHome, "\\") != 0 )
541 return strDir.c_str();
542 }
543
544 #else // Win16
545 // Win16 has no idea about home, so use the working directory instead
546 #endif // WIN16/32
547
548 // 260 was taken from windef.h
549 #ifndef MAX_PATH
550 #define MAX_PATH 260
551 #endif
552
553 wxString strPath;
554 ::GetModuleFileName(::GetModuleHandle(NULL),
555 strPath.GetWriteBuf(MAX_PATH), MAX_PATH);
556 strPath.UngetWriteBuf();
557
558 // extract the dir name
559 wxSplitPath(strPath, &strDir, NULL, NULL);
560
561 #endif // UNIX/Win
562
563 return strDir.c_str();
564}
565
566// Hack for MS-DOS
567char *wxGetUserHome (const wxString& user)
568{
569 char *home;
570 wxString user1(user);
571
572 if (user1 != "") {
573 char tmp[64];
574 if (wxGetUserId(tmp, sizeof(tmp)/sizeof(char))) {
575 // Guests belong in the temp dir
576 if (Stricmp(tmp, "annonymous") == 0) {
577 if ((home = getenv("TMP")) != NULL ||
578 (home = getenv("TMPDIR")) != NULL ||
579 (home = getenv("TEMP")) != NULL)
580 return *home ? home : "\\";
581 }
582 if (Stricmp(tmp, WXSTRINGCAST user1) == 0)
583 user1 = "";
584 }
585 }
586 if (user1 == "")
587 if ((home = getenv("HOME")) != NULL)
588 {
589 strcpy(wxBuffer, home);
590 Unix2DosFilename(wxBuffer);
591 return wxBuffer;
592 }
593 return NULL; // No home known!
594}
595
596// Check whether this window wants to process messages, e.g. Stop button
597// in long calculations.
598bool wxCheckForInterrupt(wxWindow *wnd)
599{
600 if(wnd){
601 MSG msg;
602 HWND win= (HWND) wnd->GetHWND();
603 while(PeekMessage(&msg,win,0,0,PM_REMOVE)){
604 TranslateMessage(&msg);
605 DispatchMessage(&msg);
606 }
607 return TRUE;//*** temporary?
608 }
609 else{
610 wxError("wnd==NULL !!!");
611 return FALSE;//*** temporary?
612 }
613}
614
615// MSW only: get user-defined resource from the .res file.
616// Returns NULL or newly-allocated memory, so use delete[] to clean up.
617
618#ifdef __WXMSW__
619char *wxLoadUserResource(const wxString& resourceName, const wxString& resourceType)
620{
621 char *s = NULL;
622#ifndef __WIN32__
623 HRSRC hResource = ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
624#else
625#ifdef UNICODE
626 HRSRC hResource = ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
627#else
628 HRSRC hResource = ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
629#endif
630#endif
631
632 if (hResource == 0)
633 return NULL;
634 HGLOBAL hData = ::LoadResource(wxGetInstance(), hResource);
635 if (hData == 0)
636 return NULL;
637 char *theText = (char *)LockResource(hData);
638 if (!theText)
639 return NULL;
640
641 s = copystring(theText);
642
643 // Obsolete in WIN32
644#ifndef __WIN32__
645 UnlockResource(hData);
646#endif
647
648 // No need??
649// GlobalFree(hData);
650
651 return s;
652}
653#endif
654
655void wxGetMousePosition( int* x, int* y )
656{
657 POINT pt;
658 GetCursorPos( & pt );
659 *x = pt.x;
660 *y = pt.y;
661};
662
663// Return TRUE if we have a colour display
664bool wxColourDisplay(void)
665{
666 HDC dc = ::GetDC(NULL);
667 bool flag;
668 int noCols = GetDeviceCaps(dc, NUMCOLORS);
669 if ((noCols == -1) || (noCols > 2))
670 flag = TRUE;
671 else
672 flag = FALSE;
673 ReleaseDC(NULL, dc);
674 return flag;
675}
676
677// Returns depth of screen
678int wxDisplayDepth(void)
679{
680 HDC dc = ::GetDC(NULL);
681 int planes = GetDeviceCaps(dc, PLANES);
682 int bitsPerPixel = GetDeviceCaps(dc, BITSPIXEL);
683 int depth = planes*bitsPerPixel;
684 ReleaseDC(NULL, dc);
685 return depth;
686}
687
688// Get size of display
689void wxDisplaySize(int *width, int *height)
690{
691 HDC dc = ::GetDC(NULL);
692 *width = GetDeviceCaps(dc, HORZRES); *height = GetDeviceCaps(dc, VERTRES);
693 ReleaseDC(NULL, dc);
694}
695
696bool wxDirExists(const wxString& dir)
697{
698 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
699#if defined(__WIN32__)
700 WIN32_FIND_DATA fileInfo;
701#else
702#ifdef __BORLANDC__
703 struct ffblk fileInfo;
704#else
705 struct find_t fileInfo;
706#endif
707#endif
708
709#if defined(__WIN32__)
710 HANDLE h = FindFirstFile((LPTSTR) WXSTRINGCAST dir,(LPWIN32_FIND_DATA)&fileInfo);
711
712 if (h==INVALID_HANDLE_VALUE)
713 return FALSE;
714 else {
715 FindClose(h);
716 return ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
717 }
718#else
719 // In Borland findfirst has a different argument
720 // ordering from _dos_findfirst. But _dos_findfirst
721 // _should_ be ok in both MS and Borland... why not?
722#ifdef __BORLANDC__
723 return ((findfirst(WXSTRINGCAST dir, &fileInfo, _A_SUBDIR) == 0 && (fileInfo.ff_attrib & _A_SUBDIR) != 0));
724#else
725 return (((_dos_findfirst(WXSTRINGCAST dir, _A_SUBDIR, &fileInfo) == 0) && (fileInfo.attrib & _A_SUBDIR)) != 0);
726#endif
727#endif
728}
729
730wxString WXDLLEXPORT wxGetWindowText(WXHWND hWnd)
731{
732 wxString str;
733 int len = GetWindowTextLength((HWND)hWnd) + 1;
734 GetWindowText((HWND)hWnd, str.GetWriteBuf(len), len);
735 str.UngetWriteBuf();
736
737 return str;
738}
739
740#if 0
741//------------------------------------------------------------------------
742// wild character routines
743//------------------------------------------------------------------------
744
745bool wxIsWild( const wxString& pattern )
746{
747 wxString tmp = pattern;
748 char *pat = WXSTRINGCAST(tmp);
749 while (*pat) {
750 switch (*pat++) {
751 case '?': case '*': case '[': case '{':
752 return TRUE;
753 case '\\':
754 if (!*pat++)
755 return FALSE;
756 }
757 }
758 return FALSE;
759};
760
761
762bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
763{
764 wxString tmp1 = pat;
765 char *pattern = WXSTRINGCAST(tmp1);
766 wxString tmp2 = text;
767 char *str = WXSTRINGCAST(tmp2);
768 char c;
769 char *cp;
770 bool done = FALSE, ret_code, ok;
771 // Below is for vi fans
772 const char OB = '{', CB = '}';
773
774 // dot_special means '.' only matches '.'
775 if (dot_special && *str == '.' && *pattern != *str)
776 return FALSE;
777
778 while ((*pattern != '\0') && (!done)
779 && (((*str=='\0')&&((*pattern==OB)||(*pattern=='*')))||(*str!='\0'))) {
780 switch (*pattern) {
781 case '\\':
782 pattern++;
783 if (*pattern != '\0')
784 pattern++;
785 break;
786 case '*':
787 pattern++;
788 ret_code = FALSE;
789 while ((*str!='\0')
790 && (!(ret_code=wxMatchWild(pattern, str++, FALSE))))
791 /*loop*/;
792 if (ret_code) {
793 while (*str != '\0')
794 str++;
795 while (*pattern != '\0')
796 pattern++;
797 }
798 break;
799 case '[':
800 pattern++;
801 repeat:
802 if ((*pattern == '\0') || (*pattern == ']')) {
803 done = TRUE;
804 break;
805 }
806 if (*pattern == '\\') {
807 pattern++;
808 if (*pattern == '\0') {
809 done = TRUE;
810 break;
811 }
812 }
813 if (*(pattern + 1) == '-') {
814 c = *pattern;
815 pattern += 2;
816 if (*pattern == ']') {
817 done = TRUE;
818 break;
819 }
820 if (*pattern == '\\') {
821 pattern++;
822 if (*pattern == '\0') {
823 done = TRUE;
824 break;
825 }
826 }
827 if ((*str < c) || (*str > *pattern)) {
828 pattern++;
829 goto repeat;
830 }
831 } else if (*pattern != *str) {
832 pattern++;
833 goto repeat;
834 }
835 pattern++;
836 while ((*pattern != ']') && (*pattern != '\0')) {
837 if ((*pattern == '\\') && (*(pattern + 1) != '\0'))
838 pattern++;
839 pattern++;
840 }
841 if (*pattern != '\0') {
842 pattern++, str++;
843 }
844 break;
845 case '?':
846 pattern++;
847 str++;
848 break;
849 case OB:
850 pattern++;
851 while ((*pattern != CB) && (*pattern != '\0')) {
852 cp = str;
853 ok = TRUE;
854 while (ok && (*cp != '\0') && (*pattern != '\0')
855 && (*pattern != ',') && (*pattern != CB)) {
856 if (*pattern == '\\')
857 pattern++;
858 ok = (*pattern++ == *cp++);
859 }
860 if (*pattern == '\0') {
861 ok = FALSE;
862 done = TRUE;
863 break;
864 } else if (ok) {
865 str = cp;
866 while ((*pattern != CB) && (*pattern != '\0')) {
867 if (*++pattern == '\\') {
868 if (*++pattern == CB)
869 pattern++;
870 }
871 }
872 } else {
873 while (*pattern!=CB && *pattern!=',' && *pattern!='\0') {
874 if (*++pattern == '\\') {
875 if (*++pattern == CB || *pattern == ',')
876 pattern++;
877 }
878 }
879 }
880 if (*pattern != '\0')
881 pattern++;
882 }
883 break;
884 default:
885 if (*str == *pattern) {
886 str++, pattern++;
887 } else {
888 done = TRUE;
889 }
890 }
891 }
892 while (*pattern == '*')
893 pattern++;
894 return ((*str == '\0') && (*pattern == '\0'));
895};
896
897#endif
898
899#if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
900
901/*
902When I started programming with Visual C++ v4.0, I missed one of my favorite
903tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
904on MSDN was a step in the right direction, but it is a console application
905and thus has limited features and extensibility. DBWIN32 is my creation
906to solve this problem.
907
908The code is essentially a merging of a stripped down version of the DBWIN code
909from VC 1.5 and DBMON.C with a few 32 bit changes.
910
911As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
912built into the operating system and works just by running DBWIN32. The Win95
913team decided not to support this hook, so I have provided code that will do
914this for you. See the file WIN95.TXT for instructions on installing this.
915
916If you have questions, problems or suggestions about DBWIN32, I welcome your
917feedback and plan to actively maintain the code.
918
919Andrew Tucker
920ast@halcyon.com
921
922To download dbwin32, see e.g.:
923
924http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
925*/
926
927#include <process.h>
928
929void OutputDebugStringW95(const char* lpOutputString, ...)
930{
931 HANDLE heventDBWIN; /* DBWIN32 synchronization object */
932 HANDLE heventData; /* data passing synch object */
933 HANDLE hSharedFile; /* memory mapped file shared data */
934 LPSTR lpszSharedMem;
935 char achBuffer[500];
936
937 /* create the output buffer */
938 va_list args;
939 va_start(args, lpOutputString);
940 vsprintf(achBuffer, lpOutputString, args);
941 va_end(args);
942
943 /*
944 Do a regular OutputDebugString so that the output is
945 still seen in the debugger window if it exists.
946
947 This ifdef is necessary to avoid infinite recursion
948 from the inclusion of W95TRACE.H
949 */
950#ifdef _UNICODE
951 ::OutputDebugStringW(achBuffer);
952#else
953 ::OutputDebugStringA(achBuffer);
954#endif
955
956 /* bail if it's not Win95 */
957 {
958 OSVERSIONINFO VerInfo;
959 VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
960 GetVersionEx(&VerInfo);
961 if ( VerInfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS )
962 return;
963 }
964
965 /* make sure DBWIN is open and waiting */
966 heventDBWIN = OpenEvent(EVENT_MODIFY_STATE, FALSE, "DBWIN_BUFFER_READY");
967 if ( !heventDBWIN )
968 {
969 //MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
970 return;
971 }
972
973 /* get a handle to the data synch object */
974 heventData = OpenEvent(EVENT_MODIFY_STATE, FALSE, "DBWIN_DATA_READY");
975 if ( !heventData )
976 {
977 // MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
978 CloseHandle(heventDBWIN);
979 return;
980 }
981
982 hSharedFile = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0, 4096, "DBWIN_BUFFER");
983 if (!hSharedFile)
984 {
985 //MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
986 CloseHandle(heventDBWIN);
987 CloseHandle(heventData);
988 return;
989 }
990
991 lpszSharedMem = (LPSTR)MapViewOfFile(hSharedFile, FILE_MAP_WRITE, 0, 0, 512);
992 if (!lpszSharedMem)
993 {
994 //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
995 CloseHandle(heventDBWIN);
996 CloseHandle(heventData);
997 return;
998 }
999
1000 /* wait for buffer event */
1001 WaitForSingleObject(heventDBWIN, INFINITE);
1002
1003 /* write it to the shared memory */
1004#ifdef __BORLANDC__
1005 *((LPDWORD)lpszSharedMem) = getpid();
1006#else
1007 *((LPDWORD)lpszSharedMem) = _getpid();
1008#endif
1009
1010 wsprintf(lpszSharedMem + sizeof(DWORD), "%s", achBuffer);
1011
1012 /* signal data ready event */
1013 SetEvent(heventData);
1014
1015 /* clean up handles */
1016 CloseHandle(hSharedFile);
1017 CloseHandle(heventData);
1018 CloseHandle(heventDBWIN);
1019
1020 return;
1021}
1022
1023
1024#endif
1025