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