2013-06-22 2 views
6

Я пытаюсь создать полей и без изменяемых окна WPF Aero стекла с использованием DwmEnableBlurBehindWindow метода из DmwAPI. Однако по какой-то странной причине цвет стекла этого окна выглядит так, как если бы окно было не в фокусе. Как вы можете видеть на следующих трех изображениях, обычные окна с границами (, например, рис. 1 и 2) работают просто отлично и реагируют как ожидалось (темно-синий в фокусе, беловатый, когда не в фокусе (= неактивен)).стеклянного окна WPF, без границы и не изменяют размеров вне фокуса

DwmEnableBlurBehindWindow with ToolWindow DwmEnableBlurBehindWindow with ToolWindow out of focus

без границ окна с изменением размеров животных, показывает такое же поведение:

DwmEnableBlurBehindWindow with borderless but resizable window

без изменения размера полого окна, однако всегда будет выглядеть, как будто это из фокус (как вы можете видеть в последнем рисунке 3), когда он активен и неактивен. Она всегда выглядит беловатый:

DwmEnableBlurBehindWindow with borderless and non-resizable window

Это пример кода, как я установить стиль стекла:

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

Я попытался сфокусировать окно, но это, похоже, не влияет на поведение , Любые идеи или указатели на то, как это решить?

ответ

8

Я не работал много в dwm apis, поэтому я могу ошибаться, но я думаю, что политика рендеринга dwm по умолчанию использует WindowStyle для вычисления рендеринга. Если вы отключите эту политику, она будет вести себя так, как вы ожидали.

Добавьте следующий бит, чтобы исправить ваш блюз XD

const int DWMWA_NCRENDERING_POLICY = 2; 
int DWMNCRP_DISABLED = 2; 

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

Для деталей этого вуду, пожалуйста, проверьте следующие ресурсы:

DwmSetWindowAttribute function

DWMWINDOWATTRIBUTE enumeration

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

Скриншот с фокусом

Screenshot with focus

Скриншот без внимания

Screenoshot without focus

Test Environm лор

ОС: Windows 8 - x64

Тема: Стандартные окна

+0

Я попытался это раньше, и попробовал еще раз сейчас, но не повезло, к сожалению: 'IntPtr Дис = новый IntPtr (2); DwmApi.DwmSetWindowAttribute (mainWindowSrc.Handle, DwmApi.DwmWindowAttribute.DWMWA_NCRENDERING_POLICY, Дис, SizeOf (UINT)); ' – dsfgsho

+0

Будет нужно видеть больше кода, как я могу воспроизвести проблему именно так, как вы описали и исправить его с помощью кода выше. Возможно, мы сможем переключиться на обсуждение комнаты. Я в сети почти все рабочие дни (GMT + 1) в комнате WPF – Maverik

+0

Вот полный пример кода с использованием окна WPF: http://pastebin.com/TrAe1DPd – dsfgsho

 Смежные вопросы

  • Нет связанных вопросов^_^