Mouse and Keyboard "Double Click"

Hey !... #Sorry_For_My_Bad_English :)
Any easy way to "detect" user double click?

I don't want and im not using any lib etc.
- Pure C++ and Windows

I create my own Engine using C++ ASM and Windows

My "Engine" supports atm:
QKeyboard ( Reference to Keyboard for example )

example:
QKeyboard.Key[ QKeyA ].Push;
( return true if Key "A" is pressed )

and ofc. QMouse

example:
QMouse.Button[ QLeftMouse ].Push
( return true if Left Mouse button is pushed )

to use i have:
- OnPush Event ( takes Void Function )
- OnRelease Event ( takes Void Function )
- PushTime Function ( return Time in seconds )
- ReleaseTime Function ( return Time in seconds )
- Push BOOL Value

more examples:
QMouse.Button[ QMiddleMouse ].OnPush = MyVoid;
Time = QMouse.ReleaseTime( QRightMouse );

QKeyboard.Key[ QKeyShift ].Push;
Time = QKeyboard.PushTime( QKeyShift );
QKeyboard.Key[ QESCKey ].OnRelease = MyReleaseFunction;

QTouch.x; // WIP !...
QTouch.y;

QKeyboard -> Keyboard Data
QMouse -> Mouse Data
QTouch -> Touchpad Data


NOW...
i have problem with "good" way to detect Double Click...

my actual idea is to register event after user push key
atm. ( at this moment ) i register event after 1 sec
to do ONE CLICK things but if ANOTHER function want
to register this SAME key AGAIN it "clear" register
and do DOUBLE CLICK stuff

but Time Events are atm.... well not very great in my Engine
and it take a lot CPU power to do...

i don't want to waste so much CPU power only for Double Clicks

also my Engine use only CPU
- idk how to use GPU
- my Engine isn't for games anyway
maybe ill make one or two games using it but i want it for AI and Robots

to render GUI CPU is enough :o
GUI ( Graphical User Interface )
CPU ( Central Processing Unit )
WIP ( Work in Progress )


Now... anyone with good idea to handle Double Clicks?...
And again, sorry for my Bad English :)...

//Edit:
reason because Time Events are so bad in my Engine is because
every 0.1 second Engine test every registred event if its time to cast it...

if for example we register 10 Events every 1 seconds we do 100 Tests

if anyone have better idea for this2, plz help :)...
Last edited on
There are two requirements for detecting a double click:

1. time span (whitin the second mouse down must appear)
2. area (whitin the second mouse down must appear)

You may have struct for this. That struct may also contain the std::function to call when successfull.

So when you have a mouse down you check whether the double click object exists and the requirements are fulfilled. If so call the double click function.

If the requirement are not fullfilled set the actual values for time and area.


I don't understand, if you're already using Windows, why not just use what Windows already provides? Windows can already receive double-click messages through the WM_LBUTTONDBLCLK
in WindowProc callback.
https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-lbuttondblclk

I suppose the purpose would be if you wanted to support having a configurable double-click time that was independent from the already configurable OS option.
Coder777
Ye thats my actual idea... probably... cause my english is bad xD
anyway ty for help :P


Ganado
Yes, im already using Windows...
But im not using it for stuff like this...

1) even if i start using WinApi CallBack there is no double click message
for keyboard, or im blind / stupid

https://docs.microsoft.com/en-us/windows/win32/inputdev/keyboard-input-notifications

i even check for Double Keyboard Click in WinApi
2) I don't want to use Windows Setups ( like time between clicks etc. )



Ok, so let's say i start to use WinApi and its Callback-s
How about Double Keyboard Clicks?/Push?

Edit:
atm. im using <Windows.h> only for threads
CreateThread( NULL, NULL, &QTimeThreadVoid, NULL, NULL, NULL );

but even this is very simple :o
im just using Windows.h to create and terminate thread any time i want xD
Last edited on
You're right, I didn't read your post carefully enough, there is no "double keyboard click", keeping track of the time difference would have to be done yourself.
@TobiPL,

I'll make the assumption that you're using a recent C++ compiler, and that it supports C++17.

The standard library offers good, reasonably high precision timer support. This does depend on the hardware. Many PC's have high precision timers, but some require them to be enabled.

The typical, default configuration for slightly holder hardware is a timer limited to a precision of about 15 ms, which is to say code would sense two events closer in time than 15 ms to be simultaneous, and can't usually report a difference between two events within a 15 ms time boundary. However, that represents a "rate" of about 66 events per second, which is quite fast relative to a user double click time limit.

To implement double event interface on anything (keyboard, mouse, touch, sound, or whatever), one must track the state change on every possible "item". For the keyboard this implies a container representing each key. For keyboard plus mouse, it would be all keys plus the mouse buttons.

As @coder777 noted this also implies, for the mouse, that the second event happens at a location (of the mouse) "near" the previous one, which implies tracking the mouse location at the time of a button press.

Consider my point, that every item must be tracked, in the context of the mouse alone for a moment.

If the buttons were not tracked individually, it would be possible to "accidentally" consider two mouse button events of two different buttons as a double click, which clearly wouldn't be correct.

For some devices, especially of the keyboard, this issue is spread over the entire keyboard.

Further, for some user interface purposes, it is necessary to sense a double event while yet a different key is being held during the entire double click. An obvious potential is that the shift key is held first, then a double click is issued, but for game or other inventive user interface requirements, it could be that an arrow key is held during the double click of the space, or the space is held during the double click of a letter or number.

This suggests a container is required, initialized at startup and used "globally" throughout the application's use of these interface devices, such that an entry is available for each key, each mouse button (and the mouse location at the moment of the event). Rapid lookup is desired, so it is desirable to fashion this as a fixed array such that virtual key codes (supplied by Windows) for keyboard buttons and mouse buttons can be used as unique entries into this array. A map or sorted array by key would require more time for lookup, but would likely be "fast enough" in some cases, but nothing would perform quite as fast as an indexed lookup in an array.

Every attempt to read the keyboard or mouse would thus pass through a function (or collection of functions, perhaps in a class), which records the timestamp of each event. Before it does so, it compares the previous time for that item (be it keyboard or mouse button), and if that is in the past inside the double click time margin (configured as an application level value), it becomes a candidate for a double click on that item (whatever key or mouse button).

Where the type of this entry is a mouse button, a further check should be made, as @coder777 pointed out, that the mouse has not moved beyond a certain margin, also configured as an application value.

This makes the calculation of duration between events rather quick. It requires that every keystroke and mouse button press is timed through timestamp. Perhaps it doesn't require mentioning, but these timed events are focused on the "down" messages, not the "up" messages.



pretty sure windows has a double click detector & you can add a on_double_click() method to a gui program. DIY means watching it over a period of time, as stated, but it should be done for you. Pretty sure any other OS has this too, its just too ingrained to not be part of any gui library...
The Win32 API has mouse button double-click detection as a basic part of the API.

Doing double-click detection for the keyboard will require observing every keystroke, with tracking the time between keystrokes if the same key is pressed.

Off the top of my head a program can either do that via the app's message queue or asynchronous raw key detection.

Either method has advantages and disadvantages you, the programmer, have to consider which one you will use.
my mistake, missed keyboard part of this.

you need to make a couple of design decisions...
does a key held-down count as 2 clicks, or do they have to let go and hit again.

also do you need to catch it if they were holding it down, let go and hit again rapidly?

I recommend something like
on key up (it was pressed, and now it isnt, for a specific key, not ANY key, of course)
check to see if this was the end of a double tap cycle against your timers.
if so, handle it. (double click detected)
if not, start the timer.
if timer is expired or detected double, stop/clear timer.

the above defines it for down/up down/up as a double click.
adjust as needed if you want to define it differently.
Last edited on
Topic archived. No new replies allowed.