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