【问题标题】:Creating Windows 10 Transparency effects in c# form以 c# 形式创建 Windows 10 透明效果
【发布时间】:2018-12-24 12:33:45
【问题描述】:

如何创建您在 Windows 10 中看到的透明效果?像这样的:

我不知道如何在 c# 中处理这个问题。从逻辑上讲,每次表单成为焦点时,我都会拍摄桌面快照。然后将其模糊并放置在 0, 0(屏幕到客户端坐标)。这似乎不是很有效。有什么帮助吗?再次。不是经验丰富的 C# 程序员,所以非常感谢详细解释

编辑:我看到一些答案将我引向 alpha 混合页面。这不是我要找的。我想知道如何创建您在图像中看到的模糊效果,其余的我可以按照自己的步调解决

【问题讨论】:

  • 如果你想要高级图形,WinForms 根本帮不了你。您将需要查看 WPF 或 UWP
  • 这是一个逐像素的 alpha 混合效果。实际由 DirectComposition 实现,与 [winforms] 相距二十年。在 Winforms 应用程序中是 not impossible to use,但您不能再使用工具箱中的大多数控件了。他们使用 24bpp GDI 调用进行渲染。 WPF 使用与其兼容的渲染模型。
  • 有点谷歌搜索,我发现在 SO:stackoverflow.com/questions/4096609/…
  • 几个月前我已经发布了一些相关代码。 Borderless Form Dropshadow。这是关于将 Aero 样式 DropShadow 添加到无边框 WinForm 中。但是我错误地离开了很多其他与 DWM Api 相关的方法。其中包括DwmExtendFrameIntoClientArea()(创建一块玻璃)和DwmEnableBlurBehindWindow() 的实现。也许它对你有一些用处。

标签: c# winforms windows-10


【解决方案1】:

虽然所有 cmets 和答案都说 WinForms 不可能,但它肯定也适用于 WinForms(因为 SetWindowCompositionAttribute 可以在 Win32 窗口句柄上调用):

internal enum AccentState
{
    ACCENT_DISABLED = 0,
    ACCENT_ENABLE_GRADIENT = 1,
    ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
    ACCENT_ENABLE_BLURBEHIND = 3,
    ACCENT_INVALID_STATE = 4
}

internal enum WindowCompositionAttribute
{
    WCA_ACCENT_POLICY = 19
}

[StructLayout(LayoutKind.Sequential)]
internal struct AccentPolicy
{
    public AccentState AccentState;
    public int AccentFlags;
    public int GradientColor;
    public int AnimationId;
}

[StructLayout(LayoutKind.Sequential)]
internal struct WindowCompositionAttributeData
{
    public WindowCompositionAttribute Attribute;
    public IntPtr Data;
    public int SizeOfData;
}

internal static class User32
{
    [DllImport("user32.dll")]
    internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);
}

然后在你的 Form 构造函数中:

public Form1()
{
    InitializeComponent();
    BackColor = Color.Black; // looks really bad with the default back color

    var accent = new AccentPolicy { AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND };

    var accentStructSize = Marshal.SizeOf(accent);

    var accentPtr = Marshal.AllocHGlobal(accentStructSize);
    Marshal.StructureToPtr(accent, accentPtr, false);

    var data = new WindowCompositionAttributeData
    {
        Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY,
        SizeOfData = accentStructSize,
        Data = accentPtr
    }

    User32.SetWindowCompositionAttribute(Handle, ref data);
    Marshal.FreeHGlobal(accentPtr);
}

结果:

【讨论】:

    【解决方案2】:

    你可以通过一些算法得到它

    我不知道它是否有效。当我看到你的帖子时,我只是想到并得到了这个概念。

    1. 使用copyscreen方法获取整个windows桌面壁纸图片

    2. 将该图像绘制到一个新位图中,其中位图宽度 = 屏幕分辨率.宽度和位图高度 = 屏幕分辨率.高度 例如:位图 bm = 新位图 (1920, 1080)

    3. 了解如何在 C# 中模糊位图图像。有许多博客教授如何以编程方式模糊位图。

    4. 模糊捕获的桌面壁纸图像

    5. 在form里面放一张图片,把模糊的位图绘制到picturebox中

    6. 你可以让FormBorderStyle.None摆脱旧边框

    7. 您应该保持picturebox图片样式=正常以获得完全模糊的图像

    【讨论】:

      【解决方案3】:

      到目前为止,Windows 窗体不支持AcrylicBrush。只有 UWP 支持。

      但是你有一个 Win32 API SetWindowCompositionAttribute 来模拟这种行为。


      SetWindowCompositionAttribute API

      通过调用Windows内部APISetWindowCompositionAttribute,可以得到一个稍微模糊的透明Window,但是这个透明度比AcyclicBrush小很多。

      如何实现

      调用SetWindowCompositionAttribute API 不是很容易,所以我编写了一个包装类以便于使用。但它仅适用于 WPF。

      我已经写了两篇讨论这个的帖子:

      其他选项

      建议在 UWP 中使用 AcrylicBrush,您可以阅读微软的文档Acrylic material - UWP app developer | Microsoft Docs 了解更多详情。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-25
        • 1970-01-01
        • 2014-03-27
        相关资源
        最近更新 更多