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