windows - 在 Win32 应用程序中模仿 Acrylic

标签 windows winapi dwm

Microsoft 最近宣布 Acrylic, the glass-like material in Fluent Design .它仅以 XAML/UWP 形式呈现,但看起来与玻璃非常相似,除了它可以任意着色并且可以在应用内应用到天桥控件以及应用的独立窗口。

“配方”让它看起来好像是 implemented in XAML itself ,不暴露于更广泛的系统。

Microsoft's recipe for making acrylic: background, blue, blend, tint, noise

一个相关的 SO 问题 confirms this (它没有具体的技术答案,但暗示丙烯酸不能像玻璃那样通过 WinAPI 获得。)

人们如何在普通的老式 Win32 应用程序中模仿它? 使用玻璃并混合? (哪些 API,和 what's possible in Win10 Fall Update's glass APIs that was not in Win7?)如果应用程序是使用 Win32 创建的,但使用 DirectX 表面进行渲染,是否会打开更多可能性?

最佳答案

正如@zett42 的回答中提到的,我认为它是使用 DirectComposition 实现的。

一点历史:在 Vista 中,Microsoft 推出了桌面窗口管理器 DWM,它是桌面的合成引擎。使用 DWM,窗口绘制到纹理,然后在 DWM 中组合。好处是您可以获得 3D 动画、透明度等奇特效果,而且所有内容都是双缓冲的,因此您不会出现渲染伪像。

DWM最初是基于MIL(Media integration layer),我认为是场景图API。有趣的是,当时推出的 WPF 也使用了 MIL。这真的很酷,因为 DWM 可以看到 WPF 窗口的场景图,并且当它产生这样的效果时,例如放大窗口,它会将它视为矢量而不是位图,因此它可以在没有伪影的情况下缩放它。然而,在某些时候,Microsoft fork 了 WPF 中使用的 MIL 版本,并且这种集成丢失了。

快进到 Windows 8 几年。Microsoft 推出了新的“Metro”应用程序(后来是“Modern”,现在是“UWP”)。在底层,这些现代应用程序使用新的组合 API,即 DirectComposition。此 API 也可用于 Win32 应用程序,现在由 DWM 本身使用。如果您查看公共(public) DWM 功能,一些与 MIL 相关的功能已被弃用,因此它支持我的理论,即 MS 从 MIL 转向 DC。因此,现在我们再次处于应用程序和 DWM 使用相同基础架构的初始情况,我们可以轻松添加一些有趣的效果。

在某些时候,MS 向 DirectComposition 引入了新的混合效果,由 IDCompositionDevice3 提供。界面。其中包括高斯模糊效果,还有噪声、色调和其他必要的效果。我找到了一种在我的窗口应用这些效果的方法,但我不知道如何将它们应用到我的窗口。不幸的是,我现在无法访问我的代码,我会在访问时更新我的​​答案。

我的探索基于文章 Efficient Alpha-Blended Windows: DirectComposition .基本上,您有一个对应于屏幕的“设备”和一个对应于您的窗口内容的“视觉”。您需要更改的是:

  • 您的设备可以为您创建效果。记住 QueryInterfaceIDCompositionDevice3
  • 然后,您可以在您的 IDCompositionVisual3 上调用 SetEffect

但是,正如我所说,这仅适用于窗口内容。我认为必须有一个 secret 的 API 来从 DWM 获取当前窗口的父 Visual,然后只需对该 Visual 调用 SetEffect 即可获得效果。如果有人精通调试器,应该可以通过跟踪使用 Acyllic 效果的 UWP 应用找到该 API。

作为意外事件,我将查看 GetWindowCompositionAttribute 函数。它最近获得了一些有趣的声音标志,例如 WCA_VISUAL_OWNER。

关于windows - 在 Win32 应用程序中模仿 Acrylic,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44000217/

相关文章:

windows - DirectX 12 "Full Screen Exclusive Windows"是否强制以与 DWM 相同的刷新率运行?

c# - 如何从 C# 或 VB.Net 使用 Win32 'DwmSetIconicThumbnail'?

windows - 如何在Windows中查找azure cli的位置

c++ - 如何使用对话框参数?

delphi - 如何从图像中获取摘要信息?

delphi - 像 PsSuspend 一样暂停/恢复进程

c++ - 如何查看应用程序运行的系统是否有所需的Windows API函数?

c++ - 在 Linux 上 boost windows_shared_memory

winapi - 如何使用 VC++ 使用 win32 API 创建椭圆形窗口

java - 使用 JNA (Java) 进行 Windows 缩略图预览