Jump to content

_WinAPI_DwmEnableBlurBehindWindow in Windows 10


Recommended Posts

  • 2 months later...
On 9/12/2016 at 0:15 AM, Leo1906 said:

Is there a way to color it? Like the grey/black of the notification area?
The notification area has a slight blur as well and it would be nice if you were able to build applications like this .. :)

It seems that you have to use GDI+ or other stuff to color it.

screen.jpg

Here I enabled the blur-behind on a layered window and drawn a partly transparent rectangle and some stuff on top.

Link to comment
Share on other sites

  • 8 months later...

Friends! People make it so that the blur is applied together with the color. Below are two examples of code:

; ===============================================================================================================================
; Make the windows 10 taskbar translucent (blur)
; https://autohotkey.com/boards/viewtopic.php?f=6&t=26752
; ===============================================================================================================================

/*
TaskBar_SetAttr(option, color)
option -> 0 = off
          1 = gradient    (+color)
          2 = transparent (+color)
          3 = blur
color  -> ABGR (alpha | blue | green | red) 0xffd7a78f
*/

TaskBar_SetAttr(accent_state := 0, gradient_color := "0x01000000")
{
    static init, hTrayWnd, ver := DllCall("GetVersion") & 0xff < 10
    static pad := A_PtrSize = 8 ? 4 : 0, WCA_ACCENT_POLICY := 19

    if !(init) {
        if (ver)
            throw Exception("Minimum support client: Windows 10", -1)
        if !(hTrayWnd := DllCall("user32\FindWindow", "str", "Shell_TrayWnd", "ptr", 0, "ptr"))
            throw Exception("Failed to get the handle", -1)
        init := 1
    }

    accent_size := VarSetCapacity(ACCENT_POLICY, 16, 0)
    NumPut((accent_state > 0 && accent_state < 4) ? accent_state : 0, ACCENT_POLICY, 0, "int")

    if (accent_state >= 1) && (accent_state <= 2) && (RegExMatch(gradient_color, "0x[[:xdigit:]]{8}"))
        NumPut(gradient_color, ACCENT_POLICY, 8, "int")

    VarSetCapacity(WINCOMPATTRDATA, 4 + pad + A_PtrSize + 4 + pad, 0)
    && NumPut(WCA_ACCENT_POLICY, WINCOMPATTRDATA, 0, "int")
    && NumPut(&ACCENT_POLICY, WINCOMPATTRDATA, 4 + pad, "ptr")
    && NumPut(accent_size, WINCOMPATTRDATA, 4 + pad + A_PtrSize, "uint")
    if !(DllCall("user32\SetWindowCompositionAttribute", "ptr", hTrayWnd, "ptr", &WINCOMPATTRDATA))
        throw Exception("Failed to set transparency / blur", -1)
    return true
}

; ===============================================================================================================================

TaskBar_SetAttr(1, 0xc1e3c791)    ; <- Set gradient    with color 0xd7a78f ( rgb = 0x91c7e3 ) and alpha 0xc1
sleep 3000
TaskBar_SetAttr(2, 0xa1e3c791)    ; <- Set transparent with color 0xd7a78f ( rgb = 0x91c7e3 ) and alpha 0xa1
sleep 3000
TaskBar_SetAttr(2)                ; <- Set transparent
sleep 3000
TaskBar_SetAttr(3)                ; <- Set blur
sleep 3000
TaskBar_SetAttr(0)                ; <- Set standard value
ExitApp

/*
Since clicking on Win-Start will reset the taskbar, it will be the best solution to use a SetTimer with x ms to set the Attribute
#NoEnv
#Persistent
#SingleInstance Force
SetBatchLines -1
SetTimer, UPDATE_TASKBAR, 100
return
UPDATE_TASKBAR:
    TaskBar_SetAttr(3)
return
*/


; ===============================================================================================================================

/*
Shell_TrayWnd             -> Main TaskBar
Shell_SecondaryTrayWnd    -> 2nd  TaskBar (on multiple monitors)
*/

/* C++ ==========================================================================================================================
BOOL GetWindowCompositionAttribute(
    _In_    HWND hWnd,
    _Inout_ WINDOWCOMPOSITIONATTRIBDATA* pAttrData
);
BOOL SetWindowCompositionAttribute(
    _In_    HWND hWnd,
    _Inout_ WINDOWCOMPOSITIONATTRIBDATA* pAttrData
);
typedef struct _WINDOWCOMPOSITIONATTRIBDATA {
    WINDOWCOMPOSITIONATTRIB Attrib;
    PVOID                   pvData;
    SIZE_T                  cbData;
} WINDOWCOMPOSITIONATTRIBDATA;
typedef enum _WINDOWCOMPOSITIONATTRIB {
    WCA_UNDEFINED = 0,
    WCA_NCRENDERING_ENABLED = 1,
    WCA_NCRENDERING_ENABLED = 1,
    WCA_NCRENDERING_POLICY = 2,
    WCA_TRANSITIONS_FORCEDISABLED = 3,
    WCA_ALLOW_NCPAINT = 4,
    WCA_CAPTION_BUTTON_BOUNDS = 5,
    WCA_NONCLIENT_RTL_LAYOUT = 6,
    WCA_FORCE_ICONIC_REPRESENTATION = 7,
    WCA_EXTENDED_FRAME_BOUNDS = 8,
    WCA_HAS_ICONIC_BITMAP = 9,
    WCA_THEME_ATTRIBUTES = 10,
    WCA_NCRENDERING_EXILED = 11,
    WCA_NCADORNMENTINFO = 12,
    WCA_EXCLUDED_FROM_LIVEPREVIEW = 13,
    WCA_VIDEO_OVERLAY_ACTIVE = 14,
    WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
    WCA_DISALLOW_PEEK = 16,
    WCA_CLOAK = 17,
    WCA_CLOAKED = 18,
    WCA_ACCENT_POLICY = 19,
    WCA_FREEZE_REPRESENTATION = 20,
    WCA_EVER_UNCLOAKED = 21,
    WCA_VISUAL_OWNER = 22,
    WCA_LAST = 23
} WINDOWCOMPOSITIONATTRIB;
typedef struct _ACCENT_POLICY {
    ACCENT_STATE AccentState;
    DWORD        AccentFlags;
    DWORD        GradientColor;
    DWORD        AnimationId;
} ACCENT_POLICY;
typedef enum _ACCENT_STATE {
    ACCENT_DISABLED = 0,
    ACCENT_ENABLE_GRADIENT = 1,
    ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
    ACCENT_ENABLE_BLURBEHIND = 3,
    ACCENT_INVALID_STATE = 4
} ACCENT_STATE;
_ACCENT_FLAGS {
    DrawLeftBorder = 0x20,
    DrawTopBorder = 0x40,
    DrawRightBorder = 0x80,
    DrawBottomBorder = 0x100,
    DrawAllBorders = (DrawLeftBorder | DrawTopBorder | DrawRightBorder | DrawBottomBorder)
}
============================================================================================================================== */

Exemple2 (TranslucentTB):

//used for the tray things
#include <shellapi.h>
#include "resource.h"

bool run = true; //needed for tray exit

#pragma region composition

struct ACCENTPOLICY
{
	int nAccentState;
	int nFlags;
	int nColor;
	int nAnimationId;
};
struct WINCOMPATTRDATA
{
	int nAttribute;
	PVOID pData;
	ULONG ulDataSize;
};

struct OPTIONS
{
	int taskbar_appearance;
	int color;
} opt;

const int ACCENT_ENABLE_GRADIENT = 1; // Makes the taskbar a solid color specified by nColor. This mode doesn't care about the alpha channel.
const int ACCENT_ENABLE_TRANSPARENTGRADIENT = 2; // Makes the taskbar a tinted transparent overlay. nColor is the tint color, sending nothing results in it interpreted as 0x00000000 (totally transparent, blends in with desktop)
const int ACCENT_ENABLE_BLURBEHIND = 3; // Makes the taskbar a tinted blurry overlay. nColor is same as above.



typedef BOOL(WINAPI*pSetWindowCompositionAttribute)(HWND, WINCOMPATTRDATA*);
static pSetWindowCompositionAttribute SetWindowCompositionAttribute = (pSetWindowCompositionAttribute)GetProcAddress(GetModuleHandle(TEXT("user32.dll")), "SetWindowCompositionAttribute");

void SetWindowBlur(HWND hWnd)
{
	if (SetWindowCompositionAttribute)
	{
		ACCENTPOLICY policy;

		policy = { opt.taskbar_appearance, 2, opt.color, 0 };

		WINCOMPATTRDATA data = { 19, &policy, sizeof(ACCENTPOLICY) }; // WCA_ACCENT_POLICY=19
		SetWindowCompositionAttribute(hWnd, &data);
	}

}

#pragma endregion 


#pragma region command line
void PrintHelp()
{
	// BUG - 
	// For some reason, when launching this program in cmd.exe, it won't properly "notice"
	// when the program has exited, and will not automatically write a new prompt to the console.
	// Instead of printing the current directory as usual before it waits for a new command,
	// it doesn't print anything, leading to a cluttered console.
	// It's even worse in Powershell, where it actually WILL print the PS prompt before waiting for 
	// a new command, but it does so on the line after "./TranslucentTB.exe --help", overwriting the 
	// first line of output from this function, and gradually overwriting the following lines as you
	// press enter. The PS shell just doesn't notice that anything gets printed to the console, and
	// therefore it prints the PS prompt over this output instead of after. I don't know of any 
	// solution to this, but I expect that setting the project type to SUBSYSTEM:CONSOLE would solve
	// those issues. Again - I think a help file would be the best solution, so I'll do that in my 
	// next commit.

	BOOL hasconsole = true;
	BOOL createdconsole = false;
	// Try to attach to the parent console,
	// allocate a new one if that isn't successful
	if (!AttachConsole(ATTACH_PARENT_PROCESS))
	{
		if (!AllocConsole())
		{
			hasconsole = false;
		}
		else
		{
			createdconsole = true;
		}
	}

	if (hasconsole)
	{
		FILE* outstream;
		FILE* instream;
		freopen_s(&outstream, "CONOUT$", "w", stdout);
		freopen_s(&instream, "CONIN$", "w", stdin);

		if (outstream)
		{
			using namespace std;
			cout << endl;
			cout << "TranslucentTB by /u/IronManMark20" << endl;
			cout << "This program modifies the apperance of the windows taskbar" << endl;
			cout << "You can modify its behaviour by using the following parameters when launching the program:" << endl;
			cout << "  --blur        | will make the taskbar a blurry overlay of the background (default)." << endl;
			cout << "  --opaque      | will make the taskbar a solid color specified by the tint parameter." << endl;
			cout << "  --transparent | will make the taskbar a transparent color specified by the tint parameter. " << endl;
			cout << "                  the value of the alpha channel determines the opacity of the taskbar." << endl;
			cout << "  --tint COLOR  | specifies the color applied to the taskbar. COLOR is 32 bit number in hex format," << endl;
			cout << "                  see explanation below. This will not affect the blur mode. If COLOR is zero in" << endl;
			cout << "                  combination with --transparent the taskbar becomes opaque and uses the selected" << endl;
			cout << "                  system color scheme." << endl;
			cout << "  --help        | Displays this help message." << endl;
			cout << endl;

			cout << "Color format:" << endl;
			cout << "  The parameter is interpreted as a three or four byte long number in hexadecimal format that" << endl;
			cout << "  describes the four color channels ([alpha,] red, green and blue). These look like this:" << endl;
			cout << "  0x80fe10a4 (the '0x' is optional). You often find colors in this format in the context of HTML and" << endl;
			cout << "  web design, and there are many online tools to convert from familiar names to this format. These" << endl;
			cout << "  tools might give you numbers starting with '#', in that case you can just remove the leading '#'." << endl;
			cout << "  You should be able to find online tools by searching for \"color to hex\" or something similar." << endl;
			cout << "  If the converter doesn't include alpha values (opacity), you can append them yourself at the start" << endl;
			cout << "  of the number. Just convert a value between 0 and 255 to its hexadecimal value before you append it." << endl;
			cout << endl;

			if (createdconsole && instream)
			{	
				string wait;
				
				cout << "Press enter to exit the program." << endl;
				if (!getline(cin, wait))
				{
					// Couldn't wait for user input, make the user close
					// the program themselves so they can see the output.
					cout << "Press Ctrl + C, Alt + F4, or click the close button to exit the program." << endl;
					Sleep(INFINITE);
				}

				FreeConsole();
			}

			fclose(outstream);
		}
	}
}

void ParseOptions()
{
	// Set default value
	opt.taskbar_appearance = ACCENT_ENABLE_BLURBEHIND;

	// Loop through command line arguments
	LPWSTR *szArglist;
	int nArgs;

	szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);

	for (int i = 0; i < nArgs; i++)
	{
		LPWSTR arg = szArglist[i];

		if (wcscmp(arg, L"--help") == 0)
		{
			PrintHelp();
			exit(0);
		}
		else if (wcscmp(arg, L"--blur") == 0)
		{
			opt.taskbar_appearance = ACCENT_ENABLE_BLURBEHIND;
		}
		else if (wcscmp(arg, L"--opaque") == 0)
		{
			opt.taskbar_appearance = ACCENT_ENABLE_GRADIENT;
		}
		else if (wcscmp(arg, L"--transparent") == 0)
		{
			opt.taskbar_appearance = ACCENT_ENABLE_TRANSPARENTGRADIENT;
		}
		else if (wcscmp(arg, L"--tint") == 0)
		{
			// The next argument should be a color in hex format
			if (i + 1 < nArgs && wcslen(szArglist[i + 1]) > 0)
			{
				LPWSTR param = szArglist[i + 1];
				unsigned long colval = 0;
				WCHAR* stopchar;


				colval = wcstoul(param, &stopchar, 16);


				// ACCENTPOLICY.nColor expects the byte order to be ABGR,
				// fiddle some bits to make it intuitive for the user.
				opt.color =
					(colval & 0xFF000000) +
					((colval & 0x00FF0000) >> 16) +
					(colval & 0x0000FF00) +
					((colval & 0x000000FF) << 16);
			}
			else
			{
				// TODO error handling for missing value
				// Really not much to do as we don't have functional
				// output streams, and opening a window seems overkill.
			}
		}
	}

	LocalFree(szArglist);
}

#pragma endregion

#pragma region tray

#define WM_NOTIFY_TB 3141

HMENU menu;

LRESULT CALLBACK TBPROCWND(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

	switch (message)
	{
	case WM_CLOSE:
		PostQuitMessage(0);
		break;
	case WM_NOTIFY_TB:
		if (lParam == WM_LBUTTONUP)
		{
			POINT pt;
			GetCursorPos(&pt);
			SetForegroundWindow(hWnd);
			UINT tray = TrackPopupMenu(menu, TPM_RETURNCMD | TPM_RIGHTALIGN | TPM_NONOTIFY, pt.x, pt.y, 0, hWnd, NULL);
			switch (tray)
			{
			case IDM_BLUR:
				opt.taskbar_appearance = ACCENT_ENABLE_BLURBEHIND;
				break;
			case IDM_CLEAR:
				opt.taskbar_appearance = ACCENT_ENABLE_TRANSPARENTGRADIENT;
				opt.color = 0x000000;
				break;
			case IDM_EXIT:
				run = false;
				break;
			}
		}
	}
	return DefWindowProc(hWnd, message, wParam, lParam);
}

NOTIFYICONDATA Tray;

void initTray(HWND parent)
{

	Tray.cbSize = sizeof(Tray);
	Tray.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(MAINICON));
	Tray.hWnd = parent;
	wcscpy_s(Tray.szTip, L"TransparentTB");
	Tray.uCallbackMessage = WM_NOTIFY_TB;
	Tray.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
	Tray.uID = 101;
	Shell_NotifyIcon(NIM_ADD, &Tray);
	Shell_NotifyIcon(NIM_SETVERSION, &Tray);
}

#pragma endregion

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR pCmdLine, int nCmdShow)
{
	MSG msg; // for message translation and dispatch
	HMENU popup = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_POPUP_MENU));
	menu = GetSubMenu(popup, 0);
	WNDCLASSEX wnd = { 0 };

	wnd.hInstance = hInstance;
	wnd.lpszClassName = L"TranslucentTB";
	wnd.lpfnWndProc = TBPROCWND;
	wnd.style = CS_HREDRAW | CS_VREDRAW;
	wnd.cbSize = sizeof(WNDCLASSEX);

	wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
	wnd.hbrBackground = (HBRUSH)BLACK_BRUSH;
	RegisterClassEx(&wnd);

	HWND tray_hwnd = CreateWindowEx(WS_EX_TOOLWINDOW, L"TranslucentTB", L"TrayWindow", WS_OVERLAPPEDWINDOW, 0, 0,
		400, 400, NULL, NULL, hInstance, NULL);

	initTray(tray_hwnd);
  
	ShowWindow(tray_hwnd, WM_SHOWWINDOW);
	ParseOptions(); //command line argument settings
	HWND taskbar = FindWindowW(L"Shell_TrayWnd", NULL);
	HWND secondtaskbar = FindWindow(L"Shell_SecondaryTrayWnd", NULL); // we use this for the taskbars on other monitors.
	while (run) {
		SetWindowBlur(taskbar);
		if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		while (secondtaskbar = FindWindowEx(0, secondtaskbar, L"Shell_SecondaryTrayWnd", L""))
		{
			SetWindowBlur(secondtaskbar);
		}
		Sleep(10);
	}
	Shell_NotifyIcon(NIM_DELETE, &Tray);
}

 

Please, finish the library workable!!

TranslucentTB-2017.2.zip

TaskbarTool.v1.0.8.zip

Edited by musicstashall
Link to comment
Share on other sites

If you do so, then there will be a color:

;_WindowCompozitionAttribute.au3

#Include-once

;ACCENT_STATE
Global Const $ACCENT_DISABLED = 0
Global Const $ACCENT_ENABLE_GRADIENT = 1
Global Const $ACCENT_ENABLE_TRANSPARENTGRADIENT = 2
Global Const $ACCENT_ENABLE_BLURBEHIND = 3
Global Const $ACCENT_INVALID_STATE = 4

;WINCOMPATTRDATA
Global Const $WCA_UNDEFINED = 0
Global Const $WCA_NCRENDERING_ENABLED = 1
Global Const $WCA_NCRENDERING_POLICY = 2
Global Const $WCA_TRANSITIONS_FORCEDISABLED = 3
Global Const $WCA_ALLOW_NCPAINT = 4
Global Const $WCA_CAPTION_BUTTON_BOUNDS = 5
Global Const $WCA_NONCLIENT_RTL_LAYOUT = 6
Global Const $WCA_FORCE_ICONIC_REPRESENTATION = 7
Global Const $WCA_EXTENDED_FRAME_BOUNDS = 8
Global Const $WCA_HAS_ICONIC_BITMAP = 9
Global Const $WCA_THEME_ATTRIBUTES = 10
Global Const $WCA_NCRENDERING_EXILED = 11
Global Const $WCA_NCADORNMENTINFO = 12
Global Const $WCA_EXCLUDED_FROM_LIVEPREVIEW = 13
Global Const $WCA_VIDEO_OVERLAY_ACTIVE = 14
Global Const $WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15
Global Const $WCA_DISALLOW_PEEK = 16
Global Const $WCA_CLOAK = 17
Global Const $WCA_CLOAKED = 18
Global Const $WCA_ACCENT_POLICY = 19
Global Const $WCA_FREEZE_REPRESENTATION = 20
Global Const $WCA_EVER_UNCLOAKED = 21
Global Const $WCA_VISUAL_OWNER = 22
Global Const $WCA_LAST = 23

;ACCENT_FLAGS
Global $DrawLeftBorder = 0x20
Global $DrawTopBorder = 0x40
Global $DrawRightBorder = 0x80
Global $DrawBottomBorder = 0x100
Global $DrawAllBorders = BitOr($DrawLeftBorder, $DrawRightBorder, $DrawTopBorder, $DrawBottomBorder)

Global Const $tagACCENTPOLICY = 'int AccentState; int AccentFlags; int GradientColor; int AnimationId'
Global Const $tagWINCOMPATTRDATA = 'int nAttribute; ptr pData; ulong ulDataSize;'
Global Const $tagOPTIONS = 'int Appearance; int Color;'

Global $tPolicy = DllStructCreate($tagACCENTPOLICY)
Global $tOptions = DllStructCreate($tagOPTIONS)
Global $tWinCompattrData = DllStructCreate($tagWINCOMPATTRDATA)

Func _SetWindowCompositionAttribute($HWND, $tOptions, $tWinCompattrData)
    DllStructSetData($tPolicy, 'AccentState', DllStructGetData($tOptions, 'Appearance'))
    DllStructSetData($tPolicy, 'AccentFlags', 2)
    DllStructSetData($tPolicy, 'GradientColor', DllStructGetData($tOptions, 'Color'))
    DllStructSetData($tPolicy, 'AnimationId', 0)
    DllStructSetData($tWinCompattrData, 'pData', DllStructGetPtr($tPolicy))
    DllStructSetData($tWinCompattrData, 'ulDataSize', DllStructGetSize($tPolicy))
    Local $aResult = DllCall("user32.dll", "bool", "SetWindowCompositionAttribute", "hwnd", $hWnd, "ptr", DllStructGetPtr($tWinCompattrData))
    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[0]
EndFunc

Using:

Local $PersonalizeKey = 'HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize'
Local $ColorPrevalence = RegRead($PersonalizeKey, 'ColorPrevalence')
Local $EnableTransparency = RegRead($PersonalizeKey, 'EnableTransparency')

Func SetStructure($iColor, $hWnd)
    $tWinCompattrData.nAttribute = $WCA_ACCENT_POLICY
    If $ColorPrevalence = 1 Then
        If $EnableTransparency = 1 Then
            $tOptions.Color = $Alpha & $iColor; Color = BGR!!!
            $tOptions.Appearance = $AccentState ;$ACCENT_ENABLE_BLURBEHIND = 3 or $ACCENT_ENABLE_TRANSPARENTGRADIENT = 2
        ElseIf $EnableTransparency = 0 Then
            $tOptions.Color = '0xFF' & $iColor; Color = BGR!!!
            $tOptions.Appearance = $ACCENT_ENABLE_GRADIENT  
        EndIf
    ElseIf $ColorPrevalence = 0 Then
        If $EnableTransparency = 1 Then
            $tOptions.Color = $Alpha & '000000'
            $tOptions.Appearance = $AccentState ;$ACCENT_ENABLE_BLURBEHIND = 3 or $ACCENT_ENABLE_TRANSPARENTGRADIENT = 2
        ElseIf $EnableTransparency = 0 Then
            $tOptions.Color = '0xFF000000'
            $tOptions.Appearance = $ACCENT_ENABLE_GRADIENT  
        EndIf   
    EndIf
    _SetWindowCompositionAttribute($HWND, $tOptions, $tWinCompattrData)
EndFunc

But there is a problem — you need to manage the size of the curbs. If borders are narrowed or absent in the design, then these parameters must be specified in function _WindowCompozitionAttribute. How to do it - you need to look for documentation ...

Edited by musicstashall
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...