Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Priehľadné okno s Aero Glass efektom v C # .NET WPF - Časť 2

V minulom dieli, Priehľadné okno s Aero Glass efektom v C# .NET WPF - Časť 1., sme si založili projekt a vysvetlili triedu Brushes a miešanie farieb. Dnes konečne vykreslíme rozmazané pozadie v našej C# .NET WPF aplikáciu.

Code Behind - Krok za krokom

Tu si prejdeme krok za krokom správnu implementáciu volanie API operačného systému. Bohužiaľ Microsoft neuvoľnil, alebo sa mi aspoň nikde nepodarilo dohľadať, dokumentáciu, teda vám k jednotlivým premenným nič navyše nepoviem.

1. Zavedenie Interop do using deklarácie

Najprv je treba do kompilátora zahrnúť nástroje platformy Interop:

using System.Runtime.InteropServices;
using System.Windows.Interop;

2. Nastavenie premenných načítající knižnice OS

Nasledujúce enum a štruktúry treba deklarovať v namespace nášho 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;
}

Tu sa definujú dôležité premenné požadované API operačného systému:

internal enum WindowCompositionAttribute
{
    // ...
    WCA_ACCENT_POLICY = 19
    // ...
}

Teraz si deklarujeme statické premenné s importom systémové knižnice v triede nášho okna:

[DllImport("user32.dll")]
internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);

3. Zavedenie funkcií aktivujúcich rozmazania pozadia

Aktiváciu rozmazaného pozadia nášho okna vykonáme nasledujúce funkciou, ktorú zavoláme z eventu Window_Loaded(), teda potom, až sa inicializujú všetky ovládacie 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. Nastavenie zmeny priehľadnosti pomocou jazdca a zápisu hodnôt

Pre demonštráciu zmeny priehľadnosti okna podľa rôzne farby, a najmä hodnoty Opacity farby pozadia, čiže Alpha kanála, využijeme náš <Slider>, keď počas jeho zmeny vyvoláme nasledujúce funkciu:

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 prvej časti si deklarujeme pár premenných typu int a priradíme im aktuálnu hodnotu nášho slideru. Vzápätí prevedieme hodnotu pre alpha kanál do hexadecimálne hodnoty, pomocou metódy ToString("X2");. Pokračujeme ďalej:

a = a -(a/6);
b = b - ((b / 2));
c = c - ((c / 3));

Tu si hráme s RGB farbami tak, aby sa menila aj ich hodnota v pomere podľa jednoduchej rovnice. A potom opäť prevedieme do HEX hodnoty všetky 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;

Tú finálne získame tak, že jednotlivé farebné zložky zlúčime do tvaru formátu HTML upravenej na použitie v Brush farbe, teda # + ALPHA + RED + GREEN + BLUE:

    var converter = new System.Windows.Media.BrushConverter();
    this.Background = (Brush)converter.ConvertFromString(html);
    if (barva != null) barva.Text = html;
}

A nakoniec vytvoríme nový BrushConverter, aby sme mohli priraďovať farbu konkrétny komponente, v našom prípade Okno.Background. Nakoniec hodnotu priradíme prvku TextBlock, ale najskôr si overíme, či bol <Slider> prvýkrát inicializovaný, inak nám program ihneď spadne.

5. Doplnenie funkcií formulára

Posledné čo zapracujeme, je funkcia Click and drag - čiže kliknutí pri držaní ľavého tlačidla myši na formulári, kedy jej pohybom hýbeme aj formulárom. Využijeme volanie funkcie MouseLeftButtonDown() formuláre:

private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    this.DragMove();
}

Rýchle a jednoduché, o zvyšok sa postará už existujúce funkcie.

Záver

Aplikácia by mala vyzerať tak ako na obrázku:

Priehľadné rozmazané pozadie okná v C# .NET WPF - C # - Pre pokročilých

Posuvníkom sa bude meniť lineárne úroveň transparentnosti formulára. Formulári môžete jednoducho zmeniť veľkosť a zároveň aj pozíciu na ploche.

Pre kontrolu celý Code Behind vyzerá nasledovne:

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;
        }
    }
}

Dúfam, že sa sprievodca páčil a pomohol vám s implementáciou priehľadného okna s efektom rozmazania.


 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 23x (299.53 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

Všetky články v sekcii
C # - Pre pokročilých
Článok pre vás napísal Michal Kotek
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje programování již od útlých let, aktuálně se věnuje výrobě Webových stránek jako fullstack, využívám Nette framework. Mám znalosti jazyků JS, PHP, SASS C# .NET, C++ pro Arduino. Jo a strašně rád střílím ;)
Aktivity