Janrupf
Janrupf

Reputation: 55

Win32 semi transparent window

I'm trying to get a semi transparent window with the Win32 API and C++. Despite the fact, that there are around a million results trying to answer that question, none of those seem to have worked for my case.

I have a native Win32 window with a hosted WPF content inside it. Because I'm trying to create a custom window frame (and that also works by now), I want the top part of the self drawn frame to be semi transparent, possibly also applying the acrylic blur.

Looking at WPF, I could archive my goal using AllowTransparency = True on the window and with a transparent background. Now I need a way to replicate that behavior with the Win32 API.

Technically, I can make the entire main window transparent (because the main window is the frame entirely and the WPF hosted content is the client area), but even that didn't work (no transparency).

For reference, here is how I'm creating my window:

WNDCLASSEXW window_class_ex = {
    sizeof(WNDCLASSEXW),
    CS_HREDRAW | CS_VREDRAW,
    window_callback,
    0,
    0,
    application_instance,
    nullptr,
    LoadCursorW(nullptr, IDC_ARROW),
    CreateSolidBrush(RGB(0, 0, 0)),
    nullptr,
    window_class,
    nullptr
};

const HWND window_handle = CreateWindowExW(
    0,
    window_class,
    L"WinSoup",
    WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_EX_LAYERED,
    CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,
    nullptr,
    nullptr,
    application_instance,
    reinterpret_cast<LPVOID>(owner)
);

I have seen that I should use WS_EX_LAYERED, but also that didn't have the desired effect. Of course the WPF content itself should not be transparent!

Upvotes: 0

Views: 2838

Answers (2)

Arush Agarampur
Arush Agarampur

Reputation: 1430

Your question says

The WPF content itself should not be transparent!

You can use Set/UpdateLayeredWindowAttributes, but the opacity for your WPF content will change too.

If you really want to create a high-performance transparent/semi-transparent window, you need to specify the WS_EX_NOREDIRECTIONBITMAP flag instead of WS_EX_LAYERED. Then use DirectComposition with another graphics API to render your content.

Look at https://msdn.microsoft.com/magazine/dn745861.aspx for more details.

Upvotes: 1

Janrupf
Janrupf

Reputation: 55

Ok, so, despite all the answers telling me to read the documentation and look at other examples... turns out, I misplaced the WS_EX_LAYERED.

const HWND window_handle = CreateWindowExW(
    WS_EX_LAYERED, // Needs to be placed here (extended style)
    window_class,
    L"WinSoup",
    WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX, // Not here!
    CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,
    nullptr,
    nullptr,
    application_instance,
    reinterpret_cast<LPVOID>(owner)
);

Upvotes: 1

Related Questions