microsoft / Windows.UI.Composition-Win32-Samples

Windows.UI.Composition Win32 Samples
MIT License
469 stars 186 forks source link

Use Host BackdropBrush with Win32 window #84

Closed selastingeorge closed 3 years ago

selastingeorge commented 3 years ago

Hi, i was trying to implement the acylic effect in c++ winrt but when i call the function createHostBackdropBrush() , it only creates a black visual it is not showing the content behind the window. I don't know why ? tried multiple times , seems not working did anyone have any examples which implements this in c++. Or is it not supported ?

robmikh commented 3 years ago

Using host backdrop brushes isn't currently supported for Win32 callers. This may become available in future version of Windows. In the current Insider SDK (10.0.20308 at time of writing), you can find the window attribute that enables this. Look for DWMWA_USE_HOSTBACKDROPBRUSH in dwmapi.h.

selastingeorge commented 3 years ago

Do you have any sample codes of this, finding documentation on this is very hard.

On Wed, 7 Apr, 2021, 1:51 am Robert Mikhayelyan, @.***> wrote:

Using host backdrop brushes isn't currently supported for Win32 callers. This may become available in future version of Windows. In the current Insider SDK (10.0.20308 at time of writing), you can find the window attribute that enables this. Look for DWMWA_USE_HOSTBACKDROPBRUSH in dwmapi.h.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/microsoft/Windows.UI.Composition-Win32-Samples/issues/84#issuecomment-814414065, or unsubscribe https://github.com/notifications/unsubscribe-auth/ARKGWVK3JMYFQOR3LHB3NJTTHNUOFANCNFSM42MKYHTA .

robmikh commented 3 years ago

You'll need to use DwmSetWindowAttribute, and don't forget to link against dwmapi.lib. The code would look something like this:

BOOL value = TRUE;
winrt::check_hresult(DwmSetWindowAttribute(windowHandle, DWMWA_USE_HOSTBACKDROPBRUSH, reinterpret_cast<void*>(&value), sizeof(value)));
selastingeorge commented 3 years ago

Sir is it only available in windows insider? Or is it available in build 10.0.19041

On Wed, 7 Apr, 2021, 8:08 am Robert Mikhayelyan, @.***> wrote:

You'll need to use DwmSetWindowAttribute https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmsetwindowattribute, and don't forget to link against dwmapi.lib. The code would look something like this:

BOOL value = TRUE;winrt::check_hresult(DwmSetWindowAttribute(windowHandle, DWMWA_USE_HOSTBACKDROPBRUSH, reinterpret_cast<void*>(&value), sizeof(value));

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/microsoft/Windows.UI.Composition-Win32-Samples/issues/84#issuecomment-814558264, or unsubscribe https://github.com/notifications/unsubscribe-auth/ARKGWVNRMUIQ544WTFY7VA3THPASPANCNFSM42MKYHTA .

robmikh commented 3 years ago

As I said before, this isn't currently supported (including 10.0.19041). This is currently in Insider builds.

selastingeorge commented 3 years ago

Thank you for the clarification.

On Wed, 7 Apr, 2021, 8:16 am Robert Mikhayelyan, @.***> wrote:

As I said before, this isn't currently supported (including 10.0.19041). This is currently in Insider builds.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/microsoft/Windows.UI.Composition-Win32-Samples/issues/84#issuecomment-814560712, or unsubscribe https://github.com/notifications/unsubscribe-auth/ARKGWVK3XSNQPRDIBDZAR23THPBQFANCNFSM42MKYHTA .

selastingeorge commented 3 years ago

Since DWMWA_USE_HOSTBACKDROPBRUSHis only available in insider preview, I ended up with a new solution using SetWindowCompositionAttribute().

typedef enum _WINDOWCOMPOSITIONATTRIB
{
    WCA_UNDEFINED = 0,
    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_HOLOGRAPHIC = 23,
    WCA_EXCLUDED_FROM_DDA = 24,
    WCA_PASSIVEUPDATEMODE = 25,
    WCA_LAST = 26
} WINDOWCOMPOSITIONATTRIB;

typedef struct _WINDOWCOMPOSITIONATTRIBDATA
{
    WINDOWCOMPOSITIONATTRIB Attrib;
    PVOID pvData;
    SIZE_T cbData;
} WINDOWCOMPOSITIONATTRIBDATA;

typedef enum _ACCENT_STATE
{
    ACCENT_DISABLED = 0,
    ACCENT_ENABLE_GRADIENT = 1,
    ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
    ACCENT_ENABLE_BLURBEHIND = 3,
    ACCENT_ENABLE_ACRYLICBLURBEHIND = 4, // RS4 1803
    ACCENT_ENABLE_HOSTBACKDROP = 5, // RS5 1809
    ACCENT_INVALID_STATE = 6
} ACCENT_STATE;

typedef struct _ACCENT_POLICY
{
    ACCENT_STATE AccentState;
    DWORD AccentFlags;
    DWORD GradientColor;
    DWORD AnimationId;
} ACCENT_POLICY;

typedef BOOL(WINAPI* SetWindowCompositionAttribute)(IN HWND hwnd, N WINDOWCOMPOSITIONATTRIBDATA* pwcad);
SetWindowCompositionAttribute lSetWindowCompositionAttribute;

bool InitPrivateUser32APIs()
{
    auto user32Lib = LoadLibrary(L"user32.dll");

    if (!user32Lib)
        return false;

    lSetWindowCompositionAttribute = (SetWindowCompositionAttribute)GetProcAddress(user32Lib,"SetWindowCompositionAttribute");

    if (!lSetWindowCompositionAttribute)
        return false;

    return true;
}

And in your code call the method like this:

InitPrivateUser32APIs();
if (lSetWindowCompositionAttribute)
{
    ACCENT_POLICY accent = { ACCENT_ENABLE_HOSTBACKDROP, 0, 0, 0 };
    WINDOWCOMPOSITIONATTRIBDATA data;
    data.Attrib = WCA_ACCENT_POLICY;
    data.pvData = &accent;
    data.cbData = sizeof(accent);
    lSetWindowCompositionAttribute(hwnd, &data); //replace with your window hwnd
}