Results 1 to 1 of 1

Thread: VB - Cool Scroll (Scrolling Menu)

  1. #1

    Thread Starter
    Guru Aaron Young's Avatar
    Join Date
    Jun 1999
    Location
    Red Wing, MN, USA
    Posts
    2,177

    VB - Cool Scroll (Scrolling Menu)

    Here's some code I did in response to a challenge posted in these forums some time ago.

    It's a horizontally scrolling menu bar where menu items zoom in a hot-tracking fasion,
    with scrolling speed adjusting to the mouse position. (see screenshot.)


    It's a pretty neat effect, the idea came from a website menu.

    In a Form with a Picturebox (picFrame) and a Timer (tmrScroll):
    VB Code:
    1. ' Win32 API POINT UDT
    2. Private Type POINTAPI
    3.         x As Long
    4.         y As Long
    5. End Type
    6.  
    7. ' Win32 API Declarations
    8. Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    9. Private Declare Function ScreenToClient Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long
    10. Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
    11.  
    12. ' HotSpot User Defined Type Defintion
    13. Private Type udtHotSpot
    14.     X1 As Single        ' Left Coord
    15.     Y1 As Single        ' Top Coord
    16.     X2 As Single        ' Right Coord
    17.     Y2 As Single        ' Bottom Coord
    18.     Text As String      ' Caption/Label
    19.     Active As Boolean   ' Is Mouse Over this HotSpot?
    20.     Shadow As Boolean   ' Use a Shadow?
    21. End Type
    22.  
    23.  
    24. Private mtHotSpots() As udtHotSpot  ' Array of HotSpot UDTs
    25. Private mlHotSpots As Long          ' Number of HotSpots in Array
    26. Private mlLastHotSpot As Long       ' Last Activated HotSpot
    27. Private mdScrollSpeed As Single     ' Scrolling Speed of Menu
    28. Private mlLastDown As Long          ' Last HotSpot Mouse Was Held Down On
    29.  
    30. ' Scroll Menu and HotSpot Color Constants
    31. Private Const HS_FORECOLOR = vbWhite
    32. Private Const HS_BACKCOLOR = &H80FF& '&HA0FF&
    33. Private Const SA_BACKCOLOR = &H80FF&
    34. Private Const HS_SHADOW = vbBlack
    35. Private Const HS_SPACER = "::"
    36.  
    37. ' Maximum Menu Scrolling Speed in Pixels
    38. Private Const MAX_SCROLLSPEED = 5
    39.  
    40. Private Sub Form_Load()
    41.     ' Initialize the Scroll Area (picFrame)
    42.     picFrame.BackColor = SA_BACKCOLOR
    43.     ' Use Pixels as the ScaleMode for Everything
    44.     Me.ScaleMode = vbPixels
    45.     picFrame.ScaleMode = vbPixels
    46.    
    47.     picFrame.Height = 25
    48.     picFrame.Align = vbAlignTop
    49.     picFrame.AutoRedraw = True
    50.    
    51.     Me.Height = (picFrame.Height + (Me.Height / Screen.TwipsPerPixelY - Me.ScaleHeight)) * Screen.TwipsPerPixelY
    52.    
    53.     ' Create 10 HotSpots in the Menu
    54.     Do While mlHotSpots < 10
    55.         mlHotSpots = mlHotSpots + 1
    56.         ReDim Preserve mtHotSpots(1 To mlHotSpots)
    57.         ' Make them 100 Pixels wide and space them 15 Pixels apart
    58.         With mtHotSpots(mlHotSpots)
    59.             .Y1 = 0
    60.             .X1 = 115 * (mlHotSpots - 1)
    61.             .Y2 = 20
    62.             .X2 = .X1 + 100
    63.             .Text = "hotspot " & mlHotSpots
    64.             .Active = False
    65.             .Shadow = True
    66.         End With
    67.     Loop
    68.     ' Start the Timer which will Scroll the menu
    69.     tmrScroll.Enabled = True
    70. End Sub
    71.  
    72. Private Sub tmrScroll_Timer()
    73.     ' Reposition the HotSpots
    74.     Dim lIndex As Long
    75.    
    76.     For lIndex = 1 To mlHotSpots
    77.         With mtHotSpots(lIndex)
    78.             .X1 = .X1 + mdScrollSpeed
    79.             If .X1 < -100 And Sgn(mdScrollSpeed) = -1 Then
    80.                 .X1 = mtHotSpots(((lIndex + mlHotSpots - 2) Mod mlHotSpots) + 1).X2 + 15
    81.             ElseIf .X1 > picFrame.ScaleWidth And Sgn(mdScrollSpeed) = 1 Then
    82.                 .X1 = mtHotSpots((lIndex Mod mlHotSpots) + 1).X1 - 115
    83.             End If
    84.             .X2 = .X1 + 100
    85.         End With
    86.     Next
    87.     ' Determine if we're over a HotSpot, Clicking One and the speed at which
    88.     ' the menu is scrolling (as well as direction)
    89.     HitTest
    90.     ' Redraw the Menu
    91.     PaintScroll
    92. End Sub
    93.  
    94. ' This function retuns the Smallest of 2 given values
    95. Private Function GetMin(ByVal A As Variant, ByVal B As Variant) As Variant
    96.     If A < B Then
    97.         GetMin = A
    98.     Else
    99.         GetMin = B
    100.     End If
    101. End Function
    102.  
    103. ' This Function returns the Largest of 2 given values
    104. Private Function GetMax(ByVal A As Variant, ByVal B As Variant) As Variant
    105.     If A > B Then
    106.         GetMax = A
    107.     Else
    108.         GetMax = B
    109.     End If
    110. End Function
    111.  
    112. ' This Subroutine Redraws the menu and HotSpots
    113. Private Sub PaintScroll()
    114.     Dim lIndex As Long
    115.    
    116.     ' Clear the Menu Picturebox (picFrame)
    117.     picFrame.Cls
    118.     ' Step through the HotSpot Array
    119.     For lIndex = 1 To mlHotSpots
    120.         With mtHotSpots(lIndex)
    121.            
    122.             picFrame.FontBold = True
    123.             picFrame.FontSize = 8
    124.            
    125.             ' Draw the Background of the HotSpot
    126.             picFrame.Line (.X1, .Y1)-(.X2, .Y2), HS_BACKCOLOR, BF
    127.            
    128.             ' Draw Spacer Shadow
    129.             If .Shadow Then
    130.                 picFrame.ForeColor = HS_SHADOW
    131.                 picFrame.CurrentX = .X2 + 7
    132.                 picFrame.CurrentY = .Y1 + (((.Y2 - .Y1) - picFrame.TextHeight(HS_SPACER)) / 2) + 1
    133.                 picFrame.Print HS_SPACER
    134.             End If
    135.            
    136.             ' Set the HotSpot Forecolor
    137.             picFrame.ForeColor = HS_FORECOLOR
    138.            
    139.             ' Draw Spacer
    140.             picFrame.CurrentX = .X2 + 7
    141.             picFrame.CurrentY = .Y1 + (((.Y2 - .Y1) - picFrame.TextHeight(HS_SPACER)) / 2)
    142.             picFrame.Print HS_SPACER
    143.            
    144.             ' Determine FontSize, depending on whether the user
    145.             ' is hovering over this hotspot at the time.
    146.             picFrame.FontSize = IIf(.Active, 12, 8)
    147.            
    148.             ' Draw Caption Shadow
    149.             If .Shadow Then
    150.                 picFrame.ForeColor = HS_SHADOW
    151.                 ' Center the HotSpot Caption Vertically and Horizontally
    152.                 picFrame.CurrentX = .X1 + (((.X2 - .X1) - picFrame.TextWidth(.Text)) / 2) + IIf(.Active, 2, 1)
    153.                 picFrame.CurrentY = .Y1 + (((.Y2 - .Y1) - picFrame.TextHeight(.Text)) / 2) + IIf(.Active, 2, 1)
    154.                 ' Print the HotSpot Caption
    155.                 picFrame.Print .Text
    156.                 picFrame.ForeColor = HS_FORECOLOR
    157.             End If
    158.            
    159.             ' Draw Caption
    160.             ' Center the HotSpot Caption Vertically and Horizontally
    161.             picFrame.CurrentX = .X1 + (((.X2 - .X1) - picFrame.TextWidth(.Text)) / 2)
    162.             picFrame.CurrentY = .Y1 + (((.Y2 - .Y1) - picFrame.TextHeight(.Text)) / 2)
    163.             ' Print the HotSpot Caption
    164.             picFrame.Print .Text
    165.        
    166.         End With
    167.     Next
    168.            
    169. End Sub
    170.  
    171. ' This Subroutine calculates the Mouse Coords in terms of the
    172. ' Menu Container (picFrame) and calculates menu scroll speed
    173. ' HotSpot Activation and whether a "Click" event should be raised.
    174. Private Sub HitTest()
    175.     Dim tPOINT As POINTAPI
    176.     Dim lIndex As Long, lX As Long, lY As Long
    177.     Dim bMouseDown As Boolean
    178.     Static bLastMouseDown As Boolean
    179.    
    180.     ' Get the status of the Left Mouse Button
    181.     bMouseDown = GetAsyncKeyState(vbLeftButton)
    182.    
    183.     ' Get the current Mouse Position (in Screen Coords)
    184.     Call GetCursorPos(tPOINT)
    185.     ' Convert the Screen Coords to be relative to the Menu
    186.     ' Container (picFrame)
    187.     Call ScreenToClient(picFrame.hwnd, tPOINT)
    188.    
    189.     ' Store the Coords in easier to use variables
    190.     lX = tPOINT.x
    191.     lY = tPOINT.y
    192.    
    193.     ' Calculate the Menu Scroll Speed and Direction
    194.     With picFrame
    195.         ' If the Mouse is within the menu area, calculate scroll speed
    196.         ' depending on position, i.e. to the left half of the menu, scroll right
    197.         ' to the right half of the menu, scroll left.
    198.         If lY >= 0 And lY <= .ScaleHeight And lX >= 0 And lX <= .ScaleWidth Then
    199.             mdScrollSpeed = -GetMin(MAX_SCROLLSPEED, (MAX_SCROLLSPEED / (picFrame.ScaleWidth / 2)) * (tPOINT.x - (picFrame.ScaleWidth / 2)))
    200.         Else
    201.             ' If not in the menu, use the maximum scroll speed
    202.             'mdScrollSpeed = -MAX_SCROLLSPEED
    203.         End If
    204.     End With
    205.    
    206.     ' Loop through the HotSpot UDT's to see if the
    207.     ' Mouse is over a HotSpot
    208.     For lIndex = 1 To mlHotSpots
    209.         With mtHotSpots(lIndex)
    210.             If lX >= .X1 And lX <= .X2 And lY >= .Y1 And lY <= .Y2 Then
    211.                 Exit For
    212.             End If
    213.         End With
    214.     Next
    215.    
    216.     ' If it isn't, default the Index value to Zero (no hotspot)
    217.     If lIndex > mlHotSpots Then lIndex = 0
    218.    
    219.     ' If a Hotspot is no longer active, deactivate it
    220.     If mlLastHotSpot > 0 And lIndex <> mlLastHotSpot Then
    221.         ' Restore previous hotspot
    222.         mtHotSpots(mlLastHotSpot).Active = False
    223.     End If
    224.    
    225.     ' Remeber the current hotspot (if any)
    226.     mlLastHotSpot = lIndex
    227.    
    228.     ' If Hovering over a HotSpot, Activate it
    229.     If lIndex > 0 Then
    230.         mtHotSpots(lIndex).Active = True
    231.         ' Change the Mouse Point to the Hand Icon (Stored in Resource File)
    232.         If picFrame.MousePointer <> vbCustom Then
    233.             picFrame.MouseIcon = LoadResPicture("HANDICON", vbResIcon)
    234.             picFrame.MousePointer = vbCustom
    235.         End If
    236.         'If the Mouse is no longer pressed...
    237.         If Not bMouseDown Then
    238.             ' And it was previously held down on the same HotSpot
    239.             If bLastMouseDown And mlLastDown = lIndex Then
    240.                 ' Trigger a Click event passing in the HotSpot Index
    241.                 Call Click(lIndex)
    242.             End If
    243.             ' Remember the HotSpot index we're over
    244.             mlLastDown = lIndex
    245.         End If
    246.     Else
    247.         ' Restore the Mouse Pointer
    248.         picFrame.MousePointer = vbNormal
    249.     End If
    250.    
    251.     ' Remember the status of the Mouse Button
    252.     bLastMouseDown = bMouseDown
    253. End Sub
    254.  
    255. ' This Subroutine acts as the "Click()" Event for the HotSpots
    256. ' The HotSpot being clicked is represented by the "Index" parameter.
    257. Private Sub Click(ByVal Index As Long)
    258.     Debug.Print "Clicked: """ & mtHotSpots(Index).Text & """"
    259. End Sub
    Complete Source and Additional Example Files attached
    Attached Files Attached Files

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width