5

のメソッドを使用して、Aero ガラスのボーダレスサイズ変更できないWPF ウィンドウを作成しようとしています。しかし、なぜかこの窓のガラスの色がピントが合っていないように見えます。次の 3 つの画像でわかるように、境界線のある通常のウィンドウ (図 1 と 2 など) は問題なく動作し、期待どおりに反応します (焦点が合っているときは紺色、焦点が合っていないときは白っぽい (= 非アクティブ))。DwmEnableBlurBehindWindowDmwAPI

ToolWindow を使用した DwmEnableBlurBehindWindow ToolWindow がフォーカスされていない DwmEnableBlurBehindWindow

サイズ変更が許可されたボーダレス ウィンドウは、同じ動作を示します。

DwmEnableBlurBehindWindow 枠なしでサイズ変更可能なウィンドウ

ただし、サイズ変更できないボーダレスウィンドウは、アクティブな場合と非アクティブな場合の両方で、(最後の図 3でわかるように) 常に焦点が合っていないように見えます。それは常に白っぽく見えます:

DwmEnableBlurBehindWindow (縁なしでサイズ変更不可のウィンドウ)

これは、ガラス スタイルを設定する方法のサンプル コードです。

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

ウィンドウにフォーカスを合わせてみましたが、動作に影響はないようです。これを解決する方法についてのアイデアや指針はありますか?

4

1 に答える 1

7

私は dwm API をあまり扱っていないので、間違っているかもしれませんが、デフォルトの dwm レンダリング ポリシーは WindowStyle を使用してレンダリングを把握していると思います。そのポリシーを無効にすると、期待どおりに動作します。

次のビットを追加して、ブルース xD を修正します

const int DWMWA_NCRENDERING_POLICY = 2;
int DWMNCRP_DISABLED = 2;

DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, ref DWMNCRP_DISABLED, sizeof(int));

このブードゥー教の詳細については、次のリソースを確認してください。

DwmSetWindowAttribute 関数

DWMWINDOWATTRIBUTE 列挙

MainWindow.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"/>

MainWindow.xaml.cs

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

フォーカスのあるスクリーンショット

フォーカスのあるスクリーンショット

フォーカスのないスクリーンショット

フォーカスなしのスクリーンショット

テスト環境

OS: Windows 8 - x64

テーマ: 標準的な窓

于 2013-06-24T12:44:16.313 に答える