| ||||||||||||||||
![]() | ||||||||||||||||
| ||||||||||||||||
![]() | ||||||||||||||||
| ||||||||||||||||
![]() |
Как создать 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" или "Г" - хотя это уже и не цифры). Определимся с набором свойств для данного контрола:
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"
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. Private Sub UserControl_Click() RaiseEvent Click End Sub А если пользователь попадет мышкой на лейбл, а не на контрол? Значит мы должны добавить процедуру и для него: Private Sub lblI_Click(Index As Integer) RaiseEvent Click End Sub
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
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
[Назад][Содержание][Вперед] |
|
![]() | ||||||||||||||||
| ||||||||||||||||
![]() | ||||||||||||||||
|