Changing Windows Aero color with Win32 programming
Windows Vista introduced the Desktop Window Manager (DWM), which uses hardware acceleration for the UI and enables the Aero glass effects. Each program writes to its own buffer, and DWM composites them into the final image. This requires a DirectX-compatible GPU with WDDM drivers.
Most ways to change the Aero color require either switching themes or restarting dwm.exe. But there’s another way.
Finding the Hidden APIs
While poking around, I found dwmapi.dll in the system32 folder. It handles all DWM-related API calls. Dumping the DLL revealed three functions of interest:
1
DwmIsCompositionEnabled() // Documented API, checks if DWM composition is enabled
1
DwmGetColorizationParameters() // At index 127, undocumented
1
DwmSetColorizationParameters() // At index 131, undocumented
The first function is documented. The other two aren’t officially supported, which means Microsoft could change or remove them anytime.
Loading the Functions
Since these are undocumented, we can’t use the dwmapi.h header directly. Instead, load the DLL at runtime:
1
2
3
4
5
HMODULE hDwmDLL = LoadLibrary("dwmapi.dll"); // Loads the DWM DLL
if (!hDwmDLL) {
MessageBox(hWnd, "Unable to load DWM Library!", "Error", MB_ICONERROR);
EndDialog(hWnd,0); // Close
}
Then get the function addresses. For the undocumented ones, use their index numbers:
1
2
3
4
5
6
7
8
9
10
11
// Needed Function from DWM Library
HRESULT (WINAPI *DwmIsCompositionEnabled)(BOOL *pfEnabled);
HRESULT (WINAPI *DwmSetColorizationParameters) (COLORIZATIONPARAMS *colorparam,UINT unknown);
HRESULT (WINAPI *DwmGetColorizationParameters) (COLORIZATIONPARAMS *colorparam);
// Everything is fine up to here, we can get function address
*(FARPROC *)&DwmIsCompositionEnabled = GetProcAddress(hDwmDLL,"DwmIsCompositionEnabled");
//Below two functions are undocumented thus load from there index
*(FARPROC *)&DwmGetColorizationParameters = GetProcAddress(hDwmDLL,(LPCSTR)127);
*(FARPROC *)&DwmSetColorizationParameters = GetProcAddress(hDwmDLL,(LPCSTR)131);
The Color Parameters Structure
The structure maps to registry values in HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM:
1
2
3
4
5
6
7
8
9
10
11
12
13
typedef struct COLORIZATIONPARAMS
{
COLORREF clrColor; //ColorizationColor
COLORREF clrAftGlow; //ColorizationAfterglow
UINT nIntensity; //ColorizationColorBalance -> 0-100
UINT clrAftGlowBal; //ColorizationAfterglowBalance
UINT clrBlurBal; //ColorizationBlurBalance
UINT clrGlassReflInt; //ColorizationGlassReflectionIntensity
BOOL fOpaque;
}DWMColor;
DWMColor dwmcolor;
COLORREF Restore; // This will be used to restore back the colors to default
Using the Functions
Always check if composition is enabled first, or the other calls will fail:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//Need to call DwmIsCompositionEnabled before calling the DwmSetColorizationParameters or it will fail.
DwmIsCompositionEnabled(&enabled);
// If glass composition is not enabled then close up
if(!enabled) {
MessageBox(hWnd,"Composition is not enabled\nUnable to work!","Error",MB_ICONERROR);
FreeLibrary(hDwmDLL);
EndDialog(hWnd,0);
}
// The undocumented functions are not there, sorry
if(!DwmGetColorizationParameters && !DwmSetColorizationParameters) {
MessageBox(hWnd,"Unable to find necessary functions in library","Error",MB_ICONERROR);
FreeLibrary(hDwmDLL);
EndDialog(hWnd,0);
} else {
DwmGetColorizationParameters(&dwmcolor); // Get current values
Restore = dwmcolor.clrColor; //Backup current color
}
Here’s a timer that changes the color randomly:
1
2
3
4
5
6
7
8
9
case WM_TIMER:
{
R = (rand() % 256);
G = (rand() % 256);
B = (rand() % 256);
dwmcolor.clrColor = RGB(R,G,B);
DwmSetColorizationParameters(&dwmcolor,0);
}
return TRUE;
Restore the original color when closing:
1
2
dwmcolor.clrColor = Restore;
DwmSetColorizationParameters(&dwmcolor,0); // Restore color back
And free the DLL:
1
FreeLibrary(hDwmDLL); // Free the loaded DWM Library
You can download the complete source code here
What You Could Do With This
You could build an app that changes the Aero color based on temperature, or matches it to your wallpaper’s dominant color. The color changes immediately without restarting DWM.