]> git.saurik.com Git - wxWidgets.git/blob - src/msw/utils.cpp
wxCritSection change to accomodate mem checking system
[wxWidgets.git] / src / msw / utils.cpp
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 #include "wx/intl.h"
33
34 #include <windows.h>
35
36 #include <ctype.h>
37
38 #if !defined(__GNUWIN32__) && !defined(__SALFORDC__)
39 #include <direct.h>
40
41 #ifndef __MWERKS__
42 #include <dos.h>
43 #endif
44 #endif //GNUWIN32
45
46 #if defined(__GNUWIN32__) && !defined(__TWIN32__)
47 #include <sys/unistd.h>
48 #include <sys/stat.h>
49 #endif //GNUWIN32
50
51 #include "wx/log.h"
52
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.
56 #include <dir.h>
57 #endif
58
59 #ifdef __WIN32__
60 #include <io.h>
61
62 #ifndef __GNUWIN32__
63 #include <shellapi.h>
64 #endif
65 #endif
66
67 #include <stdio.h>
68 #include <stdlib.h>
69 #include <string.h>
70 #ifndef __WATCOMC__
71 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
72 #include <errno.h>
73 #endif
74 #endif
75 #include <stdarg.h>
76
77 //// BEGIN for console support: VC++ only
78 #ifdef __VISUALC__
79
80 #include "wx/msw/msvcrt.h"
81
82 #include <fcntl.h>
83
84 #include "wx/ioswrap.h"
85
86 #if wxUSE_IOSTREAMH
87 // N.B. BC++ doesn't have istream.h, ostream.h
88 # include <io.h>
89 # include <fstream.h>
90 #else
91 # include <fstream>
92 #endif
93
94 /* Need to undef new if including crtdbg.h */
95 # ifdef new
96 # undef new
97 # endif
98
99 #ifndef __WIN16__
100 # include <crtdbg.h>
101 #endif
102
103 # if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS && wxUSE_DEBUG_NEW_ALWAYS
104 # define new new(__FILE__,__LINE__)
105 # endif
106
107 #endif
108 // __VISUALC__
109 /// END for console support
110
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";
116
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
121
122 // Get full hostname (eg. DoDo.BSn-Germany.crg.de)
123 bool wxGetHostName(char *buf, int maxSize)
124 {
125 #if defined(__WIN32__) && !defined(__TWIN32__)
126 DWORD nSize = maxSize;
127 return (::GetComputerName(buf, &nSize) != 0);
128 #else
129 char *sysname;
130 const char *default_host = "noname";
131
132 if ((sysname = getenv("SYSTEM_NAME")) == NULL) {
133 GetProfileString(WX_SECTION, eHOSTNAME, default_host, buf, maxSize - 1);
134 } else
135 strncpy(buf, sysname, maxSize - 1);
136 buf[maxSize] = '\0';
137 return *buf ? TRUE : FALSE;
138 #endif
139 }
140
141 // Get user ID e.g. jacs
142 bool wxGetUserId(char *buf, int maxSize)
143 {
144 #if defined(__WIN32__) && !defined(__win32s__) && !defined(__TWIN32__)
145
146 // VZ: why should it be so complicated??
147 #if 0
148 // Gets the current user's full name according to the MS article PSS ID
149 // Number: Q119670
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 );
156
157 WCHAR wszUserName[256]; // Unicode user name
158 WCHAR wszDomain[256];
159 LPBYTE ComputerName;
160
161 struct _SERVER_INFO_100 *si100; // Server structure
162 struct _USER_INFO_2 *ui; // User structure
163
164 // Convert ASCII user name and domain to Unicode.
165
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) );
170
171 // Get the computer name of a DC for the specified domain.
172 // >If you get a link error on this, include netapi32.lib<
173
174 NetGetDCName( NULL, wszDomain, &ComputerName );
175
176 // Look up the user on the DC.
177
178 if(NetUserGetInfo( (LPWSTR) ComputerName,
179 (LPWSTR) &wszUserName, 2, (LPBYTE *) &ui))
180 {
181 printf( "Error getting user information.\n" );
182 return( FALSE );
183 }
184
185 // Convert the Unicode full name to ASCII.
186
187 WideCharToMultiByte( CP_ACP, 0, ui->usri2_full_name,
188 -1, buf, 256, NULL, NULL );
189 }
190 return( TRUE );
191 #else // 1
192 DWORD nSize = maxSize;
193 if ( ::GetUserName(buf, &nSize) == 0 )
194 {
195 wxLogSysError("Can not get user name");
196
197 return FALSE;
198 }
199
200 return TRUE;
201 #endif // 0/1
202
203 #else // Win16 or Win32s
204 char *user;
205 const char *default_id = "anonymous";
206
207 // Can't assume we have NIS (PC-NFS) or some other ID daemon
208 // So we ...
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);
213 } else
214 strncpy(buf, user, maxSize - 1);
215 return *buf ? TRUE : FALSE;
216 #endif
217 }
218
219 // Get user name e.g. Julian Smart
220 bool wxGetUserName(char *buf, int maxSize)
221 {
222 #if wxUSE_PENWINDOWS && !defined(__WATCOMC__) && !defined(__GNUWIN32__)
223 extern HANDLE g_hPenWin; // PenWindows Running?
224 if (g_hPenWin)
225 {
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);
230 }
231 else
232 #endif
233 {
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;
237 if ( !ok )
238 {
239 ok = wxGetUserId(buf, maxSize);
240 }
241
242 if ( !ok )
243 {
244 strncpy(buf, "Unknown User", maxSize);
245 }
246 }
247
248 return TRUE;
249 }
250
251 int wxKill(long pid, int sig)
252 {
253 return 0;
254 }
255
256 //
257 // Execute a program in an Interactive Shell
258 //
259 bool
260 wxShell(const wxString& command)
261 {
262 char *shell;
263 if ((shell = getenv("COMSPEC")) == NULL)
264 shell = "\\COMMAND.COM";
265
266 char tmp[255];
267 if (command != "")
268 sprintf(tmp, "%s /c %s", shell, WXSTRINGCAST command);
269 else
270 strcpy(tmp, shell);
271
272 return (wxExecute((char *)tmp, FALSE) != 0);
273 }
274
275 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
276 long wxGetFreeMemory()
277 {
278 #if defined(__WIN32__) && !defined(__BORLANDC__) && !defined(__TWIN32__)
279 MEMORYSTATUS memStatus;
280 memStatus.dwLength = sizeof(MEMORYSTATUS);
281 GlobalMemoryStatus(&memStatus);
282 return memStatus.dwAvailPhys;
283 #else
284 return (long)GetFreeSpace(0);
285 #endif
286 }
287
288 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
289 static bool inTimer = FALSE;
290 class wxSleepTimer: public wxTimer
291 {
292 public:
293 inline void Notify()
294 {
295 inTimer = FALSE;
296 Stop();
297 }
298 };
299
300 static wxTimer *wxTheSleepTimer = NULL;
301
302 void wxSleep(int nSecs)
303 {
304 #if 0 // WIN32 hangs app
305 Sleep( 1000*nSecs );
306 #else
307 if (inTimer)
308 return;
309
310 wxTheSleepTimer = new wxSleepTimer;
311 inTimer = TRUE;
312 wxTheSleepTimer->Start(nSecs*1000);
313 while (inTimer)
314 {
315 if (wxTheApp->Pending())
316 wxTheApp->Dispatch();
317 }
318 delete wxTheSleepTimer;
319 wxTheSleepTimer = NULL;
320 #endif
321 }
322
323 // Consume all events until no more left
324 void wxFlushEvents()
325 {
326 // wxYield();
327 }
328
329 // Output a debug mess., in a system dependent fashion.
330 void wxDebugMsg(const char *fmt ...)
331 {
332 va_list ap;
333 static char buffer[512];
334
335 if (!wxTheApp->GetWantDebugOutput())
336 return ;
337
338 va_start(ap, fmt);
339
340 wvsprintf(buffer,fmt,ap) ;
341 OutputDebugString((LPCSTR)buffer) ;
342
343 va_end(ap);
344 }
345
346 // Non-fatal error: pop up message box and (possibly) continue
347 void wxError(const wxString& msg, const wxString& title)
348 {
349 sprintf(wxBuffer, "%s\nContinue?", WXSTRINGCAST msg);
350 if (MessageBox(NULL, (LPCSTR)wxBuffer, (LPCSTR)WXSTRINGCAST title,
351 MB_ICONSTOP | MB_YESNO) == IDNO)
352 wxExit();
353 }
354
355 // Fatal error: pop up message box and abort
356 void wxFatalError(const wxString& msg, const wxString& title)
357 {
358 sprintf(wxBuffer, "%s: %s", WXSTRINGCAST title, WXSTRINGCAST msg);
359 FatalAppExit(0, (LPCSTR)wxBuffer);
360 }
361
362 // Emit a beeeeeep
363 void wxBell()
364 {
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...
367 //#ifdef __WIN32__
368 // Beep(1000,1000) ; // 1kHz during 1 sec.
369 //#else
370 MessageBeep((UINT)-1) ;
371 //#endif
372 }
373
374 // Chris Breeze 27/5/98: revised WIN32 code to
375 // detect WindowsNT correctly
376 int wxGetOsVersion(int *majorVsn, int *minorVsn)
377 {
378 extern char *wxOsVersion;
379 if (majorVsn) *majorVsn = 0;
380 if (minorVsn) *minorVsn = 0;
381
382 #if defined(__WIN32__) && !defined(__SC__)
383 OSVERSIONINFO info;
384 memset(&info, 0, sizeof(OSVERSIONINFO));
385 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
386 if (GetVersionEx(&info))
387 {
388 if (majorVsn) *majorVsn = info.dwMajorVersion;
389 if (minorVsn) *minorVsn = info.dwMinorVersion;
390 switch (info.dwPlatformId)
391 {
392 case VER_PLATFORM_WIN32s:
393 return wxWIN32S;
394 break;
395 case VER_PLATFORM_WIN32_WINDOWS:
396 return wxWIN95;
397 break;
398 case VER_PLATFORM_WIN32_NT:
399 return wxWINDOWS_NT;
400 break;
401 }
402 }
403 return wxWINDOWS; // error if we get here, return generic value
404 #else
405 // Win16 code...
406 int retValue = 0;
407 # ifdef __WINDOWS_386__
408 retValue = wxWIN386;
409 # else
410 # if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
411 extern HANDLE g_hPenWin;
412 retValue = g_hPenWin ? wxPENWINDOWS : wxWINDOWS ;
413 # endif
414 # endif
415 // @@@@ To be completed. I don't have the manual here...
416 if (majorVsn) *majorVsn = 3 ;
417 if (minorVsn) *minorVsn = 1 ;
418 return retValue ;
419 #endif
420 }
421
422 // Reading and writing resources (eg WIN.INI, .Xdefaults)
423 #if wxUSE_RESOURCES
424 bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
425 {
426 if (file != "")
427 return (WritePrivateProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)value, (LPCSTR)WXSTRINGCAST file) != 0);
428 else
429 return (WriteProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)WXSTRINGCAST value) != 0);
430 }
431
432 bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
433 {
434 char buf[50];
435 sprintf(buf, "%.4f", value);
436 return wxWriteResource(section, entry, buf, file);
437 }
438
439 bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
440 {
441 char buf[50];
442 sprintf(buf, "%ld", value);
443 return wxWriteResource(section, entry, buf, file);
444 }
445
446 bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
447 {
448 char buf[50];
449 sprintf(buf, "%d", value);
450 return wxWriteResource(section, entry, buf, file);
451 }
452
453 bool wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file)
454 {
455 static const char defunkt[] = "$$default";
456 if (file != "")
457 {
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)
461 return FALSE;
462 }
463 else
464 {
465 int n = GetProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)defunkt,
466 (LPSTR)wxBuffer, 1000);
467 if (n == 0 || strcmp(wxBuffer, defunkt) == 0)
468 return FALSE;
469 }
470 if (*value) delete[] (*value);
471 *value = copystring(wxBuffer);
472 return TRUE;
473 }
474
475 bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
476 {
477 char *s = NULL;
478 bool succ = wxGetResource(section, entry, (char **)&s, file);
479 if (succ)
480 {
481 *value = (float)strtod(s, NULL);
482 delete[] s;
483 return TRUE;
484 }
485 else return FALSE;
486 }
487
488 bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file)
489 {
490 char *s = NULL;
491 bool succ = wxGetResource(section, entry, (char **)&s, file);
492 if (succ)
493 {
494 *value = strtol(s, NULL, 10);
495 delete[] s;
496 return TRUE;
497 }
498 else return FALSE;
499 }
500
501 bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file)
502 {
503 char *s = NULL;
504 bool succ = wxGetResource(section, entry, (char **)&s, file);
505 if (succ)
506 {
507 *value = (int)strtol(s, NULL, 10);
508 delete[] s;
509 return TRUE;
510 }
511 else return FALSE;
512 }
513 #endif // wxUSE_RESOURCES
514
515 // ---------------------------------------------------------------------------
516 // helper functiosn for showing a "busy" cursor
517 // ---------------------------------------------------------------------------
518
519 extern HCURSOR gs_wxBusyCursor = 0; // new, busy cursor
520 static HCURSOR gs_wxBusyCursorOld = 0; // old cursor
521 static int gs_wxBusyCursorCount = 0;
522
523 // Set the cursor to the busy cursor for all windows
524 void wxBeginBusyCursor(wxCursor *cursor)
525 {
526 if ( gs_wxBusyCursorCount++ == 0 )
527 {
528 gs_wxBusyCursor = (HCURSOR)cursor->GetHCURSOR();
529 gs_wxBusyCursorOld = ::SetCursor(gs_wxBusyCursor);
530 }
531 //else: nothing to do, already set
532 }
533
534 // Restore cursor to normal
535 void wxEndBusyCursor()
536 {
537 wxCHECK_RET( gs_wxBusyCursorCount > 0,
538 "no matching wxBeginBusyCursor() for wxEndBusyCursor()" );
539
540 gs_wxBusyCursorCount--;
541 if ( --gs_wxBusyCursorCount == 0 )
542 {
543 ::SetCursor(gs_wxBusyCursorOld);
544
545 gs_wxBusyCursorOld = 0;
546 }
547 }
548
549 // TRUE if we're between the above two calls
550 bool wxIsBusy()
551 {
552 return (gs_wxBusyCursorCount > 0);
553 }
554
555 // ---------------------------------------------------------------------------
556 const char* wxGetHomeDir(wxString *pstr)
557 {
558 wxString& strDir = *pstr;
559
560 #if defined(__UNIX__) && !defined(__TWIN32__)
561 const char *szHome = getenv("HOME");
562 if ( szHome == NULL ) {
563 // we're homeless...
564 wxLogWarning(_("can't find user's HOME, using current directory."));
565 strDir = ".";
566 }
567 else
568 strDir = szHome;
569
570 // add a trailing slash if needed
571 if ( strDir.Last() != '/' )
572 strDir << '/';
573 #else // Windows
574 #ifdef __WIN32__
575 const char *szHome = getenv("HOMEDRIVE");
576 if ( szHome != NULL )
577 strDir << szHome;
578 szHome = getenv("HOMEPATH");
579 if ( szHome != NULL ) {
580 strDir << szHome;
581
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();
590 }
591
592 #else // Win16
593 // Win16 has no idea about home, so use the working directory instead
594 #endif // WIN16/32
595
596 // 260 was taken from windef.h
597 #ifndef MAX_PATH
598 #define MAX_PATH 260
599 #endif
600
601 wxString strPath;
602 ::GetModuleFileName(::GetModuleHandle(NULL),
603 strPath.GetWriteBuf(MAX_PATH), MAX_PATH);
604 strPath.UngetWriteBuf();
605
606 // extract the dir name
607 wxSplitPath(strPath, &strDir, NULL, NULL);
608
609 #endif // UNIX/Win
610
611 return strDir.c_str();
612 }
613
614 // Hack for MS-DOS
615 char *wxGetUserHome (const wxString& user)
616 {
617 char *home;
618 wxString user1(user);
619
620 if (user1 != "") {
621 char tmp[64];
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 : "\\";
629 }
630 if (Stricmp(tmp, WXSTRINGCAST user1) == 0)
631 user1 = "";
632 }
633 }
634 if (user1 == "")
635 if ((home = getenv("HOME")) != NULL)
636 {
637 strcpy(wxBuffer, home);
638 Unix2DosFilename(wxBuffer);
639 return wxBuffer;
640 }
641 return NULL; // No home known!
642 }
643
644 // Check whether this window wants to process messages, e.g. Stop button
645 // in long calculations.
646 bool wxCheckForInterrupt(wxWindow *wnd)
647 {
648 if(wnd){
649 MSG msg;
650 HWND win= (HWND) wnd->GetHWND();
651 while(PeekMessage(&msg,win,0,0,PM_REMOVE)){
652 TranslateMessage(&msg);
653 DispatchMessage(&msg);
654 }
655 return TRUE;//*** temporary?
656 }
657 else{
658 wxFAIL_MSG("wnd==NULL !!!");
659
660 return FALSE;//*** temporary?
661 }
662 }
663
664 // MSW only: get user-defined resource from the .res file.
665 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
666
667 #ifdef __WXMSW__
668 char *wxLoadUserResource(const wxString& resourceName, const wxString& resourceType)
669 {
670 char *s = NULL;
671 #if !defined(__WIN32__) || defined(__TWIN32__)
672 HRSRC hResource = ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
673 #else
674 #ifdef UNICODE
675 HRSRC hResource = ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
676 #else
677 HRSRC hResource = ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
678 #endif
679 #endif
680
681 if (hResource == 0)
682 return NULL;
683 HGLOBAL hData = ::LoadResource(wxGetInstance(), hResource);
684 if (hData == 0)
685 return NULL;
686 char *theText = (char *)LockResource(hData);
687 if (!theText)
688 return NULL;
689
690 s = copystring(theText);
691
692 // Obsolete in WIN32
693 #ifndef __WIN32__
694 UnlockResource(hData);
695 #endif
696
697 // No need??
698 // GlobalFree(hData);
699
700 return s;
701 }
702 #endif
703
704 void wxGetMousePosition( int* x, int* y )
705 {
706 POINT pt;
707 GetCursorPos( & pt );
708 *x = pt.x;
709 *y = pt.y;
710 };
711
712 // Return TRUE if we have a colour display
713 bool wxColourDisplay()
714 {
715 HDC dc = ::GetDC((HWND) NULL);
716 bool flag;
717 int noCols = GetDeviceCaps(dc, NUMCOLORS);
718 if ((noCols == -1) || (noCols > 2))
719 flag = TRUE;
720 else
721 flag = FALSE;
722 ReleaseDC((HWND) NULL, dc);
723 return flag;
724 }
725
726 // Returns depth of screen
727 int wxDisplayDepth()
728 {
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);
734 return depth;
735 }
736
737 // Get size of display
738 void wxDisplaySize(int *width, int *height)
739 {
740 HDC dc = ::GetDC((HWND) NULL);
741 *width = GetDeviceCaps(dc, HORZRES); *height = GetDeviceCaps(dc, VERTRES);
742 ReleaseDC((HWND) NULL, dc);
743 }
744
745 bool wxDirExists(const wxString& dir)
746 {
747 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
748 #if defined(__WIN32__)
749 WIN32_FIND_DATA fileInfo;
750 #else
751 #ifdef __BORLANDC__
752 struct ffblk fileInfo;
753 #else
754 struct find_t fileInfo;
755 #endif
756 #endif
757
758 #if defined(__WIN32__)
759 HANDLE h = FindFirstFile((LPTSTR) WXSTRINGCAST dir,(LPWIN32_FIND_DATA)&fileInfo);
760
761 if (h==INVALID_HANDLE_VALUE)
762 return FALSE;
763 else {
764 FindClose(h);
765 return ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
766 }
767 #else
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?
771 #ifdef __BORLANDC__
772 return ((findfirst(WXSTRINGCAST dir, &fileInfo, _A_SUBDIR) == 0 && (fileInfo.ff_attrib & _A_SUBDIR) != 0));
773 #else
774 return (((_dos_findfirst(WXSTRINGCAST dir, _A_SUBDIR, &fileInfo) == 0) && (fileInfo.attrib & _A_SUBDIR)) != 0);
775 #endif
776 #endif
777 }
778
779 wxString WXDLLEXPORT wxGetWindowText(WXHWND hWnd)
780 {
781 wxString str;
782 int len = GetWindowTextLength((HWND)hWnd) + 1;
783 GetWindowText((HWND)hWnd, str.GetWriteBuf(len), len);
784 str.UngetWriteBuf();
785
786 return str;
787 }
788
789 #if 0
790 //------------------------------------------------------------------------
791 // wild character routines
792 //------------------------------------------------------------------------
793
794 bool wxIsWild( const wxString& pattern )
795 {
796 wxString tmp = pattern;
797 char *pat = WXSTRINGCAST(tmp);
798 while (*pat) {
799 switch (*pat++) {
800 case '?': case '*': case '[': case '{':
801 return TRUE;
802 case '\\':
803 if (!*pat++)
804 return FALSE;
805 }
806 }
807 return FALSE;
808 };
809
810
811 bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
812 {
813 wxString tmp1 = pat;
814 char *pattern = WXSTRINGCAST(tmp1);
815 wxString tmp2 = text;
816 char *str = WXSTRINGCAST(tmp2);
817 char c;
818 char *cp;
819 bool done = FALSE, ret_code, ok;
820 // Below is for vi fans
821 const char OB = '{', CB = '}';
822
823 // dot_special means '.' only matches '.'
824 if (dot_special && *str == '.' && *pattern != *str)
825 return FALSE;
826
827 while ((*pattern != '\0') && (!done)
828 && (((*str=='\0')&&((*pattern==OB)||(*pattern=='*')))||(*str!='\0'))) {
829 switch (*pattern) {
830 case '\\':
831 pattern++;
832 if (*pattern != '\0')
833 pattern++;
834 break;
835 case '*':
836 pattern++;
837 ret_code = FALSE;
838 while ((*str!='\0')
839 && (!(ret_code=wxMatchWild(pattern, str++, FALSE))))
840 /*loop*/;
841 if (ret_code) {
842 while (*str != '\0')
843 str++;
844 while (*pattern != '\0')
845 pattern++;
846 }
847 break;
848 case '[':
849 pattern++;
850 repeat:
851 if ((*pattern == '\0') || (*pattern == ']')) {
852 done = TRUE;
853 break;
854 }
855 if (*pattern == '\\') {
856 pattern++;
857 if (*pattern == '\0') {
858 done = TRUE;
859 break;
860 }
861 }
862 if (*(pattern + 1) == '-') {
863 c = *pattern;
864 pattern += 2;
865 if (*pattern == ']') {
866 done = TRUE;
867 break;
868 }
869 if (*pattern == '\\') {
870 pattern++;
871 if (*pattern == '\0') {
872 done = TRUE;
873 break;
874 }
875 }
876 if ((*str < c) || (*str > *pattern)) {
877 pattern++;
878 goto repeat;
879 }
880 } else if (*pattern != *str) {
881 pattern++;
882 goto repeat;
883 }
884 pattern++;
885 while ((*pattern != ']') && (*pattern != '\0')) {
886 if ((*pattern == '\\') && (*(pattern + 1) != '\0'))
887 pattern++;
888 pattern++;
889 }
890 if (*pattern != '\0') {
891 pattern++, str++;
892 }
893 break;
894 case '?':
895 pattern++;
896 str++;
897 break;
898 case OB:
899 pattern++;
900 while ((*pattern != CB) && (*pattern != '\0')) {
901 cp = str;
902 ok = TRUE;
903 while (ok && (*cp != '\0') && (*pattern != '\0')
904 && (*pattern != ',') && (*pattern != CB)) {
905 if (*pattern == '\\')
906 pattern++;
907 ok = (*pattern++ == *cp++);
908 }
909 if (*pattern == '\0') {
910 ok = FALSE;
911 done = TRUE;
912 break;
913 } else if (ok) {
914 str = cp;
915 while ((*pattern != CB) && (*pattern != '\0')) {
916 if (*++pattern == '\\') {
917 if (*++pattern == CB)
918 pattern++;
919 }
920 }
921 } else {
922 while (*pattern!=CB && *pattern!=',' && *pattern!='\0') {
923 if (*++pattern == '\\') {
924 if (*++pattern == CB || *pattern == ',')
925 pattern++;
926 }
927 }
928 }
929 if (*pattern != '\0')
930 pattern++;
931 }
932 break;
933 default:
934 if (*str == *pattern) {
935 str++, pattern++;
936 } else {
937 done = TRUE;
938 }
939 }
940 }
941 while (*pattern == '*')
942 pattern++;
943 return ((*str == '\0') && (*pattern == '\0'));
944 };
945
946 #endif
947
948 #if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
949
950 /*
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.
956
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.
959
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.
964
965 If you have questions, problems or suggestions about DBWIN32, I welcome your
966 feedback and plan to actively maintain the code.
967
968 Andrew Tucker
969 ast@halcyon.com
970
971 To download dbwin32, see e.g.:
972
973 http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
974 */
975
976 #if !defined(__MWERKS__) && !defined(__SALFORDC__) && !defined(__TWIN32__)
977 #include <process.h>
978 #endif
979
980 void OutputDebugStringW95(const char* lpOutputString, ...)
981 {
982 HANDLE heventDBWIN; /* DBWIN32 synchronization object */
983 HANDLE heventData; /* data passing synch object */
984 HANDLE hSharedFile; /* memory mapped file shared data */
985 LPSTR lpszSharedMem;
986 char achBuffer[500];
987
988 /* create the output buffer */
989 va_list args;
990 va_start(args, lpOutputString);
991 vsprintf(achBuffer, lpOutputString, args);
992 va_end(args);
993
994 /*
995 Do a regular OutputDebugString so that the output is
996 still seen in the debugger window if it exists.
997
998 This ifdef is necessary to avoid infinite recursion
999 from the inclusion of W95TRACE.H
1000 */
1001 #ifdef _UNICODE
1002 ::OutputDebugStringW(achBuffer);
1003 #else
1004 #ifdef __TWIN32__
1005 ::OutputDebugString(achBuffer);
1006 #else
1007 ::OutputDebugStringA(achBuffer);
1008 #endif
1009 #endif
1010
1011 /* bail if it's not Win95 */
1012 {
1013 OSVERSIONINFO VerInfo;
1014 VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
1015 GetVersionEx(&VerInfo);
1016 if ( VerInfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS )
1017 return;
1018 }
1019
1020 /* make sure DBWIN is open and waiting */
1021 heventDBWIN = OpenEvent(EVENT_MODIFY_STATE, FALSE, "DBWIN_BUFFER_READY");
1022 if ( !heventDBWIN )
1023 {
1024 //MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
1025 return;
1026 }
1027
1028 /* get a handle to the data synch object */
1029 heventData = OpenEvent(EVENT_MODIFY_STATE, FALSE, "DBWIN_DATA_READY");
1030 if ( !heventData )
1031 {
1032 // MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
1033 CloseHandle(heventDBWIN);
1034 return;
1035 }
1036
1037 hSharedFile = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0, 4096, "DBWIN_BUFFER");
1038 if (!hSharedFile)
1039 {
1040 //MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
1041 CloseHandle(heventDBWIN);
1042 CloseHandle(heventData);
1043 return;
1044 }
1045
1046 lpszSharedMem = (LPSTR)MapViewOfFile(hSharedFile, FILE_MAP_WRITE, 0, 0, 512);
1047 if (!lpszSharedMem)
1048 {
1049 //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
1050 CloseHandle(heventDBWIN);
1051 CloseHandle(heventData);
1052 return;
1053 }
1054
1055 /* wait for buffer event */
1056 WaitForSingleObject(heventDBWIN, INFINITE);
1057
1058 /* write it to the shared memory */
1059 #if defined( __BORLANDC__ ) || defined( __MWERKS__ ) || defined(__SALFORDC__)
1060 *((LPDWORD)lpszSharedMem) = getpid();
1061 #else
1062 *((LPDWORD)lpszSharedMem) = _getpid();
1063 #endif
1064
1065 wsprintf(lpszSharedMem + sizeof(DWORD), "%s", achBuffer);
1066
1067 /* signal data ready event */
1068 SetEvent(heventData);
1069
1070 /* clean up handles */
1071 CloseHandle(hSharedFile);
1072 CloseHandle(heventData);
1073 CloseHandle(heventDBWIN);
1074
1075 return;
1076 }
1077
1078
1079 #endif
1080
1081
1082 #if 0
1083
1084 // maximum mumber of lines the output console should have
1085 static const WORD MAX_CONSOLE_LINES = 500;
1086
1087 BOOL WINAPI MyConsoleHandler( DWORD dwCtrlType ) { // control signal type
1088 FreeConsole();
1089 return TRUE;
1090 }
1091
1092 void wxRedirectIOToConsole()
1093 {
1094 int hConHandle;
1095 long lStdHandle;
1096 CONSOLE_SCREEN_BUFFER_INFO coninfo;
1097 FILE *fp;
1098
1099 // allocate a console for this app
1100 AllocConsole();
1101
1102 // set the screen buffer to be big enough to let us scroll text
1103 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
1104 &coninfo);
1105 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
1106 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),
1107 coninfo.dwSize);
1108
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" );
1114 *stdout = *fp;
1115 setvbuf( stdout, NULL, _IONBF, 0 );
1116
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" );
1122 *stdin = *fp;
1123 setvbuf( stdin, NULL, _IONBF, 0 );
1124
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" );
1130 *stderr = *fp;
1131 setvbuf( stderr, NULL, _IONBF, 0 );
1132
1133 // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
1134 // point to console as well
1135 ios::sync_with_stdio();
1136
1137 SetConsoleCtrlHandler(MyConsoleHandler, TRUE);
1138 }
1139 #else
1140 // Not supported
1141 void wxRedirectIOToConsole()
1142 {
1143 }
1144 #endif
1145
1146