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