aboutsummaryrefslogtreecommitdiff
path: root/tt.doubleclick.ahk
blob: 58d83f4a43cc59495bda8ae7f950f516d38227f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
;; DoubleClick function
;; ============================================================================

;; DoubleClick returns true if a double click has been performed. The first
;; click in the double click is allowed to pass through, but the second click
;; is prevented.

;; To use the function, call it whenever the user clicks. The function returns
;; true if two calls in a row meet the requirements for a double click.

;; Function definition -> library
;; ----------------------------------------------------------------------------

;; The 'alternate' argument, if set to true, signifies a right click:

DoubleClick(alternate := false)
{
	
;; A bunch of global variables are needed to determine whether a double click
;; has been performed:
	
	global DoubleClickClicked
	global DoubleClickPriorX
	global DoubleClickPriorY
	global DoubleClickLast

;; The DoubleClickClicked variable should be set to false in the beginning of
;; the script: -> init

DoubleClickClicked := false

;; We'll continue the definition of the function. -> library

;; The maximum double click area (x * y) and time (in milliseconds) are
;; retrieved from Windows:

	SysGet, SM_CXDOUBLECLK, 36
	SysGet, SM_CYDOUBLECLK, 37
	max := DllCall("User32\GetDoubleClickTime")

;; The current absolute position of the mouse is retrieved:
	
	tmp := A_CoordModeMouse
	CoordMode, Mouse, Screen
	MouseGetPos, x, y
	CoordMode, Mouse, %tmp%

;; The DoubleClickClicked variable, if true, signifies that a first click has
;; already been performed. If false, a double click has not been initiated.

;; If a click has not already been performed, then this is the first click.
;; The first click should be allowed to pass through, but the function takes
;; note of the click and sets the global variables against which to compare
;; the next click:
	
	if (not DoubleClickClicked)
	{
		if (alternate)
			SendInput, {Click, right}
		else
			SendInput, {Click}
		DoubleClickPriorX := x
		DoubleClickPriorY := y
		DoubleClickLast := A_TickCount
		DoubleClickClicked := true
		return false
	}

;; At this point, the function has been called for the second time, signifying
;; a second click. Now, it checks whether the two clicks meet the operating
;; system's requirements for a double click; if not, then this click is treated
;; as yet another first click:
	
	if (A_TickCount - DoubleClickLast > max
			|| abs(x - DoubleClickPriorX) > SM_CXDOUBLECLK
			|| abs(y - DoubleClickPriorY) > SM_CYDOUBLECLK)
	{
		if (alternate)
			SendInput, {Click, right}
		else
			SendInput, {Click}
		DoubleClickPriorX := x
		DoubleClickPriorY := y
		DoubleClickLast := A_TickCount
		DoubleClickClicked := true
		return false
	}

;; At this point, a double click has successfully been performed. The variable
;; signifying a first click is reset to false, and the function returns true:
	
	DoubleClickClicked := false
	return true
}