首发于我的个人博客:xie-kang.com
博客内有更多文章,欢迎大家访问
原文地址
前言:
很多人看到这个需求的第一想法都是录制软件窗口后的桌面内容,并且加上个高斯模糊就能实现了。
思路没有错,操作系统提供的API本质也是这样实现的。
但是我们软件是处于用户态的,怎么获取自己窗口背后的内容?当然也只能通过系统API实现!关键是如果你录制或者截图屏幕内容,在一些操作系统,比如macOS上系统会弹窗告知用户是否允许软件录制屏幕,这用户能接受吗?
所以说这么多,使用系统提供的API实现毛玻璃这个方式是最好的。
正文:
win7上可以使用DwmEnableBlurBehindWindow、win10上使用SetWindowCompositionAttribute(MSDN未公开的API)都可以实现毛玻璃的效果;
给Qt窗口设置上 setAttribute(Qt::WA_TranslucentBackground) 属性即可除去背景色将整个窗口透明。
在默认情况下使用SetWindowCompositionAttribute边框会有三条透明边在窗口的四周,因为该API实现的毛玻璃的过程是在窗口后创建了一个包括主窗口阴影的在内的辅助窗口在主窗口之后。
要除去这三条透明边可以使用 setWindowFlag(Qt::FramelessWindowHint) 创建一个无边框的窗口,效果如下:
但有时候出于实际的业务需求或者代码兼容问题我们需要保留窗口的边框,可以考虑以下方案:
1.主窗口使用
QtWin::enableBlurBehindWindow(this);
setAttribute(Qt::WA_TranslucentBackground);
实现带边框的背景透明窗口;
2.创建一个与主窗口宽高一致的Widget(或窗口),将其设置为无边框窗口以及毛玻璃效果,使其实时跟随主窗口的宽高以及大小并保持在主窗口之下;
注:Qt上可以使用QGraphicsBlurEffect实现控件的模糊效果,如果搭配上透明背景是否可以也实现毛玻璃效果呢?这个没有实践。
SetWindowCompositionAttribute使用示例代码:
struct WCAD
{
WindowCompositionAttribute Attribute;
int * Data;
int SizeOfData;
};
typedef int* (*pfun)(HWND hwnd, WCAD *data);
HWND hWnd = HWND(winId());
HMODULE hUser = GetModuleHandle(L"user32.dll");
if (hUser) {
pfun setWindowCompositionAttribute = (pfun)GetProcAddress(hUser, "SetWindowCompositionAttribute");
if (setWindowCompositionAttribute) {
AccentPolicy accent = {3, 0, 0, 0};//ACCENT_ENABLE_BLURBEHIND 具体枚举参加MSDN
WCAD data;
data.Attribute = 19;//WCA_ACCENT_POLICY 具体枚举参加MSDN
data.Data = reinterpret_cast<int *>(&accent) ;
data.SizeOfData = sizeof(accent);
setWindowCompositionAttribute(hWnd, &data);
}
}
参考链接:
MSDN dwmapi: https://docs.microsoft.com/zh-cn/windows/win32/api/dwmapi/nf-dwmapi-dwmsetwindowattribute?redirectedfrom=MSDN
Qt 在win7上实现背景毛玻璃效果的音乐播放器: https://doc.qt.io/qt-5/qtwinextras-musicplayer-example.html
QGraphicsBlurEffect类说明: https://doc.qt.io/qt-5/qgraphicsblureffect.html
SetWindowCompositionAttribute 各设置的对比(c#): https://blog.csdn.net/wpwalter/article/details/103268596
标签:窗口,Qt,Windows,API,SetWindowCompositionAttribute,data,毛玻璃 From: https://www.cnblogs.com/xie-kang/p/16814892.html