Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Click and Double-Click issue 3

Status
Not open for further replies.

Scott24x7

Programmer
Jul 12, 2001
2,826
JP
Hi all,
Haveing an odd issue with Click and Double-Click events.
No matter how quickly I double click, my click event fires first, and then the double click-event, though I'm only looking for the double click event to fire. Is there some way to fix this? A timer property for click at a global level of some type?


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Hi

What are you clicking on?

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are not good for you.
 
Griff,
I guess I should have mentioned that, but I didn't think it should be any different from an event standpoint.

I have 2 forms that have image data on them. I've set up some code to allow for certain manipulations. They are:
Single Click - Expand/Collapse the image (This allows making the image bigger for easy view, and then return it to regular size)
Right Click - Replace/Add an image. (If the image is blank, adds one from picked selection, if exists, replace it with selected)
Double-Click - Remove the image (i.e. delete it from the table that is displaying it, a kind of "Reset to Default" - with a prompt to make sure you didn't just bump right click).

So the problem is, if you double-click, it should just prompt you to "Do you want to remove this image? Yes/No" button. But instead, it first expands the image (as with Click) and then asks you Do you want to remove it... where I would want it to keep the state of view (whatever it is) rather than execute the click code first, and then the double-click code...


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
What you are describing is standard behaviour. The click always fires before the double click.

Why not simply ignore the click? Just do whatever you want to do in the double click, and leave the click alone.

If the click has some code (perhaps in a parent class) that you don't want to execute, override it at the instance level.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I fear you would be better off with a context menu, because click seems to take precedence on dbl click
and you can only trap dbl if single has no event programmed.

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are not good for you.
 
Scott, your second post crossed with mine. I can see now more clearly what you want to achieve.

I suggest you reconsider the user interface here. As Griff suggests, a context menu would be more appropriate here. Open the menu in the right-click, and let the user choose from the three possible actions. Not only would this solve the problem of the click occurring before the double click, but it will also be easier for the user.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Well, I guess that's a matter of interface "debate", and I kind of disagree with it... Useability vs. having to navigate too many menus or structures leads users to not update things, and I don't want that. It seems a little silly (just venting) that VFP created a Click event and a Double-Click event and then expect only one of them to be used on any object...

I don't like the idea of the context menu because it means users have to move mice, and "target" their next click, and that's time. While you may see that as "easier for the user" that is only true in the first 2 or 3 uses. We find from interface design that after they are used to that, then they want speed, and you can never give them that then when using this method. It's got a lot to do with why when you highlight a word in Word for example, the most used features show up in close proximity to the mouse, instead of forcing the user to navigate all the way back up to the Ribbon bar to get what they want. Repetitive tasks are even worse, and this is a case where it could be a very repetitive task (when picking floor plans or business card images for many records, each of which is unique...)

So it's an interface issue I'm not really willing to give up so easily on. I would say, it's not easier for the user, it's easier for the programmer, and that's not what I'm trying to achieve.

(end of vent)

So... that said, any other options or ideas?


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Well, there simply is no intelligence in VFP runtimes click event handling waiting with the click until it might be a double click.

I actually don't know any button/tool/icon using both click and double click for two actions. You have an idea with the timer, but how long do you want to wait if the user really meant a click and no double click. That would be a latency for the size up and down. There's nothing yet invented predicting the future, so if you want to know you have to wait and that's making the normal clicks work less good. That has nothing to do with VFP, I'd say. I'll give it a try in C# WPF or winforms later and let you know.

What would help is three distinct actions, you could make use of DRRAG&DROP in a way not allowing to drag the image, but to let a long click, which causes the Drag Start cause the deletion. As if there is just one drag target, the recycle bin. Perhaps you're already using the drag&drop for image repositioning?

All I can contribute is there is the _DBLCLICK variable, which will tell you how long you have to wait for a double click after the click and when you can react with the click event behaviour, if no second click occurs. For me that's .5 seconds, users can set this in Windows settings as they like and so the latency of the click event may be very high, unless you override the user setting, but then enforce users to faster double clicks. In any case the click will come first.

Another route is leaving click and dblclick empty and making use of MouseDown and MouseUp and roll your own click vs double click behavour or even triple click behaviour. You even can react to the modifier keys pressed while clicking.

Bye, Olaf.
 
Hi Olaf,
Yeah, I've used MouseDown and MouseUp in the past for other things, so it's not unfamiliar to me, but from experience, I know it's a lot messier.
You may be onto something with the _DBLCLICK variable... I did try using Windows "Mouse" settings from Control panel to change speed of double click, but it had 0 bearing on the VFP case, no matter where I set it.
Thanks for the ideas, I have some options to play with now... will see how it goes.
Cheers,


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Well, it CAN be done. But, it's not perfect.

First you need somewhere to store a number, I used a text box, when your for is initiated
you need to store SECONDS() in it.

Code:
thisform.text1.value = seconds()

Then in your objects click event you put something like this:
Code:
IF SECONDS() > thisform.text1.Value+1
	MESSAGEBOX("Click Event")
        && do your click event stuff here
ENDIF
&& store the current seconds() in the text field
thisform.text1.Value = SECONDS()
and in your doubleclick event do this...
Code:
MESSAGEBOX("dblclick")
thisform.text1.Value = SECONDS()
You can tweak the value to add to the textbox value (I tried .1 to 1.0 and 1.0 worked well enough





Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are not good for you.
 
Of course, you could do it the other way around as well.
if the click event, fire the double click...
Code:
IF SECONDS() < thisform.text1.Value+1
	MESSAGEBOX("DoubleClick Event")
        && do your doubleclick event stuff here
ELSE
	MESSAGEBOX("Click Event")
        && do your click event stuff here
ENDIF
&& store the current seconds() in the text field
thisform.text1.Value = SECONDS()

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are not good for you.
 
Very clever Griff...

If I end up using it, I will use this one (second example).

I'm leaning at the moment to something I didn't want to do (which is use Click and Right Click, and overload one of them, in this case Right Click), but this just might work for me too... Will give it a bash.

Everything else I tried was abysmal.
Is there any danger in creating a property on the image class I'm executing the Click from? Something like This.Clicktime = .5 where I establish Clicktime as a property of that class.
Then I don't need spurious text boxes to store hidden values in. :)


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
I can't make this work.
I think the problem is it has to count the clicks, and by the time the CLICK event fires, VFP isn't reading mouse click any longer. You almost need a "DO LOOP" to exist within the click event that looks for another click. But by then, won't that fire the Click event again?

It didn't quite work as mentioned, but I'm still playing with it. Right now, it automatically thinks I have Double Clicked every time.


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
So I tried this in the CLICK event:

Code:
lnClickCount = 1
This.ClickTime = SECONDS()
*
DO WHILE This.ClickTime+.5 > SECONDS()
	IF This.MOUSEDOWN()
		lnClickCount = lnClickCount + 1
	ENDIF
ENDDO
*
IF lnClickCount = 1
	MESSAGEBOX("Click Event")
ENDIF
*
IF lnClickCount = 2
        MESSAGEBOX("Double Click")
ENDIF
*
IF lnClickCount > 2
        MESSAGEBOX(lnClickCount)
ENDIF

The last part was for my amusement, because something clearly goes haywire in the This.Mousedown(), as the value it returns is something like 486,235 (a lot of cycles).
So I'm not sure what's going on there...

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
In Griffs idea the moment ot store the SECONDS value would be essential, it should be done in MouseDown, but only the first mousedown.
If you do this in form start most certainly many seconds have already passed from that initial value to even the first click.
So Griff, how should this really work?

Bye, Olaf.
 
What are you clicking on?

Was this ever answered?

What control class now has two different behaviors when clicked depending on how fast the user is?

I'll be the curmudgeon in the room. When you get on an elevator, do you expect different behaviors if you push a button twice instead of once? When pushing the brake pedal in your car, do you expect different behaviors if you push it twice rapidly vs. twice slowly?

If you need an alternate to click, then alt-click (also known as right-click) is the way to go. It's why we HAVE it in the first place. It doesn't necessarily have to launch a context menu although that IS what anyone who has ever used any Windows application expects.
 
Dan,
Clearly you've never been to Japan...
Elevator buttons in Japan allow you to do EXACTLY that. Here's the logic:
You get on a lift. You press 8. Oh no! I don't want to go to level 8, that's my office floor. I live on level 17.
You double press 8 again, and it turns off. The lift now doesn't go to 8. You press 17 again, and you go right to your floor.

Starting to see this more around Asia now, as Japanese elevator makers install lifts in other countries. We find it very common here.

The question was answered as well... it's an Image class (well, sub-class of Image).

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Scott, you can't do a while in a click, because the prevents furhter events to be processed while the click code runs, also you can't check whether an event happens with IF THIS.MOUSEDOWN, you're calling an event. You have stopped developing overall, not just VFP development, right?

Sorry, I'm stopping here, good luck.

Bye, Olaf.
 
No one can know the future, neither the man, nor the machine.
When you click the object, you must wait a _DBLCLICK seconds, to see if a second click comes.
This means that dblclick would be executed immediately, but click only after a short delay.

I tried a solution, based on a timer.
The timer interval is set to 2 * _DBLCLICK
The form has two additional properties.
1) one named _clicks, to pass to the timer the name of the most recent event, click or dblclick.
2) the second named _firstclick, has the default (the "idle") value -_DBLCLICK. The first click set this property to SECONDS()

The timer event check the _clicks property.
a) If _clicks = 'DBLCLICK', then a double click was performed and the proper code is executed
b) If _clicks = 'CLICK' and SECOND() - _firstclick > _DBLCLICK, then was a single click, and the proper code is executed

The original code from click and dblclick was moved in two new myClick and myDblClick methods, to allow the delayed execution.

Here is the code
Code:
PUBLIC ofrm
ofrm = CREATEOBJECT("myform")
ofrm.show()

DEFINE CLASS myform as Form
	_clicks = ''
	_firstclick = -_DBLCLICK
	ADD OBJECT tmr as timer WITH interval = 2 * _DBLCLICK, Enabled = .T.
	PROCEDURE click
		This._clicks = 'CLICK'
		This._firstclick = SECONDS()
	ENDPROC
	PROCEDURE dblclick
		This._clicks = 'DBLCLICK'
	ENDPROC
	PROCEDURE tmr.timer
		IF ThisForm._clicks == 'DBLCLICK'
			ThisForm._firstclick = -_DBLCLICK
			ThisForm._clicks = ''
			ThisForm.myDblClick
		ENDIF
		IF ThisForm._clicks == 'CLICK' AND SECONDS() - ThisForm._firstclick > _DBLCLICK
			ThisForm._firstclick = -_DBLCLICK
			ThisForm._clicks = ''
			ThisForm.myClick
		ENDIF
	ENDPROC
	PROCEDURE myClick && the code from the click event
		GETPICT()
	ENDPROC
	PROCEDURE myDblClick && the code from the dblclick event
		IF MESSAGEBOX('Are you sure',4 + 32 + 256,'Delete') = 6
			MESSAGEBOX('Deleted',64,'Success')
		ENDIF
	ENDPROC
ENDDEFINE

Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
Thanks vgulielmus. This looks very clever too.
Can't say I fully understand what you're doing here, but I'll see if I can make it work.
Cheers.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top