gpt4 book ai didi

wpf - 删除最大化 WPF 自定义窗口的 DropShadow

转载 作者:可可西里 更新时间:2023-11-01 14:19:33 25 4
gpt4 key购买 nike

我有一个带有自定义窗口边框的 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 enter image description here

有什么我想念的吗?我一直在阅读 DWM Function library却找不到答案……

最佳答案

一段时间后,我从另一个角度重新审视了这个问题,并想出了一个更好的解决方案:

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);
}
}

关于wpf - 删除最大化 WPF 自定义窗口的 DropShadow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8573420/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com