-
Notifications
You must be signed in to change notification settings - Fork 72
/
class_WMCommand_and_Notify.ahk
284 lines (269 loc) · 13.9 KB
/
class_WMCommand_and_Notify.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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
; ======================================================================================================================
; ======================================================================================================================
; One script! Two classes! ### CLASS_ON_WMCOMMAND_AND_NOTIFY ### by justme - https://autohotkey.com/board/topic/70445-class-on-wm-command-on-wm-notify-ahk-l
; ======================================================================================================================
; On_WM_COMMAND - Helper object to handle notification messages sent through WM_COMMAND AHK version: 1.1.05.06 (U32)
; On_WM_NOTIFY - Helper object to handle notification messages sent through WM_NOTIFY AHK version: 1.1.05.06 (U32)
; ======================================================================================================================
; ======================================================================================================================
Class On_WM_COMMAND {
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PRIVATE Properties and Methods ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Static Attached := 0
Static Controls := {}
Static MessageHandler := "On_WM_COMMAND_Handler"
Static WM_COMMAND := 0x0111
; ===================================================================================================================
; META FUNCTIONS
; ===================================================================================================================
__New() {
Return False ; there is no reason to instantiate this class
}
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PUBLIC INTERFACE ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ===================================================================================================================
; METHOD Attach Register control for WM_COMMAND messages
; Parameters: Hwnd - HWND of the GUI control (Integer)
; Message - message number (Integer)
; Function - name of the function to be called (String)
; Return values: On success - True
; On failure - False
; ===================================================================================================================
Attach(Hwnd, Message, Function) {
If Message Is Not Integer
Return False
If !IsFunc(Function)
Or (Func(Function).MaxParams <> 4)
Or !DllCall("User32.dll\IsWindow", "UPtr", Hwnd)
Return False
If This.Controls.HasKey(Hwnd) {
This.Controls[Hwnd][Message] := Func(Function)
Return True
}
If (This.Attached = 0)
OnMessage(This.WM_COMMAND, This.MessageHandler)
This.Attached += 1
This.Controls[Hwnd, Message] := Func(Function)
Return True
}
; ===================================================================================================================
; METHOD Detach Unregister control for WM_COMMAND messages
; Parameters: Hwnd - HWND of the GUI control (Integer)
; Message - message number (Integer)
; Return values: On success - True
; On failure - False
; ===================================================================================================================
Detach(Hwnd, Message) {
If This.Controls[Hwnd].HasKey(Message) {
This.Controls[Hwnd].Remove(Message, "")
If !This.Controls[Hwnd].MaxIndex() {
This.Controls.Remove(Hwnd, "")
This.Attached -= 1
If (This.Attached = 0) {
OnMessage(This.WM_COMMAND, "")
}
}
Return True
}
Return False
}
}
; PRIVATE FUNCTIONS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
On_WM_COMMAND_Handler(W, L) { ; wParam, lParam
Global On_WM_COMMAND
Critical 1000
If IsObject(F := On_WM_COMMAND.Controls[L][M := (W >> 16)])
Return F.(L, M, W, L)
}
Class On_WM_NOTIFY {
; ========DESCRIPTION=====================================================================================================
; AHK 1.1 +
; ======================================================================================================================
; Namespace: On_WM_NOTIFY
; Function: Helper object to handle notification messages sent through WM_NOTIFY
; AHK version: 1.1.05.06 (U32)
; Language: English
; Tested on: WinXPSP3, WinVistaSP2 (32 bit)
; Version: 1.0.00.00/2012-02-10/just me
; Remarks: To register a function to be called on notification call On_WM_NOTIFY.Attach()
; passing three parameters:
; Hwnd - HWND of the GUI control (Integer)
; Message - Notification message number (Integer)
; Function - Name of the function which handles the message (String)
;
; To unregister notification handling call On_WM_NOTIFY.Detach()
; passing two parameters:
; Hwnd - see above
; Message - see above
;
; To get a control's HWND use either the option "HwndOutputVar" with "Gui, Add" or the command
; "GuiControlGet" with sub-command "Hwnd".
;
; The function to be called on notification has to accept exactly four parameters:
; Hwnd - Hwnd of the GUI control sending the notification message
; Message - Notification message number
; wParam - wParam passed to On_WM_NOTIFY_Handler
; lParam - lParam passed to On_WM_NOTIFY_Handler
;
; For notifications through WM_NOTIFY the contents of wParam and lParam is described at
; http://msdn.microsoft.com/en-us/library/bb775583%28VS.85%29.aspx
; (the content of the structure lParam points to is message specific in this case).
; Look at the documentation for OnMessage(), too.
;
; To get the sort of notification please look at
; http://msdn.microsoft.com/en-us/library/bb773173%28VS.85%29.aspx
; in particular at "Control Library".
;
; The class registers On_WM_COMMAND_Handler as message handler for WM_COMMAND notfications
; per OnMessage() as long as controls are attached. You cannot use own handlers for this message
; at the same time.
; ======================================================================================================================
; This software is provided 'as-is', without any express or implied warranty.
; In no event will the authors be held liable for any damages arising from the use of this software.
; ========DESCRIPTION=END=================================================================================================
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PRIVATE PROPERTIES ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Static Attached := 0
Static Controls := {}
Static MessageHandler := "On_WM_NOTIFY_Handler"
Static WM_NOTIFY = 0x4E
; ===================================================================================================================
; META FUNCTIONS
; ===================================================================================================================
__New() {
Return False ; there is no reason to instantiate this class
}
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PUBLIC INTERFACE ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ===================================================================================================================
; METHOD Attach Register control for WM_NOTIFY messages
; Parameters: Hwnd - HWND of the GUI control (Integer)
; Message - message number (Integer)
; Function - name of the function to be called (String)
; Return values: On success - True
; On failure - False
; ===================================================================================================================
Attach(Hwnd, Message, Function) {
If Message Is Not Integer
Return False
If !IsFunc(Function)
Or (Func(Function).MaxParams <> 4)
Or !DllCall("User32.dll\IsWindow", "UPtr", Hwnd)
Return False
If This.Controls.HasKey(Hwnd) {
This.Controls[Hwnd][Message] := Func(Function)
Return True
}
If (This.Attached = 0)
OnMessage(This.WM_NOTIFY, This.MessageHandler)
This.Attached += 1
This.Controls[Hwnd, Message] := Func(Function)
Return True
}
; ===================================================================================================================
; METHOD Detach Unregister control for WM_NOTIFY messages
; Parameters: Hwnd - HWND of the GUI control (Integer)
; Message - message number (Integer)
; Return values: On success - True
; On failure - False
; ===================================================================================================================
Detach(Hwnd, Message) {
If This.Controls[Hwnd].HasKey(Message) {
This.Controls[Hwnd].Remove(Message, "")
If !This.Controls[Hwnd].MaxIndex() {
This.Controls.Remove(Hwnd, "")
This.Attached -= 1
If (This.Attached = 0) {
OnMessage(This.WM_NOTIFY, "")
}
}
Return True
}
Return False
}
}
; PRIVATE FUNCTIONS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
On_WM_NOTIFY_Handler(W, L) { ; wParam, lParam
Global On_WM_NOTIFY
Critical 1000
If IsObject(F := On_WM_NOTIFY.Controls[H := NumGet(L + 0)][M := NumGet(L + 0, A_PtrSize * 2, "Int")])
Return F.(H, M, W, L)
}
/* EXAMPLES class_On_WMCommand_and_Notify.ahk
#NoEnv
#Include Class_On_WM_COMMAND.ahk
#Include Class_On_WM_NOTIFY.ahk
SetBatchLines, -1
EN_SETFOCUS := 0x0100
EN_KILLFOCUS := 0x0200
EN_UPDATE := 0x0400
NM_SETFOCUS := -7
NM_KILLFOCUS := -8
WM_NOTIFY := 0x004E
WM_COMMAND := 0x0111
Gui, Margin, 20, 20
Gui, Add, Text, xm w300, Edit:
Gui, Add, Edit, xm y+2 wp r5 vVEDIT hwndHEDIT
Gui, Add, Text, xm wp, LV:
Gui, Add, ListView, xm y+2 r5 wp Grid vLVV hwndHLV, Column1
LV_Add("", "Row 1")
LV_ModifyCol(1, "AutoHdr")
Gui, Add, Text, xm wp, Focus:
Gui, Add, Edit, xm y+2 wp vVEDIT1,
Gui, Add, Text, xm wp, EN_UPDATE notifications:
Gui, Add, Edit, xm y+2 wp vVEDIT2
Gui, Add, Button, xm wp vVBUTTON gGBUTTON, Unregister EN_UPDATE
Gui, Show, , Notifications
On_WM_COMMAND.Attach(HEDIT, EN_KILLFOCUS, "On_EN_KILLFOCUS")
On_WM_COMMAND.Attach(HEDIT, EN_SETFOCUS, "On_EN_SETFOCUS")
On_WM_COMMAND.Attach(HEDIT, EN_UPDATE, "On_EN_UPDATE")
On_WM_NOTIFY.Attach(HLV, NM_KILLFOCUS, "On_LV_KILLFOCUS" )
On_WM_NOTIFY.Attach(HLV, NM_SETFOCUS, "On_LV_SETFOCUS" )
GuiControl, Focus, VBUTTON
GuiControl, Focus, VEDIT
Return
GuiClose:
GuiEscape:
ExitApp
GBUTTON:
GuiControlGet, Cap, , VBUTTON, Text
If (Cap = "Unregister EN_UPDATE") {
On_WM_COMMAND.Detach(HEDIT, EN_UPDATE)
GuiControl, , VBUTTON, Register EN_UPDATE
} ELse {
On_WM_COMMAND.Attach(HEDIT, EN_UPDATE, "On_EN_UPDATE")
GuiControl, , VBUTTON, Unregister EN_UPDATE
}
Return
; ======================================================================================================================
On_EN_KILLFOCUS(Hwnd, Message, wParam, lParam) {
Gui, Font, cC00000
GuiControl, Font, VEDIT1
GuiControl, , VEDIT1, Edit lost focus!
}
On_EN_SETFOCUS(Hwnd, Message, wParam, lParam) {
Gui, Font, c008000
GuiControl, Font, VEDIT1
GuiControl, , VEDIT1, Edit got focus!
}
On_EN_UPDATE(Hwnd, Message, wParam, lParam) {
Static I := 0
I++
GuiControl, , VEDIT2, %A_ThisFunc% was called %I% times.
}
On_LV_KILLFOCUS(Hwnd, Message, wParam, lParam) {
Gui, Font, cC00000
GuiControl, Font, VEDIT1
GuiControl, , VEDIT1, LV lost focus!
}
On_LV_SETFOCUS(Hwnd, Message, wParam, lParam) {
Gui, Font, c008000
GuiControl, Font, VEDIT1
GuiControl, , VEDIT1, LV got focus!
}
; ======================================================================================================================
*/