Option Explicit
Public WithEvents xlbxHighLite As MSForms.ListBox
Public WithEvents xlbxMain As MSForms.ListBox
Public WithEvents xfrmContainer As MSForms.Frame
Public WithEvents xmltContainer As MSForms.MultiPage
Public TransparentWhenSelected As Boolean
Dim zIsHeader As Boolean
Dim zHighLitedIndex As Long, EventsDisable As Boolean
Property Get ListBox() As MSForms.ListBox
Set ListBox = xlbxMain
End Property
Property Set ListBox(lbxListBox As MSForms.ListBox)
Set xlbxMain = lbxListBox
If xlbxHighLite Is Nothing Then
zCreateHighLiteBox xlbxMain
End If
Call UpdateHighLite
End Property
Property Get Index() As Long
Index = zHighLitedIndex
End Property
Property Let Index(inDx As Long)
If zIsHeader Then
zHighLitedIndex = 0
Else
zHighLitedIndex = inDx
End If
If Not ((xlbxMain Is Nothing) Or (xlbxHighLite Is Nothing)) Then
Call UpdateHighLite
End If
End Property
Property Get Highlite() As MSForms.ListBox
Set Highlite = xlbxHighLite
End Property
Property Get IsHeader() As Boolean
IsHeader = zIsHeader
End Property
Property Let IsHeader(inHead As Boolean)
zIsHeader = inHead
If zIsHeader Then
Index = 0
End If
End Property
Private Sub UpdateHighLite()
Dim IndexToHighlite As Long
IndexToHighlite = zHighLitedIndex
Rem if IsHeader
With xlbxHighLite
If zIsHeader Then
IndexToHighlite = xlbxMain.TopIndex: zHighLitedIndex = 0
.BorderColor = RGB(0, 0, 0)
.BorderStyle = fmBorderStyleSingle
Else
.BorderColor = xlbxHighLite.BackColor
.BorderStyle = fmBorderStyleNone
End If
End With
Rem adjust for scrollbar, the number 16 may be version specific
With xlbxHighLite
.Width = xlbxMain.Width + 16 * CDbl((xlbxMain.Height < (.Height - 2 * .BorderStyle) * xlbxMain.ListCount))
End With
If (-1 < IndexToHighlite) And (IndexToHighlite < xlbxMain.ListCount) Then
With xlbxHighLite
If Not (.Selected(0)) Then
.Clear
.AddItem xlbxMain.List(zHighLitedIndex, 0)
End If
.Top = xlbxMain.Top + (IndexToHighlite - xlbxMain.TopIndex) * (.Height) + 1 - .BorderStyle + CLng(Not TransparentWhenSelected)
.Left = xlbxMain.Left
.Visible = (xlbxMain.Top <= .Top) And (.Top <= xlbxMain.Top + xlbxMain.Height) And xlbxMain.Visible
.Selected(0) = xlbxMain.Selected(IndexToHighlite) And TransparentWhenSelected
.Enabled = xlbxMain.Enabled
End With
Else
xlbxHighLite.Visible = False
End If
End Sub
Private Sub zCreateHighLiteBox(lbxListBox As MSForms.ListBox)
Rem make highlite list box
With xlbxMain.Parent
Set xlbxHighLite = .Controls.Add("forms.ListBox.1", Visible:=False)
With xlbxHighLite
.Height = 20: .Width = 20
.Left = 20: .Top = 20
.AddItem "x"
'.Visible = False
End With
End With
zMatchProperties
Rem expose container to events
Select Case TypeName(xlbxMain.Parent)
Case "Frame"
Set xfrmContainer = xlbxMain.Parent
Case "Page"
Set xmltContainer = xlbxMain.Parent.Parent
End Select
End Sub
Private Sub zMatchProperties()
Rem get height of highlite
With xlbxMain.Parent.Controls.Add("forms.TextBox.1", Visible:=False)
.Left = 10: .Top = 10
Rem match font to main list box
With .Font
.Bold = xlbxMain.Font.Bold
.Charset = xlbxMain.Font.Charset
.Italic = xlbxMain.Font.Italic
.Name = xlbxMain.Font.Name
.Size = xlbxMain.Font.Size
.StrikeThrough = xlbxMain.Font.StrikeThrough
.Underline = xlbxMain.Font.Underline
.Weight = xlbxMain.Font.Weight
End With
.AutoSize = True
.Text = "X"
xlbxHighLite.Height = .Height: Rem <<<<
xlbxMain.Parent.Controls.Remove .Name
End With
With xlbxHighLite
Rem initialize highlite properties to main listbox
.Width = xlbxMain.Width
.BackColor = xlbxMain.BackColor
.BorderColor = .BackColor
.BorderStyle = fmBorderStyleNone
.Enabled = xlbxMain.Enabled
With .Font
.Bold = xlbxMain.Font.Bold
.Charset = xlbxMain.Font.Charset
.Italic = xlbxMain.Font.Italic
.Name = xlbxMain.Font.Name
.Size = xlbxMain.Font.Size
.StrikeThrough = xlbxMain.Font.StrikeThrough
.Underline = xlbxMain.Font.Underline
.Weight = xlbxMain.Font.Weight
End With
.ForeColor = xlbxMain.ForeColor
xlbxMain.IntegralHeight = True
.IntegralHeight = True
.ListStyle = xlbxMain.ListStyle
.SpecialEffect = fmSpecialEffectFlat
xlbxMain.SpecialEffect = fmSpecialEffectFlat
End With
End Sub
Private Sub Class_Initialize()
zHighLitedIndex = -1
TransparentWhenSelected = True
End Sub
Private Sub Class_Terminate()
Set xlbxHighLite = Nothing
Set xlbxMain = Nothing
End Sub
Private Sub xlbxHighLite_Click()
If EventsDisable Then Exit Sub
EventsDisable = True
If zIsHeader Then
xlbxHighLite.Selected(0) = False
xlbxMain.Selected(0) = False
Else
xlbxMain.Selected(zHighLitedIndex) = True
End If
xlbxMain.SetFocus
With xlbxHighLite
If 0 < .ListCount And -1 < zHighLitedIndex And Not (zIsHeader) Then
.Selected(0) = (xlbxMain.Selected(zHighLitedIndex)) And TransparentWhenSelected
End If
End With
UpdateHighLite
EventsDisable = False
End Sub
Private Sub xlbxMain_Change()
If EventsDisable Then Exit Sub
EventsDisable = True
If zIsHeader Then
xlbxHighLite.Selected(0) = False
xlbxMain.Selected(0) = False
End If
With xlbxHighLite
If 0 < .ListCount And -1 < zHighLitedIndex And Not (zIsHeader) Then
.Selected(0) = (xlbxMain.Selected(zHighLitedIndex)) And TransparentWhenSelected
End If
End With
UpdateHighLite
ErrorHalt:
Err.Clear
On Error GoTo 0
EventsDisable = False
End Sub
Private Sub xlbxMain_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single)
UpdateHighLite
End Sub
Private Sub xfrmContainer_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single)
UpdateHighLite
End Sub
Private Sub xmltContainer_Change()
xlbxHighLite.Visible = Not (xmltContainer.Value = xlbxHighLite.Parent.Index)
UpdateHighLite
End Sub
Private Sub xmltContainer_MouseMove(ByVal Index As Long, ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single)
UpdateHighLite
End Sub