Как я могу получить Aero Glass на форме Windows без границ? - PullRequest
6 голосов
/ 12 декабря 2010

Я пытаюсь, чтобы Aero Glass выглядел в моих формах в приложении VB.NET 2010 с DWM API, но, как предполагает вызов функции, он расширяет внешний вид Frame до клиентской области, и если форма не имеет границ, ничего не будет произойдет, и форма станет невидимой. Итак, я могу получить стекло Aero в форме без каких-либо границ .... ??

1 Ответ

12 голосов
/ 12 декабря 2010

Как вы сказали, DwmExtendFrameIntoClientArea буквально расширяет эффект прозрачного стекла рамки окна на его клиентскую область, что означает, что если для FormBorderStyle вашей формы установлено значение "Нет", ваше окно будет фактически невидимым.

Вместо этого вам необходимо использовать DwmEnableBlurBehindWindow API , который позволяет использовать эффект размытого стекла на окне без необходимости иметь рамку / границу. Itпринимает два параметра.Первый (hWnd) - это указатель на форму, к которой вы хотите применить эффект размытия позади.Второй (pBlurBehind) - это структура, переданная по ссылке, которая содержит данные или параметры для эффекта.

Следовательно, вам также необходимо определить структуру DWM_BLURBEHIND , которая сама содержитчетыре члена.Первый (dwFlags) является побитовой комбинацией постоянных значений , которые указывают, какие элементы этой структуры были установлены.Второй (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 метод , чтобы получить указатель на регион, который вы хотите указать в качестве 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 объясняет, почему это так:

Когда вы применяете эффект размытия к субрегиону окна, альфа-канал окна используется для не размытой области,Это может вызвать неожиданную прозрачность в не размытой области окна.Поэтому будьте осторожны, когда применяете эффект размытия к субрегиону.

Насколько мне известно, это делает применение этого эффекта только к субрегиону окна формы относительно бесполезным.Единственный случай, когда мне кажется, что это может иметь смысл, - это если вы хотите сделать произвольную непрямоугольную форму гладкой, а остальная часть формы остается прозрачной.

...