[qrvthtool] Fix UI issues on Windows 10.

- Always use the Oxygen icon theme. Qt6 has a built-in monochrome icon
  theme on Windows 10, but it's missing some icons.

- On Windows 10, set the style to fusion. Qt's "Windows Vista" style
  (now "Modern Windows") doesn't support Dark Mode, but fusion does.

- Manifest: Add Windows 8, 8.1, and 10 OS GUIDs.

- resource.rc: Use the CreateProcess manifest ID, not IsolationAware.
  IsolationAware is only for DLLs. Without the CreateProcess ID,
  on Windows 10, GetVersion() and the version helper functions will
  assume we're actually using Windows 8.
This commit is contained in:
David Korth 2025-06-17 20:18:47 -04:00
parent 43b9691078
commit 2a5551b616
4 changed files with 167 additions and 18 deletions

View File

@ -33,6 +33,9 @@ UINT WM_TaskbarButtonCreated;
# define MSGFLT_ADD 1
#endif
// VersionHelpers
#include "rp_versionhelpers.h"
/**
* Register the TaskbarButtonCreated message.
*/
@ -84,7 +87,16 @@ int main(int argc, char *argv[])
# endif /* QT_VERSION >= 0x050600 */
#endif /* QT_VERSION >= QT_VERSION_CHECK(5,0,0) && QT_VERSION < QT_VERSION_CHECK(6,0,0) */
QApplication *app = new QApplication(argc, argv);
#ifdef _WIN32
// Windows: Set the "fusion" theme if using Windows 10 or later.
// This is needed for proper Dark Mode support.
// NOTE: It's recommended to set the style *before* creating the QApplication.
if (IsWindows10OrGreater()) {
QApplication::setStyle(QLatin1String("fusion"));
}
#endif /* _WIN32 */
QApplication *const app = new QApplication(argc, argv);
app->setApplicationName(QStringLiteral("qrvthtool"));
app->setOrganizationDomain(QStringLiteral("gerbilsoft.com"));
app->setOrganizationName(QStringLiteral("GerbilSoft"));
@ -127,13 +139,12 @@ int main(int argc, char *argv[])
#endif /* _WIN32 */
#if defined(_WIN32) || defined(__APPLE__)
// Check if an icon theme is available.
if (!QIcon::hasThemeIcon(QStringLiteral("application-exit"))) {
// Icon theme is not available.
// Use the built-in Oxygen icon theme.
// Reference: http://tkrotoff.blogspot.com/2010/02/qiconfromtheme-under-windows.html
QIcon::setThemeName(QStringLiteral("oxygen"));
}
// Use the built-in Oxygen icon theme.
// Reference: http://tkrotoff.blogspot.com/2010/02/qiconfromtheme-under-windows.html
// NOTE: On Windows 10, Qt6 has a built-in monochrome icon theme,
// but it's missing some icons.
QIcon::setThemeName(QStringLiteral("oxygen"));
#endif /* _WIN32 || __APPLE__ */
// Initialize the QRvtHToolWindow.

View File

@ -35,22 +35,28 @@
</security>
</trustInfo>
<!-- Mark this program as *not* DPI-aware on Windows Vista and later. -->
<!-- Mark this program as DPI-aware on Windows Vista and later. -->
<!-- TODO: Windows 8 per-monitor DPI awareness. -->
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>false</dpiAware>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">system</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
<!-- Operating system compatibility. -->
<!-- Operating system compatibility -->
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--The ID below indicates application support for Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!--The ID below indicates application support for Windows 7 -->
<!-- Windows 10 and Windows 11 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Enable long paths (>260 chars) on Windows 10 Anniversary Update. (1607) -->
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</application>

View File

@ -2,7 +2,7 @@
* RVT-H Tool (qrvthtool) *
* resource.rc: Win32 resource script. *
* *
* Copyright (c) 2016-2019 by David Korth. *
* Copyright (c) 2016-2025 by David Korth. *
* SPDX-License-Identifier: GPL-2.0-or-later *
***************************************************************************/
@ -13,7 +13,7 @@
#include "resource.h"
/** Manifest **/
ISOLATIONAWARE_MANIFEST_RESOURCE_ID RT_MANIFEST "resources\\win32\\qrvthtool.exe.manifest"
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "resources\\win32\\qrvthtool.exe.manifest"
/** Icons **/
IDI_QRVTHTOOL ICON "resources\\win32\\qrvthtool.ico"

View File

@ -0,0 +1,132 @@
/**
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER within this package.
*/
// rvthtool: adding this here because AppVeyor's MSVC 2015
// build system doesn't have versionhelpers.h for some reason.
// NOTE: Removing the WINAPI_FAMILY_PARTITION checks.
#pragma once
#include <windows.h>
#ifdef __cplusplus
# define VERSIONHELPERAPI inline bool
#else
# define VERSIONHELPERAPI FORCEINLINE BOOL
#endif
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
/* gcc complains about missing field initializers. */
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif
VERSIONHELPERAPI IsWindowsVersionOrGreater(WORD major, WORD minor, WORD servpack)
{
OSVERSIONINFOEXW vi = {sizeof(vi),major,minor,0,0,{0},servpack};
return VerifyVersionInfoW(&vi, VER_MAJORVERSION|VER_MINORVERSION|VER_SERVICEPACKMAJOR,
VerSetConditionMask(VerSetConditionMask(VerSetConditionMask(0,
VER_MAJORVERSION,VER_GREATER_EQUAL),
VER_MINORVERSION,VER_GREATER_EQUAL),
VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL));
}
VERSIONHELPERAPI IsWindowsXPOrGreater(void) {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0);
}
VERSIONHELPERAPI IsWindowsXPSP1OrGreater(void) {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 1);
}
VERSIONHELPERAPI IsWindowsXPSP2OrGreater(void) {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 2);
}
VERSIONHELPERAPI IsWindowsXPSP3OrGreater(void) {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 3);
}
VERSIONHELPERAPI IsWindowsVistaOrGreater(void) {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0);
}
VERSIONHELPERAPI IsWindowsVistaSP1OrGreater(void) {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 1);
}
VERSIONHELPERAPI IsWindowsVistaSP2OrGreater(void) {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2);
}
VERSIONHELPERAPI IsWindows7OrGreater(void) {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0);
}
VERSIONHELPERAPI IsWindows7SP1OrGreater(void) {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1);
}
VERSIONHELPERAPI IsWindows8OrGreater(void) {
// FIXME: _WIN32_WINNT_WIN8 is missing when building with the Windows 7 SDK.
// Defining it causes a lot of other things to break for some reason...
//return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0);
return IsWindowsVersionOrGreater(HIBYTE(0x0602), LOBYTE(0x0602), 0);
}
VERSIONHELPERAPI IsWindows8Point1OrGreater(void) {
// FIXME: _WIN32_WINNT_WINBLUE is missing when building with the Windows 7 SDK.
// Defining it causes a lot of other things to break for some reason...
//return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0);
return IsWindowsVersionOrGreater(HIBYTE(0x0603), LOBYTE(0x0603), 0);
}
VERSIONHELPERAPI IsWindowsThresholdOrGreater(void) {
// FIXME: _WIN32_WINNT_WINTHRESHOLD is missing when building with MSVC 2022 for some reason.
//return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINTHRESHOLD), LOBYTE(_WIN32_WINNT_WINTHRESHOLD), 0);
return IsWindowsVersionOrGreater(HIBYTE(0x0A00), LOBYTE(0x0A00), 0);
}
VERSIONHELPERAPI IsWindows10OrGreater(void) {
return IsWindowsThresholdOrGreater();
}
VERSIONHELPERAPI IsWindowsVersionOrGreater_BuildNumberCheck(WORD major, WORD minor, DWORD buildnumber)
{
OSVERSIONINFOEXW vi = {sizeof(vi),major,minor,buildnumber,0,{0},0};
return VerifyVersionInfoW(&vi, VER_MAJORVERSION|VER_MINORVERSION|VER_BUILDNUMBER,
VerSetConditionMask(VerSetConditionMask(VerSetConditionMask(0,
VER_MAJORVERSION,VER_GREATER_EQUAL),
VER_MINORVERSION,VER_GREATER_EQUAL),
VER_BUILDNUMBER, VER_GREATER_EQUAL));
}
VERSIONHELPERAPI IsWindows11Build21262OrGreater(void) {
// Windows 11 pre-release Build 21262 on ARM added amd64 emulation.
// NOTE: Officially it was 21277, but 21262 was leaked and supports it too.
// https://blogs.windows.com/windows-insider/2020/12/10/introducing-x64-emulation-in-preview-for-windows-10-on-arm-pcs-to-the-windows-insider-program/
return IsWindowsVersionOrGreater_BuildNumberCheck(HIBYTE(0x0A00), LOBYTE(0x0A00), 21262);
}
VERSIONHELPERAPI IsWindows11OrGreater(void) {
// Windows 11 shows up as "Windows 10 build 22000".
return IsWindowsVersionOrGreater_BuildNumberCheck(HIBYTE(0x0A00), LOBYTE(0x0A00), 22000);
}
VERSIONHELPERAPI IsWindows11Build25905OrGreater(void) {
// Windows 11 Build 25905 dropped support for 32-bit ARM applications.
// https://blogs.windows.com/windows-insider/2023/07/12/announcing-windows-11-insider-preview-build-25905/
return IsWindowsVersionOrGreater_BuildNumberCheck(HIBYTE(0x0A00), LOBYTE(0x0A00), 25905);
}
VERSIONHELPERAPI IsWindowsServer(void) {
OSVERSIONINFOEXW vi = {sizeof(vi),0,0,0,0,{0},0,0,0,VER_NT_WORKSTATION};
return !VerifyVersionInfoW(&vi, VER_PRODUCT_TYPE, VerSetConditionMask(0, VER_PRODUCT_TYPE, VER_EQUAL));
}
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
/* gcc complains about missing field initializers. */
# pragma GCC diagnostic pop
#endif