Connecting Tech Pros Worldwide Help | Site Map

Overcoming CommandButton autorepeat flaw for record navigation

 
LinkBack Thread Tools Search this Thread
  #1  
Old November 13th, 2006, 04:55 AM
Jamey Shuemaker
Guest
 
Posts: n/a
Default Overcoming CommandButton autorepeat flaw for record navigation

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.


  #2  
Old November 13th, 2006, 10:45 AM
Lyle Fairfield
Guest
 
Posts: n/a
Default Re: Overcoming CommandButton autorepeat flaw for record navigation

Jamey Shuemaker wrote:
Quote:
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.
Uh huh!

  #3  
Old November 13th, 2006, 11:45 AM
Stephen Lebans
Guest
 
Posts: n/a
Default Re: Overcoming CommandButton autorepeat flaw for record navigation

Hi Jamey,
While I appreciate an API solution more than the next person, is there a
reason you do not simply insert your CommandButtons onto a Subform to
resolve the Autorepeat issue?
http://www.lebans.com/recnavbuttons.htm
A2KRecordNavigationButtons is an MDB containing code to replace the standard
Navigation Buttons. The custom buttons exactly emulate the standard
navigation bar including the autorepeat property. A2K or higher! Modified by
MVP Graham Mandeno to work properly with multiple SubForm configurations.

A97RecordNavigationButtons is an MDB containing code to replace the standard
Navigation Buttons. The custom buttons exactly emulate the standard
navigation bar including the autorepeat property.

Version 1.7 Oct 06, 2006

Modified by MVP Graham Mandeno to work properly with multiple SubForm
configurations.


--

HTH
Stephen Lebans
http://www.lebans.com
Access Code, Tips and Tricks
Please respond only to the newsgroups so everyone can benefit.


"Jamey Shuemaker" <cantankeris@yahoo.comwrote in message
news:1163398313.180292.212820@m73g2000cwd.googlegr oups.com...
Quote:
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.
>

  #4  
Old November 13th, 2006, 03:35 PM
Jamey Shuemaker
Guest
 
Posts: n/a
Default Re: Overcoming CommandButton autorepeat flaw for record navigation


Stephen Lebans wrote:
Quote:
Hi Jamey,
While I appreciate an API solution more than the next person, is there a
reason you do not simply insert your CommandButtons onto a Subform to
resolve the Autorepeat issue?

Hey Stephen,

Honestly, didn't know these existed. I'll check them out. I'm using
them on a class object and didn't know about the subform solution.
Sounds like something worth looking into to avoid the Sleep function
which causes some minor quirkiness depending on the click speed of the
user.

I'll look them over and see if they provide a better solution. I'd like
to stay away from the API calls, and if there's a better solution, I'm
certainly game.

Thanks for the links.

  #5  
Old November 13th, 2006, 08:35 PM
Jamey Shuemaker
Guest
 
Posts: n/a
Default Re: Overcoming CommandButton autorepeat flaw for record navigation

Looks solid. I may adapt that somewhat for my purposes with the custom
class to avoid the repeat quirks.

Thanks, again.

Stephen Lebans wrote:
Quote:
Hi Jamey,
While I appreciate an API solution more than the next person, is there a
reason you do not simply insert your CommandButtons onto a Subform to
resolve the Autorepeat issue?
http://www.lebans.com/recnavbuttons.htm
A2KRecordNavigationButtons is an MDB containing code to replace the standard
Navigation Buttons. The custom buttons exactly emulate the standard
navigation bar including the autorepeat property. A2K or higher! Modified by
MVP Graham Mandeno to work properly with multiple SubForm configurations.
>
A97RecordNavigationButtons is an MDB containing code to replace the standard
Navigation Buttons. The custom buttons exactly emulate the standard
navigation bar including the autorepeat property.
>
Version 1.7 Oct 06, 2006
>
Modified by MVP Graham Mandeno to work properly with multiple SubForm
configurations.
>
>
--
>
HTH
Stephen Lebans
http://www.lebans.com
Access Code, Tips and Tricks
Please respond only to the newsgroups so everyone can benefit.
>
>
"Jamey Shuemaker" <cantankeris@yahoo.comwrote in message
news:1163398313.180292.212820@m73g2000cwd.googlegr oups.com...
Quote:
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.
 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 220,840 network members.