2012-07-08 7 views
12

Ho un modulo WPF senza bordi e non ridimensionabile (WindowStyle = None, AllowsTransparency = True, ResizeMode = NoResize) con uno sfondo semitrasparente. Ecco una foto di come la forma, un rettangolo rosso semi-trasparente, sembra in questo momento, che gira sopra il Blocco note:Sfocatura dello sfondo di una forma semitrasparente (come il vetro Aero)

the form as it currently appears on top of Notepad

Tuttavia, mi piacerebbe lo sfondo per essere offuscata, come il vetro come Aero lo fa, tranne senza tutti i bordi della finestra fantasia e lo sfondo colorato con strisce - Mi piacerebbe gestirlo da solo. Ecco un mockup di come voglio farlo sembrare come:

the form as I want it to be - blur anything that's below it

Come posso raggiungere questo obiettivo nel modo più efficiente possibile?

WinForms o WPF vanno bene per me. Spero che dovrebbe usare la stessa cosa che usa il vetro Aero (sto bene lavorando solo con Aero), invece di qualcosa di pazzo come catturare la regione dello schermo sotto come un bitmap e sfocarlo.

Ecco una foto di quello che non voglio:

I don't want the entire Aero glass window chrome

So che questo è possibile, e so come farlo, ma io non voglio l'intero Aero finestra di vetro cromato , o i bordi e la barra del titolo, o la finestra per avere il colore del vetro Aero impostato dall'utente, SOLO l'effetto di sfocare qualsiasi cosa si trovi sotto la finestra/il modulo.

+1

Avete visto http://stackoverflow.com/questions/421968/blurred-opacity? –

+0

Sì, e questo è sfocato INSIDE il modulo.Voglio che il modulo stesso offusca le altre finestre sotto di esso. –

+0

Hai provato questo: http://stackoverflow.com/questions/7815278/blur-the-background-of-the-wpf-taintainer – sloth

risposta

10

Se si desidera utilizzare l'Aero sfocatura quindi è possibile utilizzare l'API DwmEnableBlurBehindWindow. Ecco un esempio di finestra derivata che utilizza questo.

public class BlurWindow : Window 
{ 
    #region Constants 

    private const int WM_DWMCOMPOSITIONCHANGED = 0x031E; 
    private const int DWM_BB_ENABLE = 0x1; 

    #endregion //Constants 

    #region Structures 
    [StructLayout(LayoutKind.Sequential)] 
    private struct DWM_BLURBEHIND 
    { 
     public int dwFlags; 
     public bool fEnable; 
     public IntPtr hRgnBlur; 
     public bool fTransitionOnMaximized; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    private struct MARGINS 
    { 
     public int cxLeftWidth; 
     public int cxRightWidth; 
     public int cyTopHeight; 
     public int cyBottomHeight; 
    } 
    #endregion //Structures 

    #region APIs 

    [DllImport("dwmapi.dll", PreserveSig = false)] 
    private static extern void DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind); 

    [DllImport("dwmapi.dll")] 
    private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMargins); 

    [DllImport("dwmapi.dll", PreserveSig = false)] 
    private static extern bool DwmIsCompositionEnabled(); 

    #endregion //APIs 

    #region Constructor 
    public BlurWindow() 
    { 
     this.WindowStyle = System.Windows.WindowStyle.None; 
     this.ResizeMode = System.Windows.ResizeMode.NoResize; 
     this.Background = Brushes.Transparent; 
    } 
    #endregion //Constructor 

    #region Base class overrides 
    protected override void OnSourceInitialized(EventArgs e) 
    { 
     base.OnSourceInitialized(e); 

     if (Environment.OSVersion.Version.Major >= 6) 
     { 
      var hwnd = new WindowInteropHelper(this).Handle; 
      var hs = HwndSource.FromHwnd(hwnd); 
      hs.CompositionTarget.BackgroundColor = Colors.Transparent; 

      hs.AddHook(new HwndSourceHook(this.WndProc)); 
      this.InitializeGlass(hwnd); 
     } 
    } 
    #endregion //Base class overrides 

    #region Methods 

    #region InitializeGlass 
    private void InitializeGlass(IntPtr hwnd) 
    { 
     if (!DwmIsCompositionEnabled()) 
      return; 

     // fill the background with glass 
     var margins = new MARGINS(); 
     margins.cxLeftWidth = margins.cxRightWidth = margins.cyBottomHeight = margins.cyTopHeight = -1; 
     DwmExtendFrameIntoClientArea(hwnd, ref margins); 

     // initialize blur for the window 
     DWM_BLURBEHIND bbh = new DWM_BLURBEHIND(); 
     bbh.fEnable = true; 
     bbh.dwFlags = DWM_BB_ENABLE; 
     DwmEnableBlurBehindWindow(hwnd, ref bbh); 
    } 
    #endregion //InitializeGlass 

    #region WndProc 
    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
    { 
     if (msg == WM_DWMCOMPOSITIONCHANGED) 
     { 
      this.InitializeGlass(hwnd); 
      handled = false; 
     } 

     return IntPtr.Zero; 
    } 
    #endregion //WndProc 

    #endregion //Methods 
} 

E qui c'è un frammento di utilizzo di BlurWindow.

var w = new BlurWindow(); 
w.Width = 100; 
w.Height = 100; 
w.MouseLeftButtonDown += (s1, e1) => { 
    ((Window)s1).DragMove(); 
    e1.Handled = true; 
}; 
w.Background = new SolidColorBrush(Color.FromArgb(75, 255, 0, 0)); 
w.Show(); 
+1

Questo non sembra funzionare su Windows 8. – Hallgrim

+1

Probabilmente perché il vetro aerodinamico è disabilitato in Windows 8. Penso che [ci siano degli hack] (http://www.howtogeek.com/128630/how-to-enable-aero -glass-style-transparency-in-windows-8 /) per riattivarlo ma non è qualcosa che MS stia realmente supportando. – AndrewS

1

ho fatto qualcosa di simile una volta, ma non ho bisogno di quanto segue:

  1. non ho avuto bisogno di spostare la mia forma molto.
  2. Nessun movimento ha avuto luogo sotto la mia forma.

Quello che ho fatto:

  1. ho usato per ridurre al minimo la mia finestra del modulo per un momento (di programmazione).
  2. Modulo utilizzato per catturare lo snip dell'immagine delle sue dimensioni e con le stesse coordinate.
  3. Imposta l'immagine come sfondo dopo aver applicato lo BlurBitmapEffect.

Non è una buona risposta presumo, ma sto solo scrivendo quello che ho fatto!

Se siete interessati a questo approccio questo articolo vi aiuterà a: http://www.codeproject.com/Articles/91487/Screen-Capture-in-WPF-WinForms-Application

+1

Grazie, ma è quello che sto cercando di evitare. Aero è un gestore di finestre di compositing e non dovresti dover screencapare manualmente una parte dello schermo e sfocarla come una bitmap. Non solo è costoso, ma non è accelerato dall'hardware, a differenza di come Aero lo fa. –

Problemi correlati