C# WPF玻璃窗,无边框,无调整焦点
我正在尝试使用C# WPF玻璃窗,无边框,无调整焦点,c#,wpf,aero,aero-glass,C#,Wpf,Aero,Aero Glass,我正在尝试使用DmwAPI中的DwmEnableBlurBehindWindow方法创建一个Aero glass无边框和不可调整大小的WPF窗口。然而,由于某种奇怪的原因,此窗口的玻璃颜色看起来好像窗口不对焦。正如您在接下来的三幅图像中所看到的,带边框的普通窗口(如图1和图2)工作正常,并按预期反应(焦点为深蓝色,失焦时为白色(=非活动)) 允许调整大小的无边框窗口显示相同的行为: 然而,不可调整大小的无边框窗口无论处于活动状态还是处于非活动状态时,都会看起来像是失去了焦点(如上图3所示)
DmwAPI
中的DwmEnableBlurBehindWindow
方法创建一个Aero glass无边框和不可调整大小的WPF窗口。然而,由于某种奇怪的原因,此窗口的玻璃颜色看起来好像窗口不对焦。正如您在接下来的三幅图像中所看到的,带边框的普通窗口(如图1和图2)工作正常,并按预期反应(焦点为深蓝色,失焦时为白色(=非活动))
允许调整大小的无边框窗口显示相同的行为:
然而,不可调整大小的无边框窗口无论处于活动状态还是处于非活动状态时,都会看起来像是失去了焦点(如上图3所示)。它总是看起来发白:
以下是我如何设置玻璃样式的示例代码:
public MainWindow()
{
InitializeComponent();
WindowStyle = WindowStyle.None;
ResizeMode = ResizeMode.NoResize;
Height = 200;
Background = Brushes.Transparent;
Loaded += MainWindow_Loaded;
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
var windowInteropHelper = new WindowInteropHelper(this);
var handle = windowInteropHelper.Handle;
var mainWindowSrc = HwndSource.FromHwnd(handle);
if (mainWindowSrc != null)
if (mainWindowSrc.CompositionTarget != null)
mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 0, 0, 0);
var glassParams = new DwmApi.DwmBlurbehind
{
dwFlags = DwmApi.DwmBlurbehind.DWM_BB_ENABLE,
fEnable = true,
hRegionBlur = IntPtr.Zero
};
IntPtr dis = new IntPtr(2);
DwmApi.DwmSetWindowAttribute(mainWindowSrc.Handle,
DwmApi.DwmWindowAttribute.DWMWA_LAST,
dis,
sizeof(uint));
DwmApi.DwmEnableBlurBehindWindow(
handle,
glassParams
);
}
我试着聚焦窗口,但这似乎并不影响行为。关于如何解决这个问题,有什么想法或建议吗?我在dwm API方面做得不多,所以我可能错了,但我认为默认的dwm渲染策略是使用WindowsStyle进行渲染。如果禁用该策略,它将按预期运行 添加以下位以修复blues xD
const int DWMWA_NCRENDERING_POLICY = 2;
int DWMNCRP_DISABLED = 2;
DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, ref DWMNCRP_DISABLED, sizeof(int));
有关此巫毒的详细信息,请查看以下资源:
main window.xaml
<Window x:Class="dwm.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"/>
聚焦屏幕截图
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
namespace dwm
{
public partial class MainWindow
{
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmEnableBlurBehindWindow(IntPtr hwnd, ref DwmBlurbehind blurBehind);
[DllImport("dwmapi.dll", PreserveSig = true)]
private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
public MainWindow()
{
InitializeComponent();
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
var bb = new DwmBlurbehind
{
dwFlags = CoreNativeMethods.DwmBlurBehindDwFlags.DwmBbEnable,
Enabled = true
};
WindowStartupLocation = WindowStartupLocation.CenterScreen;
Background = Brushes.Transparent;
ResizeMode = ResizeMode.NoResize;
WindowStyle = WindowStyle.None;
Focus();
var hwnd = new WindowInteropHelper(this).Handle;
HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent;
DwmEnableBlurBehindWindow(hwnd, ref bb);
const int dwmwaNcrenderingPolicy = 2;
var dwmncrpDisabled = 2;
DwmSetWindowAttribute(hwnd, dwmwaNcrenderingPolicy, ref dwmncrpDisabled, sizeof(int));
}
[StructLayout(LayoutKind.Sequential)]
public struct DwmBlurbehind
{
public CoreNativeMethods.DwmBlurBehindDwFlags dwFlags;
public bool Enabled;
public IntPtr BlurRegion;
public bool TransitionOnMaximized;
}
public static class CoreNativeMethods
{
public enum DwmBlurBehindDwFlags
{
DwmBbEnable = 1,
DwmBbBlurRegion = 2,
DwmBbTransitionOnMaximized = 4
}
}
}
}
无焦点屏幕截图
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
namespace dwm
{
public partial class MainWindow
{
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmEnableBlurBehindWindow(IntPtr hwnd, ref DwmBlurbehind blurBehind);
[DllImport("dwmapi.dll", PreserveSig = true)]
private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
public MainWindow()
{
InitializeComponent();
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
var bb = new DwmBlurbehind
{
dwFlags = CoreNativeMethods.DwmBlurBehindDwFlags.DwmBbEnable,
Enabled = true
};
WindowStartupLocation = WindowStartupLocation.CenterScreen;
Background = Brushes.Transparent;
ResizeMode = ResizeMode.NoResize;
WindowStyle = WindowStyle.None;
Focus();
var hwnd = new WindowInteropHelper(this).Handle;
HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent;
DwmEnableBlurBehindWindow(hwnd, ref bb);
const int dwmwaNcrenderingPolicy = 2;
var dwmncrpDisabled = 2;
DwmSetWindowAttribute(hwnd, dwmwaNcrenderingPolicy, ref dwmncrpDisabled, sizeof(int));
}
[StructLayout(LayoutKind.Sequential)]
public struct DwmBlurbehind
{
public CoreNativeMethods.DwmBlurBehindDwFlags dwFlags;
public bool Enabled;
public IntPtr BlurRegion;
public bool TransitionOnMaximized;
}
public static class CoreNativeMethods
{
public enum DwmBlurBehindDwFlags
{
DwmBbEnable = 1,
DwmBbBlurRegion = 2,
DwmBbTransitionOnMaximized = 4
}
}
}
}
测试环境
操作系统:Windows8-x64
主题:标准windows我以前试过,现在又试了一次,但不幸的是没有成功:`IntPtr dis=new IntPtr(2);DwmApi.DwmSetWindowAttribute(mainWindowSrc.Handle,DwmApi.DwmWindowAttribute.DWMWA_NCRENDERING_POLICY,dis,sizeof(uint))`将需要看到更多的代码,因为我可以复制您的问题,正如您所描述的,并用上面的代码修复它。也许我们可以换成房间讨论。我几乎所有的工作日(GMT+1)都在WPF房间上网。我还没有看过你的代码,但我想我发现了你的问题。您使用的是
IntPtr
,我使用的是ref int
。事实上,如果我使用您的方法签名,我的代码将无法工作。尝试切换到ref int
,看看它是否适合您。@StevenHouben我刚刚使用了您的整个代码位,将方法签名更改为ref int
,您的代码也可以工作。谢谢,它可以工作!还有一件事:关于如何防止窗口失焦有什么想法吗?我需要它的行为类似于任务栏。