#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__)
#if !defined(__GNUWIN32__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
#include <direct.h>
- #ifndef __MWERKS__
- #include <dos.h>
- #endif
+ #include <dos.h>
#endif //GNUWIN32
#if defined(__CYGWIN__)
#include <sys/unistd.h>
#include <sys/stat.h>
- #include <sys/cygwin.h> // for cygwin_conv_to_full_win32_path()
+ #include <sys/cygwin.h> // for cygwin_conv_path()
+ // and cygwin_conv_to_full_win32_path()
+ #include <cygwin/version.h>
#endif //GNUWIN32
#ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
static const wxChar eUSERNAME[] = wxT("UserName");
#endif
+WXDLLIMPEXP_DATA_BASE(const wxChar *) wxUserResourceStr = wxT("TEXT");
+
// ============================================================================
// implementation
// ============================================================================
!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) )
// 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;
}
// first branch is for Cygwin
#if defined(__UNIX__) && !defined(__WINE__)
- const wxChar *szHome = wxGetenv("HOME");
+ const wxChar *szHome = wxGetenv(wxT("HOME"));
if ( szHome == NULL ) {
// we're homeless...
wxLogWarning(_("can't find user's HOME, using current directory."));
#ifdef __CYGWIN__
// Cygwin returns unix type path but that does not work well
static wxChar windowsPath[MAX_PATH];
- cygwin_conv_to_full_win32_path(strDir, windowsPath);
+ #if CYGWIN_VERSION_DLL_MAJOR >= 1007
+ cygwin_conv_path(CCP_POSIX_TO_WIN_W, strDir, windowsPath, MAX_PATH);
+ #else
+ cygwin_conv_to_full_win32_path(strDir, windowsPath);
+ #endif
strDir = windowsPath;
#endif
#elif defined(__WXWINCE__)
ULARGE_INTEGER bytesFree, bytesTotal;
// may pass the path as is, GetDiskFreeSpaceEx() is smart enough
- if ( !pGetDiskFreeSpaceEx(path.fn_str(),
+ if ( !pGetDiskFreeSpaceEx(path.t_str(),
&bytesFree,
&bytesTotal,
NULL) )
// FIXME: this is wrong, we should extract the root drive from path
// instead, but this is the job for wxFileName...
- if ( !::GetDiskFreeSpace(path.fn_str(),
+ if ( !::GetDiskFreeSpace(path.t_str(),
&lSectorsPerCluster,
&lBytesPerSector,
&lNumberOfFreeClusters,
//
// 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
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) )
{
wxKillAllChildren(pid, sig, krc);
// get the process handle to operate on
- HANDLE hProcess = ::OpenProcess(SYNCHRONIZE |
- PROCESS_TERMINATE |
- PROCESS_QUERY_INFORMATION,
- FALSE, // not inheritable
- (DWORD)pid);
+ DWORD dwAccess = PROCESS_QUERY_INFORMATION | SYNCHRONIZE;
+ if ( sig == wxSIGKILL )
+ dwAccess |= PROCESS_TERMINATE;
+
+ HANDLE hProcess = ::OpenProcess(dwAccess, FALSE, (DWORD)pid);
if ( hProcess == NULL )
{
if ( krc )
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 )
{
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"
}
// 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;
// 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;
}
}
// 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 )
return ::GetCurrentProcessId();
}
-// Emit a beeeeeep
-void wxBell()
-{
- ::MessageBeep((UINT)-1); // default sound
-}
-
bool wxIsDebuggerRunning()
{
#if wxUSE_DYNLIB_CLASS
#endif
}
+// ----------------------------------------------------------------------------
+// working with MSW resources
+// ----------------------------------------------------------------------------
+
+bool
+wxLoadUserResource(const void **outData,
+ size_t *outLen,
+ const wxString& resourceName,
+ const wxChar* resourceType,
+ WXHINSTANCE instance)
+{
+ wxCHECK_MSG( outData && outLen, false, "output pointers can't be NULL" );
+
+ HRSRC hResource = ::FindResource(instance,
+ resourceName.t_str(),
+ resourceType);
+ if ( !hResource )
+ return false;
+
+ HGLOBAL hData = ::LoadResource(instance, hResource);
+ if ( !hData )
+ {
+ wxLogSysError(_("Failed to load resource \"%s\"."), resourceName);
+ return false;
+ }
+
+ *outData = ::LockResource(hData);
+ if ( !*outData )
+ {
+ wxLogSysError(_("Failed to lock resource \"%s\"."), resourceName);
+ return false;
+ }
+
+ *outLen = ::SizeofResource(instance, hResource);
+
+ // Notice that we do not need to call neither UnlockResource() (which is
+ // obsolete in Win32) nor GlobalFree() (resources are freed on process
+ // termination only)
+
+ return true;
+}
+
+char *
+wxLoadUserResource(const wxString& resourceName,
+ const wxChar* resourceType,
+ int* pLen,
+ WXHINSTANCE instance)
+{
+ const void *data;
+ size_t len;
+ if ( !wxLoadUserResource(&data, &len, resourceName, resourceType, instance) )
+ return NULL;
+
+ char *s = new char[len + 1];
+ memcpy(s, data, len);
+ s[len] = '\0'; // NUL-terminate in case the resource itself wasn't
+
+ if (pLen)
+ *pLen = len;
+
+ return s;
+}
+
// ----------------------------------------------------------------------------
// OS version
// ----------------------------------------------------------------------------
switch ( info.dwMinorVersion )
{
case 0:
- str.Printf(_("Windows 2000 (build %lu"),
- info.dwBuildNumber);
+ str = _("Windows 2000");
break;
case 2:
// 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;
#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)
{