Sto cercando di avere Aero Glass nei miei moduli nell'app VB.NET 2010 con API DWM, ma come suggerisce la chiamata di funzione, estende l'aspetto di Frame all'area client e, se il modulo non ha confini, non accadrà nulla e la forma diventerà invisibile. Quindi, posso ottenere un vetro Aero in una forma senza bordi .... ??Come posso ottenere Aero Glass su un Windows Form senza bordi?
risposta
Come hai detto, DwmExtendFrameIntoClientArea
estende letteralmente l'effetto di vetro trasparente del frame della finestra nella sua area client, il che significa che se il tuo modulo è FormBorderStyle
impostato su "Nessuno", la tua finestra sarà effettivamente invisibile.
Invece, è necessario utilizzare lo DwmEnableBlurBehindWindow
API, che consente l'effetto sfocatura vetroso su una finestra senza che sia necessario disporre di una cornice/bordo. Sono necessari due parametri. Il primo (hWnd
) è l'handle del modulo a cui si desidera applicare l'effetto sfocatura dietro. Il secondo (pBlurBehind
) è una struttura passata per riferimento che contiene dati o parametri per l'effetto.
Pertanto, è necessario definire anche lo DWM_BLURBEHIND
structure, che a sua volta contiene quattro membri. Il primo (dwFlags
) è una combinazione bit a bit di constant values che indica quali membri di questa struttura sono stati impostati. Il secondo (fEnable
) indica se si desidera abilitare o disabilitare l'effetto sfocatura. Il terzo (hRgnBlur
) consente di specificare una particolare area all'interno dell'area client a cui verrà applicato l'effetto sfocatura; impostandolo su Nothing
indica che l'intera area client avrà l'effetto sfocatura. Il quarto (fTransitionOnMaximized
) consente di specificare se la colorazione della maschera debba o meno essere adattata alle finestre ingrandite.
Queste le dichiarazioni API finali che si devono includere nel codice per utilizzare questa funzione:
<StructLayout(LayoutKind.Sequential)> _
Private Structure DWM_BLURBEHIND
Public dwFlags As Integer
Public fEnable As Boolean
Public hRgnBlur As IntPtr
Public fTransitionOnMaximized As Boolean
End Structure
Private Const DWM_BB_ENABLE As Integer = &H1
Private Const DWM_BB_BLURREGION As Integer = &H2
Private Const DWM_BB_TRANSITIONONMAXIMIZED As Integer = &H4
<DllImport("dwmapi.dll", PreserveSig:=False)> _
Private Shared Sub DwmEnableBlurBehindWindow(ByVal hWnd As IntPtr, ByRef pBlurBehind As DWM_BLURBEHIND)
End Sub
E allora ecco un semplice esempio di come si dovrebbe chiamare questa funzione in un modulo particolare:
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
MyBase.OnLoad(e)
''#Set the form's border style to None
Me.FormBorderStyle = FormBorderStyle.None
''#Whatever region that you fill with black will become the glassy region
''# (in this example, the entire form becomes transparent)
Me.BackColor = Color.Black
''#Create and populate the blur-behind structure
Dim bb As DWM_BLURBEHIND
bb.dwFlags = DWM_BB_ENABLE
bb.fEnable = True
bb.hRgnBlur = Nothing
''#Enable the blur-behind effect
DwmEnableBlurBehindWindow(Me.Handle, bb)
End Sub
Se, invece, si desidera solo di applicare la sfocatura dietro la validità di una particolare subregione del modulo, è necessario fornire una regione valida per il membro hRgnBlur
, e aggiungere il flag DWM_BB_BLURREGION
alMembro.
È possibile utilizzare Region.GetHrgn
method per ottenere un handle per l'area che si desidera specificare come membro hRgnBlur
. Ad esempio, al posto del codice di cui sopra, è possibile utilizzare il seguente:
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
MyBase.OnLoad(e)
''#Set the form's border style to None
Me.FormBorderStyle = FormBorderStyle.None
''#Fill the entire form with black to make it appear transparent
Me.BackColor = Color.Black
''#Create a region corresponding to the area of the form you want to render as glass
Using g As Graphics = Me.CreateGraphics
Dim glassRect As New Rectangle(0, 0, 100, 150)
Using rgn As New Region(glassRect)
''#Create and populate the blur-behind structure
Dim bb As DWM_BLURBEHIND
bb.dwFlags = DWM_BB_ENABLE Or DWM_BB_BLURREGION
bb.fEnable = True
bb.hRgnBlur = rgn.GetHrgn(g)
''#Enable blur-behind effect
DwmEnableBlurBehindWindow(Me.Handle, bb)
End Using
End Using
End Sub
Notate come, anche quando si specifica un particolare subregione di applicare la sfocatura-behind effetto, ho ancora impostare il colore di sfondo di tutto il modulo al nero ? Ciò causerà la regione che abbiamo specificato di rendere con un effetto sfocato vetroso, e il resto del modulo apparirà trasparente. Naturalmente, puoi impostare il resto del colore di sfondo del modulo su qualsiasi colore che desideri (anche se assicurati di riempire il rettangolo che vuoi apparire come vetro con il colore nero, come prima), ma apparirà parzialmente trasparente , solo senza il vistoso effetto sfocato. MSDN spiega perché questo è il caso:
Quando si applica la sfocatura-behind effetto ad una subregione della finestra, viene utilizzato il canale alpha della finestra per l'area nonblurred.Questo può causare una trasparenza imprevista in l'area non offuscata di una finestra. Pertanto, prestare attenzione quando si applica un effetto sfocato a una sottoregione.
Per quanto mi riguarda, questo rende l'applicazione di questo effetto solo a una sottoregione della finestra del modulo relativamente senza valore. L'unica volta che mi sembra che abbia senso è se si desidera rendere una forma non rettangolare arbitraria come vetrosa, lasciando il resto del modulo trasparente.
+1, ma inutilizzabile a meno che non gli mostri come utilizzare la regione. –
@Hans: ho aggiunto un esempio di regioni, anche se, come faccio notare, l'utilità di ciò sembra terribilmente limitata, almeno in WinForms. –
Grazie per aver dedicato del tempo e dando una breve spiegazione, ha funzionato come suggerito. Dove posso trovare i dettagli relativi ad altri metodi di questa API, oltre a MSDN ?? – Kushal