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