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