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;
}
Kommentare zum Snippet