InfoCity
InfoCity - виртуальный город компьютерной документации
Реклама на сайте







Размещение сквозной ссылки

 

Как создать ActiveX Control - 5


Эскин М.Г.  


Вообще-то я не собирался продолжать этот цикл статей, но активная переписка с корреспондентами подтолкнула меня к этому. Основы создания ActiveX Control'ов заложены. Начинающие уже попробовали свои силы (а не просто скопировали листинги), умеющие посмотрели какие идеи они могут использовать для себя. А поделиться?.. Данная статья выходит с подзаголовком "Поделись - богаче станешь!". Т.е. здесь я хочу показать свои наработки и подходы к программированию контролов. Думаю, что у любого найдетсяся пара-другая трюков и нестандартных подходов. Подтолкнул к этой идее ActiveX Control, написанный Аркадием Оловянниковым , который воспользовался недокументированными функциями для вывода стандартных диалоговых окон Windows, типа смены ярлыка у программы, "дерева" папок и т.п. Так почему же не обнародовать свои находки, а не только готовые OCX'ы, в этом цикле статей, но уже под своей фамилией?

Поводом для этой статьи послужил мой контрол Indicator. Собственно говоря, контрол писался под конкретную задачу и ряд свойств не был просто-напросто предусмотрен. А когда Boris Rudoy выложил его на сайт, вот тут-то и посыпались просьбы улучшить, замечания об отсутствии ряда параметров и т.п. Пришлось сесть за компьютер и переработать некоторые вещи. Но что бы снова не впасть в немилость решил описать это в статье, а не выкладывать готовый OCX - пусть каждый кто хочет - переделывает под себя. Итак, создаем новый проект и называем его Indicator, а UserControl переименовываем в Ind. Зададим изначально одно свойство для UserControl'a: ScaleMode = 3 (pixel). Расположим на нем группу из 7 Label (Name = lblI, Index - от 0 до 6, Caption = "", BackColor = &H00FF0000&-синий). Первые четыре будут изображать вертикальные сегменты, а остальные - горизонтальные. Подготовительный период закончен. В принципе, можно было использовать Shape или PictureBox. Но я остановился именно на Label, так как у Shape при изменении цвета необходимо было обрабатывать кроме FillColor еще и BorderColor, а PictureBox, по-моему он просто "тяжеловат" для таких операций - не очень заметно на глаз, но ... Продолжим создание контрола. Основными просьбами пользователей были масштабируемость и произвольная засветка отдельных сегментов "электронных цифр" (например, чтобы можно было высветить "E" или "Г" - хотя это уже и не цифры). Определимся с набором свойств для данного контрола:

Название

Описание

Тип

Значение по умолчанию

Entries

Высвечивание отдельных сегментов цифры

String

"1111111"

Thickness

Толщина сегмента (в пикселах)

Long

2

BackColor

Фоновый цвет

OLE_COLOR

&H8000000F

ForeColor

Цвет цифр

OLE_COLOR

&HFF0000


NB!
Обратите внимание, что свойству ForeColor контрола мы присваиваем свойство BackColor лейблов.


События определим стандартные: Click, DblClick, MouseDown, MouseUp, MouseMove и ... добавьте свои, какие Вам необходимы.

Далее с помощью визарда генерируем основу кода. Описание (Description) свойств и методов можно производить и в нем на четвертой страничке в соответствующем поле. NB! Если вместо кириллических букв у Вас выписывается абракадабра - значит у Вас не зарегистрирован в Windows шрифт Tahoma. Сделайте это и многие другие блоки VB, которые опираются на него будут корректно показывать Вам свои кириллические записи. Для этого необходимо: открыть файл WIN.INI и в секции [FontSubstitutes] записать следующую строку Tahoma,0=Tahoma,204. После этого перезагрузите Windows.

Теперь займемся исправлением некоторых кодов. А для этого необходимо разобраться, что делает данное свойство. Итак свойство Entries: это строка, состоящая из нулей и единиц (битовый аналог), каждое значение которых говорит включен или выключен определенный сегмент цифры. Поэтому изменим соответствующим образом Propery Let для него:

Dim i%, n$  If VerificationEntries(New_Entries) = True Then  	m_Entries = New_Entries  	For i = 0 To 6  		n = Mid(m_Entries, i + 1, 1)  		lblI(i).Visible = -1 * Val(n) 'умножаем на -1, т.к. True=-1  	Next  	Else  		MsgBox "Error!" 		Exit Property 	End If 	PropertyChanged "Entries" 


Функция VerificationEntries (см. в Листинге 5) - проверяет допустимость вводимых знаков и длину строки.
Свойство Thickness - определяет толщину сегмента цифры и Property Let озвучивается у него следующим образом:

 Dim i&  m_Thickness = New_Thickness  For i = 0 To 3 	 lblI(i).Width = m_Thickness 'для вертикальных сегментов   Next  For i = 4 To 6 	 lblI(i).Height = m_Thickness 'для горизонтальных сегментов   Next  PropertyChanged "Thickness"  UserControl_Resize  

Теперь самое время обратить внимание на массив лейблов (а их у нас 7). Чтобы свойство ForeColor работало с каждым лейблом, а не с каким-нибудь одним необходимо вставить цикл For-Next в Property Let для него, присваивая новое значение каждому лейблу отдельно. Аналогичная ситуация и в процедурах UserControl_ReadProperties и UserControl_WriteProperties.

И наконец события. Создавая с помощью мастера события мы присваивали их UserControl'у. В кодах это озвучивается примерно так:

   Private Sub UserControl_Click()   RaiseEvent Click  End Sub   

А если пользователь попадет мышкой на лейбл, а не на контрол? Значит мы должны добавить процедуру и для него:

Private Sub lblI_Click(Index As Integer)  RaiseEvent Click  End Sub 


Аналогичные изменения проведем и для других событий.

Осталось чуть-чуть - придать масштабируемость нашему контролу. Это мы сделаем в UserControl_Resize.
Проверка на минимальные размеры и установка если они нарушаются.

If (ScaleHeight - 3 * m_Thickness - 8 <= 0) Or (ScaleWidth-2*m_Thickness-4<=0) Then 	Size (3 * m_Thickness + 4) * Screen.TwipsPerPixelX,(5*m_Thickness+8)*
      Screen.TwipsPerPixelY 	Exit Sub End If 

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

 lblI(0).Move 0, m_Thickness + 2, m_Thickness, ScaleHeight * 0.5 - 1.5 * 
m_Thickness - 4  lblI(1).Move 0, 0.5 * ScaleHeight + 0.5 * m_Thickness + 2, m_Thickness, 
ScaleHeight * 0.5 - 1.5 * m_Thickness - 4  lblI(2).Move ScaleWidth - m_Thickness, m_Thickness + 2, m_Thickness, 
ScaleHeight * 0.5 - 1.5 * m_Thickness - 4  lblI(3).Move ScaleWidth - m_Thickness, 0.5 * ScaleHeight + 0.5 * m_Thickness + 2, 
m_Thickness, ScaleHeight * 0.5 - 1.5 * m_Thickness - 4  lblI(4).Move m_Thickness + 2, 0, ScaleWidth - 2 * m_Thickness - 4, m_Thickness  lblI(5).Move m_Thickness + 2, 0.5 * ScaleHeight - 0.5 * m_Thickness, ScaleWidth - 2 * 
m_Thickness - 4, m_Thickness  lblI(6).Move m_Thickness + 2, ScaleHeight - m_Thickness, ScaleWidth - 2 * 
m_Thickness - 4, m_Thickness 



Создаем тестировочный проект и "играем" с нашим контролом.

Наигрались? :)

А теперь давайте подумем о пользователе (программисте), который с Вашим контролом будет работать. Всем ли необходимо отдельное высвечивание сегментов? Мне кажется нет. Многим для своих задач достаточно выведение на экран только цифр. А удобно ли в данном случае для них свойство Entries? Хорошие вопросы...

Поэтому давайте на основе нашего контрола создадим еще один, который будет манипулировать только с цифрами, поддерживая все остальные свойства (кроме Entries) и события контрола Indicator. Итак в наш проект добавим еще один UserControl с помощью меню Project/Add User Control, и поместим на него наш контрол (NB! нескомпилированный). Назовем его Num. Зайдем в мастера и увидим, что появилась еще одна страничка в самом начале, позволяющая выбрать, какой ActiveX Control будет сейчас получать свои свойства, события и методы. Выберем строку Indicator: Num. На следующих шагах выберем свойства (кроме Entries) и события те же, что и у Ind и соответственно сделаем их привязку к Ind1. Добавим новое свойство Numeric (Тип Integer, значение по-умолчанию 0).

Зайдем в окно кодов и сделаем поправку для Property Let у свойства Numeric:

Сначала проверка на вводимое значение:

If Not IsNumeric(New_Numeric) Then Exit Property  m_Numeric = New_Numeric  Теперь выводим высвечивание цифр  Select Case m_Numeric Case 0 	Ind21.Entries = "1111101" Case 1 	Ind21.Entries = "0011000" Case 2 	Ind21.Entries = "0110111" Case 3 	Ind21.Entries = "0011111" Case 4 	Ind21.Entries = "1011010" Case 5 	Ind21.Entries = "1001111" Case 6 	Ind21.Entries = "1101111" Case 7 	Ind21.Entries = "0011100" Case 8 	Ind21.Entries = "1111111" Case 9 	Ind21.Entries = "1011111" Case Else 'ну например, двузначное число  	Ind21.Entries = "0000000" End Select PropertyChanged "Numeric" 

И сделаем запись в UserControl_Resize (позиционирование и масштабирование контрола):

Ind21.Move 0, 0, ScaleWidth, ScaleHeight 


Разместим на той же тестировочной форме новый контрол Num и теперь "поиграем" с ним. Кстати, на панели контролов Вы увидите уже две кнопки для своих контролов (не забыли использовать для них разные картинки?). Здесь я не буду останавливаться на оформлении своего контрола, создании Property Page и т.п. Кто забыл - посмотрите предыдущие статьи. Можно приступать к компиляции.

В заключение хотелось бы немного поговорить о поддержке апгрейдов. В тему статьи это не особенно укладывается, но рано или поздно Вам придется с этим столкнуться. Щелкнем правой кнопкой мыши в окне проектов на Indicator и выберем меню Indicator Properties. В самом первом ярлыке General увидим, что CheckBox с названием Upgrade ActiveX Controls уже отмечен. Это говорит о том, что более поздние версии будут заменяться более свежими. А в ярлыле Component во фрейме Version Compatibility (совместимость версий) выберите Project Compatibility. При первом создании ActiveX Control'a текстовое поле под ним останется пустым. Однако, после компиляции, там появится название Вашего проекта. Т.е. все последующие изменения и компиляции контрола будут ссылаться на предыдущий контрол, для обеспечения совместимости. NB! Если в новой версии Вы не включите какое-либо свойство, событие или метод, то обновив контрол рискуете (чаще всего на машине пользователя - Вы-то помните об изменениях) получить ошибку о неподдержании соответствующей части программы.

Для особо ленивых привожу полный листинг создания этого ActiveX Control'a.

[Назад][Содержание][Вперед]


Реклама на InfoCity

Яндекс цитирования



Финансы: форекс для тебя








1999-2009 © InfoCity.kiev.ua