X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e19dbcf76b35cabe9487926b3a96d69c7f949d64..404b319a85dadd7decf7a5a5331020520031a41c:/src/msw/utils.cpp diff --git a/src/msw/utils.cpp b/src/msw/utils.cpp index 47009f0bd0..afd0bb2e6c 100644 --- a/src/msw/utils.cpp +++ b/src/msw/utils.cpp @@ -41,6 +41,7 @@ #include "wx/confbase.h" // for wxExpandEnvVars() #include "wx/msw/private.h" // includes +#include "wx/msw/private/hiddenwin.h" #include "wx/msw/missing.h" // for CHARSET_HANGUL #if defined(__CYGWIN__) @@ -59,9 +60,7 @@ #if !defined(__GNUWIN32__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__) #include - #ifndef __MWERKS__ - #include - #endif + #include #endif //GNUWIN32 #if defined(__CYGWIN__) @@ -142,7 +141,7 @@ bool wxGetHostName(wxChar *buf, int maxSize) !regKey.QueryValue(wxT("Name"), hostName) ) return false; - wxStrlcpy(buf, hostName.wx_str(), maxSize); + wxStrlcpy(buf, hostName.t_str(), maxSize); #else // !__WXWINCE__ DWORD nSize = maxSize; if ( !::GetComputerName(buf, &nSize) ) @@ -303,7 +302,7 @@ bool wxGetUserName(wxChar *buf, int maxSize) // Get the computer name of a DC for the domain. if ( NetGetDCName( NULL, wszDomain, &ComputerName ) != NERR_Success ) { - wxLogError(wxT("Can not find domain controller")); + wxLogError(wxT("Cannot find domain controller")); goto error; } @@ -627,7 +626,7 @@ bool wxDoSetEnv(const wxString& var, const wxChar *value) // // TODO: add checks for the other compilers (and update wxSetEnv() // documentation in interface/wx/utils.h accordingly) -#if defined(__VISUALC__) +#if defined(__VISUALC__) || defined(__MINGW32__) // notice that Microsoft _putenv() has different semantics from POSIX // function with almost the same name: in particular it makes a copy of the // string instead of using it as part of environment so we can safely call @@ -637,7 +636,8 @@ bool wxDoSetEnv(const wxString& var, const wxChar *value) envstr += '='; if ( value ) envstr += value; - _tputenv(envstr.t_str()); + if ( _tputenv(envstr.t_str()) != 0 ) + return false; #else // other compiler if ( !::SetEnvironmentVariable(var.t_str(), value) ) { @@ -730,6 +730,12 @@ int wxKill(long pid, wxSignal sig, wxKillError *krc, int flags) wxON_BLOCK_EXIT1(::CloseHandle, hProcess); + // Default timeout for waiting for the process termination after killing + // it. It should be long enough to allow the process to terminate even on a + // busy system but short enough to avoid blocking the main thread for too + // long. + DWORD waitTimeout = 500; // ms + bool ok = true; switch ( sig ) { @@ -751,10 +757,14 @@ int wxKill(long pid, wxSignal sig, wxKillError *krc, int flags) break; case wxSIGNONE: - // do nothing, we just want to test for process existence - if ( krc ) - *krc = wxKILL_OK; - return 0; + // Opening the process handle may succeed for a process even if it + // doesn't run any more (typically because open handles to it still + // exist elsewhere, possibly in this process itself if we're + // killing a child process) so we still need check if it hasn't + // terminated yet but, unlike when killing it, we don't need to + // wait for any time at all. + waitTimeout = 0; + break; default: // any other signal means "terminate" @@ -799,18 +809,22 @@ int wxKill(long pid, wxSignal sig, wxKillError *krc, int flags) } // the return code - DWORD rc wxDUMMY_INITIALIZE(0); if ( ok ) { // as we wait for a short time, we can use just WaitForSingleObject() // and not MsgWaitForMultipleObjects() - switch ( ::WaitForSingleObject(hProcess, 500 /* msec */) ) + switch ( ::WaitForSingleObject(hProcess, waitTimeout) ) { case WAIT_OBJECT_0: - // process terminated - if ( !::GetExitCodeProcess(hProcess, &rc) ) + // Process terminated: normally this indicates that we + // successfully killed it but when testing for the process + // existence, this means failure. + if ( sig == wxSIGNONE ) { - wxLogLastError(wxT("GetExitCodeProcess")); + if ( krc ) + *krc = wxKILL_NO_PROCESS; + + ok = false; } break; @@ -823,10 +837,15 @@ int wxKill(long pid, wxSignal sig, wxKillError *krc, int flags) // fall through case WAIT_TIMEOUT: - if ( krc ) - *krc = wxKILL_ERROR; + // Process didn't terminate: normally this is a failure but not + // when we're just testing for its existence. + if ( sig != wxSIGNONE ) + { + if ( krc ) + *krc = wxKILL_ERROR; - rc = STILL_ACTIVE; + ok = false; + } break; } } @@ -834,7 +853,7 @@ int wxKill(long pid, wxSignal sig, wxKillError *krc, int flags) // the return code is the same as from Unix kill(): 0 if killed // successfully or -1 on error - if ( !ok || rc == STILL_ACTIVE ) + if ( !ok ) return -1; if ( krc ) @@ -1058,12 +1077,6 @@ unsigned long wxGetProcessId() return ::GetCurrentProcessId(); } -// Emit a beeeeeep -void wxBell() -{ - ::MessageBeep((UINT)-1); // default sound -} - bool wxIsDebuggerRunning() { #if wxUSE_DYNLIB_CLASS @@ -1091,14 +1104,14 @@ bool wxLoadUserResource(const void **outData, size_t *outLen, const wxString& resourceName, - const wxString& resourceType, + const wxChar* resourceType, WXHINSTANCE instance) { wxCHECK_MSG( outData && outLen, false, "output pointers can't be NULL" ); HRSRC hResource = ::FindResource(instance, - resourceName.wx_str(), - resourceType.wx_str()); + resourceName.t_str(), + resourceType); if ( !hResource ) return false; @@ -1127,7 +1140,7 @@ wxLoadUserResource(const void **outData, char * wxLoadUserResource(const wxString& resourceName, - const wxString& resourceType, + const wxChar* resourceType, int* pLen, WXHINSTANCE instance) { @@ -1255,8 +1268,7 @@ wxString wxGetOsDescription() switch ( info.dwMinorVersion ) { case 0: - str.Printf(_("Windows 2000 (build %lu"), - info.dwBuildNumber); + str = _("Windows 2000"); break; case 2: @@ -1265,36 +1277,44 @@ wxString wxGetOsDescription() // type to resolve this ambiguity if ( wxIsWindowsServer() == 1 ) { - str.Printf(_("Windows Server 2003 (build %lu"), - info.dwBuildNumber); + str = _("Windows Server 2003"); break; } //else: must be XP, fall through case 1: - str.Printf(_("Windows XP (build %lu"), - info.dwBuildNumber); + str = _("Windows XP"); break; } break; case 6: - if ( info.dwMinorVersion == 0 ) + switch ( info.dwMinorVersion ) { - str.Printf(_("Windows Vista (build %lu"), - info.dwBuildNumber); + case 0: + str = wxIsWindowsServer() == 1 + ? _("Windows Server 2008") + : _("Windows Vista"); + break; + + case 1: + str = wxIsWindowsServer() == 1 + ? _("Windows Server 2008 R2") + : _("Windows 7"); + break; } break; } if ( str.empty() ) { - str.Printf(_("Windows NT %lu.%lu (build %lu"), - info.dwMajorVersion, - info.dwMinorVersion, - info.dwBuildNumber); + str.Printf(_("Windows NT %lu.%lu"), + info.dwMajorVersion, + info.dwMinorVersion); } + str << wxT(" (") + << wxString::Format(_("build %lu"), info.dwBuildNumber); if ( !wxIsEmpty(info.szCSDVersion) ) { str << wxT(", ") << info.szCSDVersion; @@ -1698,18 +1718,6 @@ extern long wxCharsetToCodepage(const char *name) #endif // wxUSE_FONTMAP/!wxUSE_FONTMAP -/* - Creates a hidden window with supplied window proc registering the class for - it if necesssary (i.e. the first time only). Caller is responsible for - destroying the window and unregistering the class (note that this must be - done because wxWidgets may be used as a DLL and so may be loaded/unloaded - multiple times into/from the same process so we cna't rely on automatic - Windows class unregistration). - - pclassname is a pointer to a caller stored classname, which must initially be - NULL. classname is the desired wndclass classname. If function successfully - registers the class, pclassname will be set to classname. - */ extern "C" WXDLLIMPEXP_BASE HWND wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc) {