【问题标题】:Remove DropShadow for Maximized WPF Custom Window删除最大化 WPF 自定义窗口的 DropShadow
【发布时间】:2011-12-20 09:39:48
【问题描述】:

我有一个带有自定义窗口边框的 WPF 应用程序 (.NET Framework 4)。我已经使用WPF Shell Integration Library 禁用了玻璃边框,并绘制了我自己的边框。但是,我想在未最大化时在窗口边框周围添加一个 DropShadow。我添加了这样的阴影:

private static bool DropShadow(Window window)
{
    try
    {
        WindowInteropHelper helper = new WindowInteropHelper(window);
        int val = 2;
        int ret1 = DwmSetWindowAttribute(helper.Handle, 2, ref val, 4);

        if (ret1 == 0)
        {
            Margins m = new Margins { Bottom = 0, Left = 0, Right = 0, Top = 0 };
            int ret2 = DwmExtendFrameIntoClientArea(helper.Handle, ref m);
            return ret2 == 0;
        }
        else
        {
            return false;
        }
    }
    catch (Exception ex)
    {
        // Probably dwmapi.dll not found (incompatible OS)
        return false;
    }
}

更多详情见:DropShadow for WPF Borderless Window

此解决方案在使用 WindowState.Normal! 时效果很好!但是,当我最大化应用程序并禁用 DWMWA_NCRENDERING_POLICY 时,窗口的背景会变得稍微透明,并且我的大多数控件呈现的效果与我习惯的完全不同。

在下图中,您可以看到最初的最大化状态以及阴影代码。如您所见,它使用阴影代码完全改变了窗口的透明度:o

我有什么遗漏吗?我一直在阅读DWM Function library,但找不到答案...

【问题讨论】:

  • 在此处使用Snoop 可能对您有所帮助 - 这是一个非常好的 WPF 间谍工具,可让您查看 WPF 应用程序的所有不同渲染层以及当前属性值。跨度>
  • Snooping 我的应用程序时什么也没出现,两个实例完全相同!它在winapi中的某个地方出错了,我只是不知道为什么..因为我在应用程序最大化时很好地禁用了渲染策略!

标签: wpf windows winapi transparency


【解决方案1】:

过了一会儿,我从不同的角度重新审视了这个问题,并找到了更好的解决方案:

public class GlassWindow : Window
{
    [SuppressUnmanagedCodeSecurity]
    internal static class DwmNativeMethods
    {
        [StructLayout(LayoutKind.Sequential)]
        internal struct DwmMargins
        {
            public int cxLeftWidth;
            public int cxRightWidth;
            public int cyTopHeight;
            public int cyBottomHeight;

            public DwmMargins(bool fullWindow)
            {
                this.cxLeftWidth = this.cxRightWidth = this.cyTopHeight = this.cyBottomHeight = fullWindow ? -1 : 0;
            }
        }

        [DllImport("DwmApi.dll")]
        internal static extern int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref DwmMargins m);

        [DllImport("DwmApi.dll")]
        internal static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
    }

    private IntPtr windowHandle;

    protected override void OnSourceInitialized(EventArgs e)
    {
        base.OnSourceInitialized(e);

        WindowInteropHelper interopHelper = new WindowInteropHelper(this);
        this.windowHandle = interopHelper.Handle;

        this.ToggleAreoGlass(this.WindowState != WindowState.Maximized);

        this.StateChanged += this.GlassWindowStateChanged;
    }

    private void ToggleAreoGlass(bool value)
    {
        // Enable NcRenderingPolicy
        int attrValue = 2;
        int result = DwmNativeMethods.DwmSetWindowAttribute(this.windowHandle, 2, ref attrValue, 4);

        if (result == 0)
        {
            // Extend DwmFrame
            DwmNativeMethods.DwmMargins margins = new DwmNativeMethods.DwmMargins(value);
            DwmNativeMethods.DwmExtendFrameIntoClientArea(this.windowHandle, ref margins);
        }
    }

    private void GlassWindowStateChanged(object sender, EventArgs e)
    {
        this.ToggleAreoGlass(this.WindowState != WindowState.Maximized);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-16
    • 1970-01-01
    • 2017-11-24
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    相关资源
    最近更新 更多