diff --git a/docs/changes.txt b/docs/changes.txt index f37f01c488..6f3aa89244 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -181,6 +181,7 @@ wxMSW: - Correct wxGetOsDescription() for Windows 10 (Tobias Taschner). - Make wxListCtrl &c appearance more native on modern systems (Tobias Taschner). - Don't send wxActivateEvent for minimized windows (bzcdr). +- Return correct OS version under Windows 8 and later. wxOSX/Cocoa: diff --git a/src/msw/utils.cpp b/src/msw/utils.cpp index 1a4e8137d6..4e17bbe659 100644 --- a/src/msw/utils.cpp +++ b/src/msw/utils.cpp @@ -997,23 +997,34 @@ wxLoadUserResource(const wxString& resourceName, namespace { -// Helper function wrapping Windows GetVersionEx() which is deprecated since -// Windows 8. For now, all we do in this wrapper is to avoid the deprecation -// warnings but this is not enough as the function now actually doesn't return -// the correct value any more and we need to use VerifyVersionInfo() to perform -// binary search to find the real Windows version. -OSVERSIONINFOEX wxGetWindowsVersionInfo() +// Helper trying to get the real Windows version which is needed because +// GetVersionEx() doesn't return it any more since Windows 8. +OSVERSIONINFOEXW wxGetWindowsVersionInfo() { - OSVERSIONINFOEX info; + OSVERSIONINFOEXW info; wxZeroMemory(info); + info.dwOSVersionInfoSize = sizeof(info); + + // The simplest way to get the version is to call the kernel + // RtlGetVersion() directly, if it is available. +#if wxUSE_DYNLIB_CLASS + wxDynamicLibrary dllNtDll; + if ( dllNtDll.RawLoad(wxS("ntdll.dll")) ) + { + typedef LONG /* NTSTATUS */ (WINAPI *RtlGetVersion_t)(OSVERSIONINFOEXW*); + + RtlGetVersion_t wxDL_INIT_FUNC(pfn, RtlGetVersion, dllNtDll); + if ( pfnRtlGetVersion && pfnRtlGetVersion(&info) ) + return info; + } +#endif // wxUSE_DYNLIB_CLASS #ifdef __VISUALC__ #pragma warning(push) #pragma warning(disable:4996) // 'xxx': was declared deprecated #endif - info.dwOSVersionInfoSize = sizeof(info); - if ( !::GetVersionEx(reinterpret_cast(&info)) ) + if ( !::GetVersionExW(reinterpret_cast(&info)) ) { // This really shouldn't ever happen. wxFAIL_MSG( "GetVersionEx() unexpectedly failed" ); @@ -1056,7 +1067,7 @@ wxString wxGetOsDescription() { wxString str; - const OSVERSIONINFOEX info = wxGetWindowsVersionInfo(); + const OSVERSIONINFOEXW info = wxGetWindowsVersionInfo(); switch ( info.dwPlatformId ) { #ifdef VER_PLATFORM_WIN32_CE @@ -1236,7 +1247,7 @@ wxOperatingSystemId wxGetOsVersion(int *verMaj, int *verMin) // query the OS info only once as it's not supposed to change if ( !s_version.initialized ) { - const OSVERSIONINFOEX info = wxGetWindowsVersionInfo(); + const OSVERSIONINFOEXW info = wxGetWindowsVersionInfo(); s_version.initialized = true;