Git Product home page Git Product logo

win32-acrylic-effect's Introduction

Win32 Acrylic Effect

A Demonstration of Acrylic Effect on C++ Win32 applications using Direct Composition and DWM private APIs.

Table of Contents
  1. Overview
    • A Short History
    • About This Project
  2. Possible Methods
    • SetWindowCompositionAttribute()
    • Windows.UI.Composition - Interop
    • Windows Maginification API
    • Desktop Duplication API
    • DWM Private APIs
  3. Backdrop Sources
    • Desktop Backdrop
    • Host Backdrop
  4. Features
  5. Known Limitations
  6. Supported Versions

Overview

sample

A Short History

The Windows 10 Acrylic Effects was first introduced on UWP Apps after the Windows Fall Creators Update on 2017, Since Then Developers were trying to implement the acrylic effect on normal Windows Applications such as WPF, Win32 etc.The most Commonly used method was SetWindowCompositionAttribute(), but it didn't last long, from Windows 10 1903 the window starts to become laggy while dragging (This issue seems to be fixed in windows insider previews but not on any stable versions of windows).

About This Project

This project is just a demonstration about implementing (or possible ways to implement) a custom acrylic effect on Win32 Application using DWM APIs and Direct Composition. This is just a basic implementation, Still there is a lot of room for improvement such as noise overlay and other blending effects. We will also discuss about possible ways to achieve Acrylic Effects.

Possible Methods

There are different ways to achieve Acrylic Effect on Windows 10 and some might be able to work on Windows 7,8 (i haven't tested yet).

SetWindowCompositionAttribute()

SetWindowCompositionAttribute() is an undocumented api in windows which allows us to enable Acrylic Effect, DWM Blur (same as DwmEnableBlurBehindWindow()) and transparency for Window. Since it is an undocumented API this api might be changed or removed in future versions of windows. As i had mentioned earlier creating acrylic effect using this API will cause lag while dragging or resizing window, And also the blur effect will disappear during maximize until the window is completely maximized

Windows.UI.Composition - Interop

The Windows.UI.Composition-Win32-Samples on microsoft repository actually provides a way to implement acrylic effect on Windows Forms and WPF. This was one of the closest way to achieve acrylic effect in WPF. But WPF uses diffrent rendering technology and the acrylic effect is rendered using direct composition, So it always cause Airspace Issue. There is only two possible ways to overcome this issue:

1. Overlapping Windows:

You can create multiple WPF windows one for rendereing the WPF Content and one for Acrylic Effect, These windows should be transparent and must communicate with each other to sync the window resize, window drag and other events, this is possible by overriding WndProc. But this method will cause Flickerng on resize and also affects the Acrylic Effect during maximize animation. (This has been tested before)

2. WPF Swapchain Hack:

This is another possible way that i haven't tested yet, but theoretically it might be working. This can be done by hacking into WPF Swapchain to obtain its back buffer and copy it into an ID2D1Bitmap or similar and then passing it to the Windows.UI.Composition.Visual by using somethng like Composition Native Interoperation. By this way we may be able to overcome the Airspace Issue with WPF Acrylic Effect. (:sweat_smile: The truth is Currently i was only able to get the swapchain backbuffer from WPF)

Windows Maginification API

The Windows Manification API can also provide the visual behind a window (Backdrop) by using the MagImageScalingCallback(), but it has been deprecated after windows 7.There might be a chance for creating the blur effect on windows 7 by passing the bitmap obtained from MagImageScalingCallback() to D2D1Effects such as gaussian blur. The MagImageScalingCallback() also throws exception if the source rectangle coordinates is out of desktop coordinates.

Desktop Duplication API

The Windows Desktop Duplication API is also one possible way for creating an acrylic effect, The Desktop Duplication API can be used to capture the entire desktop including the window itself, but on windows 10 2004 Edition Microsoft has added a new parameter WDA_EXCLUDEFROMCAPTURE in SetWindowDisplayAffinity() function which will help us to capture the whole desktop but excluding the windows for which WDA_EXCLUDEFROMCAPTURE is applied. But everything comes with a price, by doing so you wont be able to capture that window by screenshot or screencapture and earlier versions of windows doesn't support WDA_EXCLUDEFROMCAPTURE.

DWM Private API

The dwmapi.dll consist of some private api which can be used to capture each windows or a group of windows into an IDCompositionVisual. If you decompile the dwmapi.dll using some decompiler like IDA By HexRays and explore the dll functions you will be able to find DwmpCreateSharedThumbnailVisual() function which helps us to capture a window into IDCompositionVisual. In this sample we mainly use two functions DwmpCreateSharedThumbnailVisual() and DwmpCreateSharedVirtualDesktopVisual() for creating the visual and we use DwmpUpdateSharedVirtualDesktopVisual() and DwmpUpdateDesktopThumbnail() for updating the visual.

A special thanks to ADeltaX for the implementation.(DWM Thumbnail/VirtualDesktop IDCompositionVisual example)

Once the visual is obtained, The graphics effect such as Gaussian blur,Saturation etc.. is applied to the visual and finally it is rendered back to the window by using Direct Composition. This method also has several limitations such as Airspace Issue while using with other platforms like WPF.

Backdrop Sources

In this sample we have defined two backdrop sources for acrylic effect, They are:

1. Desktop Backdrop

A Desktop Backdrop use the desktop visual as the source for acrylic effect. so no other windows under the host window will be captured for blurring. it will be the plain desktop wallpaper. This is done by using DwmpCreateSharedThumbnailVisual().

2. Host Backdrop

A Host Backdrop uses Desktop Backdrop as the background visual and also captures all the windows which are under the host window for blurring. This is done by using DwmpCreateSharedVirtualDesktopVisual() function.

You can adjust the backdrop source in this example using BackdropSource enum.

// For Host Backdrop
compositor->SetAcrylicEffect(hwnd, AcrylicCompositor::BACKDROP_SOURCE_HOSTBACKDROP, param); 
// For Desktop Backdrop
compositor->SetAcrylicEffect(hwnd, AcrylicCompositor::BACKDROP_SOURCE_DESKTOP , param);     

Features

  • Reduced flickering while resizing or dragging
  • Multiple Backdrop Sources
  • You can exclude a particular window from acrylic like the host window does for itself.

Known Limitations

  • Sometimes the Desktop icons are missing in the acrylic effect.
  • There is no straight way to implement this in WPF or Win UI3.
  • Airspace Issue : Currently you can only use Direct Composition to draw something on top of acrylic effect.
  • Realtime Acrylic not supported, which means the host window redraw acrylic only when it is activated so fallback color is used.
  • Exclusion Blending and Noise effect not added (Can be implemented)

Supported Versions

This sample has been currently tested on:

Operating System Version Build
Windows 10 Pro 20H2 19042.1052

Join with us ๐Ÿšฉ

You can join our Discord Channel to connect with us. You can share your findings, thoughts and ideas on improving / implementing the Acrylic Effect on normal apps.

win32-acrylic-effect's People

Contributors

selastingeorge avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

win32-acrylic-effect's Issues

Unrelated question; thank you for your research!

Hey there!
I've frequently come back to this repo in my W11 deep-dive, as it's one of the few places online that gathers multiple different approaches and documents them clearly.
Thank you for your hard work.

I've got an unrelated question - you mention that you've been able to get the WPF SwapChain:

[..] The truth is Currently i was only able to get the swapchain backbuffer from WPF

Well, that's something I would find extremely useful. It's my understanding that many devs out there need/want a GPU-backed replacement for WPF's RenderTargetBitmap. Despite the many different flavours of XAML-based UI frameworks that exist now, it's still apparently a rare feature. If you happen to have that code lying around, I would love to take it, polish and turn it into a library.

Usage in OpenGL application

This works brilliantly in a stand-alone window, however when I try to implement it in an OpenGL & GLFW window , any objects drawn by OpenGL do not appear . Any ideas what could be wrong?
(Windows 10 21H1 )

BUG: Some cleanup is needed when closing the window

Hi, bro, thanks for the fantastic repo! It's quite impressive!

But when I was debugging this repo in Qt Creator, I got some warning messages when the window is closing:

DXGI WARNING: Process is terminating. Using simple reporting. Please call ReportLiveObjects() at runtime for standard reporting. [ STATE_CREATION WARNING #0: ]
DXGI WARNING: Live Producer at 0x0000025575ED72E8, Refcount: 4. [ STATE_CREATION WARNING #0: ]

Looks like some cleanup is needed at window shutdown. Do you have any clue of how to fix it?

BTW, I'm using a 4K monitor and I set scale factor to 250%, I found that the acrylic background is too large. But if I set dpi awareness to PerMonitorV2 programtically, it looks normal again. Maybe you should fix this as well. But using the manifest file is easier.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.