This pages show you how to use the VB wizard to create a custom ticker control. It illustrates the VB wizard in detail, how properties can be dispatched to existing controls within your own control, and how completely new properties can be created. It also shows an interesting (even though its simple) new type of control! The actual ticker example is from Chapter 5 of Custom Controls Library by Rod Stephens (O'Reilly Press).
We assume that you're going to know how to start up VB and start a new project. Its probably best if you have already tried the HelloWorld example.
Also,
download
the source if you want to see it work before you do it yourself. We will
cover:
![]() Figure 1: new project dialog |
![]() Figure 2: project properties dialog |
![]() Figure 3: the control layout |
![]() Figure 4: how to find the illusive VB ActiveX Control Interface Wizard |
BackColor | Property |
BorderStyle | Property |
Click | Event |
DblClick | Event |
Enabled | Property |
Font | Property |
ForeColor | Property |
![]() Figure 5: select interface members dialog |
AutoSize | Property |
Caption | Property |
Interval | Property |
RepeatSpacing | Property |
XChange | Property |
![]() Figure 6: create some custom interface members! |
Public Name | Maps to Control | Maps to Member |
AutoSize | (none) | |
BackColor | UserControl | BackColor |
BorderStyle | UserControl | BorderStyle |
Caption | (none) | |
Click | UserControl | Click |
DblClick | UserControl | DblClick |
Enabled | (none) | |
Font | UserControl | Font |
ForeColor | UserControl | ForeColor |
Interval | tmrTicker | Interval |
RepeatSpacing | (none) | |
XChange | (none) |
![]() Figure 7: set mapping for the members of your control |
Public Name | Data Type | Default Value | Run Time | Design Time | Description |
AutoSize | Boolean | 0 | R/W | R/W | determines whether the control resizes itself to fit the text displayed |
Caption | String | R/W | R/W | the text displayed | |
Enabled | Boolean | 0 | R/W | R/W | determines whether the control is enabled to scroll text |
RepeatSpacing | Integer | 0 | R/W | R/W | the distance in pixels between occurrences of the repeating caption |
XChange | Integer | 0 | R/W | R/W | the distance by which the text is moved when the interval expires |
![]() Figure 8: Set the attributes for the members of your control |
![]() Figure 9: and we are done. |
Okay, the complete code is spat out here. Here's how to read it:
Option Explicit ' Enumerated data values. Enum tick_BorderStyle None_tick_BorderStyle = 0 Fixed_Single_tick_BorderStyle = 1 End Enum 'Default Property Values: Const m_def_RepeatSpacing = 4 Const m_def_XChange = 1 Const m_def_AutoSize = False Const m_def_Caption = "Ticker..." Const m_def_Enabled = False 'Property Variables: Dim m_RepeatSpacing As Integer Dim m_XChange As Integer Dim m_AutoSize As Boolean Dim m_Caption As String Dim m_Enabled As Boolean 'Event Declarations: Event Click() 'MappingInfo=UserControl,UserControl,-1,Click Event DblClick() 'MappingInfo=UserControl,UserControl,-1,DblClick Dim skip_redraw As Boolean Dim X As Single Dim CaptionWidth As Single Public Property Get AutoSize() As Boolean AutoSize = m_AutoSize End Property Public Property Let AutoSize(ByVal New_AutoSize As Boolean) m_AutoSize = New_AutoSize PropertyChanged "AutoSize" SizeControl ' Resize if necessary. End Property 'WARNING! DO NOT REMOVE OR MODIFY THE FOLLOWING COMMENTED LINES! 'MappingInfo=UserControl,UserControl,-1,BackColor Public Property Get BackColor() As OLE_COLOR BackColor = UserControl.BackColor End Property Public Property Let BackColor(ByVal New_BackColor As OLE_COLOR) UserControl.BackColor() = New_BackColor PropertyChanged "BackColor" DrawText ' Redraw. End Property 'WARNING! DO NOT REMOVE OR MODIFY THE FOLLOWING COMMENTED LINES! 'MappingInfo=UserControl,UserControl,-1,BorderStyle Public Property Get BorderStyle() As tick_BorderStyle BorderStyle = UserControl.BorderStyle End Property Public Property Let BorderStyle(ByVal New_BorderStyle As tick_BorderStyle) UserControl.BorderStyle() = New_BorderStyle PropertyChanged "BorderStyle" SizeControl ' Resize if necessary. End Property Public Property Get Caption() As String Caption = m_Caption End Property Public Property Let Caption(ByVal New_Caption As String) m_Caption = New_Caption PropertyChanged "Caption" CaptionWidth = TextWidth(m_Caption) If CaptionWidth > 0 And Ambient.UserMode Then tmrTicker.Enabled = m_Enabled Else tmrTicker.Enabled = False End If SizeControl ' Resize if necessary. DrawText ' Redraw. End Property Private Sub DrawText() ' Do nothing if we're loading. If skip_redraw Then Exit Sub ' Start from scratch. Cls ' Do nothing if the text takes up no room. If CaptionWidth <= 0 Then Exit Sub ' Draw the text. CurrentX = X CurrentY = 0 Do While CurrentX < ScaleWidth Print m_Caption; CurrentX = CurrentX + m_RepeatSpacing Loop ' Shift the starting position (if it's ' run time). If Not Ambient.UserMode Then Exit Sub X = X + m_XChange If m_XChange > 0 Then If X > 0 Then _ X = -CaptionWidth - m_RepeatSpacing Else If X < -CaptionWidth Then _ X = m_RepeatSpacing End If End Sub Private Sub SizeControl() Static resizing As Boolean ' Do nothing if the caption is blank. CaptionWidth = TextWidth(m_Caption) If CaptionWidth <= 0 Then Exit Sub ' Do nothing unless AutoSize is True. If Not m_AutoSize Then Exit Sub ' Do not recurse. If resizing Then Exit Sub resizing = True Size ScaleX(TextWidth(m_Caption) - ScaleWidth, vbPixels, vbTwips) + Width, _ ScaleY(TextHeight(m_Caption) - ScaleHeight, vbPixels, vbTwips) + Height resizing = False DrawText ' Redraw. End Sub Private Sub tmrTicker_Timer() DrawText End Sub Private Sub UserControl_Click() RaiseEvent Click End Sub Private Sub UserControl_DblClick() RaiseEvent DblClick End Sub 'WARNING! DO NOT REMOVE OR MODIFY THE FOLLOWING COMMENTED LINES! 'MappingInfo=UserControl,UserControl,-1,Font Public Property Get Font() As Font Set Font = UserControl.Font End Property Public Property Set Font(ByVal New_Font As Font) Set UserControl.Font = New_Font PropertyChanged "Font" SizeControl ' Resize if necessary. DrawText ' Redraw. End Property Public Property Get Enabled() As Boolean Enabled = m_Enabled End Property Public Property Let Enabled(ByVal New_Enabled As Boolean) m_Enabled = New_Enabled PropertyChanged "Enabled" ' Enable or disable if it's run time. If Ambient.UserMode Then _ tmrTicker.Enabled() = New_Enabled End Property 'WARNING! DO NOT REMOVE OR MODIFY THE FOLLOWING COMMENTED LINES! 'MappingInfo=UserControl,UserControl,-1,ForeColor Public Property Get ForeColor() As OLE_COLOR ForeColor = UserControl.ForeColor End Property Public Property Let ForeColor(ByVal New_ForeColor As OLE_COLOR) UserControl.ForeColor() = New_ForeColor PropertyChanged "ForeColor" DrawText ' Redraw. End Property 'WARNING! DO NOT REMOVE OR MODIFY THE FOLLOWING COMMENTED LINES! 'MappingInfo=tmrTicker,tmrTicker,-1,Interval Public Property Get Interval() As Long Interval = tmrTicker.Interval End Property Public Property Let Interval(ByVal New_Interval As Long) tmrTicker.Interval() = New_Interval PropertyChanged "Interval" End Property 'Initialize Properties for User Control Private Sub UserControl_InitProperties() skip_redraw = True m_AutoSize = m_def_AutoSize m_Caption = m_def_Caption Set Font = Ambient.Font m_RepeatSpacing = m_def_RepeatSpacing m_XChange = m_def_XChange skip_redraw = False If Ambient.UserMode Then tmrTicker.Enabled = m_Enabled SizeControl ' Resize if necessary. DrawText ' Redraw. End Sub Private Sub UserControl_Paint() DrawText End Sub 'Load property values from storage Private Sub UserControl_ReadProperties(PropBag As PropertyBag) skip_redraw = True m_AutoSize = PropBag.ReadProperty("AutoSize", m_def_AutoSize) UserControl.BackColor = PropBag.ReadProperty("BackColor", &H8000000F) UserControl.BorderStyle = PropBag.ReadProperty("BorderStyle", 0) m_Caption = PropBag.ReadProperty("Caption", m_def_Caption) Set Font = PropBag.ReadProperty("Font", Ambient.Font) m_Enabled = PropBag.ReadProperty("Enabled", m_def_Enabled) UserControl.ForeColor = PropBag.ReadProperty("ForeColor", &H80000012) tmrTicker.Interval = PropBag.ReadProperty("Interval", 0) m_RepeatSpacing = PropBag.ReadProperty("RepeatSpacing", m_def_RepeatSpacing) m_XChange = PropBag.ReadProperty("XChange", m_def_XChange) skip_redraw = False If Ambient.UserMode Then tmrTicker.Enabled = m_Enabled SizeControl ' Resize if necessary. DrawText ' Redraw. End Sub Private Sub UserControl_Resize() SizeControl ' Resize if necessary. End Sub 'Write property values to storage Private Sub UserControl_WriteProperties(PropBag As PropertyBag) Call PropBag.WriteProperty("AutoSize", m_AutoSize, m_def_AutoSize) Call PropBag.WriteProperty("BackColor", UserControl.BackColor, &H8000000F) Call PropBag.WriteProperty("BorderStyle", UserControl.BorderStyle, 0) Call PropBag.WriteProperty("Caption", m_Caption, m_def_Caption) Call PropBag.WriteProperty("Font", Font, Ambient.Font) Call PropBag.WriteProperty("Enabled", m_Enabled, m_def_Enabled) Call PropBag.WriteProperty("ForeColor", UserControl.ForeColor, &H80000012) Call PropBag.WriteProperty("Interval", tmrTicker.Interval, 0) Call PropBag.WriteProperty("RepeatSpacing", m_RepeatSpacing, m_def_RepeatSpacing) Call PropBag.WriteProperty("XChange", m_XChange, m_def_XChange) End Sub Public Property Get RepeatSpacing() As Integer RepeatSpacing = m_RepeatSpacing End Property Public Property Let RepeatSpacing(ByVal New_RepeatSpacing As Integer) m_RepeatSpacing = New_RepeatSpacing PropertyChanged "RepeatSpacing" DrawText ' Redraw. End Property Public Property Get XChange() As Integer XChange = m_XChange End Property Public Property Let XChange(ByVal New_XChange As Integer) m_XChange = New_XChange PropertyChanged "XChange" End Property