Office week Slevový týden - Květen
Pouze tento týden sleva až 80 % na e-learning týkající se MS Office
30 % bodů zdarma na online výuku díky naší Slevové akci!

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

Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!

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

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é 19x (299.53 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

 

Článok pre vás napísal Michal Kotek
Avatar
Ako sa ti páči článok?
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje programování již od útlých let, aktuálně programuje rok v .NET framework pomocí C#.
Všetky články v sekcii
C # - Pre pokročilých
Aktivity (1)

 

 

Komentáre

Avatar
Michal Štěpánek:27.11.2019 11:06

Aplikace je prďácká, jen by to možná chtělo někam nenápadně umístit nějaké piditlačítko na zavření...

Odpovedať
27.11.2019 11:06
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!
Avatar
Michal Kotek
Redaktor
Avatar
Michal Kotek:27.11.2019 11:12

Díky, no a na křížek jsem zapomněl: D

Odpovedať
27.11.2019 11:12
Give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime.Teach a man to code...
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zobrazené 2 správy z 2.