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