Работа с прозрачностью. Создание нестандартных форм
Объявим функции, которые нам понадобятся
Private Declare Function CreateRoundRectRgn Lib "gdi32" _ (ByVal x1 As Long, ByVal y1 As Long, ByVal x2 As Long, _ ByVal y2 As Long, ByVal x3 As Long, ByVal y3 As Long) As Long
Private Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As Long, _ ByVal hRgn As Long, ByVal bRedraw As Long) As Long
Private Declare Function CreateRectRgn Lib "gdi32" (ByVal x1 As Long, _ ByVal y1 As Long, ByVal x2 As Long, ByVal y2 As Long) As Long
Private Declare Function CreateEllipticRgn Lib "gdi32" (ByVal x1 As Long, _ ByVal y1 As Long, ByVal x2 As Long, ByVal y2 As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" _ (ByVal hObject As Long) As Long
Private Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, _ ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, _ ByVal nCombineMode As Long) As Long
Private Declare Function CreatePolygonRgn Lib "gdi32" (lpPoint As POINTAPI, _ ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long
Private Declare Function BeginPath Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function EndPath Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function PathToRegion Lib "gdi32" (ByVal hdc As Long) As Long
Private Type POINTAPI x As Long y As Long End Type
Private Const RGN_AND = 1 Private Const RGN_OR = 2 Private Const RGN_XOR = 3 Private Const RGN_DIFF = 4 Private Const RGN_COPY = 5
Работа с прозрачностью сводится к созданию региона т.е. определение непрозрачной части и привязка региона к форме или контролу. Например создадим круглую форму
Dim r As Long ' Создаем круглый регион r = CreateEllipticRgn(10, 10, 100, 100) ' Привязываем регион к форме SetWindowRgn hwnd, r, True ' Освобождаем ресурсы DeleteObject r
При создании региона нужно учесть, что регион привязывается к левому верхнему краю формы. Существуют следующие функции для создания регионов:
CreateRectRgn(x1, y1, x2, y2) - создает прямоугольный регион; CreateRoundRectRgn(x1, y1, x2, y2, x3, y3) - создает прямоугольный регион с
закругленными краями. Параметры x3 и y3 определяют закругленность углов по ширине и высоте. CreatePolygonRgn(lpPoint, nCount, nPolyFillMode) - создает многоугольный регион, , где lpPoint - начальный элемент массива, содержащего координаты вершин многоугольника, nCount - число вершин. Последняя точка многоугольника должна совпадать с начальной. Например:
Dim p(4) As POINTAPI p(0).x = 10 p(0).y = 10 p(1).x = 100 p(1).y = 10 p(2).x = 150 p(2).y = 100 p(3).x = 150 p(3).y = 200 p(4).x = 10 p(4).y = 10 r = CreatePolygonRgn(p(0), 5, 1) SetWindowRgn hwnd, r, True ' Освобождаем ресурсы DeleteObject r
Есть еще один способ создания региона:
Dim r as Long BeginPath hdc ' Здесь мы может что-либо нарисовать с помощью следующих API функций ' ExtTextOut ' LineTo ' MoveToEx ' PolyBezier ' PolyBezierTo ' Polygon ' Polyline ' PolylineTo ' PolyPolygon ' PolyPolyline ' TextOut EndPath hdc ' Создаем регион из нарисованного r = PathToRegion(hdc)
Для примера создадим регион из текстовой строки. Для этого используем стандартный метод Print. Еще надо учесть, что регион создается только из TrueType шрифтов (например Times New Roman)
Dim r As Long Font.Name = "Times New Roman" Font.Bold = True Font.Size = 72 BeginPath hdc Print "text" EndPath hdc r = PathToRegion(hdc) SetWindowRgn hWnd, r, True ' Освобождаем ресурсы DeleteObject r
Интересных результатов можно добиться путем комбинирования регионов. Для этого используется функция CombineRgn(hDestRgn, hSrcRgn1, hSrcRgn2, nCombineMode), где hDestRgn - результирующий регион, hSrcRgn1, hSrcRgn2 - регионы, которые комбинируются, nCombineMode - способ комбинирования, может принимать следующие значения: RGN_OR - складывает 2 региона; RGN_AND - перемножает регионы т.е. непрозрачным становится то место, где регионы накладываются друг на друга; RGN_XOR - в том мете, где регионы накладываются результирующий регион становится прозрачным; RGN_DIFF - вычитает второй регион из первого; RGN_COPY - результирующим становится первый регион. К примеру создадим регионы, которые расположены следующим образом:
Вставьте следующий код в программу и, поочередно заменяя параметр nCombineMode на RGN_AND, RGN_XOR, RGN_DIFF, посмотрите, что получится
Dim r1 As Long Dim r2 As Long ' Создаем первый регион r1 = CreateEllipticRgn(0, 0, 100, 100) ' Создаем второй регион r2 = CreateEllipticRgn(50, 0, 150, 100) ' Комбинируем регионы CombineRgn r1, r1, r2, RGN_OR ' Привязываем регион к форме SetWindowRgn hwnd, r1, True ' Освобождаем ресурсы DeleteObject r1 DeleteObject r2
Чтобы закрепить материал напишем программу, которая делает прозрачной форму, оставляя видимыми лишь контролы, находящиеся на ней. Для это поместите на форме несколько контролов, установите предварительно свойство BorderStyle=0 и введите следующий код:
Private Sub Form_Load() Dim r1 As Long Dim r2 As Long ScaleMode = vbPixels ' Создаем пустой регион r1 = CreateRectRgn(0, 0, 0, 0) ' Для каждого контрола на форме For Each Control In Form1.Controls With Control ' Создаем регион в соответствии с положением и размером контрола r2 = CreateRectRgn(.Left, .Top, .Left + .Width, .Top + .Height) End With ' Комбинируем регионы CombineRgn r1, r1, r2, RGN_OR Next ' Привязываем регион к форме SetWindowRgn hwnd, r1, True ' Освобождаем ресурсы DeleteObject r1 DeleteObject r2 End Sub
|