Feedback

C# - WPF Fenster mit Aero Glass

Veröffentlicht von am 20.11.2009
(1 Bewertungen)
So nun müssen wir das ganze nur noch in unserer Anwendung benutzen. Dazu fügen wir im Konstruktor der App Klasse (App.xaml.cs) folgendes hinzu.


public partial class App : System.Windows.Application
{
public App()
{
// Neue Instanz unserer GW Klasse anlegen
GlassWindows gw = new GlassWindows();
// GW Instanz als Globale Eigenschafft mitführen
this.Properties["GlassWindows"] = gw;
}

}

Jetzt brauchen wir nur noch im jeweiligen Fenster den "OnSourceInitialized" Event überschreiben und unser Fenster in unserer GW Collection hinzufügen.

protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
((GlassWindows)App.Current.
Properties["GlassWindows"]).
Add(this, new Thickness(-1));
}
using System.Runtime.InteropServices;

static class DWMApi
{
    // Die Windows Message Konstanten benötigen wir später,
    // um auf Änderungen reagieren zu können
    public const int WM_DWMCOMPOSITIONCHANGED = 0x031E;
    public const int WM_DWMNCRENDERINGCHANGED = 0x031F;
    public const int WM_DWMCOLORIZATIONCOLORCHANGED = 0x0320;
    public const int WM_DWMWINDOWMAXIMIZEDCHANGE = 0x0321;

    // Die Margins Struktur mit der wir festlegen welcher Bereich
    // vom Fenster den Glas Effekt erhalten soll
    public struct MARGINS
    {
         public MARGINS(Thickness t)
         {
             Left = (int)t.Left;
             Right = (int)t.Right;
             Top = (int)t.Top;
             Bottom = (int)t.Bottom;
         }
         public int Left;
         public int Right;
         public int Top;
         public int Bottom;
    }

    // Diese Funktion aktiviert den Glas Effekt
    [DllImport("dwmapi.dll")]
    public static extern void DwmExtendFrameIntoClientArea(
                              IntPtr hwnd, ref MARGINS margins);
    // Diese Funktion prüft ob der Glas Effekt im System
    // überhaupt aktiv ist
    [DllImport("dwmapi.dll")]
    public static extern bool DwmIsCompositionEnabled();
}

using System.Collections.Generic;
using System.Windows.Interop;
using System.Windows.Media;

class GlassWindows
{

    // Die Generische Liste für unsere Fenster
    private List<WindowItem> windows = new List<WindowItem>();

    // Diese Funktion fügt ein Fenster und den Bereich vom
    // Glas Effekt zu unsere Liste hinzu
    public void Add(Window window, Thickness margin)
    {
        //  Instanz unserer Item Klasse erstellen
        WindowItem wi = new WindowItem();
        // Handle der WPF "Window" Klasse herausfinden
        wi.Handle = new WindowInteropHelper(window).Handle;
        // Glas Bereich zuweisen
        wi.margin = margin;
        // WPF "Window" zuweisen
        wi.window = window;
        // Listeneintrag anlegen
        windows.Add(wi);
        // Winows Nachrichten Hook hinzufügen
        HwndSource.FromHwnd(wi.Handle).AddHook(WndProc);
        // Glas Effekt einschalten
        EnableGlass(wi, true);
    }

    // Gibt den Listen Eintrag anhand des Fenster Handles zurück
    // Damit können wir später wenn die Windows Nachricht
    // eintrifft zuordnen zu welchem Eintrag diese gehört.
    private WindowItem WindowItemByHandle(IntPtr Handle)
    {
        // Schleife durch alle Fenster in der Liste
        foreach (WindowItem wi in windows)
        {
            // Wenn Handle übereinstimmt aktuellen Eintrag
            // zurückgeben und Fuktion verlassen
            if (wi.Handle == Handle)
                return wi;
        }
        return null;
    }

    // Glass Effekt an- bzw. ausschalten
    private void EnableGlass(WindowItem windowitem, bool enabled)
    {
        if (enabled && DWMApi.DwmIsCompositionEnabled())
        {
            // Hintergrundfarbe des Fensters
            // auf Transparent stellen
            windowitem.window.Background = Brushes.Transparent;
            // Die Farbe festlegen auf die der Glas Effekt
            // angewendet werden soll (Transparent)
            HwndSource.FromHwnd(windowitem.Handle).
                CompositionTarget.BackgroundColor
                    = Colors.Transparent;
            // Den Bereich für den Glas Effekt definieren
            DWMApi.MARGINS margins =
                       new DWMApi.MARGINS(windowitem.margin);
            // Glass Effekt aktivieren
            DWMApi.DwmExtendFrameIntoClientArea
                       (windowitem.Handle, ref margins);
        }
        else
        {
            // Hintergrundfarbe des Fensters zurück auf die
            // Systemfarbe stellen
            windowitem.window.Background
                = SystemColors.WindowBrush;
        }
    }

    // Windwos Nachrichten abfangen (Hook)
    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam,
                           IntPtr lParam, ref bool handled)
    {
        // Wenn Glass effekt ein- oder ausgeschalten
        // wurde entsprechend behandeln
    if (msg == DWMApi.WM_DWMCOMPOSITIONCHANGED)
        {
            EnableGlass(WindowItemByHandle(hwnd),
                        DWMApi.DwmIsCompositionEnabled());
            handled = true;
        }
        return IntPtr.Zero;
    }

}

// Kleine Klasse als Item für unsere Collection
class WindowItem
{
    public IntPtr Handle;
    public Window window;
    public Thickness margin;
}


Abgelegt unter WPF, Glass, WDM, Aero.

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!