]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/utils.cpp
fixes SetFirstItem, Thanks to David Wright
[wxWidgets.git] / src / msw / utils.cpp
index 47009f0bd093211fafc2bd3e4f5cb9cdadd6eead..9c2d7590511975fed55ad84ba47f047cde8a2d26 100644 (file)
@@ -41,6 +41,7 @@
 #include "wx/confbase.h"        // for wxExpandEnvVars()
 
 #include "wx/msw/private.h"     // includes <windows.h>
+#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 <direct.h>
 
-    #ifndef __MWERKS__
-        #include <dos.h>
-    #endif
+    #include <dos.h>
 #endif  //GNUWIN32
 
 #if defined(__CYGWIN__)
@@ -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
@@ -730,6 +729,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 +756,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 +808,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 +836,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 +852,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 )
@@ -1255,8 +1273,7 @@ wxString wxGetOsDescription()
                         switch ( info.dwMinorVersion )
                         {
                             case 0:
-                                str.Printf(_("Windows 2000 (build %lu"),
-                                           info.dwBuildNumber);
+                                str = _("Windows 2000");
                                 break;
 
                             case 2:
@@ -1265,36 +1282,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 +1723,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)
 {