ActiveX

Урок 6

Создание градиентной заливки фона

Эмуляция объема для контрола и текста

Встраивание 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

Hosted by uCoz