Win32半透明窗口

时间:2020-03-21 01:36:56

标签: c++ windows winapi transparency

我正在尝试使用Win32 API和C ++获得一个半透明的窗口。尽管事实是, 大约有100万个结果试图回答这个问题,但似乎没有一个对我的案例有用。

我有一个本地Win32窗口,其中包含托管WPF内容。因为我正在尝试创建自定义 窗口框架(现在也可以使用),我希望自绘制框架的顶部是半 透明的,也可以应用丙烯酸的模糊效果。

查看WPF,我可以在窗口中使用AllowTransparency = True并用一个 透明背景。现在,我需要一种使用Win32 API复制该行为的方法。

从技术上讲,我可以使整个主窗口透明(因为主窗口完全是框架 并且WPF托管的内容是客户端区域),但即使这样也不起作用(不透明)。

作为参考,这是我创建窗口的方式:

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)
);

我已经看到我应该使用WS_EX_LAYERED,但这也没有达到预期的效果。 当然,WPF内容本身不应该是透明的!

2 个答案:

答案 0 :(得分:0)

好吧,尽管有所有答案,但我还是要阅读文档并查看其他 例子...原来,我放错了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)
);

答案 1 :(得分:0)

您的问题是

WPF内容本身不应透明!

可以使用Set/UpdateLayeredWindowAttributes,但是WPF内容的不透明度也会改变。

如果您确实要创建一个高性能的透明/半透明窗口,则需要指定WS_EX_NOREDIRECTIONBITMAP而不是WS_EX_LAYERED.标志,然后将DirectComposition与另一个图形API结合使用来呈现您的内容。

有关https://msdn.microsoft.com/magazine/dn745861.aspx的更多信息。