Howdy,
Saw a couple threads from the past few years on this topic, but didn't
really find any solutions.
Here's one I found:
http://groups.google.com/group/comp....cff0186d12566/
That fella wanted to do pretty well the same thing I did (use a command
button to move between records in a form). Moving from record to record
is easy enough, but continuing to scroll through the records while the
left mouse button is being held down is not so easy.
As I said, none of the other threads had a workable solution, so I'm
providing one for future reference.
The AutoRepeat property of the CommandButton is ignored once you move
to a different record. Attempted various Timer functions, but didn't
like any of them. Tried various methods of recalling a MouseDown or
Click event from MouseUp, but those were unsuccessful, as well. MouseUp
is automatically fired whether it has happened or not when the current
record changes to another.
The only reliable method I found was to go to API calls and fire a
function within the form's class module (or any other class module, for
that matter) to continuously run code to move to the next/previous
record until the left button is released. Here's the code snippet:
'**************Declarations section**************
Private mlngVirtualLeft As Long
' Virtual left mouse button. If the user has elected to swap
' their mouse buttons, the physical buttons will not line up
' with the virtual buttons. To preserve expected behavior of
' apiGetAsyncKeyState calls, this value is detected on
' Form_Load or Class_Initialize for use in subsequent API calls.
Private mlngTimerInterval(1) As Long
' apiSleep timer interval in milliseconds
' (0) First pass interval
' (1) Consecutive pass interval
'**************API Constants**************
Private Const VK_LBUTTON As Long = &H1 ' Left mouse button
Private Const VK_RBUTTON As Long = &H2 ' Right mouse button
Private Const SM_SWAPBUTTON As Long = 23
' When used as nIndex in apiGetSystemMetrics this will be
' nonzero if the meanings of the left and right mouse buttons
' are swapped; otherwise, 0 (zero).
'**************API Functions**************
' The GetAsyncKeyState function determines whether a key is
' up or down at the time the function is called, and whether
' the key was pressed after a previous call to GetAsyncKeyState.
Private Declare Function apiGetAsyncKeyState Lib "user32.dll" _
Alias "GetAsyncKeyState" (ByVal vKey As Long) As Integer
' The GetSystemMetrics function retrieves various system
' metrics (widths and heights of display elements) and system
' configuration settings.
Private Declare Function apiGetSystemMetrics Lib "user32.dll" _
Alias "GetSystemMetrics" (ByVal nIndex As Long) As Long
' The Sleep function suspends the execution of the current
' thread for at least the specified interval.
Private Declare Sub apiSleep Lib "kernel32.dll" Alias "Sleep" _
(ByVal dwMilliseconds As Long)
'**************Functional code**************
Private Sub DetectState(bytRecord As AcRecord)
Dim intBtnState As Integer, blnNotFirstPass As Boolean
Do
' Move to record specified
Call RecordNav(bytRecord)
' Pause code for specified interval
Call Sleep(mlngTimerInterval(Abs(blnNotFirstPass)))
blnNotFirstPass = True
' Detect mouse button
intBtnState = GetAsyncKeyState(mlngVirtualLeft)
' Loop until button released
Loop Until (intBtnState = 0) Or (intBtnState = 1)
End Sub
Private Sub RecordNav(bytRecord As AcRecord)
' This function maintained seperately so that it may
' be called from places other than DetectState
' to provide functionality such as RecordNav(acLast)
DoCmd.GoToRecord , , bytRecord
End Sub
Private Sub Form_Load()
' Should be Class_Initialize if you're using it in a custom class
' Check virtual mouse key settings for virtual left
mlngVirtualLeft = apiGetSystemMetrics(SM_SWAPBUTTON)
If mlngVirtualLeft = 0 Then
mlngVirtualLeft = VK_LBUTTON
Else: mlngVirtualLeft = VK_RBUTTON
End If
' Default timer settings
mlngTimerInterval(0) = 500
mlngTimerInterval(1) = 50
End Sub
Private Sub NextButton_Click()
Call DetectState(acNext)
End Sub
Private Sub PreviousButton_Click()
Call DetectState(acPrevious)
End Sub
'**************End code**************
This hasn't been troubleshot completely, yet, and obviously needs some
error handling. Some structural error handling to detect movement to
the First or Last record will be needed to keep from getting error
2105: "You can't go to the specified record." This will happen under
this structure when you navigate all the way to the beginning or end of
the recordset.
If you see any problems or ways to improve the code, please reply.