1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Various utilities
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation
14 #pragma implementation "utils.h"
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
28 #include "wx/cursor.h"
31 #include "wx/msw/private.h"
42 #include <sys/unistd.h>
48 #define stricmp strcasecmp
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.
69 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
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";
81 #if !USE_SHARED_LIBRARY
82 IMPLEMENT_DYNAMIC_CLASS(wxPathList
, wxList
)
85 // For the following functions we SHOULD fill in support
86 // for Windows-NT (which I don't know) as I assume it begin
87 // a POSIX Unix (so claims MS) that it has some special
88 // functions beyond those provided by WinSock
90 // Get full hostname (eg. DoDo.BSn-Germany.crg.de)
91 bool wxGetHostName(char *buf
, int maxSize
)
94 DWORD nSize
= maxSize
;
95 return (::GetComputerName(buf
, &nSize
) != 0);
98 const char *default_host
= "noname";
100 if ((sysname
= getenv("SYSTEM_NAME")) == NULL
) {
101 GetProfileString(WX_SECTION
, eHOSTNAME
, default_host
, buf
, maxSize
- 1);
103 strncpy(buf
, sysname
, maxSize
- 1);
105 return *buf
? TRUE
: FALSE
;
109 // Get user ID e.g. jacs
110 bool wxGetUserId(char *buf
, int maxSize
)
112 #if defined(__WIN32__) && !defined(__win32s__) && 0
113 // Gets the current user's full name according to the MS article PSS ID
115 // Seems to be the same as the login name for me?
116 char *UserName
= new char[256];
117 char *Domain
= new char[256];
118 DWORD maxCharacters
= 255;
119 GetUserName( UserName
, &maxCharacters
);
120 GetComputerName( Domain
, &maxCharacters
);
122 WCHAR wszUserName
[256]; // Unicode user name
123 WCHAR wszDomain
[256];
126 struct _SERVER_INFO_100
*si100
; // Server structure
127 struct _USER_INFO_2
*ui
; // User structure
129 // Convert ASCII user name and domain to Unicode.
131 MultiByteToWideChar( CP_ACP
, 0, UserName
,
132 strlen(UserName
)+1, wszUserName
, sizeof(wszUserName
) );
133 MultiByteToWideChar( CP_ACP
, 0, Domain
,
134 strlen(Domain
)+1, wszDomain
, sizeof(wszDomain
) );
136 // Get the computer name of a DC for the specified domain.
137 // >If you get a link error on this, include netapi32.lib<
139 NetGetDCName( NULL
, wszDomain
, &ComputerName
);
141 // Look up the user on the DC.
143 if(NetUserGetInfo( (LPWSTR
) ComputerName
,
144 (LPWSTR
) &wszUserName
, 2, (LPBYTE
*) &ui
))
146 printf( "Error getting user information.\n" );
150 // Convert the Unicode full name to ASCII.
152 WideCharToMultiByte( CP_ACP
, 0, ui
->usri2_full_name
,
153 -1, buf
, 256, NULL
, NULL
);
157 DWORD nSize = maxSize;
158 return ::GetUserName(buf, &nSize);
162 const char *default_id
= "anonymous";
164 // Can't assume we have NIS (PC-NFS) or some other ID daemon
166 if ( (user
= getenv("USER")) == NULL
&&
167 (user
= getenv("LOGNAME")) == NULL
) {
168 // Use wxWindows configuration data (comming soon)
169 GetProfileString(WX_SECTION
, eUSERID
, default_id
, buf
, maxSize
- 1);
171 strncpy(buf
, user
, maxSize
- 1);
172 return *buf
? TRUE
: FALSE
;
176 // Get user name e.g. Julian Smart
177 bool wxGetUserName(char *buf
, int maxSize
)
179 const char *default_name
= "Unknown User";
180 #if defined(__WIN32__)
182 DWORD nSize = maxSize;
183 In VC++ 4.0, results in unresolved symbol __imp__GetUserNameA
184 if (GetUserName(buf, &nSize))
188 // Could use NIS, MS-Mail or other site specific programs
189 // Use wxWindows configuration data
190 GetProfileString(WX_SECTION
, eUSERNAME
, default_name
, buf
, maxSize
- 1);
191 return *buf
? TRUE
: FALSE
;
194 #if !defined(__WATCOMC__) && !defined(__GNUWIN32__) && USE_PENWINDOWS
195 extern HANDLE hPenWin
; // PenWindows Running?
198 // PenWindows Does have a user concept!
199 // Get the current owner of the recognizer
200 GetPrivateProfileString("Current", "User", default_name
, wxBuffer
, maxSize
- 1, "PENWIN.INI");
201 strncpy(buf
, wxBuffer
, maxSize
- 1);
206 // Could use NIS, MS-Mail or other site specific programs
207 // Use wxWindows configuration data
208 GetProfileString(WX_SECTION
, eUSERNAME
, default_name
, buf
, maxSize
- 1);
210 return *buf
? TRUE
: FALSE
;
214 // Execute a command (e.g. another program) in a
215 // system-independent manner.
217 long wxExecute(char **argv
, bool sync
)
226 for (argc
= 0; argv
[argc
]; argc
++)
229 strcat(command
, " ");
230 strcat(command
, argv
[argc
]);
233 return wxExecute((char *)command
, sync
);
236 long wxExecute(const wxString
& command
, bool sync
)
248 // copy the command line
249 clen
= command
.Length();
250 if (!clen
) return -1;
251 cl
= (char *) calloc( 1, 256);
253 strcpy( cl
, WXSTRINGCAST command
);
255 // isolate command and arguments
256 argp
= strchr( cl
, ' ');
260 // execute the command
262 result
= ShellExecute( (HWND
) (wxTheApp
->GetTopWindow() ? (HWND
) wxTheApp
->GetTopWindow()->GetHWND() : NULL
),
263 (const wchar_t) "open", (const wchar_t) cl
, (const wchar_t) argp
, (const wchar_t) NULL
, SW_SHOWNORMAL
);
265 result
= ShellExecute( (HWND
) (wxTheApp
->GetTopWindow() ? wxTheApp
->GetTopWindow()->GetHWND() : NULL
),
266 "open", cl
, argp
, NULL
, SW_SHOWNORMAL
);
269 if (((long)result
) <= 32) {
280 // waiting until command executed
283 dresult
= GetModuleFileName( result
, cl
, 256);
286 /* long lastError = GetLastError(); */
291 long instanceID
= WinExec((LPCSTR
) WXSTRINGCAST command
, SW_SHOW
);
292 if (instanceID
< 32) return(0);
298 running
= GetModuleUsage((HANDLE
)instanceID
);
305 int wxKill(long pid
, int sig
)
311 // Execute a program in an Interactive Shell
314 wxShell(const wxString
& command
)
317 if ((shell
= getenv("COMSPEC")) == NULL
)
318 shell
= "\\COMMAND.COM";
322 sprintf(tmp
, "%s /c %s", shell
, WXSTRINGCAST command
);
326 return (wxExecute((char *)tmp
, FALSE
) != 0);
329 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
330 long wxGetFreeMemory(void)
332 #if defined(__WIN32__) && !defined(__BORLANDC__)
333 MEMORYSTATUS memStatus
;
334 memStatus
.dwLength
= sizeof(MEMORYSTATUS
);
335 GlobalMemoryStatus(&memStatus
);
336 return memStatus
.dwAvailPhys
;
338 return (long)GetFreeSpace(0);
342 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
343 static bool inTimer
= FALSE
;
344 class wxSleepTimer
: public wxTimer
347 inline void Notify(void)
354 static wxTimer
*wxTheSleepTimer
= NULL
;
356 void wxSleep(int nSecs
)
358 #if 0 // WIN32 hangs app
364 wxTheSleepTimer
= new wxSleepTimer
;
366 wxTheSleepTimer
->Start(nSecs
*1000);
369 if (wxTheApp
->Pending())
370 wxTheApp
->Dispatch();
372 delete wxTheSleepTimer
;
373 wxTheSleepTimer
= NULL
;
377 // Consume all events until no more left
378 void wxFlushEvents(void)
383 // Output a debug mess., in a system dependent fashion.
384 void wxDebugMsg(const char *fmt
...)
387 static char buffer
[512];
389 if (!wxTheApp
->GetWantDebugOutput())
394 wvsprintf(buffer
,fmt
,ap
) ;
395 OutputDebugString((LPCSTR
)buffer
) ;
400 // Non-fatal error: pop up message box and (possibly) continue
401 void wxError(const wxString
& msg
, const wxString
& title
)
403 sprintf(wxBuffer
, "%s\nContinue?", WXSTRINGCAST msg
);
404 if (MessageBox(NULL
, (LPCSTR
)wxBuffer
, (LPCSTR
)WXSTRINGCAST title
,
405 MB_ICONSTOP
| MB_YESNO
) == IDNO
)
409 // Fatal error: pop up message box and abort
410 void wxFatalError(const wxString
& msg
, const wxString
& title
)
412 sprintf(wxBuffer
, "%s: %s", WXSTRINGCAST title
, WXSTRINGCAST msg
);
413 FatalAppExit(0, (LPCSTR
)wxBuffer
);
420 Beep(1000,1000) ; // 1kHz during 1 sec.
426 int wxGetOsVersion(int *majorVsn
, int *minorVsn
)
428 extern char *wxOsVersion
;
436 #ifdef __WINDOWS_386__
440 #if !defined(__WATCOMC__) && !defined(__GNUWIN32__) && USE_PENWINDOWS
441 extern HANDLE hPenWin
;
442 retValue
= hPenWin
? wxPENWINDOWS
: wxWINDOWS
;
447 DWORD Version
= GetVersion() ;
448 WORD lowWord
= LOWORD(Version
) ;
452 if (strcmp(wxOsVersion
, "Win95") == 0)
454 else if (strcmp(wxOsVersion
, "Win32s") == 0)
456 else if (strcmp(wxOsVersion
, "Windows") == 0)
458 else if (strcmp(wxOsVersion
, "WinNT") == 0)
461 bool Win32s
= (( Version
& 0x80000000 ) != 0);
462 bool Win95
= (( Version
& 0xFF ) >= 4);
463 bool WinNT
= Version
< 0x80000000;
465 // Get the version number
467 *majorVsn
= LOBYTE( lowWord
);
469 *minorVsn
= HIBYTE( lowWord
);
480 // retValue = ((high & 0x8000)==0) ? wxWINDOWS_NT : wxWIN32S ;
482 // @@@@ To be completed. I don't have the manual here...
483 if (majorVsn
) *majorVsn
= 3 ;
484 if (minorVsn
) *minorVsn
= 1 ;
488 // Reading and writing resources (eg WIN.INI, .Xdefaults)
490 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
)
493 return (WritePrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)value
, (LPCSTR
)WXSTRINGCAST file
) != 0);
495 return (WriteProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)WXSTRINGCAST value
) != 0);
498 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
)
501 sprintf(buf
, "%.4f", value
);
502 return wxWriteResource(section
, entry
, buf
, file
);
505 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
)
508 sprintf(buf
, "%ld", value
);
509 return wxWriteResource(section
, entry
, buf
, file
);
512 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
)
515 sprintf(buf
, "%d", value
);
516 return wxWriteResource(section
, entry
, buf
, file
);
519 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
)
521 static const char defunkt
[] = "$$default";
524 int n
= GetPrivateProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
525 (LPSTR
)wxBuffer
, 1000, (LPCSTR
)WXSTRINGCAST file
);
526 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
531 int n
= GetProfileString((LPCSTR
)WXSTRINGCAST section
, (LPCSTR
)WXSTRINGCAST entry
, (LPCSTR
)defunkt
,
532 (LPSTR
)wxBuffer
, 1000);
533 if (n
== 0 || strcmp(wxBuffer
, defunkt
) == 0)
536 if (*value
) delete[] (*value
);
537 *value
= copystring(wxBuffer
);
541 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
)
544 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
547 *value
= (float)strtod(s
, NULL
);
554 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
)
557 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
560 *value
= strtol(s
, NULL
, 10);
567 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
)
570 bool succ
= wxGetResource(section
, entry
, (char **)&s
, file
);
573 *value
= (int)strtol(s
, NULL
, 10);
579 #endif // USE_RESOURCES
582 static HCURSOR wxBusyCursorOld
= 0;
583 static int wxBusyCursorCount
= 0;
585 // Set the cursor to the busy cursor for all windows
586 void wxBeginBusyCursor(wxCursor
*cursor
)
588 wxBusyCursorCount
++;
589 if (wxBusyCursorCount
== 1)
591 wxBusyCursorOld
= ::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
595 (void)::SetCursor((HCURSOR
) cursor
->GetHCURSOR());
599 // Restore cursor to normal
600 void wxEndBusyCursor(void)
602 if (wxBusyCursorCount
== 0)
605 wxBusyCursorCount
--;
606 if (wxBusyCursorCount
== 0)
608 ::SetCursor(wxBusyCursorOld
);
613 // TRUE if we're between the above two calls
616 return (wxBusyCursorCount
> 0);
620 char *wxGetUserHome (const wxString
& user
)
623 wxString
user1(user
);
627 if (wxGetUserId(tmp
, sizeof(tmp
)/sizeof(char))) {
628 // Guests belong in the temp dir
629 if (stricmp(tmp
, "annonymous") == 0) {
630 if ((home
= getenv("TMP")) != NULL
||
631 (home
= getenv("TMPDIR")) != NULL
||
632 (home
= getenv("TEMP")) != NULL
)
633 return *home
? home
: "\\";
635 if (stricmp(tmp
, WXSTRINGCAST user1
) == 0)
640 if ((home
= getenv("HOME")) != NULL
)
642 strcpy(wxBuffer
, home
);
643 Unix2DosFilename(wxBuffer
);
646 return NULL
; // No home known!
649 // Check whether this window wants to process messages, e.g. Stop button
650 // in long calculations.
651 bool wxCheckForInterrupt(wxWindow
*wnd
)
655 HWND win
= (HWND
) wnd
->GetHWND();
656 while(PeekMessage(&msg
,win
,0,0,PM_REMOVE
)){
657 TranslateMessage(&msg
);
658 DispatchMessage(&msg
);
660 return TRUE
;//*** temporary?
663 wxError("wnd==NULL !!!");
664 return FALSE
;//*** temporary?
668 // MSW only: get user-defined resource from the .res file.
669 // Returns NULL or newly-allocated memory, so use delete[] to clean up.
672 char *wxLoadUserResource(const wxString
& resourceName
, const wxString
& resourceType
)
676 HRSRC hResource
= ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
679 HRSRC hResource
= ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
681 HRSRC hResource
= ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName
, WXSTRINGCAST resourceType
);
687 HGLOBAL hData
= ::LoadResource(wxGetInstance(), hResource
);
690 char *theText
= (char *)LockResource(hData
);
694 s
= copystring(theText
);
698 UnlockResource(hData
);
702 // GlobalFree(hData);
708 void wxGetMousePosition( int* x
, int* y
)
711 GetCursorPos( & pt
);
716 // Return TRUE if we have a colour display
717 bool wxColourDisplay(void)
719 HDC dc
= ::GetDC(NULL
);
721 int noCols
= GetDeviceCaps(dc
, NUMCOLORS
);
722 if ((noCols
== -1) || (noCols
> 2))
730 // Returns depth of screen
731 int wxDisplayDepth(void)
733 HDC dc
= ::GetDC(NULL
);
734 int planes
= GetDeviceCaps(dc
, PLANES
);
735 int bitsPerPixel
= GetDeviceCaps(dc
, BITSPIXEL
);
736 int depth
= planes
*bitsPerPixel
;
741 // Get size of display
742 void wxDisplaySize(int *width
, int *height
)
744 HDC dc
= ::GetDC(NULL
);
745 *width
= GetDeviceCaps(dc
, HORZRES
); *height
= GetDeviceCaps(dc
, VERTRES
);