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
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