DWM 模糊隐藏概述
(DWM) 效果的签名桌面窗口管理器之一是半透明和模糊的非工作区。 DWM API 使应用程序能够将这些效果应用到其顶级窗口的工作区。
备注
Windows Vista 家庭普通版不支持透明玻璃效果。 通常在其他 Windows 版本上使用透明玻璃效果呈现的区域呈现为不透明。 从 Windows 8 开始,由于窗口的呈现方式发生了样式更改,调用此函数不会导致模糊效果。
本主题讨论 DWM 启用的以下客户端模糊隐藏方案。
应用程序可以将模糊效果应用于窗口的整个客户端区域或特定子区域。 这使应用程序能够添加带样式的路径和搜索栏,这些路径和搜索栏在视觉上与应用程序的其余部分分开。
此方案中使用的 API 是 DwmEnableBlurBehindWindow 函数,该函数利用 常量后面的 DWM 模糊 和 DWM_BLURBEHIND 结构。
下面的示例函数 EnableBlurBehind
演示如何将模糊隐藏效果应用于整个窗口。
HRESULT EnableBlurBehind(HWND hwnd)
{
HRESULT hr = S_OK;
// Create and populate the blur-behind structure.
DWM_BLURBEHIND bb = {0};
// Specify blur-behind and blur region.
bb.dwFlags = DWM_BB_ENABLE;
bb.fEnable = true;
bb.hRgnBlur = NULL;
// Enable blur-behind.
hr = DwmEnableBlurBehindWindow(hwnd, &bb);
if (SUCCEEDED(hr))
{
// ...
}
return hr;
}
请注意,hRgnBlur 参数中指定 NULL。 这会告知 DWM 在整个窗口后面应用模糊。
下图演示了应用于整个窗口的模糊隐藏效果。
若要在子区域后面应用模糊,请将有效的区域句柄 (HRGN) 应用于 DWM_BLURBEHIND 结构的 hRgnBlur 成员,并将 DWM_BB_BLURREGION 标志添加到 dwFlags 成员。
将模糊隐藏效果应用于窗口的子区域时,窗口的 alpha 通道用于非模糊区域。 这可能会导致窗口的非模糊区域出现意外的透明度。 因此,在对子区域应用模糊效果时要小心。
应用程序可以将窗口框架的模糊扩展到工作区。 当你使用停靠工具栏或在视觉上将控件与应用程序的其余部分分开时,在窗口后面应用模糊效果时,这非常有用。 此功能由 DwmExtendFrameIntoClientArea 函数公开。
若要使用 DwmExtendFrameIntoClientArea 启用模糊,请使用 MARGINS 结构来指示扩展到工作区的量。 下面的示例函数 ExtendIntoClientBottom
将非客户端帧底部的模糊扩展切换到工作区。
HRESULT ExtendIntoClientBottom(HWND hwnd)
{
HRESULT hr = S_OK;
// Set the margins, extending the bottom margin.
MARGINS margins = {0,0,0,25};
// Extend the frame on the bottom of the client area.
hr = DwmExtendFrameIntoClientArea(hwnd,&margins);
if (SUCCEEDED(hr))
{
// ...
}
return hr;
}
下图演示了扩展到工作区底部的模糊隐藏效果。
也可通过 DwmExtendFrameIntoClientArea 方法使用“玻璃片”效果,其中模糊效果应用于没有可见窗口边框的整个窗口表面。 以下示例演示了这种效果,其中不带窗口边框地呈现工作区。
HRESULT ExtendIntoClientAll(HWND hwnd)
{
HRESULT hr = S_OK;
// Negative margins have special meaning to DwmExtendFrameIntoClientArea.
// Negative margins create the "sheet of glass" effect, where the client
// area is rendered as a solid surface without a window border.
MARGINS margins = {-1};
// Extend the frame across the whole window.
hr = DwmExtendFrameIntoClientArea(hwnd,&margins);
if (SUCCEEDED(hr))
{
// ...
}
return hr;
}
下图演示了“玻璃片”窗口样式中的模糊。