]> git.saurik.com Git - wxWidgets.git/blob - src/msw/utils.cpp
* Changed "true" to "TRUE" in some file: "true" doesn't exist in BC++ 5
[wxWidgets.git] / src / msw / utils.cpp
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
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation
14 #pragma implementation "utils.h"
15 #endif
16
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
19
20 #ifdef __BORLANDC__
21 #pragma hdrstop
22 #endif
23
24 #ifndef WX_PRECOMP
25 #include "wx/setup.h"
26 #include "wx/utils.h"
27 #include "wx/app.h"
28 #include "wx/cursor.h"
29 #endif
30
31 #include "wx/msw/private.h"
32 #include "wx/timer.h"
33
34 #include <ctype.h>
35
36 #ifndef __GNUWIN32__
37 #include <direct.h>
38 #include <dos.h>
39 #endif
40
41 #ifdef __GNUWIN32__
42 #include <sys/unistd.h>
43 #include <sys/stat.h>
44 #ifndef __MINGW32__
45 #include <std.h>
46 #endif
47
48 #define stricmp strcasecmp
49 #endif
50
51 #ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
52 // this (3.1 I believe) and how to test for it.
53 // If this works for Borland 4.0 as well, then no worries.
54 #include <dir.h>
55 #endif
56
57 #ifdef __WIN32__
58 #include <io.h>
59
60 #ifndef __GNUWIN32__
61 #include <shellapi.h>
62 #endif
63 #endif
64
65 #include <stdio.h>
66 #include <stdlib.h>
67 #include <string.h>
68 #ifndef __WATCOMC__
69 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
70 #include <errno.h>
71 #endif
72 #endif
73 #include <stdarg.h>
74
75 // In the WIN.INI file
76 static const char WX_SECTION[] = "wxWindows";
77 static const char eHOSTNAME[] = "HostName";
78 static const char eUSERID[] = "UserId";
79 static const char eUSERNAME[] = "UserName";
80
81 // For the following functions we SHOULD fill in support
82 // for Windows-NT (which I don't know) as I assume it begin
83 // a POSIX Unix (so claims MS) that it has some special
84 // functions beyond those provided by WinSock
85
86 // Get full hostname (eg. DoDo.BSn-Germany.crg.de)
87 bool wxGetHostName(char *buf, int maxSize)
88 {
89 #ifdef __WIN32__
90 DWORD nSize = maxSize;
91 return (::GetComputerName(buf, &nSize) != 0);
92 #else
93 char *sysname;
94 const char *default_host = "noname";
95
96 if ((sysname = getenv("SYSTEM_NAME")) == NULL) {
97 GetProfileString(WX_SECTION, eHOSTNAME, default_host, buf, maxSize - 1);
98 } else
99 strncpy(buf, sysname, maxSize - 1);
100 buf[maxSize] = '\0';
101 return *buf ? TRUE : FALSE;
102 #endif
103 }
104
105 // Get user ID e.g. jacs
106 bool wxGetUserId(char *buf, int maxSize)
107 {
108 #if defined(__WIN32__) && !defined(__win32s__) && 0
109 // Gets the current user's full name according to the MS article PSS ID
110 // Number: Q119670
111 // Seems to be the same as the login name for me?
112 char *UserName = new char[256];
113 char *Domain = new char[256];
114 DWORD maxCharacters = 255;
115 GetUserName( UserName, &maxCharacters );
116 GetComputerName( Domain, &maxCharacters );
117
118 WCHAR wszUserName[256]; // Unicode user name
119 WCHAR wszDomain[256];
120 LPBYTE ComputerName;
121
122 struct _SERVER_INFO_100 *si100; // Server structure
123 struct _USER_INFO_2 *ui; // User structure
124
125 // Convert ASCII user name and domain to Unicode.
126
127 MultiByteToWideChar( CP_ACP, 0, UserName,
128 strlen(UserName)+1, wszUserName, sizeof(wszUserName) );
129 MultiByteToWideChar( CP_ACP, 0, Domain,
130 strlen(Domain)+1, wszDomain, sizeof(wszDomain) );
131
132 // Get the computer name of a DC for the specified domain.
133 // >If you get a link error on this, include netapi32.lib<
134
135 NetGetDCName( NULL, wszDomain, &ComputerName );
136
137 // Look up the user on the DC.
138
139 if(NetUserGetInfo( (LPWSTR) ComputerName,
140 (LPWSTR) &wszUserName, 2, (LPBYTE *) &ui))
141 {
142 printf( "Error getting user information.\n" );
143 return( FALSE );
144 }
145
146 // Convert the Unicode full name to ASCII.
147
148 WideCharToMultiByte( CP_ACP, 0, ui->usri2_full_name,
149 -1, buf, 256, NULL, NULL );
150 }
151 return( TRUE );
152 /*
153 DWORD nSize = maxSize;
154 return ::GetUserName(buf, &nSize);
155 */
156 #else
157 char *user;
158 const char *default_id = "anonymous";
159
160 // Can't assume we have NIS (PC-NFS) or some other ID daemon
161 // So we ...
162 if ( (user = getenv("USER")) == NULL &&
163 (user = getenv("LOGNAME")) == NULL ) {
164 // Use wxWindows configuration data (comming soon)
165 GetProfileString(WX_SECTION, eUSERID, default_id, buf, maxSize - 1);
166 } else
167 strncpy(buf, user, maxSize - 1);
168 return *buf ? TRUE : FALSE;
169 #endif
170 }
171
172 // Get user name e.g. Julian Smart
173 bool wxGetUserName(char *buf, int maxSize)
174 {
175 const char *default_name = "Unknown User";
176 #if defined(__WIN32__)
177 /*
178 DWORD nSize = maxSize;
179 In VC++ 4.0, results in unresolved symbol __imp__GetUserNameA
180 if (GetUserName(buf, &nSize))
181 return TRUE;
182 else
183 */
184 // Could use NIS, MS-Mail or other site specific programs
185 // Use wxWindows configuration data
186 GetProfileString(WX_SECTION, eUSERNAME, default_name, buf, maxSize - 1);
187 return *buf ? TRUE : FALSE;
188 // }
189 #else
190 #if !defined(__WATCOMC__) && !defined(__GNUWIN32__) && USE_PENWINDOWS
191 extern HANDLE hPenWin; // PenWindows Running?
192 if (hPenWin)
193 {
194 // PenWindows Does have a user concept!
195 // Get the current owner of the recognizer
196 GetPrivateProfileString("Current", "User", default_name, wxBuffer, maxSize - 1, "PENWIN.INI");
197 strncpy(buf, wxBuffer, maxSize - 1);
198 }
199 else
200 #endif
201 {
202 // Could use NIS, MS-Mail or other site specific programs
203 // Use wxWindows configuration data
204 GetProfileString(WX_SECTION, eUSERNAME, default_name, buf, maxSize - 1);
205 }
206 return *buf ? TRUE : FALSE;
207 #endif
208 }
209
210 int wxKill(long pid, int sig)
211 {
212 return 0;
213 }
214
215 //
216 // Execute a program in an Interactive Shell
217 //
218 bool
219 wxShell(const wxString& command)
220 {
221 char *shell;
222 if ((shell = getenv("COMSPEC")) == NULL)
223 shell = "\\COMMAND.COM";
224
225 char tmp[255];
226 if (command != "")
227 sprintf(tmp, "%s /c %s", shell, WXSTRINGCAST command);
228 else
229 strcpy(tmp, shell);
230
231 return (wxExecute((char *)tmp, FALSE) != 0);
232 }
233
234 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
235 long wxGetFreeMemory(void)
236 {
237 #if defined(__WIN32__) && !defined(__BORLANDC__)
238 MEMORYSTATUS memStatus;
239 memStatus.dwLength = sizeof(MEMORYSTATUS);
240 GlobalMemoryStatus(&memStatus);
241 return memStatus.dwAvailPhys;
242 #else
243 return (long)GetFreeSpace(0);
244 #endif
245 }
246
247 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
248 static bool inTimer = FALSE;
249 class wxSleepTimer: public wxTimer
250 {
251 public:
252 inline void Notify(void)
253 {
254 inTimer = FALSE;
255 Stop();
256 }
257 };
258
259 static wxTimer *wxTheSleepTimer = NULL;
260
261 void wxSleep(int nSecs)
262 {
263 #if 0 // WIN32 hangs app
264 Sleep( 1000*nSecs );
265 #else
266 if (inTimer)
267 return;
268
269 wxTheSleepTimer = new wxSleepTimer;
270 inTimer = TRUE;
271 wxTheSleepTimer->Start(nSecs*1000);
272 while (inTimer)
273 {
274 if (wxTheApp->Pending())
275 wxTheApp->Dispatch();
276 }
277 delete wxTheSleepTimer;
278 wxTheSleepTimer = NULL;
279 #endif
280 }
281
282 // Consume all events until no more left
283 void wxFlushEvents(void)
284 {
285 // wxYield();
286 }
287
288 // Output a debug mess., in a system dependent fashion.
289 void wxDebugMsg(const char *fmt ...)
290 {
291 va_list ap;
292 static char buffer[512];
293
294 if (!wxTheApp->GetWantDebugOutput())
295 return ;
296
297 va_start(ap, fmt);
298
299 wvsprintf(buffer,fmt,ap) ;
300 OutputDebugString((LPCSTR)buffer) ;
301
302 va_end(ap);
303 }
304
305 // Non-fatal error: pop up message box and (possibly) continue
306 void wxError(const wxString& msg, const wxString& title)
307 {
308 sprintf(wxBuffer, "%s\nContinue?", WXSTRINGCAST msg);
309 if (MessageBox(NULL, (LPCSTR)wxBuffer, (LPCSTR)WXSTRINGCAST title,
310 MB_ICONSTOP | MB_YESNO) == IDNO)
311 wxExit();
312 }
313
314 // Fatal error: pop up message box and abort
315 void wxFatalError(const wxString& msg, const wxString& title)
316 {
317 sprintf(wxBuffer, "%s: %s", WXSTRINGCAST title, WXSTRINGCAST msg);
318 FatalAppExit(0, (LPCSTR)wxBuffer);
319 }
320
321 // Emit a beeeeeep
322 void wxBell(void)
323 {
324 #ifdef __WIN32__
325 Beep(1000,1000) ; // 1kHz during 1 sec.
326 #else
327 MessageBeep(-1) ;
328 #endif
329 }
330
331 // Chris Breeze 27/5/98: revised WIN32 code to
332 // detect WindowsNT correctly
333 int wxGetOsVersion(int *majorVsn, int *minorVsn)
334 {
335 extern char *wxOsVersion;
336 if (majorVsn) *majorVsn = 0;
337 if (minorVsn) *minorVsn = 0;
338
339 #ifdef WIN32
340 OSVERSIONINFO info;
341 memset(&info, 0, sizeof(OSVERSIONINFO));
342 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
343 if (GetVersionEx(&info))
344 {
345 if (majorVsn) *majorVsn = info.dwMajorVersion;
346 if (minorVsn) *minorVsn = info.dwMinorVersion;
347 switch (info.dwPlatformId)
348 {
349 case VER_PLATFORM_WIN32s:
350 return wxWIN32S;
351 break;
352 case VER_PLATFORM_WIN32_WINDOWS:
353 return wxWIN95;
354 break;
355 case VER_PLATFORM_WIN32_NT:
356 return wxWINDOWS_NT;
357 break;
358 }
359 }
360 return wxWINDOWS; // error if we get here, return generic value
361 #else
362 // Win16 code...
363 int retValue ;
364 # ifdef __WINDOWS_386__
365 retValue = wxWIN386;
366 # else
367 # if !defined(__WATCOMC__) && !defined(GNUWIN32)
368 extern HANDLE hPenWin;
369 retValue = hPenWin ? wxPENWINDOWS : wxWINDOWS ;
370 # endif
371 # endif
372 // @@@@ To be completed. I don't have the manual here...
373 if (majorVsn) *majorVsn = 3 ;
374 if (minorVsn) *minorVsn = 1 ;
375 return retValue ;
376 #endif
377 }
378
379 // Reading and writing resources (eg WIN.INI, .Xdefaults)
380 #if USE_RESOURCES
381 bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
382 {
383 if (file != "")
384 return (WritePrivateProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)value, (LPCSTR)WXSTRINGCAST file) != 0);
385 else
386 return (WriteProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)WXSTRINGCAST value) != 0);
387 }
388
389 bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
390 {
391 char buf[50];
392 sprintf(buf, "%.4f", value);
393 return wxWriteResource(section, entry, buf, file);
394 }
395
396 bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
397 {
398 char buf[50];
399 sprintf(buf, "%ld", value);
400 return wxWriteResource(section, entry, buf, file);
401 }
402
403 bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
404 {
405 char buf[50];
406 sprintf(buf, "%d", value);
407 return wxWriteResource(section, entry, buf, file);
408 }
409
410 bool wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file)
411 {
412 static const char defunkt[] = "$$default";
413 if (file != "")
414 {
415 int n = GetPrivateProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)defunkt,
416 (LPSTR)wxBuffer, 1000, (LPCSTR)WXSTRINGCAST file);
417 if (n == 0 || strcmp(wxBuffer, defunkt) == 0)
418 return FALSE;
419 }
420 else
421 {
422 int n = GetProfileString((LPCSTR)WXSTRINGCAST section, (LPCSTR)WXSTRINGCAST entry, (LPCSTR)defunkt,
423 (LPSTR)wxBuffer, 1000);
424 if (n == 0 || strcmp(wxBuffer, defunkt) == 0)
425 return FALSE;
426 }
427 if (*value) delete[] (*value);
428 *value = copystring(wxBuffer);
429 return TRUE;
430 }
431
432 bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
433 {
434 char *s = NULL;
435 bool succ = wxGetResource(section, entry, (char **)&s, file);
436 if (succ)
437 {
438 *value = (float)strtod(s, NULL);
439 delete[] s;
440 return TRUE;
441 }
442 else return FALSE;
443 }
444
445 bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file)
446 {
447 char *s = NULL;
448 bool succ = wxGetResource(section, entry, (char **)&s, file);
449 if (succ)
450 {
451 *value = strtol(s, NULL, 10);
452 delete[] s;
453 return TRUE;
454 }
455 else return FALSE;
456 }
457
458 bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file)
459 {
460 char *s = NULL;
461 bool succ = wxGetResource(section, entry, (char **)&s, file);
462 if (succ)
463 {
464 *value = (int)strtol(s, NULL, 10);
465 delete[] s;
466 return TRUE;
467 }
468 else return FALSE;
469 }
470 #endif // USE_RESOURCES
471
472 // Old cursor
473 static HCURSOR wxBusyCursorOld = 0;
474 static int wxBusyCursorCount = 0;
475
476 // Set the cursor to the busy cursor for all windows
477 void wxBeginBusyCursor(wxCursor *cursor)
478 {
479 wxBusyCursorCount ++;
480 if (wxBusyCursorCount == 1)
481 {
482 wxBusyCursorOld = ::SetCursor((HCURSOR) cursor->GetHCURSOR());
483 }
484 else
485 {
486 (void)::SetCursor((HCURSOR) cursor->GetHCURSOR());
487 }
488 }
489
490 // Restore cursor to normal
491 void wxEndBusyCursor(void)
492 {
493 if (wxBusyCursorCount == 0)
494 return;
495
496 wxBusyCursorCount --;
497 if (wxBusyCursorCount == 0)
498 {
499 ::SetCursor(wxBusyCursorOld);
500 wxBusyCursorOld = 0;
501 }
502 }
503
504 // TRUE if we're between the above two calls
505 bool wxIsBusy(void)
506 {
507 return (wxBusyCursorCount > 0);
508 }
509
510 // Hack for MS-DOS
511 char *wxGetUserHome (const wxString& user)
512 {
513 char *home;
514 wxString user1(user);
515
516 if (user1 != "") {
517 char tmp[64];
518 if (wxGetUserId(tmp, sizeof(tmp)/sizeof(char))) {
519 // Guests belong in the temp dir
520 if (stricmp(tmp, "annonymous") == 0) {
521 if ((home = getenv("TMP")) != NULL ||
522 (home = getenv("TMPDIR")) != NULL ||
523 (home = getenv("TEMP")) != NULL)
524 return *home ? home : "\\";
525 }
526 if (stricmp(tmp, WXSTRINGCAST user1) == 0)
527 user1 = "";
528 }
529 }
530 if (user1 == "")
531 if ((home = getenv("HOME")) != NULL)
532 {
533 strcpy(wxBuffer, home);
534 Unix2DosFilename(wxBuffer);
535 return wxBuffer;
536 }
537 return NULL; // No home known!
538 }
539
540 // Check whether this window wants to process messages, e.g. Stop button
541 // in long calculations.
542 bool wxCheckForInterrupt(wxWindow *wnd)
543 {
544 if(wnd){
545 MSG msg;
546 HWND win= (HWND) wnd->GetHWND();
547 while(PeekMessage(&msg,win,0,0,PM_REMOVE)){
548 TranslateMessage(&msg);
549 DispatchMessage(&msg);
550 }
551 return TRUE;//*** temporary?
552 }
553 else{
554 wxError("wnd==NULL !!!");
555 return FALSE;//*** temporary?
556 }
557 }
558
559 // MSW only: get user-defined resource from the .res file.
560 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
561
562 #ifdef __WINDOWS__
563 char *wxLoadUserResource(const wxString& resourceName, const wxString& resourceType)
564 {
565 char *s = NULL;
566 #ifndef __WIN32__
567 HRSRC hResource = ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
568 #else
569 #ifdef UNICODE
570 HRSRC hResource = ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
571 #else
572 HRSRC hResource = ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
573 #endif
574 #endif
575
576 if (hResource == 0)
577 return NULL;
578 HGLOBAL hData = ::LoadResource(wxGetInstance(), hResource);
579 if (hData == 0)
580 return NULL;
581 char *theText = (char *)LockResource(hData);
582 if (!theText)
583 return NULL;
584
585 s = copystring(theText);
586
587 // Obsolete in WIN32
588 #ifndef __WIN32__
589 UnlockResource(hData);
590 #endif
591
592 // No need??
593 // GlobalFree(hData);
594
595 return s;
596 }
597 #endif
598
599 void wxGetMousePosition( int* x, int* y )
600 {
601 POINT pt;
602 GetCursorPos( & pt );
603 *x = pt.x;
604 *y = pt.y;
605 };
606
607 // Return TRUE if we have a colour display
608 bool wxColourDisplay(void)
609 {
610 HDC dc = ::GetDC(NULL);
611 bool flag;
612 int noCols = GetDeviceCaps(dc, NUMCOLORS);
613 if ((noCols == -1) || (noCols > 2))
614 flag = TRUE;
615 else
616 flag = FALSE;
617 ReleaseDC(NULL, dc);
618 return flag;
619 }
620
621 // Returns depth of screen
622 int wxDisplayDepth(void)
623 {
624 HDC dc = ::GetDC(NULL);
625 int planes = GetDeviceCaps(dc, PLANES);
626 int bitsPerPixel = GetDeviceCaps(dc, BITSPIXEL);
627 int depth = planes*bitsPerPixel;
628 ReleaseDC(NULL, dc);
629 return depth;
630 }
631
632 // Get size of display
633 void wxDisplaySize(int *width, int *height)
634 {
635 HDC dc = ::GetDC(NULL);
636 *width = GetDeviceCaps(dc, HORZRES); *height = GetDeviceCaps(dc, VERTRES);
637 ReleaseDC(NULL, dc);
638 }
639