1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
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;
}
|