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