-
Notifications
You must be signed in to change notification settings - Fork 71
/
class_ControlMonitor.ahk
190 lines (168 loc) · 7.07 KB
/
class_ControlMonitor.ahk
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
; Link: https://www.autohotkey.com/boards/viewtopic.php?f=6&t=80069
; Author: RazorHalo
; Date: 18.08.2020
; for: AHK_L
; =======================================================================================================================
; Class: ControlMonitor
; Monitors controls for changes and triggers a Label or Function when modified.
; Uses WM_COMMAND notifications instead of gLabels
; Supported controls: EditBox, Radio, Checkbox, DropDownList, ComboBox, EditBox, ListBox, Push Button
; Static Controls (Text and Picture) that have SS_NOTIFY Style set
; Tested on: Win 10 (x64)
; Author: RazorHalo
; Change log: 1.0 (August 18, 2020) - Initial release.
;
; =======================================================================================================================
Class ControlMonitor {
; ===================================================================================================================
; Constructor / Destructor
; ===================================================================================================================
__New() {
; Bind the Check() method to WM_COMMAND notifications
this.fn := ObjBindMethod(this, "Check")
OnMessage(0x111, this.fn)
this.Ctrl := {}
this.State := 1
}
; ===================================================================================================================
; Destroy Frees the bound method and unregisters it from OnMessage
; ===================================================================================================================
Destroy() {
OnMessage(0x111, this.fn, 0)
this.fn := ""
}
; ===================================================================================================================
; On Turns on monitoring of controls
; ===================================================================================================================
On() {
this.State := 1
}
; ===================================================================================================================
; Off Turns off monitoring of controls
; ===================================================================================================================
Off() {
this.State := 0
}
; ===================================================================================================================
; Add Adds controls to the Monitor, saving its current value
; Parameters: hControl - passed as either a single control hWnd or an array of control hWnds
; Group (Optional) - Specify a string to identify a group of controls, these can then be reset
; together. Required when adding radio controls that are part of the same button group
; Return values: None
; ===================================================================================================================
Add(hControl, Group := "") {
If (IsObject(hControl)) {
For Each, hWnd in hControl {
this.Ctrl[hWnd] := {}
GuiControlGet, Value,, % hWnd
this.Ctrl[hWnd].Value := Value
If (Group) {
this.Ctrl[hWnd].Group := Group
}
}
} Else {
this.Ctrl[hControl] := {}
GuiControlGet, Value,, % hControl
this.Ctrl[hControl] := Value
If (Group) {
this.Ctrl[hControl].Group := Group
}
}
}
; ===================================================================================================================
; Remove Removes controls from the Monitor
; Parameters: hControl - passed as either a single control hWnd or an array of control hWnds
; Group (Optional) - Removes all controls from the specified group
; Return values: None
; ===================================================================================================================
Remove(hControl, Group := "") {
If (IsObject(hControl))
For Each, hWnd in hControl {
If (Group && this.Ctrl[hWnd].Group != Group)
Continue
Else
this.Ctrl.Delete(hWnd)
}
this.Ctrl.Delete(hControl)
}
; ===================================================================================================================
; Reset Resets the controls in the monitor, saving their current values to be the new 'unchanged' value
; Parameters: hControl - passed as either a single control hWnd or an array of control hWnds
; ** OMIT to reset all controls in the monitor
; Group (Optional) - Resets all controls in the specified group
; Return values: None
; ===================================================================================================================
Reset(hControl := "", Group := "") {
If !(hControl) {
For hWnd in this.Ctrl {
If (Group && this.Ctrl[hWnd].Group != Group)
Continue
GuiControlGet, Value,, % hWnd
this.Ctrl[hWnd].Value := Value
}
} Else If (IsObject(hControl)) {
For Each, hWnd in hControl {
GuiControlGet, Value,, % hWnd
this.Ctrl[hWnd].Value := Value
}
} Else {
GuiControlGet, Value,, % hControl
this.Ctrl[hControl].Value := Value
}
}
; ===================================================================================================================
; Target Sets the target label or function to execute when monitored control is modified
; Parameters: Target - Name of a label or function
; Return values: On success - False
; On failure - True
; Remarks: If the target is a function it will pass the controls hWnd as the first parameter
; ===================================================================================================================
Target(Target) {
If IsLabel(Target) {
this.Target := Target
Return False
} Else If IsFunc(Target) {
this.Target := Func(Target)
Return False
}
MsgBox, 16, Error, % Target " is not a valid label or function"
Return True
}
; ===================================================================================================================
; Check Checks if the value of a control has changed
; Parameters:
; Return values: On success - False
; On failure - True
; Remarks: Called by function bound to WM_COMMAND OnMessage
; ===================================================================================================================
Check(wParam, hCtrl, msg, hWnd) {
Modified := 0
NC := (wParam >> 16) ; Get notification code
If (this.State && this.Ctrl.HasKey(hCtrl)
&& (NC = 0x300 ;EN_CHANGE
|| NC = 0 ;STN_CLICKED
|| NC = 0x0 ;BN_CLICKED
|| NC = 1 ;CBN_SELCHANGE, LBN_SELCHANGE
|| NC = 5)) { ;CBN_EDITCHANGE
; Make sure click is finished if any functions are using WM_LBUTTONUP
While GetKeyState("LButton","P")
Sleep 50
; Compare the value
GuiControlGet, Value,, % hCtrl
If (this.Ctrl[hCtrl].Value != Value) {
Modified := 1
}
; Execute target if control is modified
If (Modified) {
If (this.Ctrl[hCtrl].Group)
this.Reset("", this.Ctrl[hCtrl].Group)
Else
this.Reset(hCtrl) ; Reset controls compare value to the new value
If IsLabel(this.target)
GoSub % this.Target
Else If IsFunc(this.Target)
this.Target.Call(hCtrl)
}
}
}
}