2012-07-08 18 views
12

Tengo un formulario WPF sin tamaño, sin tamaño variable (WindowStyle = None, AllowsTransparency = True, ResizeMode = NoResize) con un fondo semitransparente. Aquí está una imagen de cómo la forma, un rectángulo rojo semitransparente, se ve en este momento, que se ejecuta en la parte superior de la libreta:Difuminando el fondo de una forma semitransparente (como Aero glass)

the form as it currently appears on top of Notepad

Sin embargo, me gustaría que el fondo a difuminarse, como el cristal de cómo Aero lo hace, excepto sin todos los elegantes bordes de la ventana y el fondo de color con rayas; me gustaría manejarlo yo mismo. Aquí hay una maqueta de cómo quiero que se vea como:

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

¿Cómo puedo lograr esto de la manera más eficiente posible?

WinForms o WPF está bien para mí. Esperemos que use lo mismo que usa Aero Glass (estoy de acuerdo con que funcione solo con Aero habilitado), en lugar de algo tan loco como capturar la región de la pantalla de abajo como un mapa de bits y desenfocar eso.

Aquí está una imagen de lo que Yo NO QUIERO:

I don't want the entire Aero glass window chrome

Sé que esto es posible y sé cómo hacerlo, pero yo no quiero toda la ventana de cristal cromo Aero , o los bordes y la barra de título, o la ventana para tener el color de cristal Aero configurado por el usuario, SOLO el efecto de difuminar lo que esté debajo de la ventana/formulario.

+1

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

+0

Sí, y eso se está borrando DENTRO del formulario.Quiero que el formulario mismo desdibuje otras ventanas debajo de él. –

+0

Ha intentado esto: http://stackoverflow.com/questions/7815278/blur-the-background-of-the-wpf-container – sloth

Respuesta

10

Si desea utilizar el Aero desenfoque a continuación, puede utilizar la API de DwmEnableBlurBehindWindow. Aquí hay un ejemplo de ventana derivada que utiliza esto.

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 
} 

Y aquí hay un fragmento del uso de 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

Esto no parece funcionar en Windows 8. – Hallgrim

+1

Eso es probablemente porque Aero Glass está deshabilitado en Windows 8. Creo que [hay hacks] (http://www.howtogeek.com/128630/how-to-enable-aero -glass-style-transparency-in-windows-8 /) para volver a habilitarlo, pero no es algo que MS realmente esté soportando. – AndrewS

1

hice algo similar una vez, pero que no necesitaba el siguiente:

  1. que no necesitaba para cambiar mi forma mucho.
  2. No se produjo ningún movimiento en mi formulario.

Lo que hice:

  1. he usado para minimizar la ventana de mi forma por un momento (mediante programación).
  2. Formulario utilizado para capturar el recorte de imagen de su tamaño y en las mismas coordenadas.
  3. Establezca esa imagen como fondo después de aplicar BlurBitmapEffect.

No es una gran respuesta Supongo, ¡pero estoy escribiendo lo que hice!

Si está interesado en este enfoque de este artículo le ayudará a: http://www.codeproject.com/Articles/91487/Screen-Capture-in-WPF-WinForms-Application

+1

Gracias, pero eso es lo que trato de evitar. Aero es un gestor de ventanas de composición y no debería tener que tapar manualmente una parte de la pantalla y luego desenfocarla como un mapa de bits. No solo es costoso, sino que no está acelerado por hardware, a diferencia de cómo lo hace Aero. –

Cuestiones relacionadas