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