X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/27d2dbbccadf25bb1d892fe1c4afbf74cf76bb36..4c2740ec0f18a2e657d53377031fc2dfce974f08:/src/msw/utils.cpp diff --git a/src/msw/utils.cpp b/src/msw/utils.cpp index eb91843d61..d2238eaddb 100644 --- a/src/msw/utils.cpp +++ b/src/msw/utils.cpp @@ -32,6 +32,7 @@ #endif //WX_PRECOMP #include "wx/apptrait.h" +#include "wx/dynlib.h" #include "wx/dynload.h" #include "wx/confbase.h" // for wxExpandEnvVars() @@ -94,10 +95,8 @@ #endif #endif -// 260 was taken from windef.h -#ifndef MAX_PATH - #define MAX_PATH 260 -#endif +// For wxKillAllChildren +#include // ---------------------------------------------------------------------------- // constants @@ -434,12 +433,8 @@ const wxChar* wxGetHomeDir(wxString *pstr) } else // fall back to the program directory { - wxString strPath; - ::GetModuleFileName(::GetModuleHandle(NULL), - wxStringBuffer(strPath, MAX_PATH), MAX_PATH); - - // extract the dir name - wxSplitPath(strPath, &strDir, NULL, NULL); + // extract the directory component of the program file name + wxSplitPath(wxGetFullModuleName(), &strDir, NULL, NULL); } #endif // UNIX/Win @@ -658,8 +653,13 @@ BOOL CALLBACK wxEnumFindByPidProc(HWND hwnd, LPARAM lParam) return TRUE; } -int wxKill(long pid, wxSignal sig, wxKillError *krc) +int wxKillAllChildren(long pid, wxSignal sig, wxKillError *krc); + +int wxKill(long pid, wxSignal sig, wxKillError *krc, int flags) { + if (flags & wxKILL_CHILDREN) + wxKillAllChildren(pid, sig, krc); + // get the process handle to operate on HANDLE hProcess = ::OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE | @@ -814,6 +814,112 @@ int wxKill(long pid, wxSignal sig, wxKillError *krc) return -1; } +HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ; +BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ; +BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ; + +static void InitToolHelp32() +{ + static bool s_initToolHelpDone = false; + + if (s_initToolHelpDone) + return; + + s_initToolHelpDone = true; + + lpfCreateToolhelp32Snapshot = NULL; + lpfProcess32First = NULL; + lpfProcess32Next = NULL; + + HINSTANCE hInstLib = LoadLibrary( wxT("Kernel32.DLL") ) ; + if( hInstLib == NULL ) + return ; + + // Get procedure addresses. + // We are linking to these functions of Kernel32 + // explicitly, because otherwise a module using + // this code would fail to load under Windows NT, + // which does not have the Toolhelp32 + // functions in the Kernel 32. + lpfCreateToolhelp32Snapshot= + (HANDLE(WINAPI *)(DWORD,DWORD)) + GetProcAddress( hInstLib, +#ifdef __WXWINCE__ + wxT("CreateToolhelp32Snapshot") +#else + "CreateToolhelp32Snapshot" +#endif + ) ; + + lpfProcess32First= + (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32)) + GetProcAddress( hInstLib, +#ifdef __WXWINCE__ + wxT("Process32First") +#else + "Process32First" +#endif + ) ; + + lpfProcess32Next= + (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32)) + GetProcAddress( hInstLib, +#ifdef __WXWINCE__ + wxT("Process32Next") +#else + "Process32Next" +#endif + ) ; + + FreeLibrary( hInstLib ) ; +} + +// By John Skiff +int wxKillAllChildren(long pid, wxSignal sig, wxKillError *krc) +{ + InitToolHelp32(); + + if (krc) + *krc = wxKILL_OK; + + // If not implemented for this platform (e.g. NT 4.0), silently ignore + if (!lpfCreateToolhelp32Snapshot || !lpfProcess32First || !lpfProcess32Next) + return 0; + + // Take a snapshot of all processes in the system. + HANDLE hProcessSnap = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (hProcessSnap == INVALID_HANDLE_VALUE) { + if (krc) + *krc = wxKILL_ERROR; + return -1; + } + + //Fill in the size of the structure before using it. + PROCESSENTRY32 pe; + wxZeroMemory(pe); + pe.dwSize = sizeof(PROCESSENTRY32); + + // Walk the snapshot of the processes, and for each process, + // kill it if its parent is pid. + if (!lpfProcess32First(hProcessSnap, &pe)) { + // Can't get first process. + if (krc) + *krc = wxKILL_ERROR; + CloseHandle (hProcessSnap); + return -1; + } + + do { + if (pe.th32ParentProcessID == (DWORD) pid) { + if (wxKill(pe.th32ProcessID, sig, krc)) + return -1; + } + } while (lpfProcess32Next (hProcessSnap, &pe)); + + + return 0; +} + // Execute a program in an Interactive Shell bool wxShell(const wxString& command) { @@ -901,20 +1007,35 @@ bool wxShutdown(wxShutdownFlags wFlags) #endif // Win32/16 } +wxPowerType wxGetPowerType() +{ + // TODO + return wxPOWER_UNKNOWN; +} + +wxBatteryState wxGetBatteryState() +{ + // TODO + return wxBATTERY_UNKNOWN_STATE; +} + // ---------------------------------------------------------------------------- // misc // ---------------------------------------------------------------------------- // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX) -long wxGetFreeMemory() +wxMemorySize wxGetFreeMemory() { -#if defined(__WIN32__) && !defined(__BORLANDC__) +#if defined(__WIN64__) + MEMORYSTATUSEX memStatex; + statex.dwLength = sizeof (statex); + ::GlobalMemoryStatusEx (&statex); + return (wxMemorySize)memStatus.ullAvailPhys; +#else /* if defined(__WIN32__) */ MEMORYSTATUS memStatus; memStatus.dwLength = sizeof(MEMORYSTATUS); - GlobalMemoryStatus(&memStatus); - return memStatus.dwAvailPhys; -#else - return (long)GetFreeSpace(0); + ::GlobalMemoryStatus(&memStatus); + return (wxMemorySize)memStatus.dwAvailPhys; #endif } @@ -929,6 +1050,25 @@ void wxBell() ::MessageBeep((UINT)-1); // default sound } +bool wxIsDebuggerRunning() +{ + // IsDebuggerPresent() is not available under Win95, so load it dynamically + wxDynamicLibrary dll(_T("kernel32.dll"), wxDL_VERBATIM); + + typedef BOOL (WINAPI *IsDebuggerPresent_t)(); + if ( !dll.HasSymbol(_T("IsDebuggerPresent")) ) + { + // no way to know, assume no + return false; + } + + return (*(IsDebuggerPresent_t)dll.GetSymbol(_T("IsDebuggerPresent")))() != 0; +} + +// ---------------------------------------------------------------------------- +// OS version +// ---------------------------------------------------------------------------- + wxString wxGetOsDescription() { wxString str; @@ -946,8 +1086,39 @@ wxString wxGetOsDescription() break; case VER_PLATFORM_WIN32_WINDOWS: - str.Printf(_("Windows 9%c"), - info.dwMinorVersion == 0 ? _T('5') : _T('8')); + switch (info.dwMinorVersion) + { + case 0: + if ( info.szCSDVersion[1] == 'B' || + info.szCSDVersion[1] == 'C' ) + { + str = _("Windows 95 OSR2"); + } + else + { + str = _("Windows 95"); + } + break; + case 10: + if ( info.szCSDVersion[1] == 'B' || + info.szCSDVersion[1] == 'C' ) + { + str = _("Windows 98 SE"); + } + else + { + str = _("Windows 98"); + } + break; + case 90: + str = _("Windows ME"); + break; + default: + str.Printf(_("Windows 9x (%d.%d)"), + info.dwMajorVersion, + info.dwMinorVersion); + break; + } if ( !wxIsEmpty(info.szCSDVersion) ) { str << _T(" (") << info.szCSDVersion << _T(')'); @@ -955,10 +1126,31 @@ wxString wxGetOsDescription() break; case VER_PLATFORM_WIN32_NT: - str.Printf(_T("Windows NT %lu.%lu (build %lu"), + if ( info.dwMajorVersion == 5 ) + { + switch ( info.dwMinorVersion ) + { + case 0: + str.Printf(_("Windows 2000 (build %lu"), + info.dwBuildNumber); + break; + case 1: + str.Printf(_("Windows XP (build %lu"), + info.dwBuildNumber); + break; + case 2: + str.Printf(_("Windows Server 2003 (build %lu"), + info.dwBuildNumber); + break; + } + } + if ( wxIsEmpty(str) ) + { + str.Printf(_("Windows NT %lu.%lu (build %lu"), info.dwMajorVersion, info.dwMinorVersion, info.dwBuildNumber); + } if ( !wxIsEmpty(info.szCSDVersion) ) { str << _T(", ") << info.szCSDVersion; @@ -1123,23 +1315,77 @@ extern WXDLLIMPEXP_BASE long wxEncodingToCharset(wxFontEncoding encoding) extern WXDLLIMPEXP_BASE long wxEncodingToCodepage(wxFontEncoding encoding) { - // translate encoding into the Windows CHARSET - long charset = wxEncodingToCharset(encoding); - if ( charset == -1 ) - return -1; + // There don't seem to be symbolic names for + // these under Windows so I just copied the + // values from MSDN. + + unsigned int ret; - // translate CHARSET to code page - CHARSETINFO csetInfo; - if ( !::TranslateCharsetInfo((DWORD *)(DWORD)charset, - &csetInfo, - TCI_SRCCHARSET) ) + switch (encoding) { - wxLogLastError(_T("TranslateCharsetInfo(TCI_SRCCHARSET)")); + case wxFONTENCODING_ISO8859_1: ret = 28591; break; + case wxFONTENCODING_ISO8859_2: ret = 28592; break; + case wxFONTENCODING_ISO8859_3: ret = 28593; break; + case wxFONTENCODING_ISO8859_4: ret = 28594; break; + case wxFONTENCODING_ISO8859_5: ret = 28595; break; + case wxFONTENCODING_ISO8859_6: ret = 28596; break; + case wxFONTENCODING_ISO8859_7: ret = 28597; break; + case wxFONTENCODING_ISO8859_8: ret = 28598; break; + case wxFONTENCODING_ISO8859_9: ret = 28599; break; + case wxFONTENCODING_ISO8859_10: ret = 28600; break; + case wxFONTENCODING_ISO8859_11: ret = 28601; break; + // case wxFONTENCODING_ISO8859_12, // doesn't exist currently, but put it + case wxFONTENCODING_ISO8859_13: ret = 28603; break; + case wxFONTENCODING_ISO8859_14: ret = 28604; break; + case wxFONTENCODING_ISO8859_15: ret = 28605; break; + case wxFONTENCODING_KOI8: ret = 20866; break; + case wxFONTENCODING_KOI8_U: ret = 21866; break; + case wxFONTENCODING_CP437: ret = 437; break; + case wxFONTENCODING_CP850: ret = 850; break; + case wxFONTENCODING_CP852: ret = 852; break; + case wxFONTENCODING_CP855: ret = 855; break; + case wxFONTENCODING_CP866: ret = 866; break; + case wxFONTENCODING_CP874: ret = 874; break; + case wxFONTENCODING_CP932: ret = 932; break; + case wxFONTENCODING_CP936: ret = 936; break; + case wxFONTENCODING_CP949: ret = 949; break; + case wxFONTENCODING_CP950: ret = 950; break; + case wxFONTENCODING_CP1250: ret = 1250; break; + case wxFONTENCODING_CP1251: ret = 1251; break; + case wxFONTENCODING_CP1252: ret = 1252; break; + case wxFONTENCODING_CP1253: ret = 1253; break; + case wxFONTENCODING_CP1254: ret = 1254; break; + case wxFONTENCODING_CP1255: ret = 1255; break; + case wxFONTENCODING_CP1256: ret = 1256; break; + case wxFONTENCODING_CP1257: ret = 1257; break; + case wxFONTENCODING_EUC_JP: ret = 51932; break; + case wxFONTENCODING_MACROMAN: ret = 10000; break; + case wxFONTENCODING_MACJAPANESE: ret = 10001; break; + case wxFONTENCODING_MACCHINESETRAD: ret = 10002; break; + case wxFONTENCODING_MACKOREAN: ret = 10003; break; + case wxFONTENCODING_MACARABIC: ret = 10004; break; + case wxFONTENCODING_MACHEBREW: ret = 10005; break; + case wxFONTENCODING_MACGREEK: ret = 10006; break; + case wxFONTENCODING_MACCYRILLIC: ret = 10007; break; + case wxFONTENCODING_MACTHAI: ret = 10021; break; + case wxFONTENCODING_MACCHINESESIMP: ret = 10008; break; + case wxFONTENCODING_MACCENTRALEUR: ret = 10029; break; + case wxFONTENCODING_MACCROATIAN: ret = 10082; break; + case wxFONTENCODING_MACICELANDIC: ret = 10079; break; + case wxFONTENCODING_MACROMANIAN: ret = 10009; break; + case wxFONTENCODING_UTF7: ret = 65000; break; + case wxFONTENCODING_UTF8: ret = 65001; break; + default: return -1; + } + if (::IsValidCodePage(ret) == 0) + return -1; + + CPINFO info; + if (::GetCPInfo(ret, &info) == 0) return -1; - } - return csetInfo.ciACP; + return (long) ret; } extern long wxCharsetToCodepage(const wxChar *name)