<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>OrbLog &#187; C#</title>
	<atom:link href="http://blog.orbmu2k.de/category/coding/csharp/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.orbmu2k.de</link>
	<description>IT-Moments of Orbmu2k</description>
	<lastBuildDate>Sun, 05 Sep 2010 17:00:34 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Glas Effekte unter WPF</title>
		<link>http://blog.orbmu2k.de/coding/csharp/glass-effekte-unter-wpf</link>
		<comments>http://blog.orbmu2k.de/coding/csharp/glass-effekte-unter-wpf#comments</comments>
		<pubDate>Thu, 01 Mar 2007 09:35:24 +0000</pubDate>
		<dc:creator>Orbmu2k</dc:creator>
				<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://blog.orbmu2k.de/?p=9</guid>
		<description><![CDATA[Da ich lange geforscht habe, wie man in WPF Anwendungen den Glaseffekt von Windows Vista(tm) verwenden kann wollte ich euch die Lösung nicht vorenthalten.

Hier also meine kleine Beispiel-Klasse, mit der man die Glas Effekte für Windows Presentation Foundation Anwendungen nutzen kann.

Wir benötigen zunächst Zugriff auf die DWM API:
using System.Runtime.InteropServices;

static class DWMApi
{
    // [...]]]></description>
			<content:encoded><![CDATA[<p>Da ich lange geforscht habe, wie man in WPF Anwendungen den Glaseffekt von Windows Vista(tm) verwenden kann wollte ich euch die Lösung nicht vorenthalten.</p>
<p><span id="more-9"></span></p>
<p>Hier also meine kleine Beispiel-Klasse, mit der man die Glas Effekte für <a href="http://de.wikipedia.org/wiki/Windows_Presentation_Foundation">Windows Presentation Foundation</a> Anwendungen nutzen kann.</p>
</p>
<p>Wir benötigen zunächst Zugriff auf die <strong>DWM API</strong>:</p>
<pre class="code"><font size="2"><span style="color: blue">using </span>System.Runtime.InteropServices;

<span style="color: blue">static class </span>DWMApi
{
    </font><font size="2"><span style="color: green">// Die Windows Message Konstanten benötigen wir später,
    // um auf Änderungen reagieren zu können
    </span><span style="color: blue">public const int </span>WM_DWMCOMPOSITIONCHANGED = 0x031E;
    <span style="color: blue">public const int </span>WM_DWMNCRENDERINGCHANGED = 0x031F;
    <span style="color: blue">public const int </span>WM_DWMCOLORIZATIONCOLORCHANGED = 0x0320;
    <span style="color: blue">public const int </span>WM_DWMWINDOWMAXIMIZEDCHANGE = 0x0321;

    </font><font size="2"><span style="color: green">// Die Margins Struktur mit der wir festlegen welcher Bereich
    // vom Fenster den Glas Effekt erhalten soll
    </span><span style="color: blue">public struct </span>MARGINS
    {
         <span style="color: blue">public </span>MARGINS(Thickness t)
         {
             Left = (<span style="color: blue">int</span>)t.Left;
             Right = (<span style="color: blue">int</span>)t.Right;
             Top = (<span style="color: blue">int</span>)t.Top;
             Bottom = (<span style="color: blue">int</span>)t.Bottom;
         }
         <span style="color: blue">public int </span>Left;
         <span style="color: blue">public int </span>Right;
         <span style="color: blue">public int </span>Top;
         <span style="color: blue">public int </span>Bottom;
    }

    </font><font size="2"><span style="color: green">// Diese Funktion aktiviert den Glas Effekt
    </span>[DllImport(<span style="color: #a31515">&quot;dwmapi.dll&quot;</span>)]
    <span style="color: blue">public static extern void </span>DwmExtendFrameIntoClientArea(
                              IntPtr hwnd, <span style="color: blue">ref </span>MARGINS margins);
    </font><font size="2"><span style="color: green">// Diese Funktion prüft ob der Glas Effekt im System
    // überhaupt aktiv ist
    </span>[DllImport(<span style="color: #a31515">&quot;dwmapi.dll&quot;</span>)]
    <span style="color: blue">public static extern bool </span>DwmIsCompositionEnabled();
}</font></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Hier nun eine kleine Collection Klasse <strong>GlassWindows</strong> für alle Fenster die später den Glas Effekt bekommen sollen. </p>
<p>Sie verwaltet die Fenster und legt einen Hook auf Windows Nachrichten für jedes Fenster an. Damit können wir später reagieren, sollte während der Laufzeit unserer Anwendung der Glas Effekt im System kurzzeitig ausgeschlalten werden.</p>
<pre class="code"><font size="2"><span style="color: blue">using </span>System.Collections.Generic;
<span style="color: blue">using </span>System.Windows.Interop;
<span style="color: blue">using </span>System.Windows.Media;

<span style="color: blue">class </span></font><font size="2"><span style="color: #2b91af">GlassWindows
</span>{

    </font><font size="2"><span style="color: green">// Die Generische Liste für unsere Fenster
    </span><span style="color: blue">private </span><span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">WindowItem</span>&gt; windows = <span style="color: blue">new </span><span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">WindowItem</span>&gt;();

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

    </font><font size="2"><span style="color: green">// 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.
    </span><span style="color: blue">private </span><span style="color: #2b91af">WindowItem </span>WindowItemByHandle(<span style="color: #2b91af">IntPtr </span>Handle)
    {
        </font><font size="2"><span style="color: green">// Schleife durch alle Fenster in der Liste
        </span><span style="color: blue">foreach </span>(<span style="color: #2b91af">WindowItem </span>wi <span style="color: blue">in </span>windows)
        {
            </font><font size="2"><span style="color: green">// Wenn Handle übereinstimmt aktuellen Eintrag
            // zurückgeben und Fuktion verlassen
            </span><span style="color: blue">if </span>(wi.Handle == Handle)
                <span style="color: blue">return </span>wi;
        }
        <span style="color: blue">return null</span>;
    }

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

    </font><font size="2"><span style="color: green">// Windwos Nachrichten abfangen (Hook)
    </span><span style="color: blue">private </span><span style="color: #2b91af">IntPtr </span>WndProc(<span style="color: #2b91af">IntPtr </span>hwnd, <span style="color: blue">int </span>msg, <span style="color: #2b91af">IntPtr </span>wParam,
                           <span style="color: #2b91af">IntPtr </span>lParam, <span style="color: blue">ref bool </span>handled)
    {
        </font><font size="2"><span style="color: green">// Wenn Glass effekt ein- oder ausgeschalten
        // wurde entsprechend behandeln
    </span><span style="color: blue">if </span>(msg == <span style="color: #2b91af">DWMApi</span>.WM_DWMCOMPOSITIONCHANGED)
        {
            EnableGlass(WindowItemByHandle(hwnd),
                        <span style="color: #2b91af">DWMApi</span>.DwmIsCompositionEnabled());
            handled = <span style="color: blue">true</span>;
        }
        <span style="color: blue">return </span><span style="color: #2b91af">IntPtr</span>.Zero;
    }

}</font></pre>
<pre class="code"><font size="2"><span style="color: green">// Kleine Klasse als Item für unsere Collection
</span><span style="color: blue">class </span></font><font size="2"><span style="color: #2b91af">WindowItem
</span>{
    <span style="color: blue">public </span><span style="color: #2b91af">IntPtr </span>Handle;
    <span style="color: blue">public </span>Window window;
    <span style="color: blue">public </span>Thickness margin;
}</font></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>So nun müssen wir das ganze nur noch in unserer Anwendung benutzen. Dazu fügen wir im Konstruktor der <strong>App</strong> Klasse (App.xaml.cs) folgendes hinzu. </p>
<pre class="code"><font size="2"><span style="color: blue">public partial class </span><span style="color: #2b91af">App </span>: System.Windows.Application
{
    <span style="color: blue">public </span>App()
    {
        </font><font size="2"><span style="color: green">// Neue Instanz unserer GW Klasse anlegen
        </span><span style="color: #2b91af">GlassWindows </span>gw = <span style="color: blue">new </span><span style="color: #2b91af">GlassWindows</span>();
        </font><font size="2"><span style="color: green">// GW Instanz als Globale Eigenschafft mitführen
        </span><span style="color: blue">this</span>.Properties[<span style="color: #a31515">&quot;GlassWindows&quot;</span>] = gw;
    }

}</font></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Jetzt brauchen wir nur noch im jeweiligen Fenster den &quot;OnSourceInitialized&quot; Event überschreiben und unser Fenster in unserer GW Collection hinzufügen. </p>
<pre class="code"><font size="2"><span style="color: blue">protected override void </span>OnSourceInitialized(EventArgs e)
{
    <span style="color: blue">base</span>.OnSourceInitialized(e);
    ((GlassWindows)App.Current.
         Properties[<span style="color: #a31515">&quot;GlassWindows&quot;</span>]).
             Add(<span style="color: blue">this</span>, <span style="color: blue">new </span>Thickness(-1));
}</font></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.orbmu2k.de/coding/csharp/glass-effekte-unter-wpf/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
