Создание градиентной заливки фона
Эмуляция объема для контрола и текста
Встраивание ComboBox'а в Property Page
Этот контрол создается "с нуля", т.е. интерфейс целиком и полностью описывается с помощью кодов, а не "рисуется" на экране во время разработки. Создадим проект с названием ControlPanel, а UserControl'у присвоим имя Panel. Сразу же установим свойства для него: AutoRedraw=True, ControlContainer=True, DrawStyle=6 (InsideSolid), DrawWidth=2, ScaleMode=3 (Pixel). Определимся со свойствами:
NB! Энум constVStyle используется один и тот же у двух свойств. Полностью энумы можно просмотреть в листинге.
Название |
Описание |
Тип |
Значение по умолчанию |
BackColor |
Фоновый цвет, если Gradient=False |
OLE_COLOR |
&H8000000F& |
BorderStyle |
Приподнятый или утопленный контрол |
constVStyle |
0 |
Caption |
Надпись на контроле |
String |
"Panel" |
Font |
Шрифт |
Font |
MS Sans Serif, 8 |
FontStyle |
Приподнятый или утопленный стиль шрифта |
constVStyle |
0 |
ForeColor |
Цвет шрифта |
OLE_COLOR |
&H80000012& |
Gradient |
Наличие или отсутствие градиентной заливки фона |
Boolean |
False |
GradientColor |
Цвет градиентной заливки |
constBackColor |
0 |
GradientOrientation |
Направление заливки фона |
constOrientation |
0 |
и событиями: Click, DblClick, MouseDown, MouseMove, MouseUp. Если считаете необходимым - добавьте свои.
С помощью визарда создадим набор кодов, привязав свойства BackColor и Font к свойствам контрола.
NB! Свойство ForeColor не будем присваивать аналогичному свойству UserControl'а, а сделаем собственным для создания объемной надписи в последующем.
Вся суть данного контрола скрывается в одной-единственной процедуре, которая и руководит как цветом, так и объемом. Поэтому в Property Let каждого свойства, а так же в UserControl_Resize и UserControl_Show введем имя этой процедуры. А теперь поподробнее остановимся на ней:
Private Sub DrawControl()
Dim R%, G%, B%
Dim i%, NbrRects%, GradValue%, GradColor&
Очищаем контрол от всей графики
UserControl.Cls
Если свойство Gradient установлено, то заливаем контрол
If m_Gradient = True Then
Сам способ заливки я нашел где-то и когда-то (честно говоря уже не помню). С тех пор он претерпел у меня множество редакций и в настоящее время выглядит пока так:
NbrRects% = 128
For i = 1 To NbrRects
GradValue = 255 - (i * 2 - 1)
Определяем переменные, которые мы в дальнейшем будем использовать в функции RGB. При желании можно "поиграть" с переменными, используя не только крайние значения 0 и 255, но и промежуточные. Возможно, кто-то заинтересуется и создаст свой ActiveX Control с возможностью выбора произвольных значений цвета (желательно визуально, а не в цифрах :)).
Select Case m_GradientColor
Case 0
R = GradValue
G = 0
B = 0
Case 1
R = GradValue
G = GradValue
B = 0
Case 2
R = GradValue
G = GradValue
B = GradValue
Case 3
R = 0
G = GradValue
B = 0
Case 4
R = 0
G = GradValue
B = GradValue
Case 5
R = 0
G = 0
B = GradValue
Case 6
R = GradValue
G = 255
B = 0
Case 7
R = GradValue
G = 0
B = 255
Case 8
R = GradValue
G = 255
B = 255
Case 9
R = GradValue
G = GradValue
B = 255
Case 10
R = 0
G = GradValue
B = 255
Case 11
R = 255
G = GradValue
B = 0
Case 12
R = 255
G = GradValue
B = 255
Case 13
R = 255
G = GradValue
B = GradValue
Case 14
R = 0
G = 255
B = GradValue
Case 15
R = 255
G = 0
B = GradValue
Case 16
R = 255
G = 255
B = GradValue
Case Else 'если по ошибке поставят < 0 или > 16
R = 0
G = 0
B = GradValue
End Select
GradColor = RGB(R, G, B)
Теперь о направлении заливки. Здесь приводится образец горизонтальной и вертикальной. Используя функцию Circle - можно получить заливку с переходом от центра к краям по окружности. Экспериментируйте! Заливка по диагонали, например, только улучшит восприятие пользователя :)
Select Case m_GradientOrientation
Case 0
Line (0, ScaleHeight * (i - 1) / NbrRects)-(ScaleWidth,
_
ScaleHeight * i / NbrRects), GradColor&, BF
Case 1
Line (ScaleWidth * (i - 1) / NbrRects, 0)-(ScaleWidth *
i / NbrRects, ScaleHeight), _
GradColor&, BF
Case Else 'если по ошибке поставят < 0 или > 1
Line (0, ScaleHeight * (i - 1) / NbrRects)-(ScaleWidth,
ScaleHeight * i / NbrRects), _
GradColor&, BF
End Select
Next i
End If
Закончили с заливкой, переходим к объему. Что такое объем в графическом представлении? Это две точно-таких же фигуры, сдвинутых относительно основной (находящейся на переднем плане) в противоположные по диагонали стороны и покрашенные одна в белый, другая в темно-серый цвет. Вместо темно-серого некоторые программисты используют черный, но это в конечном итоге выглядит грубее.
Займемся оформлением объемного текста. В данном случае я использую метод Print для вывода надписи. Сначала рисуются две "задние" надписи, изображающие объем, а затем основная. Для создания такого же эффекта можно воспользоваться тремя Label'ами (не забудьте только им сразу же сделать прозрачный фон, установить AutoSize в True, и в ходе процедуры отследить смену цветов двух "задних" Label'ов).
CurrentX = (ScaleWidth - TextWidth(m_Caption)) / 2 - 0.5
CurrentY = (ScaleHeight - TextHeight(m_Caption)) / 2 - 0.5
If m_FontStyle = Выпуклый Then
UserControl.ForeColor = WHITE
Else
UserControl.ForeColor = GREY
End If
UserControl.Print m_Caption
CurrentX = (ScaleWidth - TextWidth(m_Caption)) / 2 + 1
CurrentY = (ScaleHeight - TextHeight(m_Caption)) / 2 + 1
If m_FontStyle = Выпуклый Then
UserControl.ForeColor = GREY
Else
UserControl.ForeColor = WHITE
End If
UserControl.Print m_Caption
CurrentX = (ScaleWidth - TextWidth(m_Caption)) / 2
CurrentY = (ScaleHeight - TextHeight(m_Caption)) / 2
UserControl.ForeColor = m_ForeColor
UserControl.Print m_Caption
Конец оформления объемного текста. Далее примемся за создание объема самого контрола. Принципы те же самые, только здесь используются, соответственно, белые и темно-серые линии, идущие по контуру.
Select Case m_BorderStyle
Case Вдавленный
Line (0, 0)-(0, ScaleHeight - 1), GREY
Line -(ScaleWidth - 1, ScaleHeight - 1), WHITE
Line -(ScaleWidth - 1, 0), WHITE
Line -(0, 0), GREY
Case Выпуклый
Line (0, 0)-(0, ScaleHeight - 1), WHITE
Line -(ScaleWidth - 1, ScaleHeight - 1), GREY
Line -(ScaleWidth - 1, 0), GREY
Line -(0, 0), WHITE
End Select
End Sub
Контрол готов! Создаем тестировочный проект и выискиваем недостатки :).
NB! Используя события MouseDown и MouseUp контрола, меняя свойство BorderStyle получаем уже не панель, а кнопку с градиентной заливкой.
С помощью мастера создаем страничку Property Page. И вот тут нас ждет разочарование. Мастер даже не показывает тех свойств, которые у нас опираются на собственные константы. Но все же давайте доведем до ума создание странички с тем, что нам предлагается и вручную добавим необходимое. Я покажу на примере свойства BorderStyle как можно добавить ComboBox, реагирующим на изменение данных свойств. Остальные делаются по тому же принципу.
Вначале, в разделе деклараций, объявим флаг, реагирующий на проводимые изменения,
Private bSelected As Boolean
и в каждом свойстве делаем проверку:
If Not bSelected Then Changed = True
Далее размещаем на страничке Property Page - ComboBox и изменяем его свойства: Name = cboBorderStyle; Style=2 (Dropdown List). В окне кодов странички также добавим:
Private Sub cboBorderStyle_Click()
If Not bSelected Then Changed = True
End Sub
В процедуру PropertyPage_ApplyChanges вводим строку:
SelectedControls(0).BorderStyle = cboBorderStyle.ListIndex
А в процедуру PropertyPage_SelectionChanged записываем:
Private Sub PropertyPage_SelectionChanged()
bSelected = True
cboBorderStyle.Clear
cboBorderStyle.AddItem "0 - Выпуклый"
cboBorderStyle.AddItem "1 - Вдавленный"
cboBorderStyle.ListIndex = SelectedControls(0).BorderStyle
'здесь пишем остальные свойства
bSelected = False
End Sub
На этом пока все. Полный листинг лежит здесь.
1999