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

Last reviewed: June 21, 1995
Article ID: Q118939
The information in this article applies to:
  • Professional Edition of Microsoft Visual Basic Programming System for Windows, version 3.0

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 reference words: 3.00
KBCategory: kbprg kbcode
KBSubCategory: PrgCtrlsCus


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: June 21, 1995
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.