X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/373658eb493827a9a68a79eeaaab1dbfc69a206b..46a5010a06b09318878c33a0a6a532f419ea063d:/src/msw/utils.cpp diff --git a/src/msw/utils.cpp b/src/msw/utils.cpp index c190b20543..b70c622689 100644 --- a/src/msw/utils.cpp +++ b/src/msw/utils.cpp @@ -5,8 +5,8 @@ // Modified by: // Created: 04/01/98 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows license +// Copyright: (c) Julian Smart +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // ============================================================================ @@ -38,22 +38,17 @@ #endif #endif //WX_PRECOMP -// In some mingws there is a missing extern "C" int the winsock header, -// so we put it here just to be safe. Note that this must appear _before_ -// #include "wx/msw/private.h" which itself includes , as this -// one in turn includes unless we define WIN32_LEAN_AND_MEAN. -// -#if defined(__WIN32__) && !defined(__TWIN32__) && !defined(__WXMICROWIN__) && ! (defined(__GNUWIN32__) && !defined(__MINGW32__)) -extern "C" { - #include // we use socket functions in wxGetFullHostName() -} -#endif - #include "wx/msw/private.h" // includes +#ifdef __GNUWIN32_OLD__ + // apparently we need to include winsock.h to get WSADATA and other stuff + // used in wxGetFullHostName() with the old mingw32 versions + #include +#endif + #include "wx/timer.h" -#if !defined(__GNUWIN32__) && !defined(__WXWINE__) && !defined(__SALFORDC__) && !defined(__WXMICROWIN__) +#if !defined(__GNUWIN32__) && !defined(__SALFORDC__) && !defined(__WXMICROWIN__) #include #ifndef __MWERKS__ @@ -83,8 +78,10 @@ extern "C" { #include #endif // USE_NET_API -#if defined(__WIN32__) && !defined(__WXWINE__) && !defined(__WXMICROWIN__) - #include +#if defined(__WIN32__) && !defined(__WXMICROWIN__) + #ifndef __UNIX__ + #include + #endif #ifndef __GNUWIN32__ #include @@ -178,6 +175,12 @@ bool wxGetFullHostName(wxChar *buf, int maxSize) { #if defined(__WIN32__) && !defined(__TWIN32__) && !defined(__WXMICROWIN__) && ! (defined(__GNUWIN32__) && !defined(__MINGW32__)) // TODO should use GetComputerNameEx() when available + + // the idea is that if someone had set wxUSE_SOCKETS to 0 the code + // shouldn't use winsock.dll (a.k.a. ws2_32.dll) at all so only use this + // code if we link with it anyhow +#if wxUSE_SOCKETS + WSADATA wsa; if ( WSAStartup(MAKEWORD(1, 1), &wsa) == 0 ) { @@ -194,25 +197,28 @@ bool wxGetFullHostName(wxChar *buf, int maxSize) if ( pHostEnt ) { // Windows will use DNS internally now - pHostEnt = gethostbyaddr(pHostEnt->h_addr, 4, PF_INET); + pHostEnt = gethostbyaddr(pHostEnt->h_addr, 4, AF_INET); } if ( pHostEnt ) { - host = pHostEnt->h_name; + host = wxString::FromAscii(pHostEnt->h_name); } } } WSACleanup(); - if ( !!host ) + if ( !host.empty() ) { wxStrncpy(buf, host, maxSize); return TRUE; } } + +#endif // wxUSE_SOCKETS + #endif // Win32 return wxGetHostName(buf, maxSize); @@ -382,25 +388,55 @@ const wxChar* wxGetHomeDir(wxString *pstr) #endif #else // Windows #ifdef __WIN32__ - const wxChar *szHome = wxGetenv(wxT("HOMEDRIVE")); + strDir.clear(); + + // If we have a valid HOME directory, as is used on many machines that + // have unix utilities on them, we should use that. + const wxChar *szHome = wxGetenv(wxT("HOME")); + if ( szHome != NULL ) - strDir << szHome; - szHome = wxGetenv(wxT("HOMEPATH")); - if ( szHome != NULL ) { - strDir << szHome; - - // the idea is that under NT these variables have default values - // of "%systemdrive%:" and "\\". As we don't want to create our - // config files in the root directory of the system drive, we will - // create it in our program's dir. However, if the user took care - // to set HOMEPATH to something other than "\\", we suppose that he - // knows what he is doing and use the supplied value. - if ( wxStrcmp(szHome, wxT("\\")) != 0 ) - return strDir.c_str(); + { + strDir = szHome; } + else // no HOME, try HOMEDRIVE/PATH + { + szHome = wxGetenv(wxT("HOMEDRIVE")); + if ( szHome != NULL ) + strDir << szHome; + szHome = wxGetenv(wxT("HOMEPATH")); + + if ( szHome != NULL ) + { + strDir << szHome; + + // the idea is that under NT these variables have default values + // of "%systemdrive%:" and "\\". As we don't want to create our + // config files in the root directory of the system drive, we will + // create it in our program's dir. However, if the user took care + // to set HOMEPATH to something other than "\\", we suppose that he + // knows what he is doing and use the supplied value. + if ( wxStrcmp(szHome, wxT("\\")) == 0 ) + strDir.clear(); + } + } + + if ( strDir.empty() ) + { + // If we have a valid USERPROFILE directory, as is the case in + // Windows NT, 2000 and XP, we should use that as our home directory. + szHome = wxGetenv(wxT("USERPROFILE")); + if ( szHome != NULL ) + strDir = szHome; + } + + if ( !strDir.empty() ) + { + return strDir.c_str(); + } + //else: fall back to the prograrm directory #else // Win16 - // Win16 has no idea about home, so use the working directory instead + // Win16 has no idea about home, so use the executable directory instead #endif // WIN16/32 // 260 was taken from windef.h @@ -498,14 +534,22 @@ bool wxGetDiskSpace(const wxString& path, wxLongLong *pTotal, wxLongLong *pFree) return FALSE; } + // ULARGE_INTEGER is a union of a 64 bit value and a struct containing + // two 32 bit fields which may be or may be not named - try to make it + // compile in all cases +#if defined(__BORLANDC__) && !defined(_ANONYMOUS_STRUCT) + #define UL(ul) ul.u +#else // anon union + #define UL(ul) ul +#endif if ( pTotal ) { - *pTotal = wxLongLong(bytesTotal.HighPart, bytesTotal.LowPart); + *pTotal = wxLongLong(UL(bytesTotal).HighPart, UL(bytesTotal).LowPart); } if ( pFree ) { - *pFree = wxLongLong(bytesFree.HighPart, bytesFree.LowPart); + *pFree = wxLongLong(UL(bytesFree).HighPart, UL(bytesFree).LowPart); } } else @@ -560,14 +604,16 @@ bool wxGetEnv(const wxString& var, wxString *value) { #ifdef __WIN16__ const wxChar* ret = wxGetenv(var); - if (ret) + if ( !ret ) + return FALSE; + + if ( value ) { *value = ret; - return TRUE; } - else - return FALSE; -#else + + return TRUE; +#else // Win32 // first get the size of the buffer DWORD dwRet = ::GetEnvironmentVariable(var, NULL, 0); if ( !dwRet ) @@ -583,7 +629,7 @@ bool wxGetEnv(const wxString& var, wxString *value) } return TRUE; -#endif +#endif // Win16/32 } bool wxSetEnv(const wxString& var, const wxChar *value) @@ -608,8 +654,6 @@ bool wxSetEnv(const wxString& var, const wxChar *value) // process management // ---------------------------------------------------------------------------- -#ifdef __WIN32__ - // structure used to pass parameters from wxKill() to wxEnumFindByPidProc() struct wxFindByPidParams { @@ -620,6 +664,8 @@ struct wxFindByPidParams // the PID we're looking from DWORD pid; + + DECLARE_NO_COPY_CLASS(wxFindByPidParams) }; // wxKill helper: EnumWindows() callback which is used to find the first (top @@ -643,11 +689,8 @@ BOOL CALLBACK wxEnumFindByPidProc(HWND hwnd, LPARAM lParam) return TRUE; } -#endif // __WIN32__ - int wxKill(long pid, wxSignal sig, wxKillError *krc) { -#ifdef __WIN32__ // get the process handle to operate on HANDLE hProcess = ::OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE | @@ -784,25 +827,19 @@ int wxKill(long pid, wxSignal sig, wxKillError *krc) // the return code is the same as from Unix kill(): 0 if killed // successfully or -1 on error - if ( sig == wxSIGNONE ) - { - if ( ok && rc == STILL_ACTIVE ) - { - // there is such process => success - return 0; - } - } - else // not SIGNONE + // + // be careful to interpret rc correctly: for wxSIGNONE we return success if + // the process exists, for all the other sig values -- if it doesn't + if ( ok && + ((sig == wxSIGNONE) == (rc == STILL_ACTIVE)) ) { - if ( ok && rc != STILL_ACTIVE ) + if ( krc ) { - // killed => success - return 0; + *krc = wxKILL_OK; } + + return 0; } -#else // Win15 - wxFAIL_MSG( _T("not implemented") ); -#endif // Win32/Win16 // error return -1; @@ -813,7 +850,7 @@ bool wxShell(const wxString& command) { wxChar *shell = wxGetenv(wxT("COMSPEC")); if ( !shell ) - shell = wxT("\\COMMAND.COM"); + shell = (wxChar*) wxT("\\COMMAND.COM"); wxString cmd; if ( !command ) @@ -827,7 +864,67 @@ bool wxShell(const wxString& command) cmd.Printf(wxT("%s /c %s"), shell, command.c_str()); } - return wxExecute(cmd, TRUE /* sync */) != 0; + return wxExecute(cmd, wxEXEC_SYNC) == 0; +} + +// Shutdown or reboot the PC +bool wxShutdown(wxShutdownFlags wFlags) +{ +#ifdef __WIN32__ + bool bOK = TRUE; + + if ( wxGetOsVersion(NULL, NULL) == wxWINDOWS_NT ) // if is NT or 2K + { + // Get a token for this process. + HANDLE hToken; + bOK = ::OpenProcessToken(GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, + &hToken) != 0; + if ( bOK ) + { + TOKEN_PRIVILEGES tkp; + + // Get the LUID for the shutdown privilege. + ::LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, + &tkp.Privileges[0].Luid); + + tkp.PrivilegeCount = 1; // one privilege to set + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + // Get the shutdown privilege for this process. + ::AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, + (PTOKEN_PRIVILEGES)NULL, 0); + + // Cannot test the return value of AdjustTokenPrivileges. + bOK = ::GetLastError() == ERROR_SUCCESS; + } + } + + if ( bOK ) + { + UINT flags = EWX_SHUTDOWN | EWX_FORCE; + switch ( wFlags ) + { + case wxSHUTDOWN_POWEROFF: + flags |= EWX_POWEROFF; + break; + + case wxSHUTDOWN_REBOOT: + flags |= EWX_REBOOT; + break; + + default: + wxFAIL_MSG( _T("unknown wxShutdown() flag") ); + return FALSE; + } + + bOK = ::ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE | EWX_REBOOT, 0) != 0; + } + + return bOK; +#else // Win16 + return FALSE; +#endif // Win32/16 } // ---------------------------------------------------------------------------- @@ -847,6 +944,15 @@ long wxGetFreeMemory() #endif } +unsigned long wxGetProcessId() +{ +#ifdef __WIN32__ + return ::GetCurrentProcessId(); +#else + return 0; +#endif +} + // Emit a beeeeeep void wxBell() { @@ -905,32 +1011,44 @@ wxString wxGetOsDescription() int wxGetOsVersion(int *majorVsn, int *minorVsn) { -#if defined(__WIN32__) && !defined(__SC__) - OSVERSIONINFO info; - wxZeroMemory(info); +#if defined(__WIN32__) + static int ver = -1, major = -1, minor = -1; - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if ( ::GetVersionEx(&info) ) + if ( ver == -1 ) { - if (majorVsn) - *majorVsn = info.dwMajorVersion; - if (minorVsn) - *minorVsn = info.dwMinorVersion; + OSVERSIONINFO info; + wxZeroMemory(info); - switch ( info.dwPlatformId ) + ver = wxWINDOWS; + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if ( ::GetVersionEx(&info) ) { - case VER_PLATFORM_WIN32s: - return wxWIN32S; + major = info.dwMajorVersion; + minor = info.dwMinorVersion; - case VER_PLATFORM_WIN32_WINDOWS: - return wxWIN95; + switch ( info.dwPlatformId ) + { + case VER_PLATFORM_WIN32s: + ver = wxWIN32S; + break; - case VER_PLATFORM_WIN32_NT: - return wxWINDOWS_NT; + case VER_PLATFORM_WIN32_WINDOWS: + ver = wxWIN95; + break; + + case VER_PLATFORM_WIN32_NT: + ver = wxWINDOWS_NT; + break; + } } } - return wxWINDOWS; // error if we get here, return generic value + if (majorVsn && major != -1) + *majorVsn = major; + if (minorVsn && minor != -1) + *minorVsn = minor; + + return ver; #else // Win16 int retValue = wxWINDOWS; #ifdef __WINDOWS_386__ @@ -981,6 +1099,8 @@ void wxUsleep(unsigned long milliseconds) #else // !Win32 if (gs_inTimer) return; + if (miliseconds <= 0) + return; wxTheSleepTimer = new wxSleepTimer; gs_inTimer = TRUE; @@ -999,6 +1119,8 @@ void wxSleep(int nSecs) { if (gs_inTimer) return; + if (nSecs <= 0) + return; wxTheSleepTimer = new wxSleepTimer; gs_inTimer = TRUE; @@ -1039,7 +1161,7 @@ void wxSleep(int nSecs) // deprecated (in favour of wxLog) log functions // ---------------------------------------------------------------------------- -#if wxUSE_GUI +#if WXWIN_COMPATIBILITY_2_2 // Output a debug mess., in a system dependent fashion. #ifndef __WXMICROWIN__ @@ -1049,12 +1171,12 @@ void wxDebugMsg(const wxChar *fmt ...) static wxChar buffer[512]; if (!wxTheApp->GetWantDebugOutput()) - return ; + return; va_start(ap, fmt); - wvsprintf(buffer,fmt,ap) ; - OutputDebugString((LPCTSTR)buffer) ; + wvsprintf(buffer,fmt,ap); + OutputDebugString((LPCTSTR)buffer); va_end(ap); } @@ -1076,6 +1198,10 @@ void wxFatalError(const wxString& msg, const wxString& title) } #endif // __WXMICROWIN__ +#endif // WXWIN_COMPATIBILITY_2_2 + +#if wxUSE_GUI + // ---------------------------------------------------------------------------- // functions to work with .INI files // ---------------------------------------------------------------------------- @@ -1190,7 +1316,11 @@ static HCURSOR gs_wxBusyCursor = 0; // new, busy cursor static HCURSOR gs_wxBusyCursorOld = 0; // old cursor static int gs_wxBusyCursorCount = 0; +#ifdef __DIGITALMARS__ +extern "C" HCURSOR wxGetCurrentBusyCursor() +#else extern HCURSOR wxGetCurrentBusyCursor() +#endif { return gs_wxBusyCursor; } @@ -1448,10 +1578,6 @@ WXWORD WXDLLEXPORT wxGetWindowId(WXHWND hWnd) #endif // Win16/32 } -#endif // wxUSE_GUI - -#if wxUSE_GUI - // ---------------------------------------------------------------------------- // Metafile helpers // ---------------------------------------------------------------------------- @@ -1504,7 +1630,8 @@ int wxGetOsVersion(int *majorVsn, int *minorVsn) #if defined(__WIN32__) && !defined(__WXMICROWIN__) -#if wxUSE_GUI +// wxGetNativeFontEncoding() doesn't exist neither in wxBase nor in wxUniv +#if wxUSE_GUI && !defined(__WXUNIVERSAL__) #include "wx/fontmap.h" @@ -1541,7 +1668,7 @@ extern long wxCharsetToCodepage(const wxChar *name) if ( !name ) return -1; - wxFontEncoding enc = wxTheFontMapper->CharsetToEncoding(name, FALSE); + wxFontEncoding enc = wxFontMapper::Get()->CharsetToEncoding(name, FALSE); if ( enc == wxFONTENCODING_SYSTEM ) return -1;