Avoid double click on a button?

Tags: #<Tag:0x00007f224c01dc48>

I have a window and standard button on it, when I press a button I run some long LOOP on a file.

But sometimes users can double click on that button, even if I disable it after the first click.

So is there a way to avoid the double click on a button??

Can you not subclass the window and trap the doubleclick before running the long loop?

I have standard disable (via prop:disable) before I run my loop code

It sounds like the second click is getting queued in a buffer somewhere, thats why I say have you looked at subclassing the procedure?

Another way might be to disable the loop code upon return from the loop for a few seconds using the window timer so the second click in the queue cant trigger the button code again?

I would make a 2nd button that’s HIDE and does the real processing. You’ll see this type thing with Browse NewSelection and Window Resize with Event:DoReszie.

  OF ?ProcessBtn
     IF ~DoProcessing AND ?{PROP:Enabled} THEN      !prevent click twice
         IF KEYCODE()=MouseLeft2 THEN CYCLE.  !This is THE problem, fast clicking throws a 2nd Accepted with KeyCode Left2
         DoProcessing = TRUE
         DISABLE(?)
         POST(EVENT:Accepted,?Processing_Hidden_Btn)
         Yield()
     END          

  OF ?Processing_Hidden_Btn
     IF ~DoProcessing THEN CYCLE. !Should never happen 
     DO Longgggg_Process
     DoProcessing = FALSE
     ENABLE(?ProcessBtn)

Not sure above would fix, was not tested. See post 22 below for a simpler time check method that was solution:

Reminds me of debouncing in electronics.

IMO the most effective way to avoid run the long running process twice is the add a flag that says you’re currently running the process.

IF CanRun
   CanRun = false
   RunProcess()
   CanRun = true
ELSE
   MESSAGE('Already running')
END
1 Like

If the user managed to queue 2 button click events I think your code would run twice.

An idea would be to save the Clock() after the process finishes then not allow it to run for 2 seconds.

the time window for this to happen is tiny, but perhaps wrap all access to CanRun in a critical section to be safe.

or that would probably work too. But critical section would be safest. Also with critical section the flag could safely be global in case it was done in more than one thread.

The code is Not running in 2 threads so I cannot see a CS doing anything.

The OP says the user is getting 2 button click events posted quickly, i.e. in the message queue. I wonder if the 2nd one has a double click KeyCode Mouse Left 2

You’re right.
I guess I was thinking that the long running process was being START()ed

Have you tried PROP:Delay?

do you have an example?

Help topic for Delay has the samples.

yes you are quite right Carl - no point in a single thread.

Mike, LOL :slight_smile: :slight_smile: :slight_smile: :slight_smile: :slight_smile: :slight_smile:

Guys, there is just one thread, one procedure, one button and process in the same procedure…

and one computer user non technical?

thiswindow.Takekey, before parent.
IF KEYCODE() = MouseLeft2 …

1 Like

What did you expect? ?Button1{PROP:Delay} = 50 (IMM should be turned on).
Actually I don’t know will it help in your case, just a guess.