C language > User contributions
Enable Dark Mode for Title bar
WiiLF23:
This will turn on Dark Mode for the window title bar.
--- Code: ---#include <dwmapi.h>
#pragma comment(lib, "dwmapi.lib")
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
#endif
static INT_PTR CALLBACK MainDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg)
{
case WM_INITDIALOG:
{
// Enable dark mode title bar
BOOL value = TRUE;
DwmSetWindowAttribute(hwndDlg, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
...
--- End code ---
https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/apply-windows-themes#enable-a-dark-mode-title-bar-for-win32-applications
Toggle DarkMode/LightMode
--- Code: ---BOOL isDarkModeEnabled = FALSE;
void ToggleDarkMode(HWND hWnd) {
isDarkModeEnabled = !isDarkModeEnabled;
// Enable or disable dark mode title bar
BOOL value = isDarkModeEnabled;
DwmSetWindowAttribute(hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
RECT rc;
GetWindowRect(hWnd, &rc);
if (isDarkModeEnabled) {
// Increase window size by 1 pixel
MoveWindow(hWnd, rc.left, rc.top, rc.right - rc.left + 1, rc.bottom - rc.top + 1, TRUE);
} else {
// Decrease window size by 1 pixel
MoveWindow(hWnd, rc.left, rc.top, rc.right - rc.left - 1, rc.bottom - rc.top - 1, TRUE);
}
}
--- End code ---
Turning Some Elements Dark
Undocumented - https://stackoverflow.com/a/53545935/2694720
--- Code: ---#include <uxtheme.h>
#pragma comment(lib, "uxtheme.lib")
void ApplyDarkModeToControls(HWND hwnd, BOOL darkMode)
{
HWND hChild = GetWindow(hwnd, GW_CHILD);
while (hChild)
{
if (darkMode)
{
SetWindowTheme(hChild, L"DarkMode_Explorer", NULL);
}
else
{
SetWindowTheme(hChild, NULL, NULL);
}
ApplyDarkModeToControls(hChild, darkMode);
hChild = GetWindow(hChild, GW_HWNDNEXT);
}
}
void ToggleDarkMode(HWND hWnd)
{
isDarkModeEnabled = !isDarkModeEnabled;
// Enable or disable dark mode title bar
BOOL value = isDarkModeEnabled;
DwmSetWindowAttribute(hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
// Apply the theme to all child controls recursively
ApplyDarkModeToControls(hWnd, isDarkModeEnabled);
RECT rc;
GetWindowRect(hWnd, &rc);
if (isDarkModeEnabled)
{
MoveWindow(hWnd, rc.left, rc.top, rc.right - rc.left + 1, rc.bottom - rc.top + 1, TRUE);
}
else
{
MoveWindow(hWnd, rc.left, rc.top, rc.right - rc.left - 1, rc.bottom - rc.top - 1, TRUE);
}
}
--- End code ---
I hope to actually implement a full window + full control solution
https://gist.github.com/rounk-ctrl/b04e5622e30e0d62956870d5c22b7017
Enjoy!
John Z:
Hi WiiLF23,
Thanks for the example and links. I've not used uxtheme.lib so nice to see an example.
In a program I gave the user the ability to create and save 5 themes themselves not dependent on the system theme but with some limitations. like the toolbar and menu. Maybe I'll try uxtheme for them.
John Z
WiiLF23:
--- Quote from: John Z on January 07, 2024, 09:22:39 PM ---Hi WiiLF23,
Thanks for the example and links. I've not used uxtheme.lib so nice to see an example.
In a program I gave the user the ability to create and save 5 themes themselves not dependent on the system theme but with some limitations. like the toolbar and menu. Maybe I'll try uxtheme for them.
John Z
--- End quote ---
Most welcome! I am currently implementing the full experience and I have dark mode for Menu now. The only issue im having, is applying the menu theme by calling when desired. Menu only darkens when I call in WM_INITDIALOG message.
Current progress, working successfully for full menu dark mode:
--- Code: ---typedef BOOL(WINAPI* fnShouldAppsUseDarkMode)();
typedef BOOL(WINAPI* fnAllowDarkModeForWindow)(HWND hWnd, BOOL allow);
typedef DWORD(WINAPI* fnSetPreferredAppMode)(DWORD appMode);
enum PreferredAppMode
{
Default,
AllowDark,
ForceDark,
ForceLight,
Max
};
HMODULE hUxtheme;
fnShouldAppsUseDarkMode ShouldAppsUseDarkMode;
fnAllowDarkModeForWindow AllowDarkModeForWindow;
fnSetPreferredAppMode SetPreferredAppMode;
void InitDarkMode()
{
hUxtheme = LoadLibraryExW(L"uxtheme.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (hUxtheme)
{
ShouldAppsUseDarkMode = (fnShouldAppsUseDarkMode)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(132));
AllowDarkModeForWindow = (fnAllowDarkModeForWindow)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(133));
SetPreferredAppMode = (fnSetPreferredAppMode)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(135));
}
}
--- End code ---
WM_INITDIALOG:
--- Code: ---InitDarkMode();
SetPreferredAppMode(ForceDark); // options in enum
--- End code ---
WM_DESTROY:
--- Code: ---FreeLibrary(hUxtheme);
--- End code ---
John Z:
Hi WiiLF23,
--- Quote from: WiiLF23 on January 08, 2024, 02:17:28 AM ---The only issue im having, is applying the menu theme by calling when desired. Menu only darkens when I call in WM_INITDIALOG message.
--- End quote ---
Most Menu changes need to be followed up by DrawMenuBar(gHWND); might be worth a try.
John Z
WiiLF23:
Redraw, Invalidate, DrawMenu all fail on the parent window. Its a strange issue. I read that Microsoft decided not to expose a lot of the API for dark mode for winapi so a lot of people have discussed it over time, not very happy with their findings etc but its intended for UWP apps, so its short of a miracle to get it this far at the moment.
At this point, I will keep the current dark controls possible, and paint the window and the rest of the controls accordingly. Starting to learn about this as we speak, I think this is the best option.
--- Code: ---case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwndDlg, &ps);
// Set the background color to dark (black)
SetBkColor(hdc, RGB(0, 0, 0));
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &ps.rcPaint, NULL, 0, NULL);
EndPaint(hwndDlg, &ps);
return 0;
}
--- End code ---
Navigation
[0] Message Index
[#] Next page
Go to full version