Vb.net 如何在没有边框的Windows窗体上获得Aero Glass?

Vb.net 如何在没有边框的Windows窗体上获得Aero Glass?,vb.net,winforms,dwm,aero-glass,Vb.net,Winforms,Dwm,Aero Glass,我试图在VB.NET 2010应用程序中使用DWM API在表单中使用Aero Glass外观,但正如函数调用所建议的,它将框架外观扩展到客户端区域,如果表单没有边框,则不会发生任何事情,表单将变得不可见。那么,我可以得到一种没有任何边界的空气玻璃吗 正如您所说,dwmextendframeintoclienterea从字面上将窗口框架的透明玻璃效果扩展到其客户端区域,这意味着如果窗体的FormBorderStyle设置为“无”,则窗口实际上将不可见 相反,您需要使用,它可以在窗口上启用玻璃状模

我试图在VB.NET 2010应用程序中使用DWM API在表单中使用Aero Glass外观,但正如函数调用所建议的,它将框架外观扩展到客户端区域,如果表单没有边框,则不会发生任何事情,表单将变得不可见。那么,我可以得到一种没有任何边界的空气玻璃吗

正如您所说,
dwmextendframeintoclienterea
从字面上将窗口框架的透明玻璃效果扩展到其客户端区域,这意味着如果窗体的
FormBorderStyle
设置为“无”,则窗口实际上将不可见

相反,您需要使用,它可以在窗口上启用玻璃状模糊效果,而无需具有帧/边框。它需要两个参数。第一个(
hWnd
)是要对其应用模糊隐藏效果的窗体的句柄。第二个(
pblurbhind
)是通过引用传递的结构,其中包含效果的数据或参数

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

以下是使用此函数必须包含在代码中的最终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
如果您只想将模糊隐藏效果应用于表单的特定子区域,则需要为
hRgnBlur
成员提供有效区域,并将
DWM\u BB\u BLURREGION
标记添加到
dwFlags
成员

可以使用获取要指定为
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
请注意,即使指定要应用模糊效果的特定子区域,我仍然将整个窗体的背景色设置为黑色?这将导致我们指定的区域以玻璃状模糊效果进行渲染,而窗体的其余部分将显示为透明。当然,您可以将窗体的其余背景色设置为您想要的任何颜色(尽管请确保使用黑色填充要显示为玻璃的矩形,如前所述),但它将显示为部分透明,只是没有玻璃模糊效果。解释为什么会出现这种情况:

当应用模糊隐藏效果时 在窗口的子区域中 使用窗口的alpha通道 对于非模糊区域。这个可以 造成意外的透明度 窗口的非模糊区域。 因此,在应用 模糊效果到一个子区域


就我而言,这使得仅将此效果应用于窗体窗口的一个子区域相对来说毫无价值。在我看来,唯一有意义的一次是,如果你想将任意的非矩形形状渲染为玻璃状,而形状的其余部分保持透明。

@Hans:我添加了一个区域示例,尽管正如我所指出的,它的用处似乎非常有限,至少在WinForms中是这样。感谢您花时间给出如此简短的解释,它按照您的建议工作。我在哪里可以找到关于这个API的其他方法的详细信息,除了MSDN???@Kush:除了MSDN,我真的不确定。你可以试试,但我发现它们的覆盖范围有点参差不齐,最好与MSDN上的内容进行交叉检查,因为有些声明不正确或不完整。不幸的是,微软并没有使完全利用DWM功能对我们.NET开发人员来说非常方便。一旦你知道要导入的功能,谷歌搜索通常会显示一些博客条目(其中很多来自微软员工),但恐怕我不知道有任何中心资源。这很好,但是使用win forms元素然后应用玻璃效果怎么样?我觉得这看起来不太好,解决办法是什么?@Oscar:是的,事情开始变得复杂起来。真正的答案不是把控制装置放在玻璃区域的顶部:很少有这样的情况是有意义的。问题是控件通常以黑色绘制文本,但就DWM而言,黑色是透明颜色,因此所有黑色实际上都渲染为透明(玻璃)。要真正让事情顺利进行,您需要使用GDI+进行绘制,GDI+了解透明度并区分将要透明的黑色和常规纯黑。WinForms控件包装使用GDI绘制的Win32控件。
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