Průhledné okno s Aero Glass efektem v C# .NET WPF - Část 2
V minulém dílu, Průhledné
okno s Aero Glass efektem v C# .NET WPF - Část 1., jsme si založili
projekt a vysvětlili třídu Brushes
a míchání barev. Dnes
konečně vykreslíme rozmazané pozadí v naší C# .NET WPF aplikaci.
Code Behind - Krok za krokem
Zde si projdeme krok za krokem správnou implementaci volání API operačního systému. Bohužel Microsoft neuvolnil, nebo se mi alespoň nikde nepodařilo dohledat, dokumentaci, tedy vám k jednotlivým proměnným nic navíc nepovím.
1. Zavedení Interop do using deklarace
Prvně je třeba do kompilátoru zahrnout nástroje platformy
Interop
:
using System.Runtime.InteropServices; using System.Windows.Interop;
2. Nastavení proměnných načítajících knihovny OS
Následující enum
a struktury je třeba deklarovat v namespace
našeho projektu:
internal enum AccentState { ACCENT_DISABLED = 0, ACCENT_ENABLE_GRADIENT = 1, ACCENT_ENABLE_TRANSPARENTGRADIENT = 2, ACCENT_ENABLE_BLURBEHIND = 3, ACCENT_INVALID_STATE = 4 } [StructLayout(LayoutKind.Sequential)] internal struct AccentPolicy { public AccentState AccentState; public int AccentFlags; public int GradientColor; public int AnimationId; } [StructLayout(LayoutKind.Sequential)] internal struct WindowCompositionAttributeData { public WindowCompositionAttribute Attribute; public IntPtr Data; public int SizeOfData; }
Zde se definují důležité proměnné vyžadované API operačního systému:
internal enum WindowCompositionAttribute { // ... WCA_ACCENT_POLICY = 19 // ... }
Nyní si deklarujeme statické proměnné s importem systémové knihovny ve třídě našeho okna:
[DllImport("user32.dll")] internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);
3. Zavedení funkcí aktivujících rozmazání pozadí
Aktivaci rozmazaného pozadí našeho okna provedeme následující funkcí,
kterou zavoláme z eventu Window_Loaded()
, tedy potom, až se
inicializují všechny ovládací prvky:
internal void EnableBlur() // Zapne rozmazání pozadí { var windowHelper = new WindowInteropHelper(this); var accent = new AccentPolicy(); accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND; var accentStructSize = Marshal.SizeOf(accent); var accentPtr = Marshal.AllocHGlobal(accentStructSize); Marshal.StructureToPtr(accent, accentPtr, false); var data = new WindowCompositionAttributeData(); data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY; data.SizeOfData = accentStructSize; data.Data = accentPtr; SetWindowCompositionAttribute(windowHelper.Handle, ref data); Marshal.FreeHGlobal(accentPtr); }
4. Nastavení změny průhlednosti pomocí jezdce a zápisu hodnot
Pro demonstraci změny průhlednosti okna dle různé barvy, a zejména
hodnoty Opacity
barvy pozadí, neboli Alpha kanálu, využijeme
náš <Slider>
, kdy během jeho změny vyvoláme
následující funkci:
private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { int a, b, c; a = b = c = Convert.ToInt16((sender as Slider).Value); string alpha = a.ToString("X2"); // převede na hexadecimální hodnotu
V první části si deklarujeme pár proměnných typu int
a
přiřadíme jim aktuální hodnotu našeho slideru. Vzápětí převedeme
hodnotu pro alpha kanál do hexadecimální hodnoty, pomocí metody
ToString("X2");
. Pokračujeme dále:
a = a -(a/6); b = b - ((b / 2)); c = c - ((c / 3));
Zde si hrajeme s RGB barvami tak, aby se měnila i jejich hodnota v poměru dle jednoduché rovnice. A posléze opět převedeme do hexadecimální hodnoty všechny kanály RGB:
string red = a.ToString("X2"); // převede na hexadecimální hodnotu string green = b.ToString("X2"); // převede na hexadecimální hodnotu string blue = c.ToString("X2"); // převede na hexadecimální hodnotu
/// zapis barvy ve formatu Brush string html = "#" + alpha + red + green + blue;
Tu finální získáme tak, že jednotlivé barevné složky sloučíme do
tvaru formátu HTML upraveném pro použití v Brush
barvě, tedy
#
+ ALPHA
+ RED
+ GREEN
+
BLUE
:
var converter = new System.Windows.Media.BrushConverter(); this.Background = (Brush)converter.ConvertFromString(html); if (barva != null) barva.Text = html; }
A nakonec vytvoříme nový BrushConverter
, abychom mohli
přiřazovat barvu konkrétní komponentě, v našem případě
Okno.Background
. Nakonec hodnotu přiřadíme prvku
TextBlock
, ale nejdříve si ověříme, zda byl
<Slider>
prvně inicializován, jinak nám program ihned
spadne.
5. Doplnění funkcí formuláře
Poslední co zapracujeme, je funkce Click and drag – neboli kliknutí při
držení levého tlačítka myši na formuláři, kdy jejím pohybem hýbeme i
formulářem. Využijeme volání funkce MouseLeftButtonDown()
formuláře:
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { this.DragMove(); }
Rychlé a jednoduché, o zbytek se postará již existující funkce.
Závěr
Aplikace by měla vypadat tak jako na obrázku:

Posuvníkem se bude měnit lineárně úroveň průhlednosti formuláře. Formuláři můžete jednoduše změnit velikost a zároveň i pozici na ploše.
Pro kontrolu celý Code Behind vypadá následovně:
using System.Runtime.InteropServices; using System.Windows.Interop; namespace BluredFormNETF { internal enum AccentState { ACCENT_DISABLED = 0, ACCENT_ENABLE_GRADIENT = 1, ACCENT_ENABLE_TRANSPARENTGRADIENT = 2, ACCENT_ENABLE_BLURBEHIND = 3, ACCENT_INVALID_STATE = 4 } [StructLayout(LayoutKind.Sequential)] internal struct AccentPolicy { public AccentState AccentState; public int AccentFlags; public int GradientColor; public int AnimationId; } [StructLayout(LayoutKind.Sequential)] internal struct WindowCompositionAttributeData { public WindowCompositionAttribute Attribute; public IntPtr Data; public int SizeOfData; } internal enum WindowCompositionAttribute { // ... WCA_ACCENT_POLICY = 19 // ... } /// <summary> /// Interakční logika pro MainWindow.xaml /// </summary> public partial class MainWindow : Window { [DllImport("user32.dll")] internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data); public MainWindow() { InitializeComponent(); } internal void EnableBlur() //Zapne rozmazání pozadí { var windowHelper = new WindowInteropHelper(this); var accent = new AccentPolicy(); accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND; var accentStructSize = Marshal.SizeOf(accent); var accentPtr = Marshal.AllocHGlobal(accentStructSize); Marshal.StructureToPtr(accent, accentPtr, false); var data = new WindowCompositionAttributeData(); data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY; data.SizeOfData = accentStructSize; data.Data = accentPtr; SetWindowCompositionAttribute(windowHelper.Handle, ref data); Marshal.FreeHGlobal(accentPtr); } private void Window_Loaded(object sender, RoutedEventArgs e) { EnableBlur(); } private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { this.DragMove(); } private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { int a, b, c; a = b = c = Convert.ToInt16((sender as Slider).Value); string alpha = a.ToString("X2"); //převede na hexadecimální hodnotu a = a -(a/3); b = b - ((b / 2)); c = c - ((c / 12)); string red = a.ToString("X2"); //převede na hexadecimální hodnotu string green = b.ToString("X2"); //převede na hexadecimální hodnotu string blue = c.ToString("X2"); //převede na hexadecimální hodnotu /// zapis barvy ve formatu Brush string html = "#" + alpha + red + green + blue; var converter = new System.Windows.Media.BrushConverter(); this.Background = (Brush)converter.ConvertFromString(html); if (barva != null) barva.Text = html; } } }
Doufám, že se průvodce líbil a pomohl vám s implementací průhledného okna s efektem rozmazání.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 23x (299.53 kB)
Aplikace je včetně zdrojových kódů v jazyce C#