]> git.saurik.com Git - wxWidgets.git/blob - src/msw/utils.cpp
Highly experimental, unstable code (for determining the
[wxWidgets.git] / src / msw / utils.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: msw/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
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 // #pragma implementation "utils.h" // Note: this is done in utilscmn.cpp now.
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/utils.h"
33 #include "wx/app.h"
34 #include "wx/cursor.h"
35 #include "wx/intl.h"
36 #include "wx/log.h"
37 #endif //WX_PRECOMP
38
39 #include "wx/msw/private.h" // includes <windows.h>
40
41 #include "wx/timer.h"
42
43 #include <ctype.h>
44
45 #if !defined(__GNUWIN32__) && !defined(__WXWINE__) && !defined(__SALFORDC__)
46 #include <direct.h>
47
48 #ifndef __MWERKS__
49 #include <dos.h>
50 #endif
51 #endif //GNUWIN32
52
53 #if defined(__GNUWIN32__) && !defined(__TWIN32__)
54 #include <sys/unistd.h>
55 #include <sys/stat.h>
56 #endif //GNUWIN32
57
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.
61 #include <dir.h>
62 #endif
63
64 #if defined(__WIN32__) && !defined(__TWIN32__)
65 #include <winsock.h> // we use socket functions in wxGetFullHostName()
66 #endif
67
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
78 #if defined(__WIN32__) && !defined(__WXWINE__)
79 #include <io.h>
80
81 #ifndef __GNUWIN32__
82 #include <shellapi.h>
83 #endif
84 #endif
85
86 #include <stdio.h>
87 #include <stdlib.h>
88 #include <string.h>
89 #ifndef __WATCOMC__
90 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
91 #include <errno.h>
92 #endif
93 #endif
94 #include <stdarg.h>
95
96 //// BEGIN for console support: VC++ only
97 #ifdef __VISUALC__
98
99 #include "wx/msw/msvcrt.h"
100
101 #include <fcntl.h>
102
103 #include "wx/ioswrap.h"
104
105 #if wxUSE_IOSTREAMH
106 // N.B. BC++ doesn't have istream.h, ostream.h
107 # include <io.h>
108 # include <fstream.h>
109 #else
110 # include <fstream>
111 #endif
112
113 /* Need to undef new if including crtdbg.h */
114 # ifdef new
115 # undef new
116 # endif
117
118 #ifndef __WIN16__
119 # include <crtdbg.h>
120 #endif
121
122 # if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS && wxUSE_DEBUG_NEW_ALWAYS
123 # define new new(__FILE__,__LINE__)
124 # endif
125
126 #endif
127 // __VISUALC__
128 /// END for console support
129
130 // ----------------------------------------------------------------------------
131 // constants
132 // ----------------------------------------------------------------------------
133
134 // In the WIN.INI file
135 static const wxChar WX_SECTION[] = wxT("wxWindows");
136 static const wxChar eUSERNAME[] = wxT("UserName");
137
138 // these are only used under Win16
139 #ifndef __WIN32__
140 static const wxChar eHOSTNAME[] = wxT("HostName");
141 static const wxChar eUSERID[] = wxT("UserId");
142 #endif // !Win32
143
144 // ============================================================================
145 // implementation
146 // ============================================================================
147
148 // ----------------------------------------------------------------------------
149 // get host name and related
150 // ----------------------------------------------------------------------------
151
152 // Get hostname only (without domain name)
153 bool wxGetHostName(wxChar *buf, int maxSize)
154 {
155 #if defined(__WIN32__) && !defined(__TWIN32__)
156 DWORD nSize = maxSize;
157 if ( !::GetComputerName(buf, &nSize) )
158 {
159 wxLogLastError("GetComputerName");
160
161 return FALSE;
162 }
163
164 return TRUE;
165 #else
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;
175 #endif
176 }
177
178 // get full hostname (with domain name if possible)
179 bool wxGetFullHostName(wxChar *buf, int maxSize)
180 {
181 // This breaks _at least_ mingw!!
182 #if 0
183
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
223 #endif // 0
224
225 return wxGetHostName(buf, maxSize);
226 }
227
228 // Get user ID e.g. jacs
229 bool wxGetUserId(wxChar *buf, int maxSize)
230 {
231 #if defined(__WIN32__) && !defined(__win32s__) && !defined(__TWIN32__)
232 DWORD nSize = maxSize;
233 if ( ::GetUserName(buf, &nSize) == 0 )
234 {
235 // actually, it does happen on Win9x if the user didn't log on
236 DWORD res = ::GetEnvironmentVariable(wxT("username"), buf, maxSize);
237 if ( res == 0 )
238 {
239 // not found
240 return FALSE;
241 }
242 }
243
244 return TRUE;
245 #else // Win16 or Win32s
246 wxChar *user;
247 const wxChar *default_id = wxT("anonymous");
248
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 }
261
262 return *buf ? TRUE : FALSE;
263 #endif
264 }
265
266 // Get user name e.g. Julian Smart
267 bool wxGetUserName(wxChar *buf, int maxSize)
268 {
269 #if wxUSE_PENWINDOWS && !defined(__WATCOMC__) && !defined(__GNUWIN32__)
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
279 #endif
280 {
281 #ifdef USE_NET_API
282 CHAR szUserName[256];
283 if ( !wxGetUserId(szUserName, WXSIZEOF(szUserName)) )
284 return FALSE;
285
286 // TODO how to get the domain name?
287 CHAR *szDomain = "";
288
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;
293
294 USER_INFO_2 *ui2; // User structure
295
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) );
301
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"));
306
307 goto error;
308 }
309
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;
320
321 case NERR_InvalidComputer:
322 wxLogError(wxT("Invalid domain controller name."));
323
324 goto error;
325
326 case NERR_UserNotFound:
327 wxLogError(wxT("Invalid user name '%s'."), szUserName);
328
329 goto error;
330
331 default:
332 wxLogSysError(wxT("Can't get information about user"));
333
334 goto error;
335 }
336
337 // Convert the Unicode full name to ANSI
338 WideCharToMultiByte( CP_ACP, 0, ui2->usri2_full_name, -1,
339 buf, maxSize, NULL, NULL );
340
341 return TRUE;
342
343 error:
344 wxLogError(wxT("Couldn't look up full user name."));
345
346 return FALSE;
347 #else // !USE_NET_API
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 }
355
356 if ( !ok )
357 {
358 wxStrncpy(buf, wxT("Unknown User"), maxSize);
359 }
360 #endif // Win32/16
361 }
362
363 return TRUE;
364 }
365
366 const wxChar* wxGetHomeDir(wxString *pstr)
367 {
368 wxString& strDir = *pstr;
369
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;
379
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;
391
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 }
401
402 #else // Win16
403 // Win16 has no idea about home, so use the working directory instead
404 #endif // WIN16/32
405
406 // 260 was taken from windef.h
407 #ifndef MAX_PATH
408 #define MAX_PATH 260
409 #endif
410
411 wxString strPath;
412 ::GetModuleFileName(::GetModuleHandle(NULL),
413 strPath.GetWriteBuf(MAX_PATH), MAX_PATH);
414 strPath.UngetWriteBuf();
415
416 // extract the dir name
417 wxSplitPath(strPath, &strDir, NULL, NULL);
418
419 #endif // UNIX/Win
420
421 return strDir.c_str();
422 }
423
424 wxChar *wxGetUserHome(const wxString& user)
425 {
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;
430
431 return (wxChar *)wxGetHomeDir(&s_home);
432 }
433
434 bool wxDirExists(const wxString& dir)
435 {
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
445
446 #if defined(__WIN32__)
447 HANDLE h = ::FindFirstFile(dir, &fileInfo);
448
449 if ( h == INVALID_HANDLE_VALUE )
450 {
451 wxLogLastError("FindFirstFile");
452
453 return FALSE;
454 }
455
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 }
472
473 // ----------------------------------------------------------------------------
474 // process management
475 // ----------------------------------------------------------------------------
476
477 int wxKill(long pid, int sig)
478 {
479 // TODO use SendMessage(WM_QUIT) and TerminateProcess() if needed
480
481 return 0;
482 }
483
484 // Execute a program in an Interactive Shell
485 bool wxShell(const wxString& command)
486 {
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
503 return wxExecute(cmd, TRUE /* sync */) != 0;
504 }
505
506 // ----------------------------------------------------------------------------
507 // misc
508 // ----------------------------------------------------------------------------
509
510 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
511 long wxGetFreeMemory()
512 {
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
521 }
522
523 // Emit a beeeeeep
524 void wxBell()
525 {
526 ::MessageBeep((UINT)-1); // default sound
527 }
528
529 wxString wxGetOsDescription()
530 {
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 }
578
579 int wxGetOsVersion(int *majorVsn, int *minorVsn)
580 {
581 #if defined(__WIN32__) && !defined(__SC__)
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;
592
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;
624 #endif
625 }
626
627 // ----------------------------------------------------------------------------
628 // sleep functions
629 // ----------------------------------------------------------------------------
630
631 #if wxUSE_GUI
632
633 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
634 static bool gs_inTimer = FALSE;
635
636 class wxSleepTimer: public wxTimer
637 {
638 public:
639 virtual void Notify()
640 {
641 gs_inTimer = FALSE;
642 Stop();
643 }
644 };
645
646 static wxTimer *wxTheSleepTimer = NULL;
647
648 void 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
669 void 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
687 void wxFlushEvents()
688 {
689 // wxYield();
690 }
691
692 #elif defined(__WIN32__) // wxUSE_GUI
693
694 void wxUsleep(unsigned long milliseconds)
695 {
696 ::Sleep(milliseconds);
697 }
698
699 void 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.
713 void 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
730 void 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
739 void 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
749 // Reading and writing resources (eg WIN.INI, .Xdefaults)
750 #if wxUSE_RESOURCES
751 bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
752 {
753 if (file != wxT(""))
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
759 return (WritePrivateProfileString((LPCTSTR)WXSTRINGCAST section, (LPCTSTR)WXSTRINGCAST entry, (LPCTSTR)value, (LPCTSTR)WXSTRINGCAST file) != 0);
760 #endif
761 else
762 return (WriteProfileString((LPCTSTR)WXSTRINGCAST section, (LPCTSTR)WXSTRINGCAST entry, (LPCTSTR)WXSTRINGCAST value) != 0);
763 }
764
765 bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
766 {
767 wxString buf;
768 buf.Printf(wxT("%.4f"), value);
769
770 return wxWriteResource(section, entry, buf, file);
771 }
772
773 bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
774 {
775 wxString buf;
776 buf.Printf(wxT("%ld"), value);
777
778 return wxWriteResource(section, entry, buf, file);
779 }
780
781 bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
782 {
783 wxString buf;
784 buf.Printf(wxT("%d"), value);
785
786 return wxWriteResource(section, entry, buf, file);
787 }
788
789 bool wxGetResource(const wxString& section, const wxString& entry, wxChar **value, const wxString& file)
790 {
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;
805 }
806 if (*value) delete[] (*value);
807 *value = copystring(wxBuffer);
808 return TRUE;
809 }
810
811 bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
812 {
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;
822 }
823
824 bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file)
825 {
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;
835 }
836
837 bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file)
838 {
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;
848 }
849 #endif // wxUSE_RESOURCES
850
851 // ---------------------------------------------------------------------------
852 // helper functions for showing a "busy" cursor
853 // ---------------------------------------------------------------------------
854
855 static HCURSOR gs_wxBusyCursor = 0; // new, busy cursor
856 static HCURSOR gs_wxBusyCursorOld = 0; // old cursor
857 static int gs_wxBusyCursorCount = 0;
858
859 extern HCURSOR wxGetCurrentBusyCursor()
860 {
861 return gs_wxBusyCursor;
862 }
863
864 // Set the cursor to the busy cursor for all windows
865 void wxBeginBusyCursor(wxCursor *cursor)
866 {
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
873 }
874
875 // Restore cursor to normal
876 void wxEndBusyCursor()
877 {
878 wxCHECK_RET( gs_wxBusyCursorCount > 0,
879 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
880
881 if ( --gs_wxBusyCursorCount == 0 )
882 {
883 ::SetCursor(gs_wxBusyCursorOld);
884
885 gs_wxBusyCursorOld = 0;
886 }
887 }
888
889 // TRUE if we're between the above two calls
890 bool wxIsBusy()
891 {
892 return (gs_wxBusyCursorCount > 0);
893 }
894
895 // Check whether this window wants to process messages, e.g. Stop button
896 // in long calculations.
897 bool wxCheckForInterrupt(wxWindow *wnd)
898 {
899 wxCHECK( wnd, FALSE );
900
901 MSG msg;
902 while ( ::PeekMessage(&msg, GetHwndOf(wnd), 0, 0, PM_REMOVE) )
903 {
904 ::TranslateMessage(&msg);
905 ::DispatchMessage(&msg);
906 }
907
908 return TRUE;
909 }
910
911 #endif // wxUSE_GUI
912
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
916 wxChar *wxLoadUserResource(const wxString& resourceName, const wxString& resourceType)
917 {
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;
925
926 wxChar *theText = (wxChar *)::LockResource(hData);
927 if ( !theText )
928 return NULL;
929
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);
938
939 // Obsolete in WIN32
940 #ifndef __WIN32__
941 UnlockResource(hData);
942 #endif
943
944 // No need??
945 // GlobalFree(hData);
946
947 return s;
948 }
949
950 // ----------------------------------------------------------------------------
951 // get display info
952 // ----------------------------------------------------------------------------
953
954 void wxGetMousePosition( int* x, int* y )
955 {
956 POINT pt;
957 GetCursorPos( & pt );
958 if ( x ) *x = pt.x;
959 if ( y ) *y = pt.y;
960 };
961
962 // Return TRUE if we have a colour display
963 bool wxColourDisplay()
964 {
965 ScreenHDC dc;
966 int noCols = GetDeviceCaps(dc, NUMCOLORS);
967
968 return (noCols == -1) || (noCols > 2);
969 }
970
971 // Returns depth of screen
972 int wxDisplayDepth()
973 {
974 ScreenHDC dc;
975 return GetDeviceCaps(dc, PLANES) * GetDeviceCaps(dc, BITSPIXEL);
976 }
977
978 // Get size of display
979 void wxDisplaySize(int *width, int *height)
980 {
981 ScreenHDC dc;
982
983 if ( width ) *width = GetDeviceCaps(dc, HORZRES);
984 if ( height ) *height = GetDeviceCaps(dc, VERTRES);
985 }
986
987 // ---------------------------------------------------------------------------
988 // window information functions
989 // ---------------------------------------------------------------------------
990
991 wxString 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
1001 wxString 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
1044 WXWORD WXDLLEXPORT wxGetWindowId(WXHWND hWnd)
1045 {
1046 #ifndef __WIN32__
1047 return GetWindowWord((HWND)hWnd, GWW_ID);
1048 #else // Win32
1049 return GetWindowLong((HWND)hWnd, GWL_ID);
1050 #endif // Win16/32
1051 }
1052
1053 #if 0
1054 //------------------------------------------------------------------------
1055 // wild character routines
1056 //------------------------------------------------------------------------
1057
1058 bool wxIsWild( const wxString& pattern )
1059 {
1060 wxString tmp = pattern;
1061 char *pat = WXSTRINGCAST(tmp);
1062 while (*pat) {
1063 switch (*pat++) {
1064 case '?': case '*': case '[': case '{':
1065 return TRUE;
1066 case '\\':
1067 if (!*pat++)
1068 return FALSE;
1069 }
1070 }
1071 return FALSE;
1072 };
1073
1074
1075 bool 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)
1089 return FALSE;
1090
1091 while ((*pattern != '\0') && (!done)
1092 && (((*str=='\0')&&((*pattern==OB)||(*pattern=='*')))||(*str!='\0'))) {
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 == '\\') {
1188 if (*++pattern == CB || *pattern == ',')
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 }
1204 }
1205 while (*pattern == '*')
1206 pattern++;
1207 return ((*str == '\0') && (*pattern == '\0'));
1208 };
1209
1210 #endif
1211
1212 #if 0
1213
1214 // maximum mumber of lines the output console should have
1215 static const WORD MAX_CONSOLE_LINES = 500;
1216
1217 BOOL WINAPI MyConsoleHandler( DWORD dwCtrlType ) { // control signal type
1218 FreeConsole();
1219 return TRUE;
1220 }
1221
1222 void 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
1233 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
1234 &coninfo);
1235 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
1236 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),
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 );
1262
1263 // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
1264 // point to console as well
1265 ios::sync_with_stdio();
1266
1267 SetConsoleCtrlHandler(MyConsoleHandler, TRUE);
1268 }
1269 #else
1270 // Not supported
1271 void wxRedirectIOToConsole()
1272 {
1273 }
1274 #endif
1275
1276