Classic Shell
http://www.classicshell.net/forum/

Questions about taskbar background transparency
http://www.classicshell.net/forum/viewtopic.php?f=10&t=6444
Page 1 of 1

Author:  charles.milette [ Wed Aug 03, 2016 7:35 am ]
Post subject:  Questions about taskbar background transparency

As mentionned in this article, it is possible to make the taskbar's background fully transparent with Classic Shell.

However, I feel that installing Classic Shell for this only feature overkill.

I'd like to know how Classic Shell does this, so I can write a tiny program dedicated to do that (and maybe add some features, such as having the taskbar transparent only when you're on the desktop)

I tried searching in the old source code, but the feature wasn't introduced yet.

If possible, I'd also appreciated having code snippets.

Author:  Ivo [ Wed Aug 03, 2016 7:45 am ]
Post subject:  Re: Questions about taskbar background transparency

On Windows 10 this is done by using the undocumented function SetWindowCompositionAttribute. You can control the glass color and opacity of any window.
On older versions it is achieved by replacing the painting of the taskbar window with custom code.

Author:  charles.milette [ Wed Aug 03, 2016 8:15 am ]
Post subject:  Re: Questions about taskbar background transparency

Thanks! Will check that out.

Author:  charles.milette [ Wed Aug 03, 2016 11:35 am ]
Post subject:  Re: Questions about taskbar background transparency

Ivo wrote:
On Windows 10 this is done by using the undocumented function SetWindowCompositionAttribute. You can control the glass color and opacity of any window.



As soon as the Windows 10 start menu is opened, the effect reverts back to normal. Do you know the way to prevent that?

Author:  Ivo [ Wed Aug 03, 2016 1:47 pm ]
Post subject:  Re: Questions about taskbar background transparency

When Classic Shell does it, or when you do it?

Author:  charles.milette [ Wed Aug 03, 2016 5:10 pm ]
Post subject:  Re: Questions about taskbar background transparency

Ivo wrote:
When Classic Shell does it, or when you do it?



When I do it.



For reference, here's my (quickly written) code:

Code:
using System;
using System.Runtime.InteropServices;

public class TransparentTaskbar {
static class Interop {
[DllImport("user32.dll", SetLastError = true)]
internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);

[StructLayout(LayoutKind.Sequential)]
internal struct WindowCompositionAttributeData {
public WindowCompositionAttribute Attribute;
public IntPtr Data;
public int SizeOfData;
}

[StructLayout(LayoutKind.Sequential)]
internal struct AccentPolicy {
public AccentState AccentState;
public AccentFlags AccentFlags;
public uint GradientColor;
public int AnimationId;
}

[Flags]
internal enum AccentFlags {
// ...
DrawLeftBorder = 0x20,
DrawTopBorder = 0x40,
DrawRightBorder = 0x80,
DrawBottomBorder = 0x100,
DrawAllBorders = (DrawLeftBorder | DrawTopBorder | DrawRightBorder | DrawBottomBorder)
// ...
}

internal enum WindowCompositionAttribute {
// ...
WCA_ACCENT_POLICY = 19
// ...
}

internal enum AccentState {
ACCENT_DISABLED = 0,
ACCENT_ENABLE_GRADIENT = 1,
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
ACCENT_ENABLE_BLURBEHIND = 3,
ACCENT_INVALID_STATE = 4
}
}

public static void Main(string[] CommandLine) {
var accent = new Interop.AccentPolicy();
accent.AccentState = Interop.AccentState.ACCENT_ENABLE_BLURBEHIND;

var accentPtr = Marshal.AllocHGlobal(Marshal.SizeOf(accent));
Marshal.StructureToPtr(accent, accentPtr, false);

var data = new Interop.WindowCompositionAttributeData();
data.Attribute = Interop.WindowCompositionAttribute.WCA_ACCENT_POLICY;
data.SizeOfData = Marshal.SizeOf(accent);
data.Data = accentPtr;

Interop.SetWindowCompositionAttribute(Interop.FindWindow("Shell_TrayWnd", null), ref data);
}
}

Author:  Ivo [ Thu Aug 04, 2016 7:00 am ]
Post subject:  Re: Questions about taskbar background transparency

I am doing this when the taskbar gets WM_PAINT message. And in few other cases to prevent flickering.

Author:  charles.milette [ Wed Sep 07, 2016 5:37 pm ]
Post subject:  Re: Questions about taskbar background transparency

I found an even better way!

Code:
#include <windows.h>
#include "stdafx.h"

TCHAR szClassName[] = TEXT("Blur");

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
   switch (msg)
   {
   case WM_NCHITTEST:
      wParam = DefWindowProc(hWnd, msg, wParam, lParam);
      if (wParam == HTCLIENT)
         return HTCAPTION;
      else
         return wParam;
   case WM_DESTROY:
      PostQuitMessage(0);
      break;
   default:
      return DefWindowProc(hWnd, msg, wParam, lParam);
   }
   return 0;
}

void SetWindowBlur(HWND hWnd)
{
   const HINSTANCE hModule = LoadLibrary(TEXT("user32.dll"));
   if (hModule)
   {
      struct ACCENTPOLICY
      {
         int nAccentState;
         int nFlags;
         int nColor;
         int nAnimationId;
      };
      struct WINCOMPATTRDATA
      {
         int nAttribute;
         PVOID pData;
         ULONG ulDataSize;
      };
      typedef BOOL(WINAPI*pSetWindowCompositionAttribute)(HWND, WINCOMPATTRDATA*);
      const pSetWindowCompositionAttribute SetWindowCompositionAttribute = (pSetWindowCompositionAttribute)GetProcAddress(hModule, "SetWindowCompositionAttribute");
      if (SetWindowCompositionAttribute)
      {
         ACCENTPOLICY policy = { 3, 0, 0, 0 };
         WINCOMPATTRDATA data = { 19, &policy, sizeof(ACCENTPOLICY) };
         SetWindowCompositionAttribute(hWnd, &data);
      }
      FreeLibrary(hModule);
   }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR pCmdLine, int nCmdShow)
{
   MSG msg;
   WNDCLASS wndclass = {
      0,
      WndProc,
      0,
      0,
      hInstance,
      0,
      LoadCursor(0, IDC_ARROW),
      (HBRUSH)GetStockObject(BLACK_BRUSH),
      0,
      szClassName
   };
   RegisterClass(&wndclass);
   RECT taskpos;
   HWND taskbar = FindWindow(L"Shell_TrayWnd", NULL);
   GetWindowRect(taskbar, &taskpos);
   HWND hWnd = CreateWindowEx(
      WS_EX_TOOLWINDOW | WS_EX_TOPMOST ,
      szClassName,
      TEXT("Blur"),
      WS_POPUP,
      taskpos.left,
      taskpos.top,
      taskpos.right - taskpos.left,
      taskpos.bottom - taskpos.top,
      0,
      0,
      hInstance,
      0
   );
   SetParent(taskbar, hWnd);
   SetWindowBlur(hWnd);
   ShowWindow(hWnd, SW_SHOW);
   // i wanna add some darkening effect later on, draw a half-transparent black rectangle on the whole window
   while (GetMessage(&msg, 0, 0, 0))
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }
   return msg.wParam;
}


Just create a window with the same size and position as the taskbar and then set the taskbar as the child of this window. This gives you total control over the taskbar's background (you can draw anything in the window, and it will be the taskbar's background.)

Sorry if the code is a bit messy, that's a prototype.

Page 1 of 1 All times are UTC - 8 hours [ DST ]
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/