Scrolling on the Middle Mouse Button

Create IE Style scrolling effects

Middle Mouse Button Scroll Demo

Provides a class that allows you to perform auto-scrolling from the middle Mouse button just like in IE.

Auto-Scrolling

Mouse wheels are great. Even better if you're in an idle frame of mind is the click-and-drag-to-scroll you can do when you hit the middle mouse button in an IE Window. So what about adding it to your app's super grid control so your users can have the same sort of fun whilst they're clinching that crucial trade on the phone (or, more likely, waiting until their call "that is important to us" reaches the head of the queue)?

Unfortunately, unlike the mouse wheel messages added to Windows, there is no built-in Windows behaviour for scrolling a viewport on response to the middle mouse button. But that doesn't stop you from building this functionality, provided you can implement a Windows Mouse Hook.

Cursors, Curses

Let's look at the what the drag-middle scrolling does.

  1. You click the middle button. A marker pops up on screen showing the reference point from which scrolling will occur.
  2. When you move the mouse away from the reference point, the Window starts scrolling in that direction.
  3. The amount of scrolling that occurs is related to the distance of the mouse from the reference point:
    • When the mouse is "near" the reference point, no scrolling occurs.
    • When the mouse is "not far" from the reference point, scrolling occurs slowly.
    • When the mouse is "far" from the reference point, scrolling occurs quickly (potentially increasingly so as the distance increases).
  4. Cancellation of the drag scroll can occur under two separate scenarios:
    1. If the scroll operation is started whilst the middle button is down, then the scroll operation terminates when the middle button is released.
    2. Otherwise, the scroll operation terminates when any mouse button is pressed (or the user switches focus to another application).

Given these specifications, we can implement a version of the same behaviour. The first thing to note is that the last criteria forces use of a MouseHook, because otherwise there is no way of detecting the mouse event which ends the scroll operation.

Using cMiddleScroller

The code provided with this class consists of three parts:

  1. cMiddleScroller
    This class includes the logic for performing a drag middle-scroll in response to a middle mouse down.
  2. frmRefPoint
    This form is used to display the marker whilst scrolling is occured. It uses the SetWindowRgn function so it is only opaque on the compass point arrows and the central reference spot. See Creating Geometric Windows Shapes for more details.
  3. cursors.res
    Contains the cursors which are shown whilst middle scrolling is occuring. Other resources may be added, but the cursors need to be kept at the same ids (101 to 107).

You will also need to reference the vbAccelerator Hook Library and the Subclassing and Timer assitant.

Once you have these things in your project, middle scrolling can be added to any control that has a hWnd and uses Windows API ScrollBars. For example, to add middle-scrolling to a multi-line text box with both scroll bars visible you would use this code:


' Middle scroller
Private m_cMiddleScroller As cMiddleButtonScroller

Private Sub Form_Load()
      
   ' Create the middle button scroller
   Set m_cMiddleScroller = New cMiddleButtonScroller
     
End Sub

Private Sub txtSample_MouseDown( _
      Button As Integer, Shift As Integer, _
      X As Single, Y As Single _
   )
   If (Button = vbMiddleButton) Then
      With m_cMiddleScroller
         .HorizontalMode = ePixelBased
         .VerticalMode = eLineBased
         .StartMiddleScroll txtSample.hwnd
      End With
   End If
End Sub

The HorizontalMode and VerticalMode settings of the class allow you to configure the behaviour of the scroller. These can be set one of the following three settings:

  1. eNone - if the control cannot be scrolled in this direction. For example a text box may not have a horizontal scroll bar. Note that the code will also automatically check the underlying control to see which scroll bars are present and if they are enabled.
  2. ePixelBased - when the control's scroll bar represents a pixel offset from the origin. Some controls have pixel-accurate scroll, whereas others a single scroll step represents a row or line in the control. For pixel-accurate scrolling, the size of each scroll step needs to be larger than in the case of a row or line.
  3. eLineBased - for controls in which a single scroll bar step represents a row or line.

Conclusion

This sample demonstrates how to add drag-scrolling in response to a middle mouse button press which emulates the functionality provided in Internet Explorer and Office applications. This is hardly a critical piece of functionality but it can add to the user's experience for large grids or pictures.