]> git.saurik.com Git - wxWidgets.git/blob - src/msw/utils.cpp
Menu/toolbar event handling now tries the window with the focus first.
[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 wxUsleep(unsigned long milliseconds)
303 {
304 #ifdef __WIN32__
305 ::Sleep(milliseconds);
306 #else
307 if (inTimer)
308 return;
309
310 wxTheSleepTimer = new wxSleepTimer;
311 inTimer = TRUE;
312 wxTheSleepTimer->Start(milliseconds);
313 while (inTimer)
314 {
315 if (wxTheApp->Pending())
316 wxTheApp->Dispatch();
317 }
318 delete wxTheSleepTimer;
319 wxTheSleepTimer = NULL;
320 #endif
321 }
322
323 void wxSleep(int nSecs)
324 {
325 #if 0 // WIN32 hangs app
326 Sleep( 1000*nSecs );
327 #else
328 if (inTimer)
329 return;
330
331 wxTheSleepTimer = new wxSleepTimer;
332 inTimer = TRUE;
333 wxTheSleepTimer->Start(nSecs*1000);
334 while (inTimer)
335 {
336 if (wxTheApp->Pending())
337 wxTheApp->Dispatch();
338 }
339 delete wxTheSleepTimer;
340 wxTheSleepTimer = NULL;
341 #endif
342 }
343
344 // Consume all events until no more left
345 void wxFlushEvents()
346 {
347 // wxYield();
348 }
349
350 // Output a debug mess., in a system dependent fashion.
351 void wxDebugMsg(const char *fmt ...)
352 {
353 va_list ap;
354 static char buffer[512];
355
356 if (!wxTheApp->GetWantDebugOutput())
357 return ;
358
359 va_start(ap, fmt);
360
361 wvsprintf(buffer,fmt,ap) ;
362 OutputDebugString((LPCSTR)buffer) ;
363
364 va_end(ap);
365 }
366
367 // Non-fatal error: pop up message box and (possibly) continue
368 void wxError(const wxString& msg, const wxString& title)
369 {
370 sprintf(wxBuffer, "%s\nContinue?", WXSTRINGCAST msg);
371 if (MessageBox(NULL, (LPCSTR)wxBuffer, (LPCSTR)WXSTRINGCAST title,
372 MB_ICONSTOP | MB_YESNO) == IDNO)
373 wxExit();
374 }
375
376 // Fatal error: pop up message box and abort
377 void wxFatalError(const wxString& msg, const wxString& title)
378 {
379 sprintf(wxBuffer, "%s: %s", WXSTRINGCAST title, WXSTRINGCAST msg);
380 FatalAppExit(0, (LPCSTR)wxBuffer);
381 }
382
383 // Emit a beeeeeep
384 void wxBell()
385 {
386 // Removed by RD because IHMO syncronous sound is a Bad Thing. MessageBeep
387 // will do a similar thing anyway if there is no sound card...
388 //#ifdef __WIN32__
389 // Beep(1000,1000) ; // 1kHz during 1 sec.
390 //#else
391 MessageBeep((UINT)-1) ;
392 //#endif
393 }
394
395 // Chris Breeze 27/5/98: revised WIN32 code to
396 // detect WindowsNT correctly
397 int wxGetOsVersion(int *majorVsn, int *minorVsn)
398 {
399 extern char *wxOsVersion;
400 if (majorVsn) *majorVsn = 0;
401 if (minorVsn) *minorVsn = 0;
402
403 #if defined(__WIN32__) && !defined(__SC__)
404 OSVERSIONINFO info;
405 memset(&info, 0, sizeof(OSVERSIONINFO));
406 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
407 if (GetVersionEx(&info))
408 {
409 if (majorVsn) *majorVsn = info.dwMajorVersion;
410 if (minorVsn) *minorVsn = info.dwMinorVersion;
411 switch (info.dwPlatformId)
412 {
413 case VER_PLATFORM_WIN32s:
414 return wxWIN32S;
415 break;
416 case VER_PLATFORM_WIN32_WINDOWS:
417 return wxWIN95;
418 break;
419 case VER_PLATFORM_WIN32_NT:
420 return wxWINDOWS_NT;
421 break;
422 }
423 }
424 return wxWINDOWS; // error if we get here, return generic value
425 #else
426 // Win16 code...
427 int retValue = 0;
428 # ifdef __WINDOWS_386__
429 retValue = wxWIN386;
430 # else
431 # if !defined(__WATCOMC__) && !defined(GNUWIN32) && wxUSE_PENWINDOWS
432 extern HANDLE g_hPenWin;
433 retValue = g_hPenWin ? wxPENWINDOWS : wxWINDOWS ;
434 # endif
435 # endif
436 // @@@@ To be completed. I don't have the manual here...
437 if (majorVsn) *majorVsn = 3 ;
438 if (minorVsn) *minorVsn = 1 ;
439 return retValue ;
440 #endif
441 }
442
443 // Reading and writing resources (eg WIN.INI, .Xdefaults)
444 #if wxUSE_RESOURCES
445 bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
446 {
447 if (file != "")
448 return (WritePrivateProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)value, (LPCSTR)WXSTRINGCAST file) != 0);
449 else
450 return (WriteProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)WXSTRINGCAST value) != 0);
451 }
452
453 bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
454 {
455 char buf[50];
456 sprintf(buf, "%.4f", value);
457 return wxWriteResource(section, entry, buf, file);
458 }
459
460 bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
461 {
462 char buf[50];
463 sprintf(buf, "%ld", value);
464 return wxWriteResource(section, entry, buf, file);
465 }
466
467 bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
468 {
469 char buf[50];
470 sprintf(buf, "%d", value);
471 return wxWriteResource(section, entry, buf, file);
472 }
473
474 bool wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file)
475 {
476 static const char defunkt[] = "$$default";
477 if (file != "")
478 {
479 int n = GetPrivateProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)defunkt,
480 (LPSTR)wxBuffer, 1000, (LPCSTR)WXSTRINGCAST file);
481 if (n == 0 || strcmp(wxBuffer, defunkt) == 0)
482 return FALSE;
483 }
484 else
485 {
486 int n = GetProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)defunkt,
487 (LPSTR)wxBuffer, 1000);
488 if (n == 0 || strcmp(wxBuffer, defunkt) == 0)
489 return FALSE;
490 }
491 if (*value) delete[] (*value);
492 *value = copystring(wxBuffer);
493 return TRUE;
494 }
495
496 bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
497 {
498 char *s = NULL;
499 bool succ = wxGetResource(section, entry, (char **)&s, file);
500 if (succ)
501 {
502 *value = (float)strtod(s, NULL);
503 delete[] s;
504 return TRUE;
505 }
506 else return FALSE;
507 }
508
509 bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file)
510 {
511 char *s = NULL;
512 bool succ = wxGetResource(section, entry, (char **)&s, file);
513 if (succ)
514 {
515 *value = strtol(s, NULL, 10);
516 delete[] s;
517 return TRUE;
518 }
519 else return FALSE;
520 }
521
522 bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file)
523 {
524 char *s = NULL;
525 bool succ = wxGetResource(section, entry, (char **)&s, file);
526 if (succ)
527 {
528 *value = (int)strtol(s, NULL, 10);
529 delete[] s;
530 return TRUE;
531 }
532 else return FALSE;
533 }
534 #endif // wxUSE_RESOURCES
535
536 // ---------------------------------------------------------------------------
537 // helper functiosn for showing a "busy" cursor
538 // ---------------------------------------------------------------------------
539
540 extern HCURSOR gs_wxBusyCursor = 0; // new, busy cursor
541 static HCURSOR gs_wxBusyCursorOld = 0; // old cursor
542 static int gs_wxBusyCursorCount = 0;
543
544 // Set the cursor to the busy cursor for all windows
545 void wxBeginBusyCursor(wxCursor *cursor)
546 {
547 if ( gs_wxBusyCursorCount++ == 0 )
548 {
549 gs_wxBusyCursor = (HCURSOR)cursor->GetHCURSOR();
550 gs_wxBusyCursorOld = ::SetCursor(gs_wxBusyCursor);
551 }
552 //else: nothing to do, already set
553 }
554
555 // Restore cursor to normal
556 void wxEndBusyCursor()
557 {
558 wxCHECK_RET( gs_wxBusyCursorCount > 0,
559 "no matching wxBeginBusyCursor() for wxEndBusyCursor()" );
560
561 if ( --gs_wxBusyCursorCount == 0 )
562 {
563 ::SetCursor(gs_wxBusyCursorOld);
564
565 gs_wxBusyCursorOld = 0;
566 }
567 }
568
569 // TRUE if we're between the above two calls
570 bool wxIsBusy()
571 {
572 return (gs_wxBusyCursorCount > 0);
573 }
574
575 // ---------------------------------------------------------------------------
576 const char* wxGetHomeDir(wxString *pstr)
577 {
578 wxString& strDir = *pstr;
579
580 #if defined(__UNIX__) && !defined(__TWIN32__)
581 const char *szHome = getenv("HOME");
582 if ( szHome == NULL ) {
583 // we're homeless...
584 wxLogWarning(_("can't find user's HOME, using current directory."));
585 strDir = ".";
586 }
587 else
588 strDir = szHome;
589
590 // add a trailing slash if needed
591 if ( strDir.Last() != '/' )
592 strDir << '/';
593 #else // Windows
594 #ifdef __WIN32__
595 const char *szHome = getenv("HOMEDRIVE");
596 if ( szHome != NULL )
597 strDir << szHome;
598 szHome = getenv("HOMEPATH");
599 if ( szHome != NULL ) {
600 strDir << szHome;
601
602 // the idea is that under NT these variables have default values
603 // of "%systemdrive%:" and "\\". As we don't want to create our
604 // config files in the root directory of the system drive, we will
605 // create it in our program's dir. However, if the user took care
606 // to set HOMEPATH to something other than "\\", we suppose that he
607 // knows what he is doing and use the supplied value.
608 if ( strcmp(szHome, "\\") != 0 )
609 return strDir.c_str();
610 }
611
612 #else // Win16
613 // Win16 has no idea about home, so use the working directory instead
614 #endif // WIN16/32
615
616 // 260 was taken from windef.h
617 #ifndef MAX_PATH
618 #define MAX_PATH 260
619 #endif
620
621 wxString strPath;
622 ::GetModuleFileName(::GetModuleHandle(NULL),
623 strPath.GetWriteBuf(MAX_PATH), MAX_PATH);
624 strPath.UngetWriteBuf();
625
626 // extract the dir name
627 wxSplitPath(strPath, &strDir, NULL, NULL);
628
629 #endif // UNIX/Win
630
631 return strDir.c_str();
632 }
633
634 // Hack for MS-DOS
635 char *wxGetUserHome (const wxString& user)
636 {
637 char *home;
638 wxString user1(user);
639
640 if (user1 != "") {
641 char tmp[64];
642 if (wxGetUserId(tmp, sizeof(tmp)/sizeof(char))) {
643 // Guests belong in the temp dir
644 if (Stricmp(tmp, "annonymous") == 0) {
645 if ((home = getenv("TMP")) != NULL ||
646 (home = getenv("TMPDIR")) != NULL ||
647 (home = getenv("TEMP")) != NULL)
648 return *home ? home : "\\";
649 }
650 if (Stricmp(tmp, WXSTRINGCAST user1) == 0)
651 user1 = "";
652 }
653 }
654 if (user1 == "")
655 if ((home = getenv("HOME")) != NULL)
656 {
657 strcpy(wxBuffer, home);
658 Unix2DosFilename(wxBuffer);
659 return wxBuffer;
660 }
661 return NULL; // No home known!
662 }
663
664 // Check whether this window wants to process messages, e.g. Stop button
665 // in long calculations.
666 bool wxCheckForInterrupt(wxWindow *wnd)
667 {
668 if(wnd){
669 MSG msg;
670 HWND win= (HWND) wnd->GetHWND();
671 while(PeekMessage(&msg,win,0,0,PM_REMOVE)){
672 TranslateMessage(&msg);
673 DispatchMessage(&msg);
674 }
675 return TRUE;//*** temporary?
676 }
677 else{
678 wxFAIL_MSG("wnd==NULL !!!");
679
680 return FALSE;//*** temporary?
681 }
682 }
683
684 // MSW only: get user-defined resource from the .res file.
685 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
686
687 #ifdef __WXMSW__
688 char *wxLoadUserResource(const wxString& resourceName, const wxString& resourceType)
689 {
690 char *s = NULL;
691 #if !defined(__WIN32__) || defined(__TWIN32__)
692 HRSRC hResource = ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
693 #else
694 #ifdef UNICODE
695 HRSRC hResource = ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
696 #else
697 HRSRC hResource = ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
698 #endif
699 #endif
700
701 if (hResource == 0)
702 return NULL;
703 HGLOBAL hData = ::LoadResource(wxGetInstance(), hResource);
704 if (hData == 0)
705 return NULL;
706 char *theText = (char *)LockResource(hData);
707 if (!theText)
708 return NULL;
709
710 s = copystring(theText);
711
712 // Obsolete in WIN32
713 #ifndef __WIN32__
714 UnlockResource(hData);
715 #endif
716
717 // No need??
718 // GlobalFree(hData);
719
720 return s;
721 }
722 #endif
723
724 void wxGetMousePosition( int* x, int* y )
725 {
726 POINT pt;
727 GetCursorPos( & pt );
728 *x = pt.x;
729 *y = pt.y;
730 };
731
732 // Return TRUE if we have a colour display
733 bool wxColourDisplay()
734 {
735 HDC dc = ::GetDC((HWND) NULL);
736 bool flag;
737 int noCols = GetDeviceCaps(dc, NUMCOLORS);
738 if ((noCols == -1) || (noCols > 2))
739 flag = TRUE;
740 else
741 flag = FALSE;
742 ReleaseDC((HWND) NULL, dc);
743 return flag;
744 }
745
746 // Returns depth of screen
747 int wxDisplayDepth()
748 {
749 HDC dc = ::GetDC((HWND) NULL);
750 int planes = GetDeviceCaps(dc, PLANES);
751 int bitsPerPixel = GetDeviceCaps(dc, BITSPIXEL);
752 int depth = planes*bitsPerPixel;
753 ReleaseDC((HWND) NULL, dc);
754 return depth;
755 }
756
757 // Get size of display
758 void wxDisplaySize(int *width, int *height)
759 {
760 HDC dc = ::GetDC((HWND) NULL);
761 *width = GetDeviceCaps(dc, HORZRES); *height = GetDeviceCaps(dc, VERTRES);
762 ReleaseDC((HWND) NULL, dc);
763 }
764
765 bool wxDirExists(const wxString& dir)
766 {
767 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
768 #if defined(__WIN32__)
769 WIN32_FIND_DATA fileInfo;
770 #else
771 #ifdef __BORLANDC__
772 struct ffblk fileInfo;
773 #else
774 struct find_t fileInfo;
775 #endif
776 #endif
777
778 #if defined(__WIN32__)
779 HANDLE h = FindFirstFile((LPTSTR) WXSTRINGCAST dir,(LPWIN32_FIND_DATA)&fileInfo);
780
781 if (h==INVALID_HANDLE_VALUE)
782 return FALSE;
783 else {
784 FindClose(h);
785 return ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
786 }
787 #else
788 // In Borland findfirst has a different argument
789 // ordering from _dos_findfirst. But _dos_findfirst
790 // _should_ be ok in both MS and Borland... why not?
791 #ifdef __BORLANDC__
792 return ((findfirst(WXSTRINGCAST dir, &fileInfo, _A_SUBDIR) == 0 && (fileInfo.ff_attrib & _A_SUBDIR) != 0));
793 #else
794 return (((_dos_findfirst(WXSTRINGCAST dir, _A_SUBDIR, &fileInfo) == 0) && (fileInfo.attrib & _A_SUBDIR)) != 0);
795 #endif
796 #endif
797 }
798
799 wxString WXDLLEXPORT wxGetWindowText(WXHWND hWnd)
800 {
801 wxString str;
802 int len = GetWindowTextLength((HWND)hWnd) + 1;
803 GetWindowText((HWND)hWnd, str.GetWriteBuf(len), len);
804 str.UngetWriteBuf();
805
806 return str;
807 }
808
809 #if 0
810 //------------------------------------------------------------------------
811 // wild character routines
812 //------------------------------------------------------------------------
813
814 bool wxIsWild( const wxString& pattern )
815 {
816 wxString tmp = pattern;
817 char *pat = WXSTRINGCAST(tmp);
818 while (*pat) {
819 switch (*pat++) {
820 case '?': case '*': case '[': case '{':
821 return TRUE;
822 case '\\':
823 if (!*pat++)
824 return FALSE;
825 }
826 }
827 return FALSE;
828 };
829
830
831 bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
832 {
833 wxString tmp1 = pat;
834 char *pattern = WXSTRINGCAST(tmp1);
835 wxString tmp2 = text;
836 char *str = WXSTRINGCAST(tmp2);
837 char c;
838 char *cp;
839 bool done = FALSE, ret_code, ok;
840 // Below is for vi fans
841 const char OB = '{', CB = '}';
842
843 // dot_special means '.' only matches '.'
844 if (dot_special && *str == '.' && *pattern != *str)
845 return FALSE;
846
847 while ((*pattern != '\0') && (!done)
848 && (((*str=='\0')&&((*pattern==OB)||(*pattern=='*')))||(*str!='\0'))) {
849 switch (*pattern) {
850 case '\\':
851 pattern++;
852 if (*pattern != '\0')
853 pattern++;
854 break;
855 case '*':
856 pattern++;
857 ret_code = FALSE;
858 while ((*str!='\0')
859 && (!(ret_code=wxMatchWild(pattern, str++, FALSE))))
860 /*loop*/;
861 if (ret_code) {
862 while (*str != '\0')
863 str++;
864 while (*pattern != '\0')
865 pattern++;
866 }
867 break;
868 case '[':
869 pattern++;
870 repeat:
871 if ((*pattern == '\0') || (*pattern == ']')) {
872 done = TRUE;
873 break;
874 }
875 if (*pattern == '\\') {
876 pattern++;
877 if (*pattern == '\0') {
878 done = TRUE;
879 break;
880 }
881 }
882 if (*(pattern + 1) == '-') {
883 c = *pattern;
884 pattern += 2;
885 if (*pattern == ']') {
886 done = TRUE;
887 break;
888 }
889 if (*pattern == '\\') {
890 pattern++;
891 if (*pattern == '\0') {
892 done = TRUE;
893 break;
894 }
895 }
896 if ((*str < c) || (*str > *pattern)) {
897 pattern++;
898 goto repeat;
899 }
900 } else if (*pattern != *str) {
901 pattern++;
902 goto repeat;
903 }
904 pattern++;
905 while ((*pattern != ']') && (*pattern != '\0')) {
906 if ((*pattern == '\\') && (*(pattern + 1) != '\0'))
907 pattern++;
908 pattern++;
909 }
910 if (*pattern != '\0') {
911 pattern++, str++;
912 }
913 break;
914 case '?':
915 pattern++;
916 str++;
917 break;
918 case OB:
919 pattern++;
920 while ((*pattern != CB) && (*pattern != '\0')) {
921 cp = str;
922 ok = TRUE;
923 while (ok && (*cp != '\0') && (*pattern != '\0')
924 && (*pattern != ',') && (*pattern != CB)) {
925 if (*pattern == '\\')
926 pattern++;
927 ok = (*pattern++ == *cp++);
928 }
929 if (*pattern == '\0') {
930 ok = FALSE;
931 done = TRUE;
932 break;
933 } else if (ok) {
934 str = cp;
935 while ((*pattern != CB) && (*pattern != '\0')) {
936 if (*++pattern == '\\') {
937 if (*++pattern == CB)
938 pattern++;
939 }
940 }
941 } else {
942 while (*pattern!=CB && *pattern!=',' && *pattern!='\0') {
943 if (*++pattern == '\\') {
944 if (*++pattern == CB || *pattern == ',')
945 pattern++;
946 }
947 }
948 }
949 if (*pattern != '\0')
950 pattern++;
951 }
952 break;
953 default:
954 if (*str == *pattern) {
955 str++, pattern++;
956 } else {
957 done = TRUE;
958 }
959 }
960 }
961 while (*pattern == '*')
962 pattern++;
963 return ((*str == '\0') && (*pattern == '\0'));
964 };
965
966 #endif
967
968 #if defined(__WIN95__) && defined(__WXDEBUG__) && wxUSE_DBWIN32
969
970 /*
971 When I started programming with Visual C++ v4.0, I missed one of my favorite
972 tools -- DBWIN. Finding the code for a simple debug trace utility, DBMON,
973 on MSDN was a step in the right direction, but it is a console application
974 and thus has limited features and extensibility. DBWIN32 is my creation
975 to solve this problem.
976
977 The code is essentially a merging of a stripped down version of the DBWIN code
978 from VC 1.5 and DBMON.C with a few 32 bit changes.
979
980 As of version 1.2B, DBWIN32 supports both Win95 and NT. The NT support is
981 built into the operating system and works just by running DBWIN32. The Win95
982 team decided not to support this hook, so I have provided code that will do
983 this for you. See the file WIN95.TXT for instructions on installing this.
984
985 If you have questions, problems or suggestions about DBWIN32, I welcome your
986 feedback and plan to actively maintain the code.
987
988 Andrew Tucker
989 ast@halcyon.com
990
991 To download dbwin32, see e.g.:
992
993 http://ftp.digital.com/pub/micro/NT/WinSite/programr/dbwin32.zip
994 */
995
996 #if !defined(__MWERKS__) && !defined(__SALFORDC__) && !defined(__TWIN32__)
997 #include <process.h>
998 #endif
999
1000 void OutputDebugStringW95(const char* lpOutputString, ...)
1001 {
1002 HANDLE heventDBWIN; /* DBWIN32 synchronization object */
1003 HANDLE heventData; /* data passing synch object */
1004 HANDLE hSharedFile; /* memory mapped file shared data */
1005 LPSTR lpszSharedMem;
1006 char achBuffer[500];
1007
1008 /* create the output buffer */
1009 va_list args;
1010 va_start(args, lpOutputString);
1011 vsprintf(achBuffer, lpOutputString, args);
1012 va_end(args);
1013
1014 /*
1015 Do a regular OutputDebugString so that the output is
1016 still seen in the debugger window if it exists.
1017
1018 This ifdef is necessary to avoid infinite recursion
1019 from the inclusion of W95TRACE.H
1020 */
1021 #ifdef _UNICODE
1022 ::OutputDebugStringW(achBuffer);
1023 #else
1024 #ifdef __TWIN32__
1025 ::OutputDebugString(achBuffer);
1026 #else
1027 ::OutputDebugStringA(achBuffer);
1028 #endif
1029 #endif
1030
1031 /* bail if it's not Win95 */
1032 {
1033 OSVERSIONINFO VerInfo;
1034 VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
1035 GetVersionEx(&VerInfo);
1036 if ( VerInfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS )
1037 return;
1038 }
1039
1040 /* make sure DBWIN is open and waiting */
1041 heventDBWIN = OpenEvent(EVENT_MODIFY_STATE, FALSE, "DBWIN_BUFFER_READY");
1042 if ( !heventDBWIN )
1043 {
1044 //MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
1045 return;
1046 }
1047
1048 /* get a handle to the data synch object */
1049 heventData = OpenEvent(EVENT_MODIFY_STATE, FALSE, "DBWIN_DATA_READY");
1050 if ( !heventData )
1051 {
1052 // MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
1053 CloseHandle(heventDBWIN);
1054 return;
1055 }
1056
1057 hSharedFile = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0, 4096, "DBWIN_BUFFER");
1058 if (!hSharedFile)
1059 {
1060 //MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
1061 CloseHandle(heventDBWIN);
1062 CloseHandle(heventData);
1063 return;
1064 }
1065
1066 lpszSharedMem = (LPSTR)MapViewOfFile(hSharedFile, FILE_MAP_WRITE, 0, 0, 512);
1067 if (!lpszSharedMem)
1068 {
1069 //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
1070 CloseHandle(heventDBWIN);
1071 CloseHandle(heventData);
1072 return;
1073 }
1074
1075 /* wait for buffer event */
1076 WaitForSingleObject(heventDBWIN, INFINITE);
1077
1078 /* write it to the shared memory */
1079 #if defined( __BORLANDC__ ) || defined( __MWERKS__ ) || defined(__SALFORDC__)
1080 *((LPDWORD)lpszSharedMem) = getpid();
1081 #else
1082 *((LPDWORD)lpszSharedMem) = _getpid();
1083 #endif
1084
1085 wsprintf(lpszSharedMem + sizeof(DWORD), "%s", achBuffer);
1086
1087 /* signal data ready event */
1088 SetEvent(heventData);
1089
1090 /* clean up handles */
1091 CloseHandle(hSharedFile);
1092 CloseHandle(heventData);
1093 CloseHandle(heventDBWIN);
1094
1095 return;
1096 }
1097
1098
1099 #endif
1100
1101
1102 #if 0
1103
1104 // maximum mumber of lines the output console should have
1105 static const WORD MAX_CONSOLE_LINES = 500;
1106
1107 BOOL WINAPI MyConsoleHandler( DWORD dwCtrlType ) { // control signal type
1108 FreeConsole();
1109 return TRUE;
1110 }
1111
1112 void wxRedirectIOToConsole()
1113 {
1114 int hConHandle;
1115 long lStdHandle;
1116 CONSOLE_SCREEN_BUFFER_INFO coninfo;
1117 FILE *fp;
1118
1119 // allocate a console for this app
1120 AllocConsole();
1121
1122 // set the screen buffer to be big enough to let us scroll text
1123 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
1124 &coninfo);
1125 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
1126 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),
1127 coninfo.dwSize);
1128
1129 // redirect unbuffered STDOUT to the console
1130 lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
1131 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
1132 if(hConHandle <= 0) return;
1133 fp = _fdopen( hConHandle, "w" );
1134 *stdout = *fp;
1135 setvbuf( stdout, NULL, _IONBF, 0 );
1136
1137 // redirect unbuffered STDIN to the console
1138 lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
1139 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
1140 if(hConHandle <= 0) return;
1141 fp = _fdopen( hConHandle, "r" );
1142 *stdin = *fp;
1143 setvbuf( stdin, NULL, _IONBF, 0 );
1144
1145 // redirect unbuffered STDERR to the console
1146 lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
1147 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
1148 if(hConHandle <= 0) return;
1149 fp = _fdopen( hConHandle, "w" );
1150 *stderr = *fp;
1151 setvbuf( stderr, NULL, _IONBF, 0 );
1152
1153 // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
1154 // point to console as well
1155 ios::sync_with_stdio();
1156
1157 SetConsoleCtrlHandler(MyConsoleHandler, TRUE);
1158 }
1159 #else
1160 // Not supported
1161 void wxRedirectIOToConsole()
1162 {
1163 }
1164 #endif
1165
1166