]> git.saurik.com Git - wxWidgets.git/blame - src/msw/utils.cpp
wxWindow::GetBestSize() added
[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(""))
8fb3a512
JS
485// Don't know what the correct cast should be, but it doesn't
486// compile in BC++/16-bit without this cast.
487#if !defined(__WIN32__)
488 return (WritePrivateProfileString((const char*) section, (const char*) entry, (const char*) value, (const char*) file) != 0);
489#else
837e5743 490 return (WritePrivateProfileString((LPCTSTR)WXSTRINGCAST section, (LPCTSTR)WXSTRINGCAST entry, (LPCTSTR)value, (LPCTSTR)WXSTRINGCAST file) != 0);
8fb3a512 491#endif
2bda0e17 492 else
837e5743 493 return (WriteProfileString((LPCTSTR)WXSTRINGCAST section, (LPCTSTR)WXSTRINGCAST entry, (LPCTSTR)WXSTRINGCAST value) != 0);
2bda0e17
KB
494}
495
496bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
497{
837e5743 498 wxChar buf[50];
223d09f6 499 wxSprintf(buf, wxT("%.4f"), value);
2bda0e17
KB
500 return wxWriteResource(section, entry, buf, file);
501}
502
503bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
504{
837e5743 505 wxChar buf[50];
223d09f6 506 wxSprintf(buf, wxT("%ld"), value);
2bda0e17
KB
507 return wxWriteResource(section, entry, buf, file);
508}
509
510bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
511{
837e5743 512 wxChar buf[50];
223d09f6 513 wxSprintf(buf, wxT("%d"), value);
2bda0e17
KB
514 return wxWriteResource(section, entry, buf, file);
515}
516
837e5743 517bool wxGetResource(const wxString& section, const wxString& entry, wxChar **value, const wxString& file)
2bda0e17 518{
223d09f6
KB
519 static const wxChar defunkt[] = wxT("$$default");
520 if (file != wxT(""))
2bda0e17 521 {
837e5743
OK
522 int n = GetPrivateProfileString((LPCTSTR)WXSTRINGCAST section, (LPCTSTR)WXSTRINGCAST entry, (LPCTSTR)defunkt,
523 (LPTSTR)wxBuffer, 1000, (LPCTSTR)WXSTRINGCAST file);
524 if (n == 0 || wxStrcmp(wxBuffer, defunkt) == 0)
2bda0e17
KB
525 return FALSE;
526 }
527 else
528 {
837e5743
OK
529 int n = GetProfileString((LPCTSTR)WXSTRINGCAST section, (LPCTSTR)WXSTRINGCAST entry, (LPCTSTR)defunkt,
530 (LPTSTR)wxBuffer, 1000);
531 if (n == 0 || wxStrcmp(wxBuffer, defunkt) == 0)
2bda0e17
KB
532 return FALSE;
533 }
534 if (*value) delete[] (*value);
535 *value = copystring(wxBuffer);
536 return TRUE;
537 }
538
539bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
540{
837e5743
OK
541 wxChar *s = NULL;
542 bool succ = wxGetResource(section, entry, (wxChar **)&s, file);
2bda0e17
KB
543 if (succ)
544 {
837e5743 545 *value = (float)wxStrtod(s, NULL);
2bda0e17
KB
546 delete[] s;
547 return TRUE;
548 }
549 else return FALSE;
550}
551
552bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file)
553{
837e5743
OK
554 wxChar *s = NULL;
555 bool succ = wxGetResource(section, entry, (wxChar **)&s, file);
2bda0e17
KB
556 if (succ)
557 {
837e5743 558 *value = wxStrtol(s, NULL, 10);
2bda0e17
KB
559 delete[] s;
560 return TRUE;
561 }
562 else return FALSE;
563}
564
565bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file)
566{
837e5743
OK
567 wxChar *s = NULL;
568 bool succ = wxGetResource(section, entry, (wxChar **)&s, file);
2bda0e17
KB
569 if (succ)
570 {
837e5743 571 *value = (int)wxStrtol(s, NULL, 10);
b07135ba 572 delete[] s;
2bda0e17
KB
573 return TRUE;
574 }
575 else return FALSE;
576}
47d67540 577#endif // wxUSE_RESOURCES
2bda0e17 578
634903fd 579// ---------------------------------------------------------------------------
25889d3c 580// helper functions for showing a "busy" cursor
634903fd
VZ
581// ---------------------------------------------------------------------------
582
25889d3c
JS
583HCURSOR gs_wxBusyCursor = 0; // new, busy cursor
584HCURSOR gs_wxBusyCursorOld = 0; // old cursor
634903fd 585static int gs_wxBusyCursorCount = 0;
2bda0e17
KB
586
587// Set the cursor to the busy cursor for all windows
588void wxBeginBusyCursor(wxCursor *cursor)
589{
634903fd
VZ
590 if ( gs_wxBusyCursorCount++ == 0 )
591 {
592 gs_wxBusyCursor = (HCURSOR)cursor->GetHCURSOR();
593 gs_wxBusyCursorOld = ::SetCursor(gs_wxBusyCursor);
594 }
595 //else: nothing to do, already set
2bda0e17
KB
596}
597
598// Restore cursor to normal
634903fd 599void wxEndBusyCursor()
2bda0e17 600{
634903fd 601 wxCHECK_RET( gs_wxBusyCursorCount > 0,
223d09f6 602 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
b07135ba 603
634903fd
VZ
604 if ( --gs_wxBusyCursorCount == 0 )
605 {
606 ::SetCursor(gs_wxBusyCursorOld);
607
608 gs_wxBusyCursorOld = 0;
609 }
2bda0e17
KB
610}
611
612// TRUE if we're between the above two calls
634903fd 613bool wxIsBusy()
2bda0e17 614{
634903fd 615 return (gs_wxBusyCursorCount > 0);
b07135ba 616}
2bda0e17 617
634903fd 618// ---------------------------------------------------------------------------
837e5743 619const wxChar* wxGetHomeDir(wxString *pstr)
743e0a66
VZ
620{
621 wxString& strDir = *pstr;
622
57c208c5 623 #if defined(__UNIX__) && !defined(__TWIN32__)
837e5743 624 const wxChar *szHome = wxGetenv("HOME");
743e0a66
VZ
625 if ( szHome == NULL ) {
626 // we're homeless...
627 wxLogWarning(_("can't find user's HOME, using current directory."));
223d09f6 628 strDir = wxT(".");
743e0a66
VZ
629 }
630 else
631 strDir = szHome;
632
633 // add a trailing slash if needed
223d09f6
KB
634 if ( strDir.Last() != wxT('/') )
635 strDir << wxT('/');
743e0a66
VZ
636 #else // Windows
637 #ifdef __WIN32__
223d09f6 638 const wxChar *szHome = wxGetenv(wxT("HOMEDRIVE"));
743e0a66
VZ
639 if ( szHome != NULL )
640 strDir << szHome;
223d09f6 641 szHome = wxGetenv(wxT("HOMEPATH"));
743e0a66
VZ
642 if ( szHome != NULL ) {
643 strDir << szHome;
644
645 // the idea is that under NT these variables have default values
646 // of "%systemdrive%:" and "\\". As we don't want to create our
647 // config files in the root directory of the system drive, we will
648 // create it in our program's dir. However, if the user took care
649 // to set HOMEPATH to something other than "\\", we suppose that he
650 // knows what he is doing and use the supplied value.
223d09f6 651 if ( wxStrcmp(szHome, wxT("\\")) != 0 )
743e0a66
VZ
652 return strDir.c_str();
653 }
654
655 #else // Win16
656 // Win16 has no idea about home, so use the working directory instead
657 #endif // WIN16/32
658
659 // 260 was taken from windef.h
660 #ifndef MAX_PATH
661 #define MAX_PATH 260
662 #endif
663
664 wxString strPath;
665 ::GetModuleFileName(::GetModuleHandle(NULL),
666 strPath.GetWriteBuf(MAX_PATH), MAX_PATH);
667 strPath.UngetWriteBuf();
668
669 // extract the dir name
670 wxSplitPath(strPath, &strDir, NULL, NULL);
671
672 #endif // UNIX/Win
673
674 return strDir.c_str();
675}
676
2bda0e17 677// Hack for MS-DOS
837e5743 678wxChar *wxGetUserHome (const wxString& user)
2bda0e17 679{
837e5743 680 wxChar *home;
2bda0e17
KB
681 wxString user1(user);
682
223d09f6 683 if (user1 != wxT("")) {
837e5743 684 wxChar tmp[64];
2bda0e17
KB
685 if (wxGetUserId(tmp, sizeof(tmp)/sizeof(char))) {
686 // Guests belong in the temp dir
223d09f6
KB
687 if (wxStricmp(tmp, wxT("annonymous")) == 0) {
688 if ((home = wxGetenv(wxT("TMP"))) != NULL ||
689 (home = wxGetenv(wxT("TMPDIR"))) != NULL ||
690 (home = wxGetenv(wxT("TEMP"))) != NULL)
691 return *home ? home : (wxChar*)wxT("\\");
2bda0e17 692 }
837e5743 693 if (wxStricmp(tmp, WXSTRINGCAST user1) == 0)
223d09f6 694 user1 = wxT("");
2bda0e17
KB
695 }
696 }
223d09f6
KB
697 if (user1 == wxT(""))
698 if ((home = wxGetenv(wxT("HOME"))) != NULL)
2bda0e17 699 {
837e5743 700 wxStrcpy(wxBuffer, home);
2bda0e17
KB
701 Unix2DosFilename(wxBuffer);
702 return wxBuffer;
703 }
704 return NULL; // No home known!
705}
706
707// Check whether this window wants to process messages, e.g. Stop button
708// in long calculations.
709bool wxCheckForInterrupt(wxWindow *wnd)
710{
743e0a66
VZ
711 if(wnd){
712 MSG msg;
713 HWND win= (HWND) wnd->GetHWND();
714 while(PeekMessage(&msg,win,0,0,PM_REMOVE)){
715 TranslateMessage(&msg);
716 DispatchMessage(&msg);
717 }
718 return TRUE;//*** temporary?
719 }
720 else{
223d09f6 721 wxFAIL_MSG(wxT("wnd==NULL !!!"));
634903fd 722
743e0a66
VZ
723 return FALSE;//*** temporary?
724 }
2bda0e17
KB
725}
726
727// MSW only: get user-defined resource from the .res file.
728// Returns NULL or newly-allocated memory, so use delete[] to clean up.
729
2049ba38 730#ifdef __WXMSW__
837e5743 731wxChar *wxLoadUserResource(const wxString& resourceName, const wxString& resourceType)
2bda0e17 732{
837e5743 733 wxChar *s = NULL;
57c208c5 734#if !defined(__WIN32__) || defined(__TWIN32__)
2bda0e17
KB
735 HRSRC hResource = ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
736#else
737#ifdef UNICODE
738 HRSRC hResource = ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
739#else
740 HRSRC hResource = ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
741#endif
742#endif
743
744 if (hResource == 0)
745 return NULL;
746 HGLOBAL hData = ::LoadResource(wxGetInstance(), hResource);
747 if (hData == 0)
748 return NULL;
837e5743 749 wxChar *theText = (wxChar *)LockResource(hData);
2bda0e17
KB
750 if (!theText)
751 return NULL;
b07135ba 752
2bda0e17
KB
753 s = copystring(theText);
754
755 // Obsolete in WIN32
756#ifndef __WIN32__
757 UnlockResource(hData);
758#endif
759
760 // No need??
761// GlobalFree(hData);
762
763 return s;
764}
765#endif
766
767void wxGetMousePosition( int* x, int* y )
768{
769 POINT pt;
770 GetCursorPos( & pt );
771 *x = pt.x;
772 *y = pt.y;
773};
774
775// Return TRUE if we have a colour display
634903fd 776bool wxColourDisplay()
2bda0e17 777{
57c208c5 778 HDC dc = ::GetDC((HWND) NULL);
2bda0e17
KB
779 bool flag;
780 int noCols = GetDeviceCaps(dc, NUMCOLORS);
781 if ((noCols == -1) || (noCols > 2))
782 flag = TRUE;
783 else
784 flag = FALSE;
57c208c5 785 ReleaseDC((HWND) NULL, dc);
2bda0e17
KB
786 return flag;
787}
788
789// Returns depth of screen
634903fd 790int wxDisplayDepth()
2bda0e17 791{
57c208c5 792 HDC dc = ::GetDC((HWND) NULL);
2bda0e17
KB
793 int planes = GetDeviceCaps(dc, PLANES);
794 int bitsPerPixel = GetDeviceCaps(dc, BITSPIXEL);
795 int depth = planes*bitsPerPixel;
57c208c5 796 ReleaseDC((HWND) NULL, dc);
2bda0e17
KB
797 return depth;
798}
799
800// Get size of display
801void wxDisplaySize(int *width, int *height)
802{
57c208c5 803 HDC dc = ::GetDC((HWND) NULL);
2bda0e17 804 *width = GetDeviceCaps(dc, HORZRES); *height = GetDeviceCaps(dc, VERTRES);
57c208c5 805 ReleaseDC((HWND) NULL, dc);
2bda0e17
KB
806}
807
7f555861
JS
808bool wxDirExists(const wxString& dir)
809{
810 /* MATTHEW: [6] Always use same code for Win32, call FindClose */
811#if defined(__WIN32__)
812 WIN32_FIND_DATA fileInfo;
813#else
814#ifdef __BORLANDC__
815 struct ffblk fileInfo;
816#else
817 struct find_t fileInfo;
818#endif
819#endif
820
821#if defined(__WIN32__)
3f4a0c5b
VZ
822 HANDLE h = FindFirstFile((LPTSTR) WXSTRINGCAST dir,(LPWIN32_FIND_DATA)&fileInfo);
823
824 if (h==INVALID_HANDLE_VALUE)
825 return FALSE;
826 else {
827 FindClose(h);
828 return ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
829 }
7f555861
JS
830#else
831 // In Borland findfirst has a different argument
832 // ordering from _dos_findfirst. But _dos_findfirst
833 // _should_ be ok in both MS and Borland... why not?
834#ifdef __BORLANDC__
835 return ((findfirst(WXSTRINGCAST dir, &fileInfo, _A_SUBDIR) == 0 && (fileInfo.ff_attrib & _A_SUBDIR) != 0));
836#else
837 return (((_dos_findfirst(WXSTRINGCAST dir, _A_SUBDIR, &fileInfo) == 0) && (fileInfo.attrib & _A_SUBDIR)) != 0);
838#endif
839#endif
840}
841
cc2b7472
VZ
842// ---------------------------------------------------------------------------
843// window information functions
844// ---------------------------------------------------------------------------
845
1c4a764c
VZ
846wxString WXDLLEXPORT wxGetWindowText(WXHWND hWnd)
847{
848 wxString str;
849 int len = GetWindowTextLength((HWND)hWnd) + 1;
850 GetWindowText((HWND)hWnd, str.GetWriteBuf(len), len);
851 str.UngetWriteBuf();
852
853 return str;
854}
855
cc2b7472
VZ
856wxString WXDLLEXPORT wxGetWindowClass(WXHWND hWnd)
857{
858 wxString str;
859
860 int len = 256; // some starting value
861
862 for ( ;; )
863 {
864 // as we've #undefined GetClassName we must now manually choose the
865 // right function to call
866 int count =
867
868 #ifndef __WIN32__
869 GetClassName
870 #else // Win32
871 #ifdef UNICODE
872 GetClassNameW
873 #else // !Unicode
874 #ifdef __TWIN32__
875 GetClassName
876 #else // !Twin32
877 GetClassNameA
878 #endif // Twin32/!Twin32
879 #endif // Unicode/ANSI
880 #endif // Win16/32
881 ((HWND)hWnd, str.GetWriteBuf(len), len);
882
883 str.UngetWriteBuf();
884 if ( count == len )
885 {
886 // the class name might have been truncated, retry with larger
887 // buffer
888 len *= 2;
889 }
890 else
891 {
892 break;
893 }
894 }
895
896 return str;
897}
898
42e69d6b 899WXWORD WXDLLEXPORT wxGetWindowId(WXHWND hWnd)
cc2b7472
VZ
900{
901#ifndef __WIN32__
42e69d6b 902 return GetWindowWord((HWND)hWnd, GWW_ID);
cc2b7472 903#else // Win32
42e69d6b 904 return GetWindowLong((HWND)hWnd, GWL_ID);
cc2b7472
VZ
905#endif // Win16/32
906}
907
7f555861
JS
908#if 0
909//------------------------------------------------------------------------
910// wild character routines
911//------------------------------------------------------------------------
912
913bool wxIsWild( const wxString& pattern )
914{
915 wxString tmp = pattern;
916 char *pat = WXSTRINGCAST(tmp);
917 while (*pat) {
3f4a0c5b
VZ
918 switch (*pat++) {
919 case '?': case '*': case '[': case '{':
920 return TRUE;
921 case '\\':
922 if (!*pat++)
923 return FALSE;
924 }
7f555861
JS
925 }
926 return FALSE;
927};
928
929
930bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
931{
932 wxString tmp1 = pat;
933 char *pattern = WXSTRINGCAST(tmp1);
934 wxString tmp2 = text;
935 char *str = WXSTRINGCAST(tmp2);
936 char c;
937 char *cp;
938 bool done = FALSE, ret_code, ok;
939 // Below is for vi fans
940 const char OB = '{', CB = '}';
941
942 // dot_special means '.' only matches '.'
943 if (dot_special && *str == '.' && *pattern != *str)
3f4a0c5b 944 return FALSE;
7f555861
JS
945
946 while ((*pattern != '\0') && (!done)
947 && (((*str=='\0')&&((*pattern==OB)||(*pattern=='*')))||(*str!='\0'))) {
3f4a0c5b
VZ
948 switch (*pattern) {
949 case '\\':
950 pattern++;
951 if (*pattern != '\0')
952 pattern++;
953 break;
954 case '*':
955 pattern++;
956 ret_code = FALSE;
957 while ((*str!='\0')
958 && (!(ret_code=wxMatchWild(pattern, str++, FALSE))))
959 /*loop*/;
960 if (ret_code) {
961 while (*str != '\0')
962 str++;
963 while (*pattern != '\0')
964 pattern++;
965 }
966 break;
967 case '[':
968 pattern++;
969 repeat:
970 if ((*pattern == '\0') || (*pattern == ']')) {
971 done = TRUE;
972 break;
973 }
974 if (*pattern == '\\') {
975 pattern++;
976 if (*pattern == '\0') {
977 done = TRUE;
978 break;
979 }
980 }
981 if (*(pattern + 1) == '-') {
982 c = *pattern;
983 pattern += 2;
984 if (*pattern == ']') {
985 done = TRUE;
986 break;
987 }
988 if (*pattern == '\\') {
989 pattern++;
990 if (*pattern == '\0') {
991 done = TRUE;
992 break;
993 }
994 }
995 if ((*str < c) || (*str > *pattern)) {
996 pattern++;
997 goto repeat;
998 }
999 } else if (*pattern != *str) {
1000 pattern++;
1001 goto repeat;
1002 }
1003 pattern++;
1004 while ((*pattern != ']') && (*pattern != '\0')) {
1005 if ((*pattern == '\\') && (*(pattern + 1) != '\0'))
1006 pattern++;
1007 pattern++;
1008 }
1009 if (*pattern != '\0') {
1010 pattern++, str++;
1011 }
1012 break;
1013 case '?':
1014 pattern++;
1015 str++;
1016 break;
1017 case OB:
1018 pattern++;
1019 while ((*pattern != CB) && (*pattern != '\0')) {
1020 cp = str;
1021 ok = TRUE;
1022 while (ok && (*cp != '\0') && (*pattern != '\0')
1023 && (*pattern != ',') && (*pattern != CB)) {
1024 if (*pattern == '\\')
1025 pattern++;
1026 ok = (*pattern++ == *cp++);
1027 }
1028 if (*pattern == '\0') {
1029 ok = FALSE;
1030 done = TRUE;
1031 break;
1032 } else if (ok) {
1033 str = cp;
1034 while ((*pattern != CB) && (*pattern != '\0')) {
1035 if (*++pattern == '\\') {
1036 if (*++pattern == CB)
1037 pattern++;
1038 }
1039 }
1040 } else {
1041 while (*pattern!=CB && *pattern!=',' && *pattern!='\0') {
1042 if (*++pattern == '\\') {
7f555861 1043 if (*++pattern == CB || *pattern == ',')
3f4a0c5b
VZ
1044 pattern++;
1045 }
1046 }
1047 }
1048 if (*pattern != '\0')
1049 pattern++;
1050 }
1051 break;
1052 default:
1053 if (*str == *pattern) {
1054 str++, pattern++;
1055 } else {
1056 done = TRUE;
1057 }
1058 }
7f555861
JS
1059 }
1060 while (*pattern == '*')
3f4a0c5b 1061 pattern++;
7f555861
JS
1062 return ((*str == '\0') && (*pattern == '\0'));
1063};
1064
1065#endif
1066
cf45d1f4 1067#if 0
c030b70f
JS
1068
1069// maximum mumber of lines the output console should have
1070static const WORD MAX_CONSOLE_LINES = 500;
1071
1072BOOL WINAPI MyConsoleHandler( DWORD dwCtrlType ) { // control signal type
3f4a0c5b
VZ
1073 FreeConsole();
1074 return TRUE;
c030b70f
JS
1075}
1076
1077void wxRedirectIOToConsole()
1078{
1079 int hConHandle;
1080 long lStdHandle;
1081 CONSOLE_SCREEN_BUFFER_INFO coninfo;
1082 FILE *fp;
1083
1084 // allocate a console for this app
1085 AllocConsole();
1086
1087 // set the screen buffer to be big enough to let us scroll text
3f4a0c5b 1088 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
c030b70f
JS
1089 &coninfo);
1090 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
3f4a0c5b 1091 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),
c030b70f
JS
1092 coninfo.dwSize);
1093
1094 // redirect unbuffered STDOUT to the console
1095 lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
1096 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
1097 if(hConHandle <= 0) return;
1098 fp = _fdopen( hConHandle, "w" );
1099 *stdout = *fp;
1100 setvbuf( stdout, NULL, _IONBF, 0 );
1101
1102 // redirect unbuffered STDIN to the console
1103 lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
1104 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
1105 if(hConHandle <= 0) return;
1106 fp = _fdopen( hConHandle, "r" );
1107 *stdin = *fp;
1108 setvbuf( stdin, NULL, _IONBF, 0 );
1109
1110 // redirect unbuffered STDERR to the console
1111 lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
1112 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
1113 if(hConHandle <= 0) return;
1114 fp = _fdopen( hConHandle, "w" );
1115 *stderr = *fp;
1116 setvbuf( stderr, NULL, _IONBF, 0 );
3f4a0c5b
VZ
1117
1118 // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
c030b70f
JS
1119 // point to console as well
1120 ios::sync_with_stdio();
1121
3f4a0c5b 1122 SetConsoleCtrlHandler(MyConsoleHandler, TRUE);
c030b70f
JS
1123}
1124#else
1125// Not supported
1126void wxRedirectIOToConsole()
1127{
1128}
1129#endif
1130
1131