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