Checks whether system is using dark mode or not.
Signature:
using fnShouldAppsUseDarkMode = bool (WINAPI*)(); // ordinal 132
Switches the control's theme to the dark variant if available.
Signature:
using fnAllowDarkModeForWindow = bool (WINAPI*)(HWND hWnd, bool allow); // ordinal 133
Dark Context menu for the app. I don't know what else this does.
Signature(1903+):
using fnSetPreferredAppMode = PreferredAppMode(WINAPI*)(PreferredAppMode appMode); // ordinal 135, in 1903
enum class PreferredAppMode
{
Default,
AllowDark,
ForceDark,
ForceLight,
Max
};
First we need to load uxtheme dll as a HMODULE.
HMODULE hUxtheme = LoadLibraryExW(L"uxtheme.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
Then we need to get the Process Address of the functions. We already know their ordinal numbers.
First initialize a instance of the signature.
fnSetPreferredAppMode SetPreferredAppMode;
then set the process address by using GetProcAddress
SetPreferredAppMode = (fnSetPreferredAppMode)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(135));
You can do like this for any API. Dont forget to free it
FreeLibrary(hUxtheme);
Enables dark context menus which change automatically depending on the theme.
SetPreferredAppMode(PreferredAppMode::AllowDark);
First we need to know which all controls support Dark Mode.
If you open aero.msstyles in msstylesEditor, you would be able to see a lot of DarkMode elements.
And no you cant just do SetWindowTheme([handle to the control], L"DarkMode_Explorer", NULL);
SetWindowTheme([handle to the control], L"Explorer", NULL);
AllowDarkModeForWindow([handle to the control], true);
SendMessageW([handle to the control], WM_THEMECHANGED, 0, 0);
SetWindowTheme([handle to the control], L"CFD", NULL);
AllowDarkModeForWindow([handle to the control], true);
SendMessageW([handle to the control], WM_THEMECHANGED, 0, 0);
SetWindowTheme([handle to the control], L"CFD", NULL);
AllowDarkModeForWindow([handle to the control], true);
SendMessageW([handle to the control], WM_THEMECHANGED, 0, 0);
SetWindowTheme([handle to the control], L"Explorer", NULL);
AllowDarkModeForWindow([handle to the control], true);
SendMessageW([handle to the control], WM_THEMECHANGED, 0, 0);
For dark scrollbars you need to iat hook and change the scrollbar theme before its created.
First download this header file and add it to your project.
Then use this function before the creation of HWND.
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);
}
}
}
}
Hi, thank you for sharing the info.
May I ask how to set the menu bar to dark mode? I've tried to send TB_SETWINDOWTHEME message (DarkMode_Explorer) but nothing changed.
It happen in the original example code as well and not just my project
The menu bar is white by default and dropdown menu always in dark mode
I'm sorry if this isn't the right place to ask.
EDIT: I'm using latest Windows Version
EDIT: End up custom draw the menu bar, Thank you @rounk-ctrl.