vb.net - 如何在无边框 Windows 窗体上获得 Aero Glass?

标签 vb.net winforms dwm aero-glass

我正在尝试使用 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解释了为什么会出现这种情况:

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.

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

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

相关文章:

vb.net - 使用 .Skip() 和 .Take() 方法对 DataTable 进行 Linq

mysql - 自动递增字符串的最后一个整数值

c# - 从具有 Distinct/GroupBy 的 IEnumerable 中选择并排序——可能吗?

vb.net - VB.NET 中不使用定时器的表单转换

c# - 如何获得平滑的颜色变化?

c# - 需要两个用户控件(winforms)进行通信时的最佳实践

winforms - 将一个窗体移动到另一个 winform - C#

wpf - 对于商业应用程序来说,WPF 应用程序与 Winform 相比有何优势?

uwp - win32 app中的亚克力 Material

gdi - Windows 10 中带有标题栏的模糊窗口? Windows 更新后停止工作