#39 - Trasparenza delle finestre ed effetto glass in WPF

Può capitare, specialmente quando si realizzano splash form, di dover ricorrere a finestre che non abbiano ne il classico riquadro Windows ne senza nessuno sfondo, per mostrare esclusivamente il logo dell'applicazione.
In WPF realizzare ciò è molto semplice: prima di tutto occorre abilitare la trasparenza sulla finestra con AllowsTransparency ed obbligatoriamente cambiare la proprietà WindowStyle in None. In questo modo la finestra è spoglia, supporta le trasparenze ed è quindi possibile in secondo luogo impostare lo sfondo su un colore trasparente o effettuare semi trasparenze agendo sulla proprietà Opacity. Ecco quindi un semplice esempio di splash form:

public MyWindow()
{
    InitializeComponent();

    // Cambio stile della finestra

    this.WindowStyle= WindowStyle.None;
    // Abilito la trasparenza

    this.AllowsTransparency = true;
    // Imposto uno sfondo trasparente

    this.Background = Brushes.Transparent;
}

In Windows Vista inoltre sono state introdotte delle nuove API che sfruttano il nuovo Desktop Window Manager e permettono di creare un effetto glass su finestre trasparenti. Queste nuove API sono: DwmIsCompositionEnabled e DwmExtendFrameIntoClientArea. Occorre quindi dichiararle in una classe nel seguente modo:


[DllImport("dwmapi.dll")]
public static extern int DwmExtendFrameIntoClientArea(
  IntPtr hWnd,
  ref MARGINS pMarInset);

[DllImport("dwmapi.dll", PreserveSig = false)]
static extern bool DwmIsCompositionEnabled();

A questo punto, nel metodo OnSourceInitialized (si verifica dopo la creazione della finestra) o eventi successivi occorre  indicare l'area da utilizzare. In questo caso, inoltre, Background va obbligatoriamente impostato su Transparent, mentre AllowsTransparency non è richiesto e lo stile della finestra può essere uno di quelli messi a disposizione dalle Win32:

public MyWindow()
{
    InitializeComponent();

    this.Background = Brushes.Transparent;
}

protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);

    // Controllo che l'effetto Glass sia supportato

    if (DwmIsCompositionEnabled())
    {
        // Recupero l'handle Win32 della finestra nativa

        IntPtr hWnd = new WindowInteropHelper(this).Handle;

        // Imposto la trasparenza sulla finestra

        HwndSource.FromHwnd(hWnd).CompositionTarget.BackgroundColor = Colors.Transparent;

        // Margini di disegno dell'effetto Glass

        // -1 significa l'intera area

        MARGINS margins = new MARGINS();
        margins.cxLeftWidth = -1;
        margins.cxRightWidth = -1;
        margins.cyTopHeight = -1;
        margins.cyBottomHeight = -1;

        // Imposto l'effetto Glass sulla finestra

        if (DwmExtendFrameIntoClientArea(hWnd, ref margins) != 0)
            throw new Win32Exception();
    }
}

Di seguito un esempio di finestra con effetto Glass:



Approfondimenti

Commenti

Esprimi il tuo giudizio su questo script:

Per procedere devi essere autenticato.

Per inserire un commento, devi registrarti alla nostra community.





IN EVIDENZA
MISC