Search code examples
vbams-access

Using Mouse Wheel into the Memo Box or Combo Box in Access Forms


I have an Access form named "NewStaff" that contains a Memo box. When I clicked inside it, rolling the mouse wheel would cause an exit to this field and it would not be placed on the text inside the Memo box. Finally, I put the following code on the MouseWheel Event form and now I can move the Memo box lines by rolling the mouse wheel.

 Private Sub Form_MouseWheel(ByVal Page As Boolean, ByVal Count As Long)
         Dim i As Long
         Dim s As String
         If Me.ActiveControl.Name = "ُNewStaff" Then
             If Count > 0 Then
                 For i = 1 To Count
                     s = s & "{DOWN}"
                 Next i
             Else
                 For i = 1 To -Count
                     s = s & "{UP}"
                 Next i
             End If
             SendKeys s
         End If
 End Sub

The problem is that the cursor has jumping three lines to three lines and finally leaves the field!

Is there a way to go line by line and stay in Memo box for the cursor? ... Thanks


Solution

  • Using SendKeys UP/DOWN to scroll is clunky - users don't necessarily want the cursor to move, only the text to scroll. Plus the "sudden exit" effect you noticed.

    A long time ago I found and adapted this solution.
    Paste all the code into a module, and call it as shown in the comments.

    Option Compare Database
    Option Explicit
    
    Private Const WM_VSCROLL = &H115
    Private Const SB_LINEUP = 0
    Private Const SB_LINEDOWN = 1
    
    Public Declare Function SendMessage Lib "user32" _
       Alias "SendMessageA" _
       (ByVal hWnd As Long, _
       ByVal wMsg As Long, _
       ByVal wParam As Long, _
       LParam As Any) _
       As Long
       
    Private Declare Function apiGetFocus Lib "user32" _
            Alias "GetFocus" _
             () As Long
    '
    
    ' Scroll multi-line textboxes with the mouse wheel. The textbox must have the focus.
    '
    ' Call this sub in the MouseWheel event of the form(s) containing multi-line textboxes, like this:
    '
    ' Private Sub Form_MouseWheel(ByVal Page As Boolean, ByVal Count As Long)
    '    Call MouseWheelScroll(Count)
    ' End Sub
    '
    ' Sources
    ' http://www.access-programmers.co.uk/forums/showthread.php?t=195679
    ' http://www.extramiledata.com/scroll-microsoft-access-text-box-using-mouse-wheel/
    
    Public Sub MouseWheelScroll(ByVal Count As Long)
    
        Dim LinesToScroll As Integer
        Dim hwndActiveControl As Long
        
        If Screen.ActiveControl.Properties.Item("ControlType") = acTextBox Then
            hwndActiveControl = fhWnd(Screen.ActiveControl)
            For LinesToScroll = 1 To Abs(Count)
                SendMessage hwndActiveControl, WM_VSCROLL, IIf(Count < 0, SB_LINEUP, SB_LINEDOWN), 0&
            Next
        End If
    
    End Sub
    
    ' Source: http://access.mvps.org/access/api/api0027.htm
    ' Code Courtesy of Dev Ashish
    
    Private Function fhWnd(ctl As Control) As Long
        
        On Error Resume Next
        ' We only use this function for Screen.ActiveControl, so this is not necessary.
        ' I can't remember if I found it harmful in some situations.
        ' ctl.SetFocus
        
        fhWnd = apiGetFocus
        On Error GoTo 0
        
    End Function