aboutsummaryrefslogtreecommitdiff
path: root/tt.doubleclick.ahk
blob: 0b2454bcfb53539c4ae4b5585a6ec05d27a41318 (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
}