Feedback

C# - WPF Fenster mit Aero Glass

Veröffentlicht von am 11/20/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!