我正在尝试使用DWM API在VB.NET 2010应用程序的表单中显示Aero Glass,但是正如函数调用所建议的那样,它将Frame的外观扩展到客户区域,如果表单没有边框,则不会发生任何事情和表单会变得隐形。所以,我能以没有任何边界的形式获得Aero玻璃吗?

最佳答案

就像您说的那样,DwmExtendFrameIntoClientArea从字面上将窗口框架的透明玻璃效果扩展到其客户区,这意味着,如果窗体的FormBorderStyle设置为“None”,则窗口实际上将是不可见的。

相反,您需要使用 DwmEnableBlurBehindWindow API,它可以在窗口上启用玻璃模糊效果,而无需框架/边框。 它带有两个参数。第一个(hWnd)是您要将模糊效果应用到的表单的句柄。第二个(pBlurBehind)是通过引用传递的结构,其中包含该效果的数据或参数。

因此,您还必须定义 DWM_BLURBEHIND structure,它本身包含四个成员。第一个(dwFlags)是constant values的按位组合,指示已设置此结构的哪些成员。第二个(fEnable)指示要启用还是禁用模糊效果。第三个(hRgnBlur)允许您在客户区域内指定将要应用模糊效果的特定区域;将此设置为Nothing表示整个客户区都将具有模糊效果。第四个(fTransitionOnMaximized)允许您指定是否应转换表单的颜色以匹配最大化的窗口。

这是您必须包含在代码中的最终API声明,才能使用此功能:

<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

接下来是一个简单的示例,说明如何在特定表单上调用此函数:
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

如果相反,您只想将模糊效果应用于表单的特定子区域,则需要为hRgnBlur成员提供有效区域,并将DWM_BB_BLURREGION标志添加到dwFlags成员。

您可以使用 Region.GetHrgn method获取要指定为hRgnBlur成员的区域的句柄。例如,除了上面的代码,您可以使用以下代码:
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

请注意,即使指定特定的子区域以应用模糊效果,如何仍将整个表单的背景颜色设置为黑色?这将使我们指定的区域呈现出玻璃状的模糊效果,而表单的其余部分则显得透明。当然,您可以将表单的其余背景颜色设置为所需的任何颜色(尽管请确保像以前一样用黑色填充要显示为玻璃的矩形),但是它将显示为部分透明,只是没有玻璃状的模糊效果。 MSDN解释了为什么会这样:



就我而言,这使得将这种效果仅应用于窗体窗口的一个子区域相对毫无值(value)。在我看来,这唯一有意义的一次是,如果您想将任意非矩形形状呈现为玻璃状,而其余的形状保持透明。

关于vb.net - 如何在无边框的Windows窗体上获取Aero Glass?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4420528/

10-08 21:14