]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Dark mode.
authorToni Wilen <twilen@winuae.net>
Sun, 9 Jul 2023 18:42:17 +0000 (21:42 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 9 Jul 2023 18:42:17 +0000 (21:42 +0300)
12 files changed:
od-win32/IatHook.h [new file with mode: 0644]
od-win32/darkmode.cpp [new file with mode: 0644]
od-win32/darkmode.h [new file with mode: 0644]
od-win32/resources/resource.h
od-win32/resources/winuae.rc
od-win32/win32.cpp
od-win32/win32.h
od-win32/win32gfx.cpp
od-win32/win32gui.cpp
od-win32/win32gui_extra.cpp
od-win32/winuae_msvc15/winuae_msvc.vcxproj
od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters

diff --git a/od-win32/IatHook.h b/od-win32/IatHook.h
new file mode 100644 (file)
index 0000000..6b359ed
--- /dev/null
@@ -0,0 +1,91 @@
+// This file contains code from
+// https://github.com/stevemk14ebr/PolyHook_2_0/blob/master/sources/IatHook.cpp
+// which is licensed under the MIT License.
+// See PolyHook_2_0-LICENSE for more information.
+
+#pragma once
+
+template <typename T, typename T1, typename T2>
+constexpr T RVA2VA(T1 base, T2 rva)
+{
+       return reinterpret_cast<T>(reinterpret_cast<ULONG_PTR>(base) + rva);
+}
+
+template <typename T>
+constexpr T DataDirectoryFromModuleBase(void *moduleBase, size_t entryID)
+{
+       auto dosHdr = reinterpret_cast<PIMAGE_DOS_HEADER>(moduleBase);
+       auto ntHdr = RVA2VA<PIMAGE_NT_HEADERS>(moduleBase, dosHdr->e_lfanew);
+       auto dataDir = ntHdr->OptionalHeader.DataDirectory;
+       return RVA2VA<T>(moduleBase, dataDir[entryID].VirtualAddress);
+}
+
+PIMAGE_THUNK_DATA FindAddressByName(void *moduleBase, PIMAGE_THUNK_DATA impName, PIMAGE_THUNK_DATA impAddr, const char *funcName)
+{
+       for (; impName->u1.Ordinal; ++impName, ++impAddr)
+       {
+               if (IMAGE_SNAP_BY_ORDINAL(impName->u1.Ordinal))
+                       continue;
+
+               auto import = RVA2VA<PIMAGE_IMPORT_BY_NAME>(moduleBase, impName->u1.AddressOfData);
+               if (strcmp(import->Name, funcName) != 0)
+                       continue;
+               return impAddr;
+       }
+       return nullptr;
+}
+
+PIMAGE_THUNK_DATA FindAddressByOrdinal(void *moduleBase, PIMAGE_THUNK_DATA impName, PIMAGE_THUNK_DATA impAddr, uint16_t ordinal)
+{
+       for (; impName->u1.Ordinal; ++impName, ++impAddr)
+       {
+               if (IMAGE_SNAP_BY_ORDINAL(impName->u1.Ordinal) && IMAGE_ORDINAL(impName->u1.Ordinal) == ordinal)
+                       return impAddr;
+       }
+       return nullptr;
+}
+
+PIMAGE_THUNK_DATA FindIatThunkInModule(void *moduleBase, const char *dllName, const char *funcName)
+{
+       auto imports = DataDirectoryFromModuleBase<PIMAGE_IMPORT_DESCRIPTOR>(moduleBase, IMAGE_DIRECTORY_ENTRY_IMPORT);
+       for (; imports->Name; ++imports)
+       {
+               if (_stricmp(RVA2VA<LPCSTR>(moduleBase, imports->Name), dllName) != 0)
+                       continue;
+
+               auto origThunk = RVA2VA<PIMAGE_THUNK_DATA>(moduleBase, imports->OriginalFirstThunk);
+               auto thunk = RVA2VA<PIMAGE_THUNK_DATA>(moduleBase, imports->FirstThunk);
+               return FindAddressByName(moduleBase, origThunk, thunk, funcName);
+       }
+       return nullptr;
+}
+
+PIMAGE_THUNK_DATA FindDelayLoadThunkInModule(void *moduleBase, const char *dllName, const char *funcName)
+{
+       auto imports = DataDirectoryFromModuleBase<PIMAGE_DELAYLOAD_DESCRIPTOR>(moduleBase, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT);
+       for (; imports->DllNameRVA; ++imports)
+       {
+               if (_stricmp(RVA2VA<LPCSTR>(moduleBase, imports->DllNameRVA), dllName) != 0)
+                       continue;
+
+               auto impName = RVA2VA<PIMAGE_THUNK_DATA>(moduleBase, imports->ImportNameTableRVA);
+               auto impAddr = RVA2VA<PIMAGE_THUNK_DATA>(moduleBase, imports->ImportAddressTableRVA);
+               return FindAddressByName(moduleBase, impName, impAddr, funcName);
+       }
+       return nullptr;
+}
+
+PIMAGE_THUNK_DATA FindDelayLoadThunkInModule(void *moduleBase, const char *dllName, uint16_t ordinal)
+{
+       auto imports = DataDirectoryFromModuleBase<PIMAGE_DELAYLOAD_DESCRIPTOR>(moduleBase, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT);
+       for (; imports->DllNameRVA; ++imports)
+       {
+               if (_stricmp(RVA2VA<LPCSTR>(moduleBase, imports->DllNameRVA), dllName) != 0)
+                       continue;
+
+               auto impName = RVA2VA<PIMAGE_THUNK_DATA>(moduleBase, imports->ImportNameTableRVA);
+               auto impAddr = RVA2VA<PIMAGE_THUNK_DATA>(moduleBase, imports->ImportAddressTableRVA);
+               return FindAddressByOrdinal(moduleBase, impName, impAddr, ordinal);
+       }
+       return nullptr;
+}
diff --git a/od-win32/darkmode.cpp b/od-win32/darkmode.cpp
new file mode 100644 (file)
index 0000000..1688f80
--- /dev/null
@@ -0,0 +1,712 @@
+
+#include <climits>
+#include <cstdint>
+
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
+#include <Windows.h>
+#include <CommCtrl.h>
+#include <Uxtheme.h>
+#include <WindowsX.h>
+#include <Vssym32.h>
+
+#pragma comment(lib, "Comctl32.lib")
+#pragma comment(lib, "Uxtheme.lib")
+
+#include "resource.h"
+
+#include "darkmode.h"
+
+#include "IatHook.h"
+
+extern void write_log(const char *, ...);
+
+bool g_darkModeSupported = false;
+bool g_darkModeEnabled = false;
+int darkModeForced = 0;
+DWORD g_buildNumber = 0;
+
+fnSetWindowCompositionAttribute _SetWindowCompositionAttribute = nullptr;
+fnShouldAppsUseDarkMode _ShouldAppsUseDarkMode = nullptr;
+fnAllowDarkModeForWindow _AllowDarkModeForWindow = nullptr;
+fnAllowDarkModeForApp _AllowDarkModeForApp = nullptr;
+fnFlushMenuThemes _FlushMenuThemes = nullptr;
+fnRefreshImmersiveColorPolicyState _RefreshImmersiveColorPolicyState = nullptr;
+fnIsDarkModeAllowedForWindow _IsDarkModeAllowedForWindow = nullptr;
+fnGetIsImmersiveColorUsingHighContrast _GetIsImmersiveColorUsingHighContrast = nullptr;
+fnOpenNcThemeData _OpenNcThemeData = nullptr;
+// 1903 18362
+fnShouldSystemUseDarkMode _ShouldSystemUseDarkMode = nullptr;
+fnSetPreferredAppMode _SetPreferredAppMode = nullptr;
+
+COLORREF dark_text_color, dark_bg_color;
+
+bool AllowDarkModeForWindow(HWND hWnd, bool allow)
+{
+       if (g_darkModeSupported)
+               return _AllowDarkModeForWindow(hWnd, allow);
+       return false;
+}
+
+bool IsHighContrast()
+{
+       HIGHCONTRASTW highContrast = { sizeof(highContrast) };
+       if (SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(highContrast), &highContrast, FALSE))
+               return highContrast.dwFlags & HCF_HIGHCONTRASTON;
+       return false;
+}
+
+void RefreshTitleBarThemeColor(HWND hWnd)
+{
+       BOOL dark = FALSE;
+       if (_IsDarkModeAllowedForWindow(hWnd) &&
+               _ShouldAppsUseDarkMode() &&
+               !IsHighContrast())
+       {
+               dark = TRUE;
+       }
+       if (g_buildNumber < 18362)
+               SetPropW(hWnd, L"UseImmersiveDarkModeColors", reinterpret_cast<HANDLE>(static_cast<INT_PTR>(dark)));
+       else if (_SetWindowCompositionAttribute)
+       {
+               WINDOWCOMPOSITIONATTRIBDATA data = { WCA_USEDARKMODECOLORS, &dark, sizeof(dark) };
+               _SetWindowCompositionAttribute(hWnd, &data);
+       }
+}
+
+bool IsColorSchemeChangeMessage(LPARAM lParam)
+{
+       bool is = false;
+       if (lParam && CompareStringOrdinal(reinterpret_cast<LPCWCH>(lParam), -1, L"ImmersiveColorSet", -1, TRUE) == CSTR_EQUAL)
+       {
+               _RefreshImmersiveColorPolicyState();
+               is = true;
+       }
+       _GetIsImmersiveColorUsingHighContrast(IHCM_REFRESH);
+       return is;
+}
+
+bool IsColorSchemeChangeMessage(UINT message, LPARAM lParam)
+{
+       if (message == WM_SETTINGCHANGE)
+               return IsColorSchemeChangeMessage(lParam);
+       return false;
+}
+
+void AllowDarkModeForApp(PreferredAppMode dark)
+{
+       if (_AllowDarkModeForApp)
+               _AllowDarkModeForApp(dark != PreferredAppMode::Default);
+       else if (_SetPreferredAppMode)
+               _SetPreferredAppMode(dark);
+}
+
+static void FixDarkScrollBar()
+{
+       HMODULE hComctl = LoadLibraryExW(L"comctl32.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
+       if (hComctl)
+       {
+               auto addr = FindDelayLoadThunkInModule(hComctl, "uxtheme.dll", 49); // OpenNcThemeData
+               if (addr)
+               {
+                       DWORD oldProtect;
+                       if (VirtualProtect(addr, sizeof(IMAGE_THUNK_DATA), PAGE_READWRITE, &oldProtect))
+                       {
+                               auto MyOpenThemeData = [](HWND hWnd, LPCWSTR classList) -> HTHEME {
+                                       if (wcscmp(classList, L"ScrollBar") == 0)
+                                       {
+                                               hWnd = nullptr;
+                                               classList = L"Explorer::ScrollBar";
+                                       }
+                                       return _OpenNcThemeData(hWnd, classList);
+                               };
+
+                               addr->u1.Function = reinterpret_cast<ULONG_PTR>(static_cast<fnOpenNcThemeData>(MyOpenThemeData));
+                               VirtualProtect(addr, sizeof(IMAGE_THUNK_DATA), oldProtect, &oldProtect);
+                       }
+               }
+       }
+}
+
+static void GetDarkmodeFontColor(void)
+{
+
+       HTHEME hTheme = OpenThemeData(nullptr, L"ItemsView");
+       if (hTheme) {
+               COLORREF color;
+               if (SUCCEEDED(GetThemeColor(hTheme, 0, 0, TMT_TEXTCOLOR, &color)))
+               {
+                       dark_text_color = color;
+               }
+               if (SUCCEEDED(GetThemeColor(hTheme, 0, 0, TMT_FILLCOLOR, &color)))
+               {
+                       dark_bg_color = color;
+               }
+               CloseThemeData(hTheme);
+       }
+
+}
+
+constexpr bool CheckBuildNumber(DWORD buildNumber)
+{
+       return buildNumber <= 22621;
+}
+
+void InitDarkMode(int enable)
+{
+       auto RtlGetNtVersionNumbers = reinterpret_cast<fnRtlGetNtVersionNumbers>(GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlGetNtVersionNumbers"));
+       if (RtlGetNtVersionNumbers)
+       {
+               DWORD major, minor;
+               RtlGetNtVersionNumbers(&major, &minor, &g_buildNumber);
+               g_buildNumber &= ~0xF0000000;
+               if (major == 10 && minor == 0 && CheckBuildNumber(g_buildNumber))
+               {
+                       HMODULE hUxtheme = LoadLibraryExW(L"uxtheme.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
+                       if (hUxtheme)
+                       {
+                               _OpenNcThemeData = reinterpret_cast<fnOpenNcThemeData>(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(49)));
+                               _RefreshImmersiveColorPolicyState = reinterpret_cast<fnRefreshImmersiveColorPolicyState>(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(104)));
+                               _GetIsImmersiveColorUsingHighContrast = reinterpret_cast<fnGetIsImmersiveColorUsingHighContrast>(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(106)));
+                               _ShouldAppsUseDarkMode = reinterpret_cast<fnShouldAppsUseDarkMode>(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(132)));
+                               _AllowDarkModeForWindow = reinterpret_cast<fnAllowDarkModeForWindow>(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(133)));
+
+                               auto ord135 = GetProcAddress(hUxtheme, MAKEINTRESOURCEA(135));
+                               if (g_buildNumber < 18362)
+                                       _AllowDarkModeForApp = reinterpret_cast<fnAllowDarkModeForApp>(ord135);
+                               else
+                                       _SetPreferredAppMode = reinterpret_cast<fnSetPreferredAppMode>(ord135);
+
+                               //_FlushMenuThemes = reinterpret_cast<fnFlushMenuThemes>(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(136)));
+                               _IsDarkModeAllowedForWindow = reinterpret_cast<fnIsDarkModeAllowedForWindow>(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(137)));
+
+                               _SetWindowCompositionAttribute = reinterpret_cast<fnSetWindowCompositionAttribute>(GetProcAddress(GetModuleHandleW(L"user32.dll"), "SetWindowCompositionAttribute"));
+
+                               if (_OpenNcThemeData &&
+                                       _RefreshImmersiveColorPolicyState &&
+                                       _ShouldAppsUseDarkMode &&
+                                       _AllowDarkModeForWindow &&
+                                       (_AllowDarkModeForApp || _SetPreferredAppMode) &&
+                                       _IsDarkModeAllowedForWindow)
+                               {
+                                       g_darkModeSupported = true;
+
+                                       if (darkModeForced > 0) {
+                                               AllowDarkModeForApp(PreferredAppMode::ForceDark);
+                                       } else  if (darkModeForced < 0) {
+                                               AllowDarkModeForApp(PreferredAppMode::ForceLight);
+                                       } else if (enable == -1 || enable == 1) {
+                                               AllowDarkModeForApp(PreferredAppMode::AllowDark);
+                                       } else {
+                                               AllowDarkModeForApp(PreferredAppMode::Default);
+                                       }
+                                       _RefreshImmersiveColorPolicyState();
+
+                                       g_darkModeEnabled = _ShouldAppsUseDarkMode() && !IsHighContrast();
+                                       
+                                       if (g_darkModeEnabled && enable < -1) {
+                                               AllowDarkModeForApp(PreferredAppMode::ForceDark);
+                                       }
+
+                                       if (!g_darkModeEnabled && enable > 0 && darkModeForced >= 0) {
+                                               AllowDarkModeForApp(PreferredAppMode::ForceDark);
+                                               _RefreshImmersiveColorPolicyState();
+                                               g_darkModeEnabled = _ShouldAppsUseDarkMode() && !IsHighContrast();
+                                       }
+
+                                       if (g_darkModeEnabled) {
+                                               FixDarkScrollBar();
+                                               GetDarkmodeFontColor();
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if (!enable && g_darkModeSupported) {
+               AllowDarkModeForApp(PreferredAppMode::Default);
+               if (_RefreshImmersiveColorPolicyState != NULL) {
+                       _RefreshImmersiveColorPolicyState();
+               }
+               g_darkModeEnabled = false;
+       }
+}
+
+
+struct SubClassData
+{
+       HTHEME hTheme = nullptr;
+       COLORREF headerTextColor;
+       int iStateID = 0;
+
+       ~SubClassData()
+       {
+               CloseTheme();
+       }
+
+       bool EnsureTheme(HWND hwnd, const TCHAR *theme)
+       {
+               if (!hTheme)
+               {
+                       hTheme = OpenThemeData(hwnd, theme);
+               }
+               return hTheme != nullptr;
+       }
+
+       void CloseTheme()
+       {
+               if (hTheme)
+               {
+                       CloseThemeData(hTheme);
+                       hTheme = nullptr;
+               }
+       }
+};
+
+static void RenderButton(HWND hwnd, HDC hdc, HTHEME hTheme, int iPartID, int iStateID)
+{
+       RECT rcClient = { 0 };
+       TCHAR szText[256] = { 0 };
+       DWORD nState = static_cast<DWORD>(SendMessage(hwnd, BM_GETSTATE, 0, 0));
+       DWORD uiState = static_cast<DWORD>(SendMessage(hwnd, WM_QUERYUISTATE, 0, 0));
+       DWORD nStyle = GetWindowLong(hwnd, GWL_STYLE);
+
+       HFONT hFont = nullptr;
+       HFONT hOldFont = nullptr;
+       HFONT hCreatedFont = nullptr;
+       LOGFONT lf = { 0 };
+       if (SUCCEEDED(GetThemeFont(hTheme, hdc, iPartID, iStateID, TMT_FONT, &lf)))
+       {
+               hCreatedFont = CreateFontIndirect(&lf);
+               hFont = hCreatedFont;
+       }
+
+       if (!hFont) {
+               hFont = reinterpret_cast<HFONT>(SendMessage(hwnd, WM_GETFONT, 0, 0));
+       }
+
+       hOldFont = (HFONT)SelectObject(hdc, hFont);
+
+       DWORD dtFlags = DT_LEFT; // DT_LEFT is 0
+       dtFlags |= (nStyle & BS_MULTILINE) ? DT_WORDBREAK : DT_SINGLELINE;
+       dtFlags |= ((nStyle & BS_CENTER) == BS_CENTER) ? DT_CENTER : (nStyle & BS_RIGHT) ? DT_RIGHT : 0;
+       dtFlags |= ((nStyle & BS_VCENTER) == BS_VCENTER) ? DT_VCENTER : (nStyle & BS_BOTTOM) ? DT_BOTTOM : 0;
+       dtFlags |= (uiState & UISF_HIDEACCEL) ? DT_HIDEPREFIX : 0;
+
+       if (!(nStyle & BS_MULTILINE) && !(nStyle & BS_BOTTOM) && !(nStyle & BS_TOP))
+       {
+               dtFlags |= DT_VCENTER;
+       }
+
+       GetClientRect(hwnd, &rcClient);
+       GetWindowText(hwnd, szText, sizeof(szText) / sizeof(TCHAR));
+
+       SIZE szBox = { 13, 13 };
+       GetThemePartSize(hTheme, hdc, iPartID, iStateID, NULL, TS_DRAW, &szBox);
+
+       RECT rcText = rcClient;
+       GetThemeBackgroundContentRect(hTheme, hdc, iPartID, iStateID, &rcClient, &rcText);
+
+       RECT rcBackground = rcClient;
+       if (dtFlags & DT_SINGLELINE)
+       {
+               rcBackground.top += (rcText.bottom - rcText.top - szBox.cy) / 2;
+       }
+       rcBackground.bottom = rcBackground.top + szBox.cy;
+       rcBackground.right = rcBackground.left + szBox.cx;
+       rcText.left = rcBackground.right + 3;
+
+       DrawThemeParentBackground(hwnd, hdc, &rcClient);
+       DrawThemeBackground(hTheme, hdc, iPartID, iStateID, &rcBackground, nullptr);
+
+       DTTOPTS dtto = { sizeof(DTTOPTS), DTT_TEXTCOLOR };
+       dtto.crText = dark_text_color;
+
+       DrawThemeTextEx(hTheme, hdc, iPartID, iStateID, szText, -1, dtFlags, &rcText, &dtto);
+
+       if ((nState & BST_FOCUS) && !(uiState & UISF_HIDEFOCUS))
+       {
+               RECT rcTextOut = rcText;
+               dtto.dwFlags |= DTT_CALCRECT;
+               DrawThemeTextEx(hTheme, hdc, iPartID, iStateID, szText, -1, dtFlags | DT_CALCRECT, &rcTextOut, &dtto);
+               RECT rcFocus = rcTextOut;
+               rcFocus.bottom++;
+               rcFocus.left--;
+               rcFocus.right++;
+               DrawFocusRect(hdc, &rcFocus);
+       }
+
+       if (hCreatedFont) DeleteObject(hCreatedFont);
+       SelectObject(hdc, hOldFont);
+}
+
+static void PaintButton(HWND hwnd, HDC hdc, SubClassData &buttonData)
+{
+       DWORD nState = static_cast<DWORD>(SendMessage(hwnd, BM_GETSTATE, 0, 0));
+       DWORD nStyle = GetWindowLong(hwnd, GWL_STYLE);
+       DWORD nButtonStyle = nStyle & 0xF;
+
+       int iPartID = BP_PUSHBUTTON;
+       if (nButtonStyle == BS_CHECKBOX || nButtonStyle == BS_AUTOCHECKBOX || nButtonStyle == BS_3STATE || nButtonStyle == BS_AUTO3STATE) {
+               iPartID = BP_CHECKBOX;
+       } else if (nButtonStyle == BS_RADIOBUTTON || nButtonStyle == BS_AUTORADIOBUTTON) {
+               iPartID = BP_RADIOBUTTON;
+       } else {
+               return;
+       }
+
+       // states of BP_CHECKBOX and BP_RADIOBUTTON are the same
+       int iStateID = RBS_UNCHECKEDNORMAL;
+
+       if (nStyle & WS_DISABLED)
+               iStateID = RBS_UNCHECKEDDISABLED;
+       else if (nState & BST_PUSHED)
+               iStateID = RBS_UNCHECKEDPRESSED;
+       else if (nState & BST_HOT)
+               iStateID = RBS_UNCHECKEDHOT;
+       
+       if (nState & BST_CHECKED)
+               iStateID += 4;
+       else if ((nButtonStyle == BS_3STATE || nButtonStyle == BS_AUTO3STATE) && (nStyle & BST_INDETERMINATE))
+               iStateID += 8;
+
+       if (BufferedPaintRenderAnimation(hwnd, hdc)) {
+               return;
+       }
+
+       BP_ANIMATIONPARAMS animParams = { sizeof(animParams) };
+       animParams.style = BPAS_LINEAR;
+       if (iStateID != buttonData.iStateID) {
+               GetThemeTransitionDuration(buttonData.hTheme, iPartID, buttonData.iStateID, iStateID, TMT_TRANSITIONDURATIONS, &animParams.dwDuration);
+       }
+
+       RECT rcClient = { 0 };
+       GetClientRect(hwnd, &rcClient);
+
+       HDC hdcFrom = nullptr;
+       HDC hdcTo = nullptr;
+       HANIMATIONBUFFER hbpAnimation = BeginBufferedAnimation(hwnd, hdc, &rcClient, BPBF_COMPATIBLEBITMAP, nullptr, &animParams, &hdcFrom, &hdcTo);
+       if (hbpAnimation) {
+               if (hdcFrom) {
+                       RenderButton(hwnd, hdcFrom, buttonData.hTheme, iPartID, buttonData.iStateID);
+               }
+               if (hdcTo) {
+                       RenderButton(hwnd, hdcTo, buttonData.hTheme, iPartID, iStateID);
+               }
+               buttonData.iStateID = iStateID;
+               EndBufferedAnimation(hbpAnimation, TRUE);
+       } else {
+               RenderButton(hwnd, hdc, buttonData.hTheme, iPartID, iStateID);
+               buttonData.iStateID = iStateID;
+       }
+}
+
+
+static void PaintGroupbox(HWND hwnd, HDC hdc, SubClassData &buttonData)
+{
+       DWORD nStyle = GetWindowLong(hwnd, GWL_STYLE);
+       int iPartID = BP_GROUPBOX;
+       int iStateID = GBS_NORMAL;
+
+       if (nStyle & WS_DISABLED) {
+               iStateID = GBS_DISABLED;
+       }
+
+       RECT rcClient = { 0 };
+       GetClientRect(hwnd, &rcClient);
+
+       RECT rcText = rcClient;
+       RECT rcBackground = rcClient;
+
+       HFONT hFont = nullptr;
+       HFONT hOldFont = nullptr;
+       HFONT hCreatedFont = nullptr;
+       LOGFONT lf = { 0 };
+       if (SUCCEEDED(GetThemeFont(buttonData.hTheme, hdc, iPartID, iStateID, TMT_FONT, &lf))) {
+               hCreatedFont = CreateFontIndirect(&lf);
+               hFont = hCreatedFont;
+       }
+
+       if (!hFont) {
+               hFont = reinterpret_cast<HFONT>(SendMessage(hwnd, WM_GETFONT, 0, 0));
+       }
+
+       hOldFont = (HFONT)SelectObject(hdc, hFont);
+
+       TCHAR szText[256] = { 0 };
+       GetWindowText(hwnd, szText, sizeof(szText) / sizeof(TCHAR));
+
+       if (szText[0]) {
+               SIZE textSize = { 0 };
+               GetTextExtentPoint32(hdc, szText, static_cast<int>(wcslen(szText)), &textSize);
+               rcBackground.top += textSize.cy / 2;
+               rcText.left += 7;
+               rcText.bottom = rcText.top + textSize.cy;
+               rcText.right = rcText.left + textSize.cx + 4;
+               ExcludeClipRect(hdc, rcText.left, rcText.top, rcText.right, rcText.bottom);
+       } else {
+               SIZE textSize = { 0 };
+               GetTextExtentPoint32(hdc, L"M", 1, &textSize);
+               rcBackground.top += textSize.cy / 2;
+       }
+
+       RECT rcContent = rcBackground;
+       GetThemeBackgroundContentRect(buttonData.hTheme, hdc, BP_GROUPBOX, iStateID, &rcBackground, &rcContent);
+       ExcludeClipRect(hdc, rcContent.left, rcContent.top, rcContent.right, rcContent.bottom);
+
+       DrawThemeParentBackground(hwnd, hdc, &rcClient);
+       DrawThemeBackground(buttonData.hTheme, hdc, BP_GROUPBOX, iStateID, &rcBackground, nullptr);
+
+       SelectClipRgn(hdc, nullptr);
+
+       if (szText[0]) {
+               rcText.right -= 2;
+               rcText.left += 2;
+               DTTOPTS dtto = { sizeof(DTTOPTS), DTT_TEXTCOLOR };
+               dtto.crText = dark_text_color;
+               DrawThemeTextEx(buttonData.hTheme, hdc, BP_GROUPBOX, iStateID, szText, -1, DT_LEFT | DT_SINGLELINE, &rcText, &dtto);
+       }
+
+       if (hCreatedFont) DeleteObject(hCreatedFont);
+       SelectObject(hdc, hOldFont);
+}
+
+void SubclassButtonControl(HWND hwnd)
+{
+       if (g_darkModeSupported && g_darkModeEnabled) {
+               SetWindowSubclass(hwnd, [](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR /*uIdSubclass*/, DWORD_PTR dwRefData) -> LRESULT {
+                       auto data = reinterpret_cast<SubClassData *>(dwRefData);
+                       switch (uMsg)
+                       {
+                               case WM_UPDATEUISTATE:
+                               if (HIWORD(wParam) & (UISF_HIDEACCEL | UISF_HIDEFOCUS))
+                               {
+                                       InvalidateRect(hWnd, nullptr, FALSE);
+                               }
+                               break;
+                               case WM_NCDESTROY:
+                               {
+                                       delete data;
+                               }
+                               break;
+                               case WM_ERASEBKGND:
+                               {
+                                       if (g_darkModeEnabled && data->EnsureTheme(hWnd, L"Button")) {
+                                               return TRUE;
+                                       } else {
+                                               break;
+                                       }
+                               }
+                               case WM_THEMECHANGED:
+                                       data->CloseTheme();
+                                       break;
+                               case WM_PRINTCLIENT:
+                               case WM_PAINT:
+                                       if (g_darkModeEnabled && data->EnsureTheme(hWnd, L"Button")) {
+                                               DWORD nStyle = GetWindowLong(hWnd, GWL_STYLE);
+                                               DWORD nButtonStyle = nStyle & 0xF;
+                                               if (nButtonStyle == BS_CHECKBOX || nButtonStyle == BS_AUTOCHECKBOX || nButtonStyle == BS_RADIOBUTTON || nButtonStyle == BS_AUTORADIOBUTTON ||
+                                                       nButtonStyle == BS_3STATE || nButtonStyle == BS_AUTO3STATE || nButtonStyle == BS_GROUPBOX) {
+                                                       PAINTSTRUCT ps = { 0 };
+                                                       HDC hdc = reinterpret_cast<HDC>(wParam);
+                                                       if (!hdc) {
+                                                               hdc = BeginPaint(hWnd, &ps);
+                                                       }
+                                                       if (nButtonStyle == BS_GROUPBOX) {
+                                                               PaintGroupbox(hWnd, hdc, *data);
+                                                       } else {
+                                                               PaintButton(hWnd, hdc, *data);
+                                                       }
+                                                       if (ps.hdc) {
+                                                               EndPaint(hWnd, &ps);
+                                                       }
+                                                       return 0;
+                                               }
+                                       }
+                                       break;
+                               case WM_SIZE:
+                               case WM_DESTROY:
+                                       BufferedPaintStopAllAnimations(hWnd);
+                                       break;
+                       }
+                       return DefSubclassProc(hWnd, uMsg, wParam, lParam);
+                       }, 0, reinterpret_cast<DWORD_PTR>(new SubClassData{}));
+       }
+       SendMessageW(hwnd, WM_THEMECHANGED, 0, 0);
+}
+
+void SubclassListViewControl(HWND hListView)
+{
+       if (g_darkModeSupported && g_darkModeEnabled) {
+               HWND hHeader = ListView_GetHeader(hListView);
+
+               SetWindowSubclass(hListView, [](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR /*uIdSubclass*/, DWORD_PTR dwRefData) -> LRESULT {
+                       switch (uMsg)
+                       {
+                               case WM_NOTIFY:
+                               {
+                                       if (reinterpret_cast<LPNMHDR>(lParam)->code == NM_CUSTOMDRAW) {
+                                               LPNMCUSTOMDRAW nmcd = reinterpret_cast<LPNMCUSTOMDRAW>(lParam);
+                                               switch (nmcd->dwDrawStage)
+                                               {
+                                                       case CDDS_PREPAINT:
+                                                               return CDRF_NOTIFYITEMDRAW;
+                                                       case CDDS_ITEMPREPAINT:
+                                                       {
+                                                               auto info = reinterpret_cast<SubClassData*>(dwRefData);
+                                                               SetTextColor(nmcd->hdc, info->headerTextColor);
+                                                               return CDRF_DODEFAULT;
+                                                       }
+                                               }
+                                       }
+                               }
+                               break;
+                               case WM_THEMECHANGED:
+                               {
+                                       if (g_darkModeSupported) {
+                                               HWND hHeader = ListView_GetHeader(hWnd);
+
+                                               AllowDarkModeForWindow(hWnd, g_darkModeEnabled);
+                                               if (hHeader) {
+                                                       AllowDarkModeForWindow(hHeader, g_darkModeEnabled);
+                                               }
+
+                                               HTHEME hTheme = OpenThemeData(nullptr, L"ItemsView");
+                                               if (hTheme) {
+                                                       COLORREF color;
+                                                       if (SUCCEEDED(GetThemeColor(hTheme, 0, 0, TMT_TEXTCOLOR, &color)))
+                                                       {
+                                                               ListView_SetTextColor(hWnd, color);
+                                                       }
+                                                       if (SUCCEEDED(GetThemeColor(hTheme, 0, 0, TMT_FILLCOLOR, &color)))
+                                                       {
+                                                               ListView_SetTextBkColor(hWnd, color);
+                                                               ListView_SetBkColor(hWnd, color);
+                                                       }
+                                                       CloseThemeData(hTheme);
+                                               }
+
+                                               hTheme = OpenThemeData(hHeader, L"Header");
+                                               if (hTheme) {
+                                                       auto info = reinterpret_cast<SubClassData*>(dwRefData);
+                                                       GetThemeColor(hTheme, HP_HEADERITEM, 0, TMT_TEXTCOLOR, &(info->headerTextColor));
+                                                       CloseThemeData(hTheme);
+                                               }
+
+                                               if (hHeader != NULL) {
+                                                       SendMessageW(hHeader, WM_THEMECHANGED, wParam, lParam);
+                                               }
+
+                                               RedrawWindow(hWnd, nullptr, nullptr, RDW_FRAME | RDW_INVALIDATE);
+                                       }
+                               }
+                               break;
+                               case WM_DESTROY:
+                               {
+                                       auto data = reinterpret_cast<SubClassData*>(dwRefData);
+                                       delete data;
+                               }
+                               break;
+                       }
+                       return DefSubclassProc(hWnd, uMsg, wParam, lParam);
+                       }, 0, reinterpret_cast<DWORD_PTR>(new SubClassData{}));
+
+               ListView_SetExtendedListViewStyle(hListView, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_HEADERDRAGDROP);
+
+               // Hide focus dots
+               SendMessage(hListView, WM_CHANGEUISTATE, MAKELONG(UIS_SET, UISF_HIDEFOCUS), 0);
+
+               if (hHeader != NULL) {
+                       SetWindowTheme(hHeader, L"ItemsView", nullptr); // DarkMode
+               }
+               SetWindowTheme(hListView, L"ItemsView", nullptr); // DarkMode
+       }
+}
+
+void SubclassTreeViewControl(HWND hListView)
+{
+       if (g_darkModeSupported && g_darkModeEnabled) {
+               SetWindowSubclass(hListView, [](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR /*uIdSubclass*/, DWORD_PTR dwRefData) -> LRESULT {
+                       switch (uMsg)
+                       {
+                               case WM_NOTIFY:
+                               {
+                                       if (reinterpret_cast<LPNMHDR>(lParam)->code == NM_CUSTOMDRAW && 0)
+                                       {
+                                               LPNMCUSTOMDRAW nmcd = reinterpret_cast<LPNMCUSTOMDRAW>(lParam);
+                                               switch (nmcd->dwDrawStage)
+                                               {
+                                                       case CDDS_PREPAINT:
+                                                               return CDRF_NOTIFYITEMDRAW;
+                                                       case CDDS_ITEMPREPAINT:
+                                                       {
+                                                               auto info = reinterpret_cast<SubClassData*>(dwRefData);
+                                                               SetTextColor(nmcd->hdc, info->headerTextColor);
+                                                               return CDRF_DODEFAULT;
+                                                       }
+                                               }
+                                       }
+                               }
+                               break;
+                               case WM_THEMECHANGED:
+                               {
+                                       if (g_darkModeSupported) {
+                                               AllowDarkModeForWindow(hWnd, g_darkModeEnabled);
+
+                                               HTHEME hTheme = OpenThemeData(nullptr, L"ItemsView");
+                                               if (hTheme) {
+                                                       COLORREF color;
+                                                       if (SUCCEEDED(GetThemeColor(hTheme, 0, 0, TMT_TEXTCOLOR, &color))) {
+                                                               TreeView_SetTextColor(hWnd, color);
+                                                       }
+                                                       if (SUCCEEDED(GetThemeColor(hTheme, 0, 0, TMT_FILLCOLOR, &color))) {
+                                                               TreeView_SetBkColor(hWnd, color);
+                                                       }
+                                                       CloseThemeData(hTheme);
+                                               }
+
+                                               RedrawWindow(hWnd, nullptr, nullptr, RDW_FRAME | RDW_INVALIDATE);
+                                       }
+                               }
+                               break;
+                               case WM_DESTROY:
+                               {
+                                       auto data = reinterpret_cast<SubClassData*>(dwRefData);
+                                       delete data;
+                               }
+                               break;
+                       }
+                       return DefSubclassProc(hWnd, uMsg, wParam, lParam);
+                       }, 0, reinterpret_cast<DWORD_PTR>(new SubClassData{}));
+
+               SendMessageW(hListView, WM_THEMECHANGED, 0, 0);
+       }
+}
+
+
+void SubClassStatusBar(HWND hwnd)
+{
+       if (g_darkModeSupported && g_darkModeEnabled) {
+               SetWindowSubclass(hwnd, [](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR /*uIdSubclass*/, DWORD_PTR dwRefData) -> LRESULT {
+                       switch (uMsg)
+                       {
+                               case WM_ERASEBKGND:
+                               {
+                                       if (g_darkModeEnabled) {
+                                               HDC hdc = (HDC)wParam;
+                                               HBRUSH brush = CreateSolidBrush(dark_bg_color);
+                                               RECT rect;
+                                               GetClientRect(hWnd, &rect);
+                                               FillRect(hdc, &rect, brush);
+                                               DeleteObject(brush);
+                                               return TRUE;
+                                       } else {
+                                               break;
+                                       }
+                               }
+                       }
+                       return DefSubclassProc(hWnd, uMsg, wParam, lParam);
+                       }, 0, reinterpret_cast<DWORD_PTR>(new SubClassData{}));
+       }
+       SendMessageW(hwnd, WM_THEMECHANGED, 0, 0);
+}
diff --git a/od-win32/darkmode.h b/od-win32/darkmode.h
new file mode 100644 (file)
index 0000000..4ab5fd2
--- /dev/null
@@ -0,0 +1,87 @@
+#pragma once
+
+enum IMMERSIVE_HC_CACHE_MODE
+{
+       IHCM_USE_CACHED_VALUE,
+       IHCM_REFRESH
+};
+
+// 1903 18362
+enum PreferredAppMode
+{
+       Default,
+       AllowDark,
+       ForceDark,
+       ForceLight,
+       Max
+};
+
+enum WINDOWCOMPOSITIONATTRIB
+{
+       WCA_UNDEFINED = 0,
+       WCA_NCRENDERING_ENABLED = 1,
+       WCA_NCRENDERING_POLICY = 2,
+       WCA_TRANSITIONS_FORCEDISABLED = 3,
+       WCA_ALLOW_NCPAINT = 4,
+       WCA_CAPTION_BUTTON_BOUNDS = 5,
+       WCA_NONCLIENT_RTL_LAYOUT = 6,
+       WCA_FORCE_ICONIC_REPRESENTATION = 7,
+       WCA_EXTENDED_FRAME_BOUNDS = 8,
+       WCA_HAS_ICONIC_BITMAP = 9,
+       WCA_THEME_ATTRIBUTES = 10,
+       WCA_NCRENDERING_EXILED = 11,
+       WCA_NCADORNMENTINFO = 12,
+       WCA_EXCLUDED_FROM_LIVEPREVIEW = 13,
+       WCA_VIDEO_OVERLAY_ACTIVE = 14,
+       WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
+       WCA_DISALLOW_PEEK = 16,
+       WCA_CLOAK = 17,
+       WCA_CLOAKED = 18,
+       WCA_ACCENT_POLICY = 19,
+       WCA_FREEZE_REPRESENTATION = 20,
+       WCA_EVER_UNCLOAKED = 21,
+       WCA_VISUAL_OWNER = 22,
+       WCA_HOLOGRAPHIC = 23,
+       WCA_EXCLUDED_FROM_DDA = 24,
+       WCA_PASSIVEUPDATEMODE = 25,
+       WCA_USEDARKMODECOLORS = 26,
+       WCA_LAST = 27
+};
+
+struct WINDOWCOMPOSITIONATTRIBDATA
+{
+       WINDOWCOMPOSITIONATTRIB Attrib;
+       PVOID pvData;
+       SIZE_T cbData;
+};
+
+using fnRtlGetNtVersionNumbers = void (WINAPI *)(LPDWORD major, LPDWORD minor, LPDWORD build);
+using fnSetWindowCompositionAttribute = BOOL(WINAPI *)(HWND hWnd, WINDOWCOMPOSITIONATTRIBDATA *);
+// 1809 17763
+using fnShouldAppsUseDarkMode = bool (WINAPI *)(); // ordinal 132
+using fnAllowDarkModeForWindow = bool (WINAPI *)(HWND hWnd, bool allow); // ordinal 133
+using fnAllowDarkModeForApp = bool (WINAPI *)(bool allow); // ordinal 135, in 1809
+using fnFlushMenuThemes = void (WINAPI *)(); // ordinal 136
+using fnRefreshImmersiveColorPolicyState = void (WINAPI *)(); // ordinal 104
+using fnIsDarkModeAllowedForWindow = bool (WINAPI *)(HWND hWnd); // ordinal 137
+using fnGetIsImmersiveColorUsingHighContrast = bool (WINAPI *)(IMMERSIVE_HC_CACHE_MODE mode); // ordinal 106
+using fnOpenNcThemeData = HTHEME(WINAPI *)(HWND hWnd, LPCWSTR pszClassList); // ordinal 49
+// 1903 18362
+using fnShouldSystemUseDarkMode = bool (WINAPI *)(); // ordinal 138
+using fnSetPreferredAppMode = PreferredAppMode(WINAPI *)(PreferredAppMode appMode); // ordinal 135, in 1903
+using fnIsDarkModeAllowedForApp = bool (WINAPI *)(); // ordinal 139
+
+extern bool g_darkModeSupported;
+extern bool g_darkModeEnabled;
+extern int darkModeForced;
+extern COLORREF dark_text_color, dark_bg_color;;
+
+bool AllowDarkModeForWindow(HWND hWnd, bool allow);
+void InitDarkMode(int enable);
+void RefreshTitleBarThemeColor(HWND hWnd);
+extern fnAllowDarkModeForWindow _AllowDarkModeForWindow;
+void AllowDarkModeForApp(bool allow);
+void SubclassListViewControl(HWND hListView);
+void SubclassTreeViewControl(HWND hListView);
+void SubclassButtonControl(HWND hwnd);
+void SubClassStatusBar(HWND hwnd);
\ No newline at end of file
index df79991fa617c7b3387516a9a5d614d198ab12b8..225435a8907a07b32700ab90fcfbae73fa6ddd46 100644 (file)
 #define IDC_SER_CTSRTS                  1554
 #define IDC_GUI_FULLSCREEN              1554
 #define IDC_SER_DIRECT                  1555
+#define IDC_GUI_DARKMODE                1555
 #define IDC_PSPRINTER                   1556
 #define IDC_PSPRINTERDETECT             1557
 #define IDC_UAESERIAL                   1558
index 540266091092f1efb335d8c8cc7038762c52d5d9..9a4dbc0b9bcadfee8fad9d66436325ef66615d07 100644 (file)
@@ -219,12 +219,12 @@ BEGIN
     CONTROL         "Double, fields+",IDC_LM_IDOUBLED3,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,281,90,10
 END
 
-IDD_MEMORY DIALOGEX 0, 0, 396, 303
+IDD_MEMORY DIALOGEX 0, 0, 396, 304
 STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
 EXSTYLE WS_EX_CONTEXTHELP
 FONT 8, "MS Sans Serif", 0, 0, 0x1
 BEGIN
-    GROUPBOX        "Memory Settings",IDC_STATIC,1,26,393,117
+    GROUPBOX        "Memory Settings",IDC_STATIC,1,20,393,117
     RTEXT           "Chip:",IDC_STATIC,7,44,60,15,SS_CENTERIMAGE
     CONTROL         "Slider1",IDC_CHIPMEM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,68,41,60,20
     EDITTEXT        IDC_CHIPRAM,135,44,40,12,ES_CENTER | ES_READONLY
@@ -241,7 +241,7 @@ BEGIN
     CONTROL         "",IDC_Z3CHIPMEM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,248,90,60,20
     EDITTEXT        IDC_Z3CHIPRAM,311,95,40,12,ES_CENTER | ES_READONLY
     EDITTEXT        IDC_MAX32RAM,14,118,366,12,ES_CENTER | ES_READONLY
-    GROUPBOX        "Advanced Memory Settings",IDC_STATIC,1,134,393,161
+    GROUPBOX        "Advanced Memory Settings",IDC_STATIC,1,141,393,157
     COMBOBOX        IDC_MEMORYSELECT,14,170,228,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     CONTROL         "",IDC_MEMORYMEM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,253,164,68,20
     EDITTEXT        IDC_MEMORYRAM,328,167,40,12,ES_CENTER | ES_READONLY
@@ -620,22 +620,21 @@ STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
 FONT 8, "MS Sans Serif", 0, 0, 0x1
 BEGIN
     CONTROL         "",IDC_MISCLIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,3,5,258,232
-    GROUPBOX        "Miscellaneous Options",IDC_STATIC,266,2,128,123
+    GROUPBOX        "Miscellaneous Options",IDC_STATIC,266,2,128,111
     CTEXT           "SCSI and CD/DVD access:",IDC_STATIC,272,14,117,10,SS_CENTERIMAGE
     COMBOBOX        IDC_SCSIMODE,273,28,114,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     CTEXT           "Windowed style:",IDC_STATIC,272,45,117,10,SS_CENTERIMAGE
     COMBOBOX        IDC_WINDOWEDMODE,273,59,114,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
-    CTEXT           "Graphics API:",IDC_STATIC,272,76,117,10,SS_CENTERIMAGE
-    COMBOBOX        IDC_DXMODE,273,89,114,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
-    COMBOBOX        IDC_DXMODE_OPTIONS,273,107,114,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
-    GROUPBOX        "GUI",IDC_STATIC,266,125,128,112
-    COMBOBOX        IDC_LANGUAGE,273,138,114,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    PUSHBUTTON      "GUI Font...",IDC_GUI_FONT,272,155,54,14
-    PUSHBUTTON      "Set default",IDC_GUI_DEFAULT,272,174,54,14
-    COMBOBOX        IDC_GUI_SIZE,333,175,54,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    PUSHBUTTON      "Reset list customizations",IDC_GUI_LVDEFAULT,272,192,115,14
-    CONTROL         "Resizeable GUI",IDC_GUI_RESIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,273,209,114,11
-    CONTROL         "Fullscreen GUI",IDC_GUI_FULLSCREEN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,273,222,114,11
+    COMBOBOX        IDC_DXMODE,273,77,114,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_DXMODE_OPTIONS,273,95,114,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    GROUPBOX        "GUI",IDC_STATIC,266,117,128,121
+    COMBOBOX        IDC_LANGUAGE,273,129,114,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "GUI Font...",IDC_GUI_FONT,272,146,54,14
+    PUSHBUTTON      "Set default",IDC_GUI_DEFAULT,272,165,54,14
+    COMBOBOX        IDC_GUI_SIZE,333,166,54,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "Reset list customizations",IDC_GUI_LVDEFAULT,272,183,115,14
+    CONTROL         "Resizeable GUI",IDC_GUI_RESIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,273,199,114,11
+    CONTROL         "Fullscreen GUI",IDC_GUI_FULLSCREEN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,273,212,114,11
     GROUPBOX        "State Files",IDC_STATIC,1,242,393,38
     COMBOBOX        IDC_STATENAME,5,258,232,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
     CONTROL         "",IDC_STATECLEAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,244,261,9,10
@@ -646,6 +645,7 @@ BEGIN
     COMBOBOX        IDC_KBLED2,97,295,64,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     COMBOBOX        IDC_KBLED3,184,295,64,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     CONTROL         "USB mode",IDC_KBLED_USB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,264,296,64,11
+    CONTROL         "Dark mode",IDC_GUI_DARKMODE,"Button",BS_AUTO3STATE | WS_TABSTOP,273,224,114,11
 END
 
 IDD_HARDFILE DIALOGEX 0, 0, 397, 292
@@ -918,18 +918,18 @@ BEGIN
     COMBOBOX        IDC_INPUTAMIGA,33,248,286,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "Test [] Test input mappings.",IDC_INPUTTEST,324,248,34,14
     PUSHBUTTON      "Remap [] Find and remap quickly.",IDC_INPUTREMAP,361,248,34,14
-    RTEXT           "Joystick dead zone (%):",-1,5,271,106,10,SS_CENTERIMAGE
-    EDITTEXT        IDC_INPUTDEADZONE,116,270,29,12,ES_NUMBER
-    RTEXT           "Autofire rate (lines):",-1,5,288,106,10,SS_CENTERIMAGE
-    EDITTEXT        IDC_INPUTAUTOFIRERATE,116,286,29,12,ES_NUMBER
-    RTEXT           "Digital joy-mouse speed:",-1,147,271,108,10,SS_CENTERIMAGE
-    EDITTEXT        IDC_INPUTSPEEDD,260,270,29,12,ES_NUMBER
-    RTEXT           "Analog joy-mouse speed:",-1,147,288,108,10,SS_CENTERIMAGE
-    EDITTEXT        IDC_INPUTSPEEDA,260,287,29,12,ES_NUMBER
-    PUSHBUTTON      "Copy from:",IDC_INPUTCOPY,324,268,70,14
-    COMBOBOX        IDC_INPUTCOPYFROM,324,286,70,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
-    PUSHBUTTON      "Swap 1<>2",IDC_INPUTSWAP,324,303,70,14
-    CONTROL         "Swap Backslash/F11",IDC_KEYBOARD_SWAPHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,209,303,87,10
+    RTEXT           "Joystick dead zone (%):",-1,5,270,106,10,SS_CENTERIMAGE
+    EDITTEXT        IDC_INPUTDEADZONE,116,269,29,12,ES_NUMBER
+    RTEXT           "Autofire rate (lines):",-1,5,287,106,10,SS_CENTERIMAGE
+    EDITTEXT        IDC_INPUTAUTOFIRERATE,116,285,29,12,ES_NUMBER
+    RTEXT           "Digital joy-mouse speed:",-1,147,270,108,10,SS_CENTERIMAGE
+    EDITTEXT        IDC_INPUTSPEEDD,260,269,29,12,ES_NUMBER
+    RTEXT           "Analog joy-mouse speed:",-1,147,287,108,10,SS_CENTERIMAGE
+    EDITTEXT        IDC_INPUTSPEEDA,260,286,29,12,ES_NUMBER
+    PUSHBUTTON      "Copy from:",IDC_INPUTCOPY,324,267,70,14
+    COMBOBOX        IDC_INPUTCOPYFROM,324,285,70,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "Swap 1<>2",IDC_INPUTSWAP,324,302,70,14
+    CONTROL         "Swap Backslash/F11",IDC_KEYBOARD_SWAPHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,209,302,87,10
 END
 
 IDD_FILTER DIALOGEX 0, 0, 396, 316
@@ -1369,21 +1369,21 @@ IDD_EXPANSION2 DIALOGEX 0, 0, 396, 316
 STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
 FONT 8, "MS Sans Serif", 0, 0, 0x1
 BEGIN
-    GROUPBOX        "Expansion Board Settings",IDC_STATIC,1,42,394,88
-    COMBOBOX        IDC_SCSIROMSELECTCAT,12,59,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    COMBOBOX        IDC_SCSIROMSELECT,12,78,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    COMBOBOX        IDC_SCSIROMSUBSELECT,12,95,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    COMBOBOX        IDC_EXPANSIONBOARDITEMSELECTOR,12,112,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    COMBOBOX        IDC_SCSIROMSELECTNUM,175,78,22,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    CONTROL         "24-bit DMA",IDC_SCSIROM24BITDMA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,61,84,12
-    RTEXT           "Controller ID:",IDC_STATIC,281,59,70,15,SS_CENTERIMAGE
-    COMBOBOX        IDC_SCSIROMID,356,60,29,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    COMBOBOX        IDC_SCSIROMFILE,202,78,171,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    PUSHBUTTON      "...",IDC_SCSIROMCHOOSER,376,78,10,15
-    CONTROL         "Autoboot disabled",IDC_SCSIROMFILEAUTOBOOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,98,94,12
-    CONTROL         "PCMCIA inserted",IDC_SCSIROMFILEPCMCIA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,301,98,84,12
-    CONTROL         "",IDC_EXPANSIONBOARDCHECKBOX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,112,99,12
-    GROUPBOX        "Accelerator Board Settings",IDC_STATIC,1,133,394,91
+    GROUPBOX        "Expansion Board Settings",IDC_STATIC,1,27,394,104
+    COMBOBOX        IDC_SCSIROMSELECTCAT,12,43,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_SCSIROMSELECT,12,62,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_SCSIROMSUBSELECT,12,79,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_EXPANSIONBOARDITEMSELECTOR,12,104,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_SCSIROMSELECTNUM,175,62,22,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    CONTROL         "24-bit DMA",IDC_SCSIROM24BITDMA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,45,84,12
+    RTEXT           "Controller ID:",IDC_STATIC,281,43,70,15,SS_CENTERIMAGE
+    COMBOBOX        IDC_SCSIROMID,356,44,29,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_SCSIROMFILE,202,62,171,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "...",IDC_SCSIROMCHOOSER,376,62,10,15
+    CONTROL         "Autoboot disabled",IDC_SCSIROMFILEAUTOBOOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,82,94,12
+    CONTROL         "PCMCIA inserted",IDC_SCSIROMFILEPCMCIA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,301,82,84,12
+    CONTROL         "",IDC_EXPANSIONBOARDCHECKBOX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,104,99,12
+    GROUPBOX        "Accelerator Board Settings",IDC_STATIC,1,133,394,104
     COMBOBOX        IDC_CPUBOARD_TYPE,13,154,117,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     COMBOBOX        IDC_CPUBOARD_SUBTYPE,13,173,117,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     LTEXT           "Accelerator board ROM file:",IDC_STATIC,203,141,170,15,SS_CENTERIMAGE
@@ -1392,18 +1392,20 @@ BEGIN
     RTEXT           "Accelerator board memory:",IDC_STATIC,155,181,104,15,SS_CENTERIMAGE
     CONTROL         "",IDC_CPUBOARDMEM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,269,179,68,20
     EDITTEXT        IDC_CPUBOARDRAM,343,183,40,12,ES_CENTER | ES_READONLY
-    COMBOBOX        IDC_ACCELERATORBOARDITEMSELECTOR,12,205,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    COMBOBOX        IDC_ACCELERATORBOARDSELECTOR,202,205,171,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    GROUPBOX        "Miscellaneous Expansions",IDC_STATIC,1,228,394,51
+    COMBOBOX        IDC_ACCELERATORBOARDITEMSELECTOR,12,213,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_ACCELERATORBOARDSELECTOR,202,213,171,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    GROUPBOX        "Miscellaneous Expansions",IDC_STATIC,1,245,394,51
     CONTROL         "bsdsocket.library [] bsdsocket network library emulation.",IDC_SOCKETS,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,243,179,11
-    CONTROL         "uaescsi.device",IDC_SCSIDEVICE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,259,180,11
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,260,179,11
+    CONTROL         "uaescsi.device",IDC_SCSIDEVICE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,276,180,11
     CONTROL         "uaenet.device [] Sana 2 compatible network device emulation.",IDC_SANA2,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,193,243,187,11
-    EDITTEXT        IDC_EXPANSIONBOARDSTRINGBOX,202,112,172,14,ES_AUTOHSCROLL
-    COMBOBOX        IDC_EXPANSIONBOARDSELECTOR,202,112,171,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    CONTROL         "",IDC_ACCELERATORBOARDCHECKBOX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,206,99,12
-    CONTROL         "Enabled",IDC_SCSIROMSELECTED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,79,99,12
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,193,260,187,11
+    EDITTEXT        IDC_EXPANSIONBOARDSTRINGBOX,202,104,172,14,ES_AUTOHSCROLL
+    COMBOBOX        IDC_EXPANSIONBOARDSELECTOR,202,104,171,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    CONTROL         "",IDC_ACCELERATORBOARDCHECKBOX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,214,99,12
+    CONTROL         "Enabled",IDC_SCSIROMSELECTED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,63,99,12
+    GROUPBOX        "",IDC_STATIC,6,94,384,30,0,WS_EX_TRANSPARENT
+    GROUPBOX        "",IDC_STATIC,5,202,384,30,0,WS_EX_TRANSPARENT
 END
 
 IDD_CHSQUERY DIALOGEX 0, 0, 396, 85
@@ -1596,7 +1598,6 @@ BEGIN
 
     IDD_MEMORY, DIALOG
     BEGIN
-        BOTTOMMARGIN, 289
     END
 
     IDD_CPU, DIALOG
@@ -1725,7 +1726,7 @@ BEGIN
 
     IDD_EXPANSION, DIALOG
     BEGIN
-        BOTTOMMARGIN, 198
+        BOTTOMMARGIN, 246
     END
 
     IDD_INPUTMAP, DIALOG
index 0e306c1c2c55fffcd767753290de8ba73b625b5c..63dcafaa57a746202f9c8ae163879985f1c2b16a 100644 (file)
@@ -41,6 +41,7 @@
 #include <Cfgmgr32.h>
 #include <shellscalingapi.h>
 #include <dinput.h>
+#include <dwmapi.h>
 
 #include "resource.h"
 
 #include "debug.h"
 #include "disasm.h"
 
+#include "darkmode.h"
+
 const static GUID GUID_DEVINTERFACE_HID =  { 0x4D1E55B2L, 0xF16F, 0x11CF,
 { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
 const static GUID GUID_DEVINTERFACE_KEYBOARD = { 0x884b96c3, 0x56ef, 0x11d1,
@@ -2888,7 +2891,7 @@ static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam,
                                FillRect(lpDIS->hDC, &lpDIS->rcItem, mon->hStatusBkgB);
                                if (txt) {
                                        SetBkMode(lpDIS->hDC, TRANSPARENT);
-                                       oc = SetTextColor(lpDIS->hDC, RGB(0x00, 0x00, 0x00));
+                                       oc = SetTextColor(lpDIS->hDC, g_darkModeEnabled ? dark_text_color : RGB(0x00, 0x00, 0x00));
                                        DrawText(lpDIS->hDC, txt, uaetcslen(txt), &lpDIS->rcItem, flags);
                                        SetTextColor(lpDIS->hDC, oc);
                                }
@@ -2961,7 +2964,13 @@ static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam,
                                } else if (tflags & 8) {
                                        oc = SetTextColor (lpDIS->hDC, RGB(0x00, 0xcc, 0x00)); // playing
                                } else {
-                                       oc = SetTextColor (lpDIS->hDC, GetSysColor ((tflags & 2) ? COLOR_BTNTEXT : COLOR_GRAYTEXT));
+                                       COLORREF c;
+                                       if (g_darkModeEnabled) {
+                                               c = (tflags & 2) ? dark_text_color : (dark_text_color & 0xfefefe) >> 1;
+                                       } else {
+                                               c = GetSysColor((tflags & 2) ? COLOR_BTNTEXT : COLOR_GRAYTEXT);
+                                       }
+                                       oc = SetTextColor (lpDIS->hDC, c);
                                }
                                if (tflags & 32) {
                                        ;
@@ -5969,17 +5978,7 @@ static int osdetect (void)
                }
        }
 
-       typedef HRESULT(CALLBACK* DWMISCOMPOSITIONENABLED)(BOOL*);
-       HMODULE dwmapihandle;
-       DWMISCOMPOSITIONENABLED pDwmIsCompositionEnabled;
-       dwmapihandle = LoadLibrary(_T("dwmapi.dll"));
-       if (dwmapihandle) {
-               pDwmIsCompositionEnabled = (DWMISCOMPOSITIONENABLED)GetProcAddress(dwmapihandle, "DwmIsCompositionEnabled");
-               if (pDwmIsCompositionEnabled) {
-                       pDwmIsCompositionEnabled(&os_dwm_enabled);
-               }
-               FreeLibrary(dwmapihandle);
-       }
+       DwmIsCompositionEnabled(&os_dwm_enabled);
 
        return 1;
 }
@@ -6910,6 +6909,14 @@ static int parseargs(const TCHAR *argx, const TCHAR *np, const TCHAR *np2)
                }
                return 2;
        }
+       if (!_tcscmp(arg, _T("theme"))) {
+               if (!_tcsicmp(np, _T("dark"))) {
+                       darkModeForced = 1;
+               } else if (!_tcsicmp(np, _T("light"))) {
+                       darkModeForced = -1;
+               }
+               return 2;
+       }
 
 #endif
        return 0;
@@ -8028,6 +8035,23 @@ bool is_mainthread(void)
        return GetCurrentThreadId() == mainthreadid;
 }
 
+void InitializeDarkMode(int v)
+{
+       static int initialized = -10;
+       if (darkModeForced) {
+               v = 1;
+       }
+       if (initialized != v) {
+               InitDarkMode(v);
+               write_log("dark mode supported: %d enabled: %d\n", g_darkModeSupported, g_darkModeEnabled);
+               initialized = v;
+       }
+       if (initialized && g_darkModeEnabled && !v) {
+               InitDarkMode(0);
+               initialized = 0;
+       }
+}
+
 typedef BOOL (CALLBACK* CHANGEWINDOWMESSAGEFILTER)(UINT, DWORD);
 typedef DPI_AWARENESS_CONTEXT (CALLBACK* GETTHREADDPIAWARENESSCONTEXT)(void);
 typedef DPI_AWARENESS (CALLBACK* GETAWARENESSFROMDPIAWARENESSCONTEXT)(DPI_AWARENESS_CONTEXT);
index 3c1822b1184a70e3510fdf38186b92054afe7bbf..bc7c77adaf4203875647459d34e324d3623ccc83 100644 (file)
@@ -75,6 +75,7 @@ extern void updatemouseclip(struct AmigaMonitor*);
 extern void updatewinrect(struct AmigaMonitor*, bool);
 int getdpiformonitor(HMONITOR mon);
 int getdpiforwindow(HWND hwnd);
+void InitializeDarkMode(int v);
 
 extern bool resumepaused (int priority);
 extern bool setpaused (int priority);
index b2c6ff5b39a955a33688be1251be12ce3b46662c..80b4e18eb4149ec90a8d9b7688cdf43573fa6937 100644 (file)
@@ -63,6 +63,8 @@
 #include "statusline.h"
 #include "devices.h"
 
+#include "darkmode.h"
+
 #define DM_DX_FULLSCREEN 1
 #define DM_W_FULLSCREEN 2
 #define DM_D3D_FULLSCREEN 16
@@ -2306,6 +2308,8 @@ int check_prefs_changed_gfx(void)
                                c = 1024;
                        } else if (display_change_requested == 2) {
                                c = 512;
+                       } else if (display_change_requested == 4) {
+                               c = 32;
                        } else {
                                c = 2;
                                keepfsmode = 0;
@@ -3209,6 +3213,13 @@ static void createstatuswindow(struct AmigaMonitor *mon)
                0, 0, 0, 0, mon->hMainWnd, (HMENU) 1, hInst, NULL);
        if (!mon->hStatusWnd)
                return;
+       if (g_darkModeSupported) {
+               BOOL value = g_darkModeEnabled;
+               DwmSetWindowAttribute(mon->hStatusWnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
+               if (g_darkModeEnabled) {
+                       SubClassStatusBar(mon->hStatusWnd);
+               }
+       }
        wi.cbSize = sizeof wi;
        GetWindowInfo(mon->hMainWnd, &wi);
        extra = wi.rcClient.top - wi.rcWindow.top;
@@ -3234,7 +3245,7 @@ static void createstatuswindow(struct AmigaMonitor *mon)
                if (lpParts) {
                        int i = 0, i1;
                        // left side, msg area
-                       lpParts[i] = rc.left + 2;
+                       lpParts[i] = rc.left;
                        i++;
                        window_led_msg_start = i;
                        /* Calculate the right edge coordinate for each part, and copy the coords to the array.  */
@@ -3569,6 +3580,7 @@ static int create_windows(struct AmigaMonitor *mon)
                        else
                                ny = rc.top + (rc.bottom - rc.top - nh);
                }
+
                if (w != nw || h != nh || x != nx || y != ny || sbheight != mon->window_extra_height_bar || dpi != mon->dpi) {
                        w = nw;
                        h = nh;
@@ -3731,6 +3743,10 @@ static int create_windows(struct AmigaMonitor *mon)
                                }
                                break;
                        }
+                       if (g_darkModeSupported) {
+                               BOOL value = g_darkModeEnabled;
+                               DwmSetWindowAttribute(mon->hMainWnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
+                       }
                        GetWindowRect(mon->hMainWnd, &rc2);
                        mon->window_extra_width = rc2.right - rc2.left - mon->currentmode.current_width;
                        mon->window_extra_height = rc2.bottom - rc2.top - mon->currentmode.current_height;
@@ -3781,6 +3797,10 @@ static int create_windows(struct AmigaMonitor *mon)
                close_hwnds(mon);
                return 0;
        }
+       if (g_darkModeSupported) {
+               BOOL value = g_darkModeEnabled;
+               DwmSetWindowAttribute(mon->hAmigaWnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
+       }
        if (mon->hMainWnd == NULL) {
                mon->hMainWnd = mon->hAmigaWnd;
                registertouch(mon->hAmigaWnd);
index 25cf8b4e4210b56ff6e6eb3d45c9d6f6127e1bd9..71cdb140cf0f63eab8d2aed71aec6e94e5b137fb 100644 (file)
@@ -30,6 +30,7 @@
 #include <shobjidl.h>
 #include <dbt.h>
 #include <Cfgmgr32.h>
+#include <dwmapi.h>
 
 #include "resource.h"
 #include "sysconfig.h"
 #include "floppybridge/floppybridge_lib.h"
 #endif
 
+#include <Vssym32.h>
+#include "darkmode.h"
+
 #define GUI_SCALE_DEFAULT 100
 
 
@@ -138,6 +142,41 @@ int dialog_inhibit;
 static HMODULE hHtmlHelp;
 pathtype path_type;
 
+static void darkmode_initdialog(HWND hDlg)
+{
+       if (g_darkModeSupported)
+       {
+               SendMessageW(hDlg, WM_THEMECHANGED, 0, 0);
+       }
+}
+static void darkmode_themechanged(HWND hDlg)
+{
+       if (g_darkModeSupported)
+       {
+               RefreshTitleBarThemeColor(hDlg);
+               UpdateWindow(hDlg);
+       }
+}
+static INT_PTR darkmode_ctlcolor(WPARAM wParam, bool *handled)
+{
+       constexpr COLORREF darkBkColor = 0x383838;
+       constexpr COLORREF darkTextColor = 0xFFFFFF;
+       static HBRUSH hbrBkgnd = nullptr;
+
+       if (g_darkModeSupported && g_darkModeEnabled)
+       {
+               HDC hdc = reinterpret_cast<HDC>(wParam);
+               SetTextColor(hdc, darkTextColor);
+               SetBkColor(hdc, darkBkColor);
+               if (!hbrBkgnd)
+                       hbrBkgnd = CreateSolidBrush(darkBkColor);
+               *handled = true;
+               return reinterpret_cast<INT_PTR>(hbrBkgnd);
+       }
+       *handled = false;
+       return 0;
+}
+
 void HtmlHelp(const TCHAR *panel)
 {
        TCHAR help_file[MAX_DPATH];
@@ -400,12 +439,36 @@ static int gui_get_string_cursor(int *table, HWND hDlg, int item)
        return table[posn];
 }
 
-static void commonproc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+static INT_PTR commonproc2(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam, bool *handled)
 {
+       if (msg == WM_INITDIALOG) {
+               darkmode_initdialog(hDlg);
+       } else if (msg == WM_CTLCOLORDLG || msg == WM_CTLCOLORSTATIC) {
+               INT_PTR v = darkmode_ctlcolor(wParam, handled);
+               if (*handled) {
+                       return v;
+               }
+       } else if (msg == WM_THEMECHANGED) {
+               darkmode_themechanged(hDlg);
+       }
+       *handled = false;
+       return 0;
+}
+
+static INT_PTR commonproc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam, bool *handled)
+{
+       *handled = false;
        if (msg == WM_DPICHANGED) {
                RECT *const r = (RECT *)lParam;
                SetWindowPos(hDlg, NULL, r->left, r->top, r->right - r->left, r->bottom - r->top, SWP_NOZORDER | SWP_NOACTIVATE);
+               *handled = true;
+       } else {
+               INT_PTR v = commonproc2(hDlg, msg, wParam, lParam, handled);
+               if (*handled) {
+                       return v;
+               }
        }
+       return 0;
 }
 
 static int stringboxdialogactive;
@@ -414,6 +477,12 @@ static INT_PTR CALLBACK StringBoxDialogProc (HWND hDlg, UINT msg, WPARAM wParam,
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR v = commonproc(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return v;
+       }
+
        switch(msg)
        {
        case WM_DESTROY:
@@ -439,7 +508,6 @@ static INT_PTR CALLBACK StringBoxDialogProc (HWND hDlg, UINT msg, WPARAM wParam,
                }
                break;
        }
-       commonproc(hDlg, msg, wParam, lParam);
        return FALSE;
 }
 
@@ -1749,6 +1817,12 @@ static INT_PTR CALLBACK InfoBoxDialogProc (HWND hDlg, UINT msg, WPARAM wParam, L
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR v = commonproc(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return v;
+       }
+
        switch(msg)
        {
        case WM_DESTROY:
@@ -1769,7 +1843,6 @@ static INT_PTR CALLBACK InfoBoxDialogProc (HWND hDlg, UINT msg, WPARAM wParam, L
                }
                break;
        }
-       commonproc(hDlg, msg, wParam, lParam);
        return FALSE;
 }
 static bool scan_rom_hook (const TCHAR *name, int line)
@@ -2279,7 +2352,7 @@ int target_cfgfile_load (struct uae_prefs *p, const TCHAR *filename, int type, i
 }
 
 static int gui_width, gui_height;
-int gui_fullscreen;
+int gui_fullscreen, gui_darkmode;
 static RECT gui_fullscreen_rect;
 static bool gui_resize_enabled = true;
 static bool gui_resize_allowed = true;
@@ -5071,6 +5144,7 @@ static void InitializeListView (HWND hDlg)
        }
 
        list = GetDlgItem(hDlg, listview_id);
+       SubclassListViewControl(list);
        listview_type = lv_type;
        listview_columns = listview_num_columns;
 
@@ -5728,6 +5802,12 @@ static INT_PTR CALLBACK InfoSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LP
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR v = commonproc(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return v;
+       }
+
        switch (msg)
        {
        case WM_INITDIALOG:
@@ -5815,7 +5895,6 @@ static INT_PTR CALLBACK InfoSettingsProc (HWND hDlg, UINT msg, WPARAM wParam, LP
                recursive--;
                break;
        }
-       commonproc(hDlg, msg, wParam, lParam);
        return FALSE;
 }
 
@@ -6055,6 +6134,7 @@ static HTREEITEM InitializeConfigTreeView (HWND hDlg)
 {
        HIMAGELIST himl = ImageList_Create (16, 16, ILC_COLOR8 | ILC_MASK, 3, 0);
        HWND TVhDlg = GetDlgItem(hDlg, IDC_CONFIGTREE);
+       SubclassTreeViewControl(TVhDlg);
        HTREEITEM parent;
        TCHAR path[MAX_DPATH];
 
@@ -6267,7 +6347,7 @@ static void loadsavecommands (HWND hDlg, WPARAM wParam, struct ConfigStruct **co
                break;
        case IDC_SETINFO:
                InfoSettingsProcConfig = config;
-               if (CustomDialogBox(IDD_SETINFO, hDlg, InfoSettingsProc))
+               if (CustomCreateDialog(IDD_SETINFO, hDlg, InfoSettingsProc))
                        EnableWindow( GetDlgItem( hDlg, IDC_VIEWINFO ), workprefs.info[0] );
                break;
        }
@@ -6283,6 +6363,12 @@ static INT_PTR CALLBACK LoadSaveDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg)
        {
        case WM_INITDIALOG:
@@ -6414,6 +6500,12 @@ static INT_PTR CALLBACK ErrorLogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR v = commonproc(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return v;
+       }
+
        switch (msg) {
        case WM_COMMAND:
                if (wParam == IDOK) {
@@ -6438,7 +6530,6 @@ static INT_PTR CALLBACK ErrorLogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
                xSendDlgItemMessage (hDlg, IDC_ERRORLOGMESSAGE, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) & CharFormat);
                return TRUE;
        }
-       commonproc(hDlg, msg, wParam, lParam);
        return FALSE;
 }
 
@@ -6453,6 +6544,12 @@ static INT_PTR CALLBACK ContributorsProc (HWND hDlg, UINT msg, WPARAM wParam, LP
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR v = commonproc(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return v;
+       }
+
        switch (msg) {
        case WM_COMMAND:
                if (wParam == ID_OK) {
@@ -6476,13 +6573,12 @@ static INT_PTR CALLBACK ContributorsProc (HWND hDlg, UINT msg, WPARAM wParam, LP
                xSendDlgItemMessage (hDlg, IDC_CONTRIBUTORS, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) & CharFormat);
                return TRUE;
        }
-       commonproc(hDlg, msg, wParam, lParam);
        return FALSE;
 }
 
 static void DisplayContributors (HWND hDlg)
 {
-       CustomDialogBox (IDD_CONTRIBUTORS, hDlg, ContributorsProc);
+       CustomCreateDialog(IDD_CONTRIBUTORS, hDlg, ContributorsProc);
 }
 
 typedef struct url_info
@@ -6859,6 +6955,12 @@ static INT_PTR CALLBACK PathsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg)
        {
        case WM_INITDIALOG:
@@ -7699,6 +7801,12 @@ static INT_PTR CALLBACK QuickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, L
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch(msg)
        {
        case WM_INITDIALOG:
@@ -7953,6 +8061,12 @@ static INT_PTR CALLBACK AboutDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch( msg )
        {
        case WM_INITDIALOG:
@@ -8978,6 +9092,12 @@ static INT_PTR CALLBACK DisplayDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPAR
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg)
        {
        case WM_INITDIALOG:
@@ -9228,6 +9348,12 @@ static INT_PTR CALLBACK ChipsetDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPAR
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg) {
        case WM_INITDIALOG:
        {
@@ -9641,6 +9767,12 @@ static INT_PTR CALLBACK ChipsetDlgProc2 (HWND hDlg, UINT msg, WPARAM wParam, LPA
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg) {
        case WM_INITDIALOG:
        {
@@ -11166,6 +11298,12 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg)
        {
                case WM_INITDIALOG:
@@ -11558,6 +11696,12 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg)
        {
        case WM_INITDIALOG:
@@ -11861,6 +12005,12 @@ static INT_PTR CALLBACK BoardsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg)
        {
                case WM_INITDIALOG:
@@ -11868,7 +12018,9 @@ static INT_PTR CALLBACK BoardsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM
                pages[BOARD_ID] = hDlg;
                currentpage = BOARD_ID;
                setchecked(hDlg, IDC_AUTOCONFIGCUSTOMSORT, workprefs.autoconfig_custom_sort);
-               ew(hDlg, IDC_BOARDLIST, workprefs.autoconfig_custom_sort != 0 && full_property_sheet);
+               if (!g_darkModeEnabled) { // dark mode makes disabled list bright..
+                       ew(hDlg, IDC_BOARDLIST, workprefs.autoconfig_custom_sort != 0 && full_property_sheet);
+               }
                ew(hDlg, IDC_BOARDS_UP, FALSE);
                ew(hDlg, IDC_BOARDS_DOWN, FALSE);
                ew(hDlg, IDC_AUTOCONFIGCUSTOMSORT, full_property_sheet);
@@ -11884,7 +12036,9 @@ static INT_PTR CALLBACK BoardsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM
                                case IDC_AUTOCONFIGCUSTOMSORT:
                                workprefs.autoconfig_custom_sort = ischecked(hDlg, IDC_AUTOCONFIGCUSTOMSORT);
                                expansion_set_autoconfig_sort(&workprefs);
-                               ew(hDlg, IDC_BOARDLIST, workprefs.autoconfig_custom_sort != 0);
+                               if (!g_darkModeEnabled) { // dark mode makes disabled list bright..
+                                       ew(hDlg, IDC_BOARDLIST, workprefs.autoconfig_custom_sort != 0);
+                               }
                                InitializeListView(hDlg);
                                break;
                                case IDC_BOARDS_UP:
@@ -11998,6 +12152,12 @@ static INT_PTR CALLBACK MemoryDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg)
        {
        case WM_INITDIALOG:
@@ -12403,6 +12563,12 @@ static INT_PTR CALLBACK KickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg)
        {
        case WM_INITDIALOG:
@@ -12739,13 +12905,24 @@ static void values_to_miscdlg (HWND hDlg)
 
        if (currentpage == MISC1_ID) {
 
-               misc_kbled (hDlg, IDC_KBLED1, workprefs.keyboard_leds[0]);
-               misc_kbled (hDlg, IDC_KBLED2, workprefs.keyboard_leds[1]);
-               misc_kbled (hDlg, IDC_KBLED3, workprefs.keyboard_leds[2]);
-               CheckDlgButton (hDlg, IDC_KBLED_USB, workprefs.win32_kbledmode);
-               CheckDlgButton (hDlg, IDC_GUI_RESIZE, gui_resize_enabled);
-               CheckDlgButton (hDlg, IDC_GUI_FULLSCREEN, gui_fullscreen > 0);
-               ew (hDlg, IDC_GUI_RESIZE, gui_resize_allowed);
+               misc_kbled(hDlg, IDC_KBLED1, workprefs.keyboard_leds[0]);
+               misc_kbled(hDlg, IDC_KBLED2, workprefs.keyboard_leds[1]);
+               misc_kbled(hDlg, IDC_KBLED3, workprefs.keyboard_leds[2]);
+               CheckDlgButton(hDlg, IDC_KBLED_USB, workprefs.win32_kbledmode);
+               CheckDlgButton(hDlg, IDC_GUI_RESIZE, gui_resize_enabled);
+               CheckDlgButton(hDlg, IDC_GUI_FULLSCREEN, gui_fullscreen > 0);
+               ew(hDlg, IDC_GUI_DARKMODE, os_win10 && !rp_isactive() && !darkModeForced);
+               if (!os_win10) {
+                       gui_darkmode = 0;
+               }
+               if (darkModeForced > 0 || gui_darkmode > 0) {
+                       CheckDlgButton(hDlg, IDC_GUI_DARKMODE, 1);
+               } else if (darkModeForced < 0 || gui_darkmode == 0) {
+                       CheckDlgButton(hDlg, IDC_GUI_DARKMODE, 0);
+               } else {
+                       CheckDlgButton(hDlg, IDC_GUI_DARKMODE, BST_INDETERMINATE);
+               }
+               ew(hDlg, IDC_GUI_RESIZE, gui_resize_allowed);
 
                misc_scsi (hDlg);
                misc_lang (hDlg);
@@ -12880,6 +13057,12 @@ static INT_PTR MiscDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
        static int recursive;
        TCHAR tmp[MAX_DPATH];
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        if (recursive)
                return FALSE;
        recursive++;
@@ -13088,13 +13271,32 @@ static INT_PTR MiscDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
                        gui_size_changed = 10;
                break;
                case IDC_GUI_FULLSCREEN:
-                       gui_fullscreen = ischecked (hDlg, IDC_GUI_FULLSCREEN);
+                       gui_fullscreen = ischecked(hDlg, IDC_GUI_FULLSCREEN);
                        if (!gui_fullscreen) {
                                gui_fullscreen = -1;
                                getstoredguisize();
                        }
                        gui_size_changed = 10;
-               break;
+                       break;
+               case IDC_GUI_DARKMODE:
+                       {
+                               int v = IsDlgButtonChecked(hDlg, IDC_GUI_DARKMODE);
+                               if (!rp_isactive() && !darkModeForced) {
+                                       if (v == BST_INDETERMINATE) {
+                                               gui_darkmode = -1;
+                                       } else if (v) {
+                                               gui_darkmode = 1;
+                                       } else {
+                                               gui_darkmode = 0;
+                                       }
+                                       regsetint(NULL, _T("GUIDarkMode"), gui_darkmode);
+                                       gui_size_changed = 10;
+                                       if (!full_property_sheet) {
+                                               WIN32GFX_DisplayChangeRequested(4);
+                                       }
+                               }
+                       }
+                       break;
                case IDC_ASSOCIATE_ON:
                        for (i = 0; exts[i].ext; i++)
                                exts[i].enabled = 1;
@@ -13121,10 +13323,11 @@ static INT_PTR MiscDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
                        setstatefilename (hDlg);
                        break;
                case IDC_DOLOADSTATE:
-                       if (DiskSelection(hDlg, wParam, 10, &workprefs, NULL, NULL))
+                       if (DiskSelection(hDlg, wParam, 10, &workprefs, NULL, NULL)) {
                                savestate_state = STATE_DORESTORE;
-                       _tcscpy (workprefs.statefile, savestate_fname);
-                       setstatefilename (hDlg);
+                               _tcscpy (workprefs.statefile, savestate_fname);
+                               setstatefilename (hDlg);
+                       }
                        break;
                case IDC_INACTIVE_NOJOY:
                        if (!ischecked(hDlg, IDC_INACTIVE_NOJOY))
@@ -13565,6 +13768,12 @@ static INT_PTR CALLBACK CPUDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg) {
        case WM_INITDIALOG:
                recursive++;
@@ -14100,6 +14309,12 @@ static INT_PTR CALLBACK SoundDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg) {
        case WM_INITDIALOG:
                {
@@ -14365,6 +14580,12 @@ static INT_PTR CALLBACK VolumeSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR v = commonproc(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return v;
+       }
+
        switch (msg) {
        case WM_INITDIALOG:
                {
@@ -14469,7 +14690,6 @@ static INT_PTR CALLBACK VolumeSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
                recursive--;
                break;
        }
-       commonproc(hDlg, msg, wParam, lParam);
        return FALSE;
 }
 
@@ -14959,6 +15179,12 @@ static INT_PTR CALLBACK TapeDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR v = commonproc(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return v;
+       }
+
        switch (msg) {
 
        case WM_INITDIALOG:
@@ -15057,7 +15283,6 @@ static INT_PTR CALLBACK TapeDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                recursive--;
                break;
        }
-       commonproc(hDlg, msg, wParam, lParam);
        return FALSE;
 }
 
@@ -15069,6 +15294,12 @@ static INT_PTR CALLBACK CDDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR v = commonproc(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return v;
+       }
+
        switch (msg) {
 
        case WM_INITDIALOG:
@@ -15122,7 +15353,6 @@ static INT_PTR CALLBACK CDDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
                recursive--;
                break;
        }
-       commonproc(hDlg, msg, wParam, lParam);
        return FALSE;
 }
 
@@ -15167,6 +15397,12 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg) {
        case WM_DROPFILES:
                dragdrop (hDlg, (HDROP)wParam, &changed_prefs, -2);
@@ -15433,7 +15669,6 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam
 
                break;
        }
-       commonproc(hDlg, msg, wParam, lParam);
        return FALSE;
 }
 
@@ -15449,6 +15684,12 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg) {
        case WM_INITDIALOG:
                {
@@ -15675,7 +15916,6 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                recursive--;
                break;
        }
-       commonproc(hDlg, msg, wParam, lParam);
        return FALSE;
 }
 
@@ -15781,12 +16021,12 @@ static void harddisk_edit (HWND hDlg)
 
        if (uci->ci.type == UAEDEV_CD) {
                memcpy (&current_cddlg.ci, uci, sizeof (struct uaedev_config_info));
-               if (CustomDialogBox (IDD_CDDRIVE, hDlg, CDDriveSettingsProc)) {
+               if (CustomCreateDialog(IDD_CDDRIVE, hDlg, CDDriveSettingsProc)) {
                        new_cddrive (hDlg, entry);
                }
        } else if (uci->ci.type == UAEDEV_TAPE) {
                memcpy (&current_tapedlg.ci, uci, sizeof (struct uaedev_config_info));
-               if (CustomDialogBox (IDD_TAPEDRIVE, hDlg, TapeDriveSettingsProc)) {
+               if (CustomCreateDialog(IDD_TAPEDRIVE, hDlg, TapeDriveSettingsProc)) {
                        new_tapedrive (hDlg, entry);
                }
        }
@@ -15794,14 +16034,14 @@ static void harddisk_edit (HWND hDlg)
        {
                current_hfdlg.forcedcylinders = uci->ci.highcyl;
                memcpy (&current_hfdlg.ci, uci, sizeof (struct uaedev_config_info));
-               if (CustomDialogBox (IDD_HARDFILE, hDlg, HardfileSettingsProc)) {
+               if (CustomCreateDialog(IDD_HARDFILE, hDlg, HardfileSettingsProc)) {
                        new_hardfile (hDlg, entry);
                }
        }
        else if (type == FILESYS_HARDDRIVE) /* harddisk */
        {
                memcpy (&current_hfdlg.ci, uci, sizeof (struct uaedev_config_info));
-               if (CustomDialogBox (IDD_HARDDRIVE, hDlg, HarddriveSettingsProc)) {
+               if (CustomCreateDialog(IDD_HARDDRIVE, hDlg, HarddriveSettingsProc)) {
                        new_harddrive (hDlg, entry);
                }
        }
@@ -15809,7 +16049,7 @@ static void harddisk_edit (HWND hDlg)
        {
                memcpy (&current_fsvdlg.ci, uci, sizeof (struct uaedev_config_info));
                archivehd = -1;
-               if (CustomDialogBox (IDD_FILESYS, hDlg, VolumeSettingsProc)) {
+               if (CustomCreateDialog(IDD_FILESYS, hDlg, VolumeSettingsProc)) {
                        new_filesys (hDlg, entry);
                }
        }
@@ -15860,30 +16100,30 @@ static int harddiskdlg_button (HWND hDlg, WPARAM wParam)
        case IDC_NEW_FS:
                default_fsvdlg (&current_fsvdlg);
                archivehd = 0;
-               if (CustomDialogBox (IDD_FILESYS, hDlg, VolumeSettingsProc))
+               if (CustomCreateDialog(IDD_FILESYS, hDlg, VolumeSettingsProc))
                        new_filesys (hDlg, -1);
                return 1;
        case IDC_NEW_FSARCH:
                archivehd = 1;
                default_fsvdlg (&current_fsvdlg);
-               if (CustomDialogBox (IDD_FILESYS, hDlg, VolumeSettingsProc))
+               if (CustomCreateDialog(IDD_FILESYS, hDlg, VolumeSettingsProc))
                        new_filesys (hDlg, -1);
                return 1;
 
        case IDC_NEW_HF:
                default_hfdlg (&current_hfdlg, false);
-               if (CustomDialogBox (IDD_HARDFILE, hDlg, HardfileSettingsProc))
+               if (CustomCreateDialog(IDD_HARDFILE, hDlg, HardfileSettingsProc))
                        new_hardfile (hDlg, -1);
                return 1;
 
        case IDC_NEW_CD:
-               if (CustomDialogBox (IDD_CDDRIVE, hDlg, CDDriveSettingsProc))
+               if (CustomCreateDialog(IDD_CDDRIVE, hDlg, CDDriveSettingsProc))
                        new_cddrive (hDlg, -1);
                return 1;
 
        case IDC_NEW_TAPE:
                default_tapedlg (&current_tapedlg);
-               if (CustomDialogBox (IDD_TAPEDRIVE, hDlg, TapeDriveSettingsProc))
+               if (CustomCreateDialog(IDD_TAPEDRIVE, hDlg, TapeDriveSettingsProc))
                        new_tapedrive (hDlg, -1);
                return 1;
 
@@ -15895,7 +16135,7 @@ static int harddiskdlg_button (HWND hDlg, WPARAM wParam)
                        WIN32GUI_LoadUIString (IDS_NOHARDDRIVES, tmp, sizeof (tmp) / sizeof (TCHAR));
                        gui_message (tmp);
                } else {
-                       if (CustomDialogBox (IDD_HARDDRIVE, hDlg, HarddriveSettingsProc))
+                       if (CustomCreateDialog(IDD_HARDDRIVE, hDlg, HarddriveSettingsProc))
                                new_harddrive (hDlg, -1);
                }
                return 1;
@@ -15994,6 +16234,12 @@ static INT_PTR CALLBACK HarddiskDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg) {
        case WM_INITDIALOG:
                clicked_entry = 0;
@@ -16759,6 +17005,12 @@ static INT_PTR CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg)
        {
        case WM_INITDIALOG:
@@ -17091,6 +17343,12 @@ static INT_PTR CALLBACK SwapperDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPAR
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg)
        {
        case WM_INITDIALOG:
@@ -17968,9 +18226,15 @@ static INT_PTR CALLBACK GamePortsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg)
        {
-       case WM_INITDIALOG:
+               case WM_INITDIALOG:
                {
                        recursive++;
                        pages[GAMEPORTS_ID] = hDlg;
@@ -18185,6 +18449,12 @@ static INT_PTR CALLBACK IOPortsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPAR
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg)
        {
        case WM_INITDIALOG:
@@ -19268,7 +19538,7 @@ static INT_PTR CALLBACK RemapSpecialsProc(HWND hDlg, UINT msg, WPARAM wParam, LP
 
 static void input_remapspecials(HWND hDlg)
 {
-       CustomDialogBox(IDD_LIST, hDlg, RemapSpecialsProc);
+       CustomCreateDialog(IDD_LIST, hDlg, RemapSpecialsProc);
 }
 
 static INT_PTR CALLBACK InputMapDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -19276,6 +19546,12 @@ static INT_PTR CALLBACK InputMapDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR v = commonproc(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return v;
+       }
+
        static int recursive;
        HWND h = GetDlgItem (hDlg, IDC_INPUTMAPLIST);
        TCHAR tmp[256];
@@ -19426,7 +19702,6 @@ static INT_PTR CALLBACK InputMapDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA
        break;
        }
        handlerawinput (hDlg, msg, wParam, lParam);
-       commonproc(hDlg, msg, wParam, lParam);
        return FALSE;
 }
 
@@ -19588,10 +19863,15 @@ static INT_PTR CALLBACK QualifierProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR v = commonproc(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return v;
+       }
+
        static int recursive = 0;
        HWND list = GetDlgItem (hDlg, IDC_LISTDIALOG_LIST);
 
-
        switch (msg)
        {
        case WM_INITDIALOG:
@@ -19691,7 +19971,6 @@ static INT_PTR CALLBACK QualifierProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
                recursive--;
                break;
        }
-       commonproc(hDlg, msg, wParam, lParam);
        return FALSE;
 }
 
@@ -19709,7 +19988,7 @@ static void input_qualifiers (HWND hDlg)
        if (evt <= 0)
                name[0] = 0;
        
-       CustomDialogBox (IDD_LIST, hDlg, QualifierProc);
+       CustomCreateDialog(IDD_LIST, hDlg, QualifierProc);
 #if 0
        int item = genericpopupmenu (hDlg, names, mflags, MAX_INPUT_QUALIFIERS * 2);
        if (item >= 0)
@@ -19785,6 +20064,12 @@ static INT_PTR CALLBACK InputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg)
        {
        case WM_INITDIALOG:
@@ -20734,6 +21019,12 @@ static INT_PTR CALLBACK hw3dDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg)
        {
        case WM_INITDIALOG:
@@ -21224,6 +21515,12 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch(msg)
        {
        case WM_INITDIALOG:
@@ -21871,6 +22168,7 @@ static void createTreeView (HWND hDlg)
        }
 
        TVhDlg = GetDlgItem (hDlg, IDC_PANELTREE);
+       SubclassTreeViewControl(TVhDlg);
        SetWindowRedraw(TVhDlg, FALSE);
        TreeView_SetImageList (TVhDlg, himl, TVSIL_NORMAL);
 
@@ -22336,6 +22634,12 @@ static INT_PTR CALLBACK DialogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
        if (dialog_inhibit)
                return 0;
 
+       bool handled;
+       INT_PTR vv = commonproc2(hDlg, msg, wParam, lParam, &handled);
+       if (handled) {
+               return vv;
+       }
+
        switch (msg)
        {
        case  WM_DPICHANGED:
@@ -22508,7 +22812,7 @@ static INT_PTR CALLBACK DialogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
                        {
                        case IDC_ERRORLOG:
                                {
-                                       CustomDialogBox (IDD_ERRORLOG, hDlg, ErrorLogProc);
+                                       CustomCreateDialog(IDD_ERRORLOG, hDlg, ErrorLogProc);
                                        ShowWindow (GetDlgItem (guiDlg, IDC_ERRORLOG), is_error_log () ? SW_SHOW : SW_HIDE);
                                }
                                break;
@@ -22547,8 +22851,8 @@ static INT_PTR CALLBACK DialogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
                        }
                        break;
                }
+
        case WM_DWMCOMPOSITIONCHANGED:
-       case WM_THEMECHANGED:
                gui_size_changed = 1;
                return 0;
        }
@@ -22622,7 +22926,7 @@ INT_PTR CustomDialogBox (int templ, HWND hDlg, DLGPROC proc)
        return h;
 }
 
-HWND CustomCreateDialog (int templ, HWND hDlg, DLGPROC proc)
+HWND CustomCreateDialog(int templ, HWND hDlg, DLGPROC proc)
 {
        struct newresource *res;
        struct dlgcontext dctx;
@@ -22836,6 +23140,13 @@ static int GetSettings (int all_options, HWND hwnd)
                regexists = regqueryint (NULL, _T("GUIResize"), &v);
                gui_fullscreen = 0;
                gui_resize_allowed = true;
+               v = -1;
+               regqueryint(NULL, _T("GUIDarkMode"), &v);
+               gui_darkmode = v;
+               if (rp_isactive()) {
+                       v = -2;
+               }
+               InitializeDarkMode(v);
                v = 0;
                regqueryint(NULL, _T("GUIFullscreen"), &v);
                if (v) {
@@ -22851,9 +23162,9 @@ static int GetSettings (int all_options, HWND hwnd)
                if (!regexists) {
                        scaleresource_setdefaults(hwnd);
                        fmultx = 0;
-                       write_log (_T("GUI default size\n"));
-                       regsetint (NULL, _T("GUIResize"), 0);
-                       regsetint (NULL, _T("GUIFullscreen"), 0);
+                       write_log(_T("GUI default size\n"));
+                       regsetint(NULL, _T("GUIResize"), 0);
+                       regsetint(NULL, _T("GUIFullscreen"), 0);
                } else {
                        if (gui_width < MIN_GUI_INTERNAL_WIDTH || gui_width > 8192 || gui_height < MIN_GUI_INTERNAL_HEIGHT || gui_height > 8192) {
                                scaleresource_setdefaults(hwnd);
@@ -22974,6 +23285,10 @@ static int GetSettings (int all_options, HWND hwnd)
                                start_gui_height = h;
                        }
 
+                       if (g_darkModeSupported && g_darkModeEnabled) {
+                               BOOL value = TRUE;
+                               DwmSetWindowAttribute(dhwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
+                       }
                        setguititle (dhwnd);
                        RedrawWindow(dhwnd, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
                        ShowWindow (dhwnd, SW_SHOW);
index 122df259b758ad043b14a1025daaa6f7283b3768..e66627c38c690fad10c929d4c3d663ea43703d14 100644 (file)
@@ -18,6 +18,8 @@
 #include "xwin.h"
 #include "zfile.h"
 
+#include "darkmode.h"
+
 #define MAX_GUI_FONTS 2
 #define DEFAULT_FONTSIZE_OLD 8
 #define DEFAULT_FONTSIZE_NEW 9
@@ -325,6 +327,22 @@ static BOOL DIALOG_CreateControls32(HWND hwnd, LPCSTR tmpl, const DLG_TEMPLATE *
                        hwndDefButton = hwndCtrl;
                        dlgInfo->idResult = GetWindowLongPtrA(hwndCtrl, GWLP_ID);
                }
+               if (g_darkModeSupported) {
+                       _AllowDarkModeForWindow(hwndCtrl, g_darkModeEnabled);
+                       if (g_darkModeEnabled) {
+                               //write_log(_T("%s\n"), info.className);
+                               if (!_tcsicmp(info.className, _T("Button"))) {
+                                       SubclassButtonControl(hwndCtrl);
+                               } else if (!_tcsicmp(info.className, _T("ComboBox")) || !_tcsicmp(info.className, _T("Edit"))) {
+                                       SetWindowTheme(hwndCtrl, L"CFD", nullptr);
+                               } else if (!_tcsicmp(info.className, _T("SysListView32")) || !_tcsicmp(info.className, _T("SysTreeView32"))) {
+                                       //
+                               } else {
+                                       SetWindowTheme(hwndCtrl, L"Explorer", nullptr);
+                               }
+                               SendMessageW(hwndCtrl, WM_THEMECHANGED, 0, 0);
+                       }
+               }
        }
        return TRUE;
 }
@@ -628,10 +646,17 @@ static HWND DIALOG_CreateIndirect(HINSTANCE hInst, LPCVOID dlgTemplate,
                mon_info.cbSize = sizeof(mon_info);
                if (tmpl->style & DS_CENTER)
                {
-                       monitor = MonitorFromWindow(owner ? owner : GetActiveWindow(), MONITOR_DEFAULTTOPRIMARY);
-                       GetMonitorInfoW(monitor, &mon_info);
-                       pos.x = (mon_info.rcWork.left + mon_info.rcWork.right - size.cx) / 2;
-                       pos.y = (mon_info.rcWork.top + mon_info.rcWork.bottom - size.cy) / 2;
+                       if (!owner) {
+                               monitor = MonitorFromWindow(owner ? owner : GetActiveWindow(), MONITOR_DEFAULTTOPRIMARY);
+                               GetMonitorInfoW(monitor, &mon_info);
+                               pos.x = (mon_info.rcWork.left + mon_info.rcWork.right - size.cx) / 2;
+                               pos.y = (mon_info.rcWork.top + mon_info.rcWork.bottom - size.cy) / 2;
+                       } else {
+                               RECT r;
+                               GetWindowRect(owner, &r);
+                               pos.x = (r.left + r.right - size.cx) / 2;
+                               pos.y = (r.top + r.bottom - size.cy) / 2;
+                       }
                }
                else if (tmpl->style & DS_CENTERMOUSE)
                {
@@ -723,6 +748,10 @@ static HWND DIALOG_CreateIndirect(HINSTANCE hInst, LPCVOID dlgTemplate,
        if (dlgProc && dlgInfo->hUserFont)
                SendMessage(hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0);
 
+       if (g_darkModeSupported) {
+               _AllowDarkModeForWindow(hwnd, g_darkModeEnabled);
+       }
+
        /* Create controls */
        if (createcontrols(hwnd, res))
                return hwnd;
index 578c3b79703364d61f4f42566173694a82668374..a35078740474a4036158db13604e077ec386f10f 100644 (file)
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;shlwapi.lib;libpng16.lib;lglcd.lib;openal32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;shlwapi.lib;libpng16.lib;lglcd.lib;openal32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\</AdditionalLibraryDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;shlwapi.lib;libpng16.lib;lglcd.lib;openal32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;shlwapi.lib;libpng16.lib;lglcd.lib;openal32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\</AdditionalLibraryDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;shlwapi.lib;libpng16.lib;lglcd.lib;openal32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;shlwapi.lib;libpng16.lib;lglcd.lib;openal32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\</AdditionalLibraryDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ShowProgress>NotSet</ShowProgress>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ShowProgress>NotSet</ShowProgress>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ShowProgress>NotSet</ShowProgress>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ShowProgress>NotSet</ShowProgress>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ShowProgress>NotSet</ShowProgress>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ShowProgress>NotSet</ShowProgress>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;shlwapi.lib;libpng16.lib;lglcd.lib;openal32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;winio.lib;setupapi.lib;wininet.lib;shlwapi.lib;libpng16.lib;lglcd.lib;openal32.lib;portaudio_x86.lib;vfw32.lib;wtsapi32.lib;enet.lib;lzmalib.lib;prowizard.lib;libFLAC_static.lib;hid.lib;zlibstat.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\</AdditionalLibraryDirectories>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ShowProgress>NotSet</ShowProgress>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <Culture>0x0409</Culture>
     </ResourceCompile>
     <Link>
-      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ws2_32.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;openal32.lib;libpng16.lib;lglcd.lib;wtsapi32.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;hid.lib;Iphlpapi.lib;luastatic.lib;libmpeg2_ff.lib;softfloat.lib;gdiplus.lib;effects11.lib;Msimg32.lib;Dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <ShowProgress>NotSet</ShowProgress>
       <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
     <ClCompile Include="..\caps\caps_win32.cpp" />
     <ClCompile Include="..\cda_play.cpp" />
     <ClCompile Include="..\clipboard_win32.cpp" />
+    <ClCompile Include="..\darkmode.cpp" />
     <ClCompile Include="..\debug_win32.cpp" />
     <ClCompile Include="..\dinput.cpp" />
     <ClCompile Include="..\direct3d.cpp" />
index 1606b48b3dd04688dac2c9ba4fca22381caeef5d..808e4271c525c05b26ae667968c2135d20e538d5 100644 (file)
     <ClCompile Include="..\gdirender.cpp">
       <Filter>win32</Filter>
     </ClCompile>
+    <ClCompile Include="..\darkmode.cpp">
+      <Filter>win32</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\resources\35floppy.ico">