Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to make a button command repeat until the mouse button is released

67 views
Skip to first unread message

Craig Skipsey

unread,
Oct 3, 2000, 2:09:19 AM10/3/00
to
I need to be able to run a module (currently mouseclick) repeatedly until
the mousebutton is released
the algorithm would be something like this

press left mouse button

goto next record
wait 1 sec
do while mousebuttonleft = pressed
goto next record
check state of mousebuttonleft
loop

so when the mouse button is pressed the "goto next record" & "check state of
mousebuttonleft" repeat until mousebuttonleft = released

in other words i need an easy way for users to scroll through records

this sort of procedure was a piss easy in C/C++, doesn't seem to be as
straight forward in VBA
--
Craig Skipsey ski...@primus.com.au
JJ Steelworks P/L
CAD Computer Operator / Network Administrator


Stuart Steedman

unread,
Oct 3, 2000, 3:00:00 AM10/3/00
to
How about this:

Dim bMouseDown As Boolean

Private Sub UserForm_MouseDown(ByVal Button As Integer, ByVal Shift As
Integer, ByVal X As Single, ByVal Y As Single)
bMouseDown = True
Call NextRecord
End Sub

Private Sub UserForm_MouseUp(ByVal Button As Integer, ByVal Shift As
Integer, ByVal X As Single, ByVal Y As Single)
bMouseDown = False
End Sub

Private Sub NextRecord()

Do While bMouseDown
Recordset.MoveNext
DoEvents
Next

End Sub

Apologies for the lack of detail, but I'm sure you get the idea...

含u


"Craig Skipsey" <ski...@primus.com.au> wrote in message
news:39d9...@news.iprimus.com.au...> I need to be able to run a module

Darryl

unread,
Oct 3, 2000, 3:00:00 AM10/3/00
to
Craig,

There's an AutoRepeat property available for command buttons. However, it
has never worked for me, even for something as simple as going to the next
record. Let us know if you get it to work.

Darryl


Craig Skipsey <ski...@primus.com.au> wrote in message
news:39d9...@news.iprimus.com.au...

Rolf Řstvik

unread,
Oct 3, 2000, 3:00:00 AM10/3/00
to

I think this should work.
Use the forms on_timer event, also needs a global variable
MouseButtonDown.

In my example i have a double check, maybe you don't need the
MousebuttonDown variable

'Mouse down subroutine
Private Sub XXXXXXX_MouseDown(Button As Integer, Shift As Integer, X
As Single, Y As Single)

MousebuttonDown = True
Me.TimeInterval = 100 'Timer interval is in mililiseconds

End Sub

'Mouse up subroutine
Private Sub Text0_MouseUp(Button As Integer, Shift As Integer, X As
Single, Y As Single)

Me.TimerInterval = 0
MousebuttonDown = False

End Sub

Private Sub Form_Timer()

If Mousebuttondown then

endif

End Sub

Ian

unread,
Oct 3, 2000, 3:00:00 AM10/3/00
to
Hi

The only way I've ever got this to work is like this.

This gives a single record movement with just the mouse, if the Shift key is
pressed it starts/stops the Timer.

Dim RecNav As Byte 'form level variable

Private Sub Nav_Next_MouseDown(Button As Integer, Shift As Integer, _


X As Single, Y As Single)

If Button = 1 And Shift = 1 And Me.TimerInterval Then
Me.TimerInterval = 0
End If
End Sub

Private Sub Nav_Next_MouseUp(Button As Integer, Shift As Integer, _


X As Single, Y As Single)

If Button = 1 Then
If Me.CurrentRecord = Me.RecordsetClone.RecordCount Then
DoCmd.RunCommand acCmdRecordsGoToFirst
Else
DoCmd.RunCommand acCmdRecordsGoToNext
End If
If Shift = 1 Then
RecNav = 2
Me.TimerInterval = 500
Else
Me.TimerInterval = 0
RecNav = 0
End If
DoEvents
End If
End Sub

Private Sub Nav_Prev_MouseDown(Button As Integer, Shift As Integer, _


X As Single, Y As Single)

If Button = 1 And Shift = 1 And Me.TimerInterval Then
Me.TimerInterval = 0
End If
End Sub

Private Sub Nav_Prev_MouseUp(Button As Integer, Shift As Integer, _


X As Single, Y As Single)

If Button = 1 Then
If Me.CurrentRecord = 1 Then
DoCmd.RunCommand acCmdRecordsGoToLast
Else
DoCmd.RunCommand acCmdRecordsGoToPrevious
End If
If Shift = 1 Then
RecNav = 1
Me.TimerInterval = 500
Else
Me.TimerInterval = 0
RecNav = 0
End If
DoEvents
End If
End Sub


Private Sub Form_Timer()
DoEvents
Select Case RecNav
Case 1
If Me.CurrentRecord = 1 Then
DoCmd.RunCommand acCmdRecordsGoToLast
Else
DoCmd.RunCommand acCmdRecordsGoToPrevious
End If
Case 2
If Me.CurrentRecord = Me.RecordsetClone.RecordCount Then
DoCmd.RunCommand acCmdRecordsGoToFirst
Else
DoCmd.RunCommand acCmdRecordsGoToNext
End If
Case Else
Me.TimerInterval = 0
End Select

End Sub

regards

Ian

** invalid email address, change dk to denmark

homepage http://www.kingsoft-denmark.com/
Tips & Tricks page http://tips.kingsoft-denmark.com/

Darryl <no_...@spam.com> wrote in message
news:4UgC5.11663$TP6.1...@newsread2.prod.itd.earthlink.net...


> Craig,
>
> There's an AutoRepeat property available for command buttons. However, it
> has never worked for me, even for something as simple as going to the next
> record. Let us know if you get it to work.
>
> Darryl
>
>
> Craig Skipsey <ski...@primus.com.au> wrote in message
> news:39d9...@news.iprimus.com.au...

Lyle Fairfield

unread,
Oct 3, 2000, 3:00:00 AM10/3/00
to
I guess you want something the arrow at the bottom of a vertical
scroll bar, or the "next" button in the set of navigation
buttons.

The AutoRepeat property seems to be a candidate but:

From the help file:

"If the code attached to the command button causes the current
record to change, the AutoRepeat property has no effect."

I suppose one could write code to accomplish this, vba being
what it is, but why not use the scroll bar or navigation button?

ski...@primus.com.au (Craig Skipsey) wrote in
<39d9...@news.iprimus.com.au>:

--
Lyle
http://www.cyriv.com/

Lyle Fairfield

unread,
Oct 3, 2000, 3:00:00 AM10/3/00
to
Well, it's an interesting question ... really revolves around how do we know if
a button is pressed; here's a start (my friend, Vincent will add the comments
no doubt, but in what language?):

Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As
Integer
Private Const VK_LBUTTON = &H1
Private Const WM_KEYDOWN = &H100

Private Function isPushed(ByRef ctl As Control) As Boolean
On Error Resume Next
isPushed = (Screen.ActiveControl.Name = ctl.Name) And
(GetKeyState(VK_LBUTTON) And WM_KEYDOWN)
End Function

Private Sub cmdTest_Click()
If Not Me.NewRecord Then DoCmd.RunCommand acCmdRecordsGoToNext
End Sub

Private Sub Form_Open(Cancel As Integer)
Me.TimerInterval = 500
End Sub

Private Sub Form_Timer()
If isPushed(Me.cmdTest) Then cmdTest_Click
End Sub

>I need to be able to run a module (currently mouseclick)

--
Lyle
http://www.cyriv.com/

Dimitri Furman

unread,
Oct 3, 2000, 8:36:28 PM10/3/00
to
On Oct 03 2000, 05:21 pm, lyle...@yahoo.com (Lyle Fairfield) wrote in
<8FC2B1E8Alyl...@24.9.0.17>:

>Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As
>Long) As Integer
>Private Const VK_LBUTTON = &H1
>Private Const WM_KEYDOWN = &H100

Hi Lyle,

Are you sure VK_LBUTTON works with GetKeyState? MSDN doesn't seem to
mention it. It does work with GetAsyncKeyState, but that is system-wide, so
even if Access loses focus it will still continue to scroll if the mouse is
held down. Well, I guess one can always a check for active window.

--
(remove a 9 to reply by email)

Lyle Fairfield

unread,
Oct 3, 2000, 9:15:02 PM10/3/00
to
Dimitri ...

Not sure about it at all ...

I ran a quickie on a sample form, that's all.

dfu...@cloud99.net (Dimitri Furman) wrote in
<8FC2D38C6df...@207.126.101.100>:


--
Lyle
http://www.cyriv.com/

Lyle Fairfield

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Perhaps this is safer ... might guard against multiple instances of same form
being open, in which case clicking button would move record pointer of all?
Nested Ifs could make it a tad more efficient as well.

Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As
Integer

Private Declare Function GetFocus Lib "user32" () As Long


Private Const VK_LBUTTON = &H1
Private Const WM_KEYDOWN = &H100

Private Function isPushed(ByRef ctl As Control) As Boolean
On Error Resume Next
If GetFocus() = Me.hwnd Then
If Screen.ActiveControl.Name = ctl.Name Then
isPushed = CBool(GetKeyState(VK_LBUTTON) And WM_KEYDOWN)
End If
End If
End Function

>On Oct 03 2000, 05:21 pm, lyle...@yahoo.com (Lyle Fairfield)


--
Lyle
http://www.cyriv.com/

Vincent Veyron

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
On Tue, 03 Oct 2000 21:21:48 GMT, lyle...@yahoo.com (Lyle Fairfield)
wrote:

>Well, it's an interesting question ... really revolves around how do we know if
>a button is pressed; here's a start (my friend, Vincent will add the comments
>no doubt, but in what language?):


I'll pick Verlan, literally "verse-re", which is a slang used by
suburban kids; all you have to do is reverse the order of words'
syllabes

Chez oim, ça chemar 'ap

Next task: run a perl strict onto some french on-line dictionary for a
translation. Nothing you can't handle :)


>
>Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As
>Integer
>Private Const VK_LBUTTON = &H1
>Private Const WM_KEYDOWN = &H100
>

>Private Function isPushed(ByRef ctl As Control) As Boolean
> On Error Resume Next

> isPushed = (Screen.ActiveControl.Name = ctl.Name) And
>(GetKeyState(VK_LBUTTON) And WM_KEYDOWN)
>End Function
>
>Private Sub cmdTest_Click()
> If Not Me.NewRecord Then DoCmd.RunCommand acCmdRecordsGoToNext
>End Sub
>
>Private Sub Form_Open(Cancel As Integer)
> Me.TimerInterval = 500
>End Sub
>
>Private Sub Form_Timer()
> If isPushed(Me.cmdTest) Then cmdTest_Click
>End Sub
>
>
>
>ski...@primus.com.au (Craig Skipsey) wrote in
><39d9...@news.iprimus.com.au>:
>

>--
>Lyle
>http://www.cyriv.com/


Arvin Meyer

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Dimitri,

The Beep does not function sequentially for periods of short duration. Try:

For i = 1 To 5
Beep
Next

You'll only get the first Beep.
--
Arvin Meyer

"Dimitri Furman" <dfu...@cloud99.net> wrote in message
news:8FC3D5663df...@207.126.101.100...
> Well... A new form with one single Beep in OnTimer and TimerInterval=1000.
> Open form, starts beeping, hold the mouse down, stops beeping, release the
> mouse - beeping again, etc.
>
> (Are you sure your mouse is plugged in? <gdr>)
>
> Well, actually, what's the OS? 95 here.
>
> On Oct 04 2000, 08:54 pm, lyle...@yahoo.com (Lyle Fairfield) wrote in
> <8FC3D6CFBlyl...@24.9.0.17>:
>
> >It seems to, here in Canader.


> >
> >dfu...@cloud99.net (Dimitri Furman) wrote in

> ><8FC3DBA4Fdf...@207.126.101.100>:
> >
> >>Just did some quick testing... Seems that GetKeyState toggles
> >>its output value between 0 and 1 on each call if mouse is
> >>down... AND'ed with WM_KEYDOWN it's never True...
> >>
> >>Wait... a small discovery here... Timer never fires while the
> >>mouse is down... hm... ;)
> >>
> >>On Oct 04 2000, 10:05 am, lyle...@yahoo.com (Lyle Fairfield)
> >>wrote in
> >><8FC36E6F6lyl...@24.9.0.17>:


> >>
> >>>Perhaps this is safer ... might guard against multiple
> >>>instances of same form being open, in which case clicking
> >>>button would move record pointer of all? Nested Ifs could
> >>>make it a tad more efficient as well.
> >>>

> >>>Private Declare Function GetKeyState Lib "user32" (ByVal
> >>>nVirtKey As Long) As Integer

> >>>Private Declare Function GetFocus Lib "user32" () As Long

> >>>Private Const VK_LBUTTON = &H1
> >>>Private Const WM_KEYDOWN = &H100
> >>>

> >>>Private Function isPushed(ByRef ctl As Control) As Boolean
> >>> On Error Resume Next

> >>> If GetFocus() = Me.hwnd Then
> >>> If Screen.ActiveControl.Name = ctl.Name Then
> >>> isPushed = CBool(GetKeyState(VK_LBUTTON) And
> >>> WM_KEYDOWN)
> >>> End If
> >>> End If
> >>>End Function
> >>>
> >>>
> >>>dfu...@cloud99.net (Dimitri Furman) wrote in
> >>><8FC2D38C6df...@207.126.101.100>:
> >>>

Dimitri Furman

unread,
Oct 4, 2000, 8:47:13 PM10/4/00
to
Just did some quick testing... Seems that GetKeyState toggles its output
value between 0 and 1 on each call if mouse is down... AND'ed with
WM_KEYDOWN it's never True...

Wait... a small discovery here... Timer never fires while the mouse is
down... hm... ;)

On Oct 04 2000, 10:05 am, lyle...@yahoo.com (Lyle Fairfield) wrote in
<8FC36E6F6lyl...@24.9.0.17>:

>Perhaps this is safer ... might guard against multiple instances of same
>form being open, in which case clicking button would move record pointer
>of all? Nested Ifs could make it a tad more efficient as well.
>

>Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As
>Long) As Integer

>Private Declare Function GetFocus Lib "user32" () As Long

>Private Const VK_LBUTTON = &H1
>Private Const WM_KEYDOWN = &H100
>

>Private Function isPushed(ByRef ctl As Control) As Boolean
> On Error Resume Next
> If GetFocus() = Me.hwnd Then
> If Screen.ActiveControl.Name = ctl.Name Then
> isPushed = CBool(GetKeyState(VK_LBUTTON) And WM_KEYDOWN)
> End If
> End If
>End Function
>
>
>dfu...@cloud99.net (Dimitri Furman) wrote in
><8FC2D38C6df...@207.126.101.100>:
>

Lyle Fairfield

unread,
Oct 4, 2000, 8:54:18 PM10/4/00
to
It seems to, here in Canader.

dfu...@cloud99.net (Dimitri Furman) wrote in
<8FC3DBA4Fdf...@207.126.101.100>:

--
Lyle
http://www.cyriv.com/

Dimitri Furman

unread,
Oct 4, 2000, 9:29:39 PM10/4/00
to
Well... A new form with one single Beep in OnTimer and TimerInterval=1000.
Open form, starts beeping, hold the mouse down, stops beeping, release the
mouse - beeping again, etc.

(Are you sure your mouse is plugged in? <gdr>)

Well, actually, what's the OS? 95 here.

On Oct 04 2000, 08:54 pm, lyle...@yahoo.com (Lyle Fairfield) wrote in
<8FC3D6CFBlyl...@24.9.0.17>:


--

Lyle Fairfield

unread,
Oct 4, 2000, 9:47:16 PM10/4/00
to
Perhaps, it's beep that is disabled when mouse button is down?
Test DB is 25KB zipped. Let me know if you want it.

dfu...@cloud99.net (Dimitri Furman) wrote in

<8FC3D5663df...@207.126.101.100>:


--
Lyle
http://www.cyriv.com/

Dimitri Furman

unread,
Oct 5, 2000, 3:00:00 AM10/5/00
to
I replaced Beep with Debug.Print "beep" in the Timer code, and it wasn't
executing either with the mouse down. I would think it may be the OS or
Access version difference (I used A97). Or maybe serial mouse vs PS/2
mouse?

If the test db is in A97, I'd like to take a look (don't have 2000 here).
Thanks

On Oct 04 2000, 09:47 pm, lyle...@yahoo.com (Lyle Fairfield) wrote in
<8FC3D20C6lyl...@24.9.0.17>:

--

Dimitri Furman

unread,
Oct 5, 2000, 3:00:00 AM10/5/00
to
Yes, I know that, but in this case there was a one second interval between
beeps. I could hear them every second, but only with the mouse not
depressed.

On Oct 04 2000, 11:41 pm, a...@m.com (Arvin Meyer) wrote in
<8rgt7e$tjp$1...@slb7.atl.mindspring.net>:

>Dimitri,
>
>The Beep does not function sequentially for periods of short duration.
>Try:
>
>For i = 1 To 5
> Beep
>Next
>
>You'll only get the first Beep.
>--
>Arvin Meyer
>
>"Dimitri Furman" <dfu...@cloud99.net> wrote in message
>news:8FC3D5663df...@207.126.101.100...

Arvin Meyer

unread,
Oct 5, 2000, 3:00:00 AM10/5/00
to
I think you need to possibly throw in a DoEvents. I simply use the
AutoRepeat property which works nicely if a DoEvents is thrown in. The
drawback to autorepeat is that the timer isn't controllable. You are limited
to 1/2 second for the first repeat, and 1/4 second thereafter.
--
Arvin Meyer

"Dimitri Furman" <dfu...@cloud99.net> wrote in message

news:8FC447D41df...@207.126.101.100...


> I replaced Beep with Debug.Print "beep" in the Timer code, and it wasn't
> executing either with the mouse down. I would think it may be the OS or
> Access version difference (I used A97). Or maybe serial mouse vs PS/2
> mouse?
>
> If the test db is in A97, I'd like to take a look (don't have 2000 here).
> Thanks
>

> On Oct 04 2000, 09:47 pm, lyle...@yahoo.com (Lyle Fairfield) wrote in
> <8FC3D20C6lyl...@24.9.0.17>:

Vincent Quesnoit

unread,
Oct 5, 2000, 3:00:00 AM10/5/00
to
Same here with A97 on NT4 and A2K on W2K (ps/2 wheel mice), keeping either
button down stops the timer event.
I tried it with a small db with just one form, one control and
Me.<control>.Visible = Not Me.<control>.Visible as the timer event routine
Stops blinking when I hold any mouse button down
FWIW (not much more than 2 € cents)
Vincent


Dimitri Furman a écrit :

> I replaced Beep with Debug.Print "beep" in the Timer code, and it wasn't
> executing either with the mouse down. I would think it may be the OS or
> Access version difference (I used A97). Or maybe serial mouse vs PS/2
> mouse?
>
> If the test db is in A97, I'd like to take a look (don't have 2000 here).
> Thanks
>

> On Oct 04 2000, 09:47 pm, lyle...@yahoo.com (Lyle Fairfield) wrote in


Dimitri Furman

unread,
Oct 5, 2000, 3:00:00 AM10/5/00
to
On Oct 05 2000, 08:08 am, a...@m.com (Arvin Meyer) wrote in
<8rhqsi$neq$1...@slb6.atl.mindspring.net>:

>I think you need to possibly throw in a DoEvents.

Tried that, still blocking the Timer.

>I simply use the
>AutoRepeat property which works nicely if a DoEvents is thrown in.

But does that work when changing the current record? I couldn't make that
autorepeat even with Doevents.

Arvin Meyer

unread,
Oct 6, 2000, 3:00:00 AM10/6/00
to
No, you can't use AutoRepeat when changing a record, only on the same
record.
--
Arvin Meyer

"Dimitri Furman" <dfu...@cloud99.net> wrote in message

news:8FC48E7F5df...@129.250.35.5...

Dev Ashish

unread,
Oct 6, 2000, 9:14:04 PM10/6/00
to
[sorry, joining the thread late]

I haven't tried this in Access, but I can't see why it won't work... This
is from Scheduler.exe (VB app) available at
http://www.mvps.org/access/resources/downloads.htm ; just some code I added
on top of Terry's.

' ******** Snippet start *******
Private Sub cmdDown_MouseDown(Index As Integer, Button As Integer, Shift As
Integer, X As Single, Y As Single)
On Error GoTo ErrHandler
Dim lngInterval As Long
Dim i As Integer

With Me(fGetControlName(Index))
mblnMouseUp = False
If IsNull(.Text) Or Not IsDate(.Text) Then .Text = Format(Now, "Long
Time")
lngInterval = 200
Do While Not mblnMouseUp
Call sWait(lngInterval)
i = i + 1
.Text = Format(DateAdd("s", -1, .Text), "Long Time")
.Refresh
DoEvents
If i = 4 Then lngInterval = 0
Loop
End With

ExitHere:
Exit Sub
ErrHandler:
Resume ExitHere
End Sub

Private Sub sWait(lngInterval As Long)
Dim lngTicks As Long
lngTicks = GetTickCount + lngInterval
Do
DoEvents
Loop While GetTickCount < lngTicks
End Sub

Private Sub cmdDown_MouseUp(Index As Integer, Button As Integer, Shift As
Integer, X As Single, Y As Single)
mblnMouseUp = True
End Sub

Private Sub cmdUp_MouseDown(Index As Integer, Button As Integer, Shift As
Integer, X As Single, Y As Single)
On Error GoTo ErrHandler
Dim lngInterval As Long
Dim i As Integer

With Me(fGetControlName(Index))
mblnMouseUp = False
If IsNull(.Text) Or Not IsDate(.Text) Then .Text = Format(Now, "Long
Time")
lngInterval = 200
Do While Not mblnMouseUp
Call sWait(lngInterval)
i = i + 1
.Text = Format(DateAdd("s", 1, .Text), "Long Time")
.Refresh
DoEvents
If i = 4 Then lngInterval = 0
Loop
End With

ExitHere:
Exit Sub
ErrHandler:
Resume ExitHere
End Sub

Private Sub cmdUp_MouseUp(Index As Integer, Button As Integer, Shift As
Integer, X As Single, Y As Single)
mblnMouseUp = True
End Sub

Private Function fGetControlName(Index As Integer) As String
fGetControlName = LoadResString(Index + 100)
End Function
' ******** Snippet end *******

-- Dev


Dimitri Furman

unread,
Oct 6, 2000, 10:33:23 PM10/6/00
to
On Oct 06 2000, 09:14 pm, d...@nomail.please (Dev Ashish) wrote in
<wNuD5.20584$tl2.1...@bgtnsc07-news.ops.worldnet.att.net>:

>[sorry, joining the thread late]
>
>I haven't tried this in Access, but I can't see why it won't work...
>This is from Scheduler.exe (VB app) available at
>http://www.mvps.org/access/resources/downloads.htm ; just some code I
>added on top of Terry's.
>

<code snipped>

Well, that does work, but in a rather unusual way <g>: When one of the
buttons is clicked, the control's value starts to spin up or down as it
should, however, the button *stays* depressed, even if the mouse is
released and moved off it (looks cool :). IOW, it gets into an endless loop
in the mousedown event, and mouseup, which is supposed to stop it, just
doesn't have a chance to fire.

I guess in VB an event can fire while the code in another is still
executing, but it seems not to be the case in VBA...

0 new messages