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);
}
}
}
}
Thank you for your code @ericoporto .
I am trying:
And it looks like this on the dialog:
My question concerns when the dropdown is displayed:
How do we get the back to render the same as for the List Box?
I went to try the
FixDarkScrollBar
method, to see if it would fix it, but encountered two issues:_OpenNcThemeData
is not defined.fnOpenNcThemeData
is not defined.I am not sure if I need to get that function operational for my
CListBox
scrollbars to turn dark?