Как я могу получить Aero Glass в форме Windows без границ?

122
20

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

спросил(а) 2021-01-19T16:51:41+03:00 9 месяцев, 1 неделя назад
1
Решение
164

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


Вместо этого вам необходимо использовать DwmEnableBlurBehindWindow API, который позволяет эффект стекловидного размытия на окне, не требуя, чтобы он имел рамку/границу. Требуется два параметра. Первый (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 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 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 объясняет, почему это так:


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



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

ответил(а) 2021-01-19T16:51:41+03:00 9 месяцев, 1 неделя назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема