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