Skip to content

Instantly share code, notes, and snippets.

@rounk-ctrl
Last active March 15, 2026 00:54
Show Gist options
  • Select an option

  • Save rounk-ctrl/b04e5622e30e0d62956870d5c22b7017 to your computer and use it in GitHub Desktop.

Select an option

Save rounk-ctrl/b04e5622e30e0d62956870d5c22b7017 to your computer and use it in GitHub Desktop.
Win32 Dark Mode

Dark Mode

How to use the newly added dark mode system added in recent Windows 11 builds. They added a dark mode variant of almost every control.

API Signatures.

ShouldAppsUseDarkMode

Whether apps should use dark mode or not.

typedef bool (WINAPI* ShouldAppsUseDarkMode_t)(); // ordinal 132

SetPreferredAppMode

Dark Context menu for the app. I don't know what else this does.

enum class PreferredAppMode
{
	Default,
	AllowDark,
	ForceDark,
	ForceLight,
	Max
};
typedef PreferredAppMode (WINAPI* SetPreferredAppMode_t)(PreferredAppMode); // ordinal 135

AllowDarkModeForWindowWithParentFallback

New function in recent Windows 11 builds.
bAutoThemeChange- it will automatically switch the controls whenever theme change happens between light and dark mode.

typedef bool (WINAPI* AllowDarkModeForWindowWithParentFallback_t)(HWND, bool bAutoThemeChange); // ordinal 145

Importing the functions

This is how we load functions exported as ordinals by any dll:

HMODULE hUxtheme = LoadLibraryExW(L"uxtheme.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
SetPreferredAppMode_t SetPreferredAppMode;
SetPreferredAppMode = (SetPreferredAppMode_t)GetProcAddress(hUxtheme, MAKEINTRESOURCEA(135));

You can do like this for any API. Dont forget to free it

Using them

Enables dark context menus which change automatically depending on the theme.

SetPreferredAppMode(PreferredAppMode::AllowDark);

To apply to all controls, just call AllowDarkModeForWindowWithParentFallback on the main HWND

AllowDarkModeForWindowWithParentFallback(hWnd, TRUE);

All supported controls will automatically get dark mode. But some stubborn controls still don't work (atleast for me), for that you need to handle it in the wndproc.

Static control

The background of the static control doesnt change
clr- the background color of the static

case WM_CTLCOLORSTATIC: 
{
	if (ShouldAppsUseDarkMode())
	{
		HDC hdc = reinterpret_cast<HDC>(wParam);
		SetBkMode(hdc, TRANSPARENT);
	}
	return reinterpret_cast<INT_PTR>(CreateSolidBrush(clr));
}

Button

There will be a while border around the button if you dont do this

case WM_CTLCOLORBTN:
{
	if (ShouldAppsUseDarkMode())
	{
		HDC hdc = reinterpret_cast<HDC>(wParam);
		SetBkMode(hdc, TRANSPARENT);
	}
	return reinterpret_cast<INT_PTR>(CreateSolidBrush(clr));
}

Combobox/Edit

Their text field will behave weirdly

case WM_CTLCOLOREDIT:
case WM_CTLCOLORLISTBOX:
{
	if (ShouldAppsUseDarkMode())
	{
		HDC hdc = reinterpret_cast<HDC>(wParam);
		SetBkColor(hdc, editBg);
		SetTextColor(hdc, clrTxt);
	}
	return reinterpret_cast<INT_PTR>(CreateSolidBrush(editBg));
}

Update the stored color values accordingly whenever theme changes by refreshing it in WM_THEMECHANGED.
For window background, handle WM_ERASEBKGND.

Dark Scrollbars:

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. IatHook.h
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);
			}
		}
	}
}

For a sample project, check https://github.com/rounk-ctrl/win32-darkmode/

@ajtruckle
Copy link

@rounk-ctrl what new method?

@rounk-ctrl
Copy link
Author

check the gist, i updated it

@levicki
Copy link

levicki commented Mar 14, 2026

What about the status bar?

@ajtruckle
Copy link

I ended up doing an owner draw status bar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment