2010-12-12 28 views
6

Estoy intentando que Aero Glass se vea en mis formularios en la aplicación VB.NET 2010 con DWM API, pero como lo sugiere la función invocada, extiende la apariencia de Frame al área del cliente, y si la forma no tiene ningún límite, no pasará nada y la forma se volverá invisible. Entonces, ¿puedo obtener Aero Glass de una forma sin ningún borde ...?¿Cómo puedo obtener Aero Glass en un Windows Form sin fronteras?

Respuesta

12

Como dijiste, DwmExtendFrameIntoClientArea extiende literalmente el efecto de cristal transparente del marco de la ventana a su área de cliente, lo que significa que si su formulario FormBorderStyle está configurado en "Ninguno", su ventana será efectivamente invisible.

En su lugar, debe utilizar el DwmEnableBlurBehindWindow API, que permite el efecto de desenfoque vidrioso en una ventana sin necesidad de tener un marco/borde. Toma dos parámetros. El primero (hWnd) es el manejador de la forma en la que desea aplicar el efecto de desenfoque. El segundo (pBlurBehind) es una estructura pasada por referencia que contiene datos o parámetros para el efecto.

Por lo tanto, también debe definir DWM_BLURBEHIND structure, que a su vez contiene cuatro miembros. La primera (dwFlags) es una combinación bit a bit de constant values que indica qué miembros de esta estructura se han establecido. El segundo (fEnable) indica si desea habilitar o deshabilitar el efecto de desenfoque. El tercero (hRgnBlur) le permite especificar una región particular dentro del área del cliente a la que se aplicará el efecto de desenfoque; establecer esto en Nothing indica que toda el área del cliente tendrá el efecto de desenfoque. El cuarto (fTransitionOnMaximized) le permite especificar si la coloración del formulario debe hacer la transición para coincidir con las ventanas maximizadas.

Estas son las declaraciones de API finales que hay que incluir en su código con el fin de utilizar esta función:

<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 

Y entonces aquí hay un ejemplo sencillo de cómo se llame a esta función en una forma particular:

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 

Si por el contrario, sólo se desea aplicar el desenfoque detrás de la validez de una subregión particular de la forma, tendrá que suministrar una región válida para el miembro hRgnBlur, y añadir la bandera DWM_BB_BLURREGION a la dwFlags miembro.

Puede usar el Region.GetHrgn method para obtener un control de la región que desea especificar como el miembro hRgnBlur. Por ejemplo, en lugar del código anterior, puede utilizar la siguiente:

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 

Aviso cómo, incluso cuando se especifica una subregión en particular para aplicar el efecto borroso detrás de la validez de, todavía establece el color de fondo de toda la forma de negro ? Esto causará que la región que especificamos muestre con un efecto vidrioso de desenfoque y el resto de la forma parezca transparente. Por supuesto, puede establecer el resto del color de fondo del formulario en cualquier color que desee (aunque asegúrese de rellenar el rectángulo que desea que aparezca como cristal con el color negro, como antes), pero aparecerá como parcialmente transparente , solo sin el efecto vidrioso de desenfoque. MSDN explica por qué este es el caso:

Cuando se aplica el -detrás efecto de desenfoque a una subregión de la ventana, se utiliza el canal alfa de la ventana para el área nonblurred.Esto puede causar una transparencia inesperada en la región no difuminada de una ventana. Por lo tanto, tenga cuidado cuando aplique un efecto de desenfoque a una subregión.

Por lo que a mí respecta, eso hace que aplicar este efecto a solo una subregión de la ventana del formulario sea relativamente inútil. La única vez que me parece que podría tener sentido es si desea convertir una forma no rectangular arbitraria en vidriosa, con el resto de la forma restante transparente.

+0

+1, pero inutilizable a menos que le muestre cómo usar la región. –

+0

@Hans: Agregué un ejemplo de regiones, aunque como señalo, la utilidad de esto parece muy limitada, al menos en WinForms. –

+0

Gracias por tomarse el tiempo y dar una explicación tan breve, funcionó como sugirió. ¿Dónde puedo encontrar detalles sobre otros métodos de esta API, aparte de MSDN? – Kushal

Cuestiones relacionadas