Knowledge Base |

# How to Add Highlight Ability to Visual Basic's Outline Control

Article ID: 118939

Article Last Modified on 1/8/2003

APPLIES TO

- Microsoft Visual Basic 3.0 Professional Edition

This article was previously published under Q118939

## SUMMARY

The Outline control (MSOutLin.VBX) supplied with Visual Basic does not automatically highlight the current list element when the Outline control is used as the destination for a drag-and-drop operation. This article shows how to add the highlight facility to the Outline control through code.

## MORE INFORMATION

When you drag list items from one location to another, the Windows File Manager program highlights the current destination element as the item being dragged is moved over it. This lets you know visually where the dragged element will go when "dropped."

### Step-by-Step Example

1. Start Visual Basic, or from the File menu, choose New Project (ALT + F, N)if Visual Basic is already running. Form1 is created by default.
2. Add one Outline control (Outline1) and one command button (Command1) to Form1.
3. Set the ClipControls property of Form1 to "False". This allows the program to draw on top of the Outline control. By default, the form's ScaleMode should be set to "Twips". The sample code uses Twips as its unit of measurement for drawing and, therefore, it requires the ScaleMode of the form to be set to Twips.
4. Set the DragMode property of Command1 to "1 - Automatic".
5. The font properties of the Outline control, such as FontName and FontSize, must match the font properties of the form. (They should match by default when starting a new project.) It is important that the fonts match so that the TextHeight() function reports the proper height of a row in the Outline control.
6. Add the following declarations and ScrollBarVisible function to the General Declaration section of Form1:

             Const SM_CXBORDER = 5
             Const SM_CXVSCROLL = 2
             Const WS_VSCROLL = &H200000
             Const GWL_STYLE = (-16)

             'Enter each the following declarations on a single line:
             Declare Function GetSystemMetrics Lib "User" (ByVal nIndex As Integer
                ) As Integer
             Declare Function GetWindowLong Lib "User" (ByVal hWnd As Integer,
                ByVal nIndex As Integer) As Long

             Function ScrollBarVisible (MyControl As Control) As Integer
                Dim StyleFlag As Long
                StyleFlag = GetWindowLong(MyControl.hWnd, GWL_STYLE)
                If StyleFlag And WS_VSCROLL Then
                   ScrollBarVisible = True
                Else
                   ScrollBarVisible = False
                End If
             End Function

   NOTE: to make this a more generic routine, these declarations may be moved into a BAS module. Add the keyword "Global" to the front of the Const declarations if this is done.
7. Add the following code to the DragOver event for Outline1:

             ' Note the following Sub and Line statements
             ' must be entered on a single line:
             Sub Outline1_DragOver (Source As Control, x As Single, y As Single,
                State As Integer)

                Dim iScrollBarOffset As Integer
                Static iDropIndex As Integer
                Dim iCurrentIndex As Integer
                Dim iTextHeight As Integer

                If ScrollBarVisible(Outline1) Then
                   ' If the contents don't fit in the available outline space,
                   ' then we have to compensate for the width of the scrollbar.
                   iScrollBarOffset = Screen.TwipsPerPixelX *
                      GetSystemMetrics(SM_CXVSCROLL)
                Else
                   ' Otherwise, we don't have a scrollbar.
                   iScrollBarOffset = 0
                End If
                ' This value is used to compensate for the width of scrollbars.
                ' If the elements in the outline control do not all fit in the
                ' controls display area, the scrollbars will automatically be
                ' added, reducing the length required for our highlight lines.

                iTextHeight = TextHeight("A")
                ' iTextHeight is needed to determine which
                ' element of the list the MousePointer is
                ' over. This assumes that the fontname and
                ' fontsize on Form1 and Outline1 are the same.

                Select Case State
                'Action determined by the state of the source control.

                   Case 0 'Enter
                   iDropIndex = -1

                   Case 1 'Leave
                   If iDropIndex <> -1 Then
                      ' Clean up highlight if we left one behind.

                      ' The following must be entered on a single line:
                      Line (Outline1.Left, Outline1.Top + iDropIndex *
                         iTextHeight)-Step(Outline1.Width - iScrollBarOffset,
                         iTextHeight), Outline1.BackColor, B

                      ' The following must be entered on a single line:
                      Line (Outline1.Left, Outline1.Top)-Step(Outline1.Width -
                         iScrollBarOffset, Outline1.Height), Outline1.ForeColor, B

                   End If
                   iDropIndex = -1

                   Case 2 'Over
                   iTextHeight = TextHeight("A")
                   iCurrentIndex = y / iTextHeight
                   If iDropIndex <> iCurrentIndex Then
                      ' If the source control is over a different Outline element
                      ...
                      If iDropIndex <> -1 Then 'Erase old highlight.

                         ' The following must be entered on a single line:
                         Line (Outline1.Left, Outline1.Top + iDropIndex *
                            iTextHeight)-Step(Outline1.Width - iScrollBarOffset,
                            iTextHeight), Outline1.BackColor, B

                         ' The following must be entered on a single line:
                         Line (Outline1.Left, Outline1.Top)-Step(Outline1.Width -
                            iScrollBarOffset, Outline1.Height),
          Outline1.ForeColor, B
                      End If
                      iDropIndex = iCurrentIndex
                      If iDropIndex <= Outline1.ListCount - Outline1.TopIndex - 1
          Then

                         ' Do the highlighting.
                         ' The following must be entered on a single line:
                         Line (Outline1.Left, Outline1.Top + iDropIndex *
                            iTextHeight)-Step(Outline1.Width - iScrollBarOffset,
                            iTextHeight), Outline1.ForeColor, B

                      Else
                         iDropIndex = -1
                      End If
                   End If

                End Select
             End Sub

8. Add the following code to the Form_Load event for Form1. This code adds some "dummy" elements to the Outline control. Remove this code if you already have code to populate your Outline control.

             Sub Form_Load ()
                Dim i As Integer
                For i = 1 To 20
                   Outline1.AddItem Str(i)
                Next
             End Sub

9. From the Run menu, choose Start (ALT + R, S), or press the F5 key to run the program.
10. Drag Command1 over Outline1: Position the Mouse pointer over Command1; press and hold the left mouse button. While holding the left mouse button, move the mouse over the Outline control.
11. To perform an action when Command1 is dropped on Outline1, add the following code to the DragDrop event of Outline1:

              Sub Outline1_DragDrop (Source As Control, x As Single, y As Single)
                 Dim iTextHeight As Integer
                 Dim iCurrentIndex As Integer
                 iTextHeight = TextHeight("A")
                 iCurrentIndex = y / iTextHeight
                 If iCurrentIndex <= Outline1.ListCount - Outline1.TopIndex - 1
           Then
                    ' Add your own code here to perform an
                    ' action on the current list element:
                    Outline1.List(iCurrentIndex + Outline1.TopIndex) =
           Command1.Caption

                 End If
              End Sub

Additional query words: 3.00

Keywords: KB118939