How can I get Aero Glass on a Windows Form without Borders?
I'm trying to have Aero Glass look in my forms in VB.NET 2010 app with DWM API, but as function call suggests, it extends look of Frame to the client area, and if form has no border, nothing will hap开发者_如何学Cpen and form will become invisible. So, can I get Aero glass in a form without any border.... ??
As you've said, DwmExtendFrameIntoClientArea
literally extends the transparent glass effect of the window's frame into its client area, which means that if your form's FormBorderStyle
is set to "None", your window will effectively be invisible.
Instead, you need to use the DwmEnableBlurBehindWindow
API, which enables the glassy blur effect on a window without requiring it to have a frame/border. It takes two parameters. The first (hWnd
) is the handle to the form that you wish to apply the blur behind effect to. The second (pBlurBehind
) is a structure passed by reference that contains data or parameters for the effect.
Therefore, you also have to define the DWM_BLURBEHIND
structure, which itself contains four members. The first (dwFlags
) is a bitwise combination of constant values that indicate which members of this structure have been set. The second (fEnable
) indicates whether you want to enable or disable the blur effect. The third (hRgnBlur
) allows you to specify a particular region within the client area that the blur effect will be applied to; setting this to Nothing
indicates that the entire client area will have the blur effect. The fourth (fTransitionOnMaximized
) allows you to specify whether or not the form's colorization should transition to match the maximized windows.
Here are the final API declarations that you have to include in your code in order to use this function:
<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
And then here's a simple example of how you would call this function on a particular form:
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
If instead, you only want to apply the blur behind effect to a particular subregion of the form, you will need to supply a valid region for the hRgnBlur
member, and add the DWM_BB_BLURREGION
flag to the dwFlags
member.
You can use the Region.GetHrgn
method to get a handle to the region you want to specify as the hRgnBlur
member. For example, instead of the above code, you can use the following:
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
Notice how, even when specifying a particular subregion to apply the blur-behind effect to, I still set the entire form's background color to black? This will cause the region we specified to render with a glassy blur-behind effect, and the rest of the form to appear transparent. Of course, you can set the rest of the form's background color to any color that you want (although make sure to fill the rectangle that you want to appear as glass with the color black, as before), but it will appear as partially transparent, just without the glassy blur-behind effect. MSDN explains why this is the case:
When you apply the blur-behind effect to a subregion of the window, the alpha channel of the window is used for the nonblurred area. This can cause an unexpected transparency in the nonblurred region of a window. Therefore, be careful when you apply a blur effect to a subregion.
As far as I'm concerned, that makes applying this effect to only a subregion of the form's window relatively worthless. The only time it seems to me like it might make sense is if you want to render an arbitrary non-rectangular shape as glassy, with the rest of the form remaining transparent.
精彩评论