Click here to Skip to main content
Click here to Skip to main content
Go to top

Changing Windows Aero Color

, 24 Jun 2013
Rate this:
Please Sign up or sign in to vote.
Ever wanted to change the windows Aero color without restarting the DWM?

Introduction

From the Windows Vista and above [ till now], Windows introduced a new engine called Desktop Window Manager which enables the use of hardware acceleration to render the user interface. It is used to enable the new Windows Aero look and design which enables the glassy look, 3D view and switching. The Desktop Window Manager is a compositing window manager. This means that each program has a buffer that it writes data to, then it composites each buffer into final image and look. Hence it needs a DirectX compatible graphic device and WDDM drivers.

When  the DWM was introduced, Windows introduced a colorful transparent UI called Aero. There are many ways to change the Aero color, mostly upon changing the Windows Aero enabled theme, the Aero color changes. Rest of other ways needs the restart of the DWM process that it dwm.exe

Hence, when I tried to know more about this Aero color changing values, I found the DLL "dwmapi.dll", which can be found in system32 folder of the Windows installation directory. This DLL holds and serves all the needed API calls related to DWM. I tried to look the function's inside this DLL and I found 3 function which can change the Aero colors.

Background

There are several API which is not documented in the Windows API lists. These undocumented API's are private for Windows OS. To obtain these API's we can use Microsoft public symbol server. When dumped the dwmapi.dll we can find three functions.

DwmIsCompositionEnabled() // Documented API,check if DWM composition is enabled or not
DwmGetColorizationParameters() // At index 127, undocumented API
DwmSetColorizationParameters() // At index 131, undocumented API

As I said, the first function is used to check that DWM composition is enabled or not. If it's not enabled then all calls to other functions will fail. So before using other functions, it's necessary that we check it. Next two functions are used to get and set the Aero color parameters respectively.

As the 2 functions are undocumented, hence Microsoft can modify or remove back them at anytime without notification.

Using the code

As the 2 functions are undocumented, hence we can not use the direct API call or header file "dwmapi.h". So I decided to load the "dwmapi.dll" at the runtime using the LoadLibrary() function. According to the MSDN LoadLibrary() can load the DLL and using the GetProcAddress() function we can load the address of the desired function. The GetProcAddress() can load the address of the function by either using the function name or the Index of the function. As, we have the Index of those 2 undocumented API, so we can load them too using GetProcAddress().

So first let's load the "dwmapi.dll"

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
}
 

When we have loaded the DLL, now it's time to load the needed functions.

// 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 upto 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);

Now we have to check the COLORIZATIONPARAMS used by the 2 undocumented API's. Do find out the PARAMS, we can take a look at the registry key  HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM

The structure in C, looks like below

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

Now, when we know everything, it's time to use the needed functions. Let's take a look at the sample.

DwmIsCompositionEnabled(&enabled);//Need to call DwmIsCompositionEnabled before calling the DwmSetColorizationParameters or it will fail.
if(!enabled) // If glass composition is not enabled then close up
{
  MessageBox(hWnd,"Composition is not enabled\nUnable to work!","Error",MB_ICONERROR);
  FreeLibrary(hDwmDLL);
  EndDialog(hWnd,0);
}
if(!DwmGetColorizationParameters && !DwmSetColorizationParameters) // The undocumented functions are not there,sorry
{
  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
}

To change the color at runtime, I have used the timer. We will generate the color automatically using random values and then set the color to the Aero.

case WM_TIMER:
{
  R = (rand() % 256);
  G = (rand() % 256);
  B = (rand() % 256);
  dwmcolor.clrColor = RGB(R,G,B);
  DwmSetColorizationParameters(&dwmcolor,0);
}
return TRUE;

Now, this will change the Windows Aero color without need to restart the DWM. But, it's good if we set back the default color when we close this application. So at the start of the application, we will save the default Aero color and restore it back to the Aero on closing of the application

dwmcolor.clrColor = Restore;
DwmSetColorizationParameters(&dwmcolor,0); // Restore color back

And then finally, we will free the loaded DLL

FreeLibrary(hDwmDLL); // Free the loaded DWM Library

The complete source code, for this job, goes below:

#include <windows.h>
#include <stdlib.h>
#include <time.h>
#include "resource.h"

HMODULE hDwmDLL;
BOOL enabled = FALSE;
time_t t;
int R=0,G=0,B=0; // Colors
#define ID_TIMER 1 // Timer ID
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

// Needed Function from DWM Library
HRESULT (WINAPI *DwmIsCompositionEnabled)(BOOL *pfEnabled);
HRESULT (WINAPI *DwmSetColorizationParameters) (COLORIZATIONPARAMS *colorparam,UINT unknown);
HRESULT (WINAPI *DwmGetColorizationParameters) (COLORIZATIONPARAMS *colorparam);

BOOL CALLBACK DlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	switch(message)
	{
		case WM_INITDIALOG:
			hDwmDLL = LoadLibrary("dwmapi.dll"); // Loads the DWM DLL
			if(!hDwmDLL)
			{
				MessageBox(hWnd,"Unable to load DWM Library!","Error",MB_ICONERROR);
				EndDialog(hWnd,0); // Close
			}
			else
			{
				// Everything is fine upto 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);
			}
			DwmIsCompositionEnabled(&enabled);//Need to call DwmIsCompositionEnabled before calling the DwmSetColorizationParameters or it will fail.
			if(!enabled) // If glass composition is not enabled then close up
			{
				MessageBox(hWnd,"Composition is not enabled\nUnable to work!","Error",MB_ICONERROR);
				FreeLibrary(hDwmDLL);
				EndDialog(hWnd,0);
			}
			if(!DwmGetColorizationParameters && !DwmSetColorizationParameters) // The undocumented functions are not there,sorry
			{
				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
				srand((unsigned) time(&t)); // seed for random number
			}
			return TRUE;
		case WM_TIMER:
			{
				R = (rand() % 256);
				G = (rand() % 256);
				B = (rand() % 256);
				dwmcolor.clrColor = RGB(R,G,B);
				DwmSetColorizationParameters(&dwmcolor,0);
			}
			return TRUE;
		case WM_COMMAND:
			switch(LOWORD(wParam))
			{
			case IDC_BUTTON1: //Stop
				KillTimer(hWnd,ID_TIMER);
				dwmcolor.clrColor = Restore;
				DwmSetColorizationParameters(&dwmcolor,0); // Restore color back
				break;
			case IDC_BUTTON2: //Start
				SetTimer(hWnd,ID_TIMER,300,NULL);
				break;
			}
			return TRUE;
		case WM_CLOSE:
			KillTimer(hWnd,ID_TIMER);
			dwmcolor.clrColor = Restore;
			DwmSetColorizationParameters(&dwmcolor,0); // Restore color back
			FreeLibrary(hDwmDLL); // Free the loaded DWM Library
			EndDialog(hWnd,0);
			return TRUE;
	}
	return FALSE;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
	DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,DLGPROC(DlgProc),0);
}

Points of Interest

It is good to experiment with the internals of windows. Suppose an application which can change the Windows Aero color according to the current temprature or according to the average color of your wallpaper. Sounds interesting. This source code can be used to easily manipulate the Aero color and what's good that you don't have to restart DWM.

History

Initial release: 1.0

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Tejashwi Kalp Taru
Software Developer
India India
Tejashwi Kalp Taru is a software developer from New Delhi, India. His area of interest are Windows application development with Windows native API, Cryptography, Reverse Code Engineering (Software Debugging), also a security specialist (Ethical Hacker).
 
He developed few software that can be found on Softpedia:
http://www.softpedia.com/developer/Tejashwi-Kalp-Taru-74306.html
 
Homepage : http://www.tejashwi.com
TechTejash : http://www.tejashwi.com/techtejash
Follow on   Twitter   Google+   LinkedIn

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web03 | 2.8.140921.1 | Last Updated 24 Jun 2013
Article Copyright 2013 by Tejashwi Kalp Taru
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid