Visual Basic, .NET, ASP, VBScript
 

   
 

Михаил Эскин немало сделал для развития русскоязычных VB сайтов. Многие знают его по статьям про ActiveX на VB сайтах, другие читают статьи Михаила уже на его собственном сайте. Михаил родился в Городском роддоме №1 города Астрахани, в “черную пятницу”, ну, так скажем, почти сорок лет назад. По-прежнему живет на Юге, правда теперь уже Германии, в прекрасном городе Мюнхене.

 
     
   
 

    Я неоднократно сталкивался с ситуациями, когда создавая нестандартный интерфейс, вынужден был использовать стандартные компоненты, не отвечающие общей идее. Самым ярким примером может служить линейка прокрутки. Это наверное единственный элемент управления, который не может изменять свою окраску. Поэтому создавая разноцветные формы, чтобы избежать не согласованности, всегда приходится думать чем заменить линейку прокрутки. В конце концов это меня вынудило создать свой собственный ActiveX Control, который отвечал бы моему интерфейсу. Художник я неважный поэтому нашел способ, позволяющий без особых проблем создавать различного вида схематические рисунки. В данном случае я использовал Автофигуры в Word'е с последующей их раскраской. Сохранив документ как HTML-файл, я получил возможность использовать их в своей программе.

    Если уж делать, то делать, убивая сразу двух зайцев. Я решил вместо двух линеек прокрутки (горизонтальной и вертикальной) создать один элемент управления, обладающий свойствами обеих. Если Вам это интересно, то последовательно вместе со мной Вы сможете создать себе такой же.

    Создадим проект ActiveX Control: Name = DoubleScroll; сам UserControl назовем DblScroll. Расположим на нем: 

pic PictureBox Является контейнером для нижеуказанных элементов управления
picSignH PictureBox Height=Width=195 твипов
picSignV PictureBox Height=Width=195 твипов

    На первом этапе, еще не создавая свойств и событий, добьемся чтобы наш будущий контрол имел прозрачную подложку. Я не буду подробно останавливаться на на этих функциях (они достаточно хорошо описаны на сайте vbrussian.com). Скажу только, что смысл их заключается в попиксельном считывании картинки и невключении пикселов заданного цвета в регион. Далее выводим этот регион на нашем UserControl'е. Данную процедуру (Draw) необходимо инициализировать в событии UserControl_Show, для полноценного отображения всех наших преобразований во время выполнения.

NB! Попиксельное считывание картинки - достаточно длительная процедура. Помните об этом, когда будете создавать свои картинки, не делайте их слишком большими!

    Создайте тестировочный проект, расположите на форме создаваемый контрол и посмотрите промежуточный результат.

    Расположите picSignH на горизонтальной части линейки прокрутки, а picSignV - на вертикальной. Займемся движениями бегунков при нажатии на них и перетаскивании.

NB! Обратите внимание на константы, объявляемые нами в разделе деклараций:

Private Const SIGN_SIZE = 195 'высота(ширина) бегунка в твипах
Private Const SIDE_SIZE = 420 'высота(ширина) звездочки (заменяет стрелку на обычной линейке) в твипах

    Если Вы будете использовать свой рисунок, не забудьте поменять значения этих констант для корректной работы контрола.

Создадим 2 процедуры, считывающие начальную и конечную координаты бегунков:

Private Sub picSignMouseDown()
    Dim res As Long
    startMove = True
    res = GetCursorPos(FirstPos)
End Sub

Private Sub picSignMouseUp()
    Dim res As Long
    res = GetCursorPos(LastPos)
    startMove = False
End Sub

    И используем их, соответственно, для событий MouseDown и MouseUp наших бегунков. А вот в событии MouseMove мы будем перемещать непосредственно сам бегунок, предварительно ограничив его движения по краям.

    Если сейчас мы запустим тестировочный проект, то вполне сможем насладиться нашим контролом и перетаскиванием бегунков. Однако, до получения законченного результата еще далеко, так как в настоящий момент мы имеем "вещь в себе". Красивая безделушка, не связанная ни с чем. Настало самое время добавить свойства и методы.

    Воспользуемся мастером создания ActiveX Control'ов и создадим элементы интерфейса, указанные ниже в таблице. Учитывая, что у нас, по сути, 2 линейки прокрутки, все свойства придется дублировать (вертикальные и горизонтальные):

Имя Тип Значение по умолчанию Описание
Свойство

MaxH

Long 100 Максимальное значение горизонтальной части
Свойство

MaxV

Long 100 Максимальное значение вертикальной части
Свойство

MinH

Long 0 Минимальное значение горизонтальной части
Свойство

MinV

Long 0 Минимальное значение вертикальной части
Свойство

LargeChangeH

Long 10 Смещение (в единицах) при щелчке между бегунком и краем по горизонтали
Свойство

LargeChangeV

Long 10 Смещение (в единицах) при щелчке между бегунком и краем по вертикали
Свойство

SmallChangeH

Long 1 Смещение (в единицах) при щелчке на концевую часть по горизонтали
Свойство

SmallChangeV

Long 1 Смещение (в единицах) при щелчке на концевую часть по вертикали
Свойство

ValueH

Long 0 Текущее горизонтальное значение
Свойство

ValueV

Long 0 Текущее вертикальное значение
Событие

Scroll

Событие, возникающее при щелчке на любую из линеек
Событие

HorizontalScroll

Событие, возникающее при щелчке на горизонтальную линейку
Событие

VerticalScroll

Событие, возникающее при щелчке на вертикальную линейку

    Напишем две процедуры, описывающие положение бегунка, с учетом ограничения движения (вот где нам понадобились константы!):

Private Sub PosHorizontal()
    picSignH.Left = (pic.ScaleWidth - (2 * SIDE_SIZE) - SIGN_SIZE) * m_ValueH / (m_MaxH - m_MinH) + SIDE_SIZE
End Sub

Private Sub PosVertical()
    picSignV.Top = (pic.ScaleHeight - (2 * SIDE_SIZE) - SIGN_SIZE) * m_ValueV / (m_MaxV - m_MinV) + SIDE_SIZE
End Sub

    Вставим эти процедуры в Property Let свойств Min, Max и Value (горизонтальные и вертикальные соответственно).

    И теперь (наверно, самое сложное в этом контроле) мы должны описать реакцию нашего элемента на щелчок по его различным "частям тела". Делается это в событии pic_MouseDown. Здесь же устанавливаются проверки на допустимость выставляемых значений свойств.

    Не забудьте добавить выполнение событий контрола в picSignV_MouseMove и picSignV_MouseMove.

    Вот теперь наш контрол готов. Осталось добавить необходимые мелочи: описание свойств и событий для возможности их прочтения в Object Browser, создания PropertyPage, формы About и желательно Help).

    Данный контрол вполне работоспособен, но это не ограничивает Вас от дальнейших экспериментов и наращивания его мощностей.

 
     

   
   
     
  VBNet рекомендует