-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathHookManager.py
672 lines (583 loc) · 22.8 KB
/
HookManager.py
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
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
import cpyHook
def GetKeyState(key_id):
return cpyHook.cGetKeyState(key_id)
class HookConstants:
'''
Stores internal windows hook constants including hook types, mappings from virtual
keycode name to value and value to name, and event type value to name.
'''
WH_MIN = -1
WH_MSGFILTER = -1
WH_JOURNALRECORD = 0
WH_JOURNALPLAYBACK = 1
WH_KEYBOARD = 2
WH_GETMESSAGE = 3
WH_CALLWNDPROC = 4
WH_CBT = 5
WH_SYSMSGFILTER = 6
WH_MOUSE = 7
WH_HARDWARE = 8
WH_DEBUG = 9
WH_SHELL = 10
WH_FOREGROUNDIDLE = 11
WH_CALLWNDPROCRET = 12
WH_KEYBOARD_LL = 13
WH_MOUSE_LL = 14
WH_MAX = 15
WM_MOUSEFIRST = 0x0200
WM_MOUSEMOVE = 0x0200
WM_LBUTTONDOWN = 0x0201
WM_LBUTTONUP = 0x0202
WM_LBUTTONDBLCLK = 0x0203
WM_RBUTTONDOWN =0x0204
WM_RBUTTONUP = 0x0205
WM_RBUTTONDBLCLK = 0x0206
WM_MBUTTONDOWN = 0x0207
WM_MBUTTONUP = 0x0208
WM_MBUTTONDBLCLK = 0x0209
WM_MOUSEWHEEL = 0x020A
WM_MOUSELAST = 0x020A
WM_KEYFIRST = 0x0100
WM_KEYDOWN = 0x0100
WM_KEYUP = 0x0101
WM_CHAR = 0x0102
WM_DEADCHAR = 0x0103
WM_SYSKEYDOWN = 0x0104
WM_SYSKEYUP = 0x0105
WM_SYSCHAR = 0x0106
WM_SYSDEADCHAR = 0x0107
WM_KEYLAST = 0x0108
#VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 -' : 0x39)
#VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 -' : 0x5A)
#virtual keycode constant names to virtual keycodes numerical id
vk_to_id = {'VK_LBUTTON' : 0x01, 'VK_RBUTTON' : 0x02, 'VK_CANCEL' : 0x03, 'VK_MBUTTON' : 0x04,
'VK_BACK' : 0x08, 'VK_TAB' : 0x09, 'VK_CLEAR' : 0x0C, 'VK_RETURN' : 0x0D, 'VK_SHIFT' : 0x10,
'VK_CONTROL' : 0x11, 'VK_MENU' : 0x12, 'VK_PAUSE' : 0x13, 'VK_CAPITAL' : 0x14, 'VK_KANA' : 0x15,
'VK_HANGEUL' : 0x15, 'VK_HANGUL' : 0x15, 'VK_JUNJA' : 0x17, 'VK_FINAL' : 0x18, 'VK_HANJA' : 0x19,
'VK_KANJI' : 0x19, 'VK_ESCAPE' : 0x1B, 'VK_CONVERT' : 0x1C, 'VK_NONCONVERT' : 0x1D, 'VK_ACCEPT' : 0x1E,
'VK_MODECHANGE' : 0x1F, 'VK_SPACE' : 0x20, 'VK_PRIOR' : 0x21, 'VK_NEXT' : 0x22, 'VK_END' : 0x23,
'VK_HOME' : 0x24, 'VK_LEFT' : 0x25, 'VK_UP' : 0x26, 'VK_RIGHT' : 0x27, 'VK_DOWN' : 0x28,
'VK_SELECT' : 0x29, 'VK_PRINT' : 0x2A, 'VK_EXECUTE' : 0x2B, 'VK_SNAPSHOT' : 0x2C, 'VK_INSERT' : 0x2D,
'VK_DELETE' : 0x2E, 'VK_HELP' : 0x2F, 'VK_LWIN' : 0x5B, 'VK_RWIN' : 0x5C, 'VK_APPS' : 0x5D,
'VK_NUMPAD0' : 0x60, 'VK_NUMPAD1' : 0x61, 'VK_NUMPAD2' : 0x62, 'VK_NUMPAD3' : 0x63, 'VK_NUMPAD4' : 0x64,
'VK_NUMPAD5' : 0x65, 'VK_NUMPAD6' : 0x66, 'VK_NUMPAD7' : 0x67, 'VK_NUMPAD8' : 0x68, 'VK_NUMPAD9' : 0x69,
'VK_MULTIPLY' : 0x6A, 'VK_ADD' : 0x6B, 'VK_SEPARATOR' : 0x6C, 'VK_SUBTRACT' : 0x6D, 'VK_DECIMAL' : 0x6E,
'VK_DIVIDE' : 0x6F ,'VK_F1' : 0x70, 'VK_F2' : 0x71, 'VK_F3' : 0x72, 'VK_F4' : 0x73, 'VK_F5' : 0x74,
'VK_F6' : 0x75, 'VK_F7' : 0x76, 'VK_F8' : 0x77, 'VK_F9' : 0x78, 'VK_F10' : 0x79, 'VK_F11' : 0x7A,
'VK_F12' : 0x7B, 'VK_F13' : 0x7C, 'VK_F14' : 0x7D, 'VK_F15' : 0x7E, 'VK_F16' : 0x7F, 'VK_F17' : 0x80,
'VK_F18' : 0x81, 'VK_F19' : 0x82, 'VK_F20' : 0x83, 'VK_F21' : 0x84, 'VK_F22' : 0x85, 'VK_F23' : 0x86,
'VK_F24' : 0x87, 'VK_NUMLOCK' : 0x90, 'VK_SCROLL' : 0x91, 'VK_LSHIFT' : 0xA0, 'VK_RSHIFT' : 0xA1,
'VK_LCONTROL' : 0xA2, 'VK_RCONTROL' : 0xA3, 'VK_LMENU' : 0xA4, 'VK_RMENU' : 0xA5, 'VK_PROCESSKEY' : 0xE5,
'VK_ATTN' : 0xF6, 'VK_CRSEL' : 0xF7, 'VK_EXSEL' : 0xF8, 'VK_EREOF' : 0xF9, 'VK_PLAY' : 0xFA,
'VK_ZOOM' : 0xFB, 'VK_NONAME' : 0xFC, 'VK_PA1' : 0xFD, 'VK_OEM_CLEAR' : 0xFE, 'VK_BROWSER_BACK' : 0xA6,
'VK_BROWSER_FORWARD' : 0xA7, 'VK_BROWSER_REFRESH' : 0xA8, 'VK_BROWSER_STOP' : 0xA9, 'VK_BROWSER_SEARCH' : 0xAA,
'VK_BROWSER_FAVORITES' : 0xAB, 'VK_BROWSER_HOME' : 0xAC, 'VK_VOLUME_MUTE' : 0xAD, 'VK_VOLUME_DOWN' : 0xAE,
'VK_VOLUME_UP' : 0xAF, 'VK_MEDIA_NEXT_TRACK' : 0xB0, 'VK_MEDIA_PREV_TRACK' : 0xB1, 'VK_MEDIA_STOP' : 0xB2,
'VK_MEDIA_PLAY_PAUSE' : 0xB3, 'VK_LAUNCH_MAIL' : 0xB4, 'VK_LAUNCH_MEDIA_SELECT' : 0xB5, 'VK_LAUNCH_APP1' : 0xB6,
'VK_LAUNCH_APP2' : 0xB7, 'VK_OEM_1' : 0xBA, 'VK_OEM_PLUS' : 0xBB, 'VK_OEM_COMMA' : 0xBC, 'VK_OEM_MINUS' : 0xBD,
'VK_OEM_PERIOD' : 0xBE, 'VK_OEM_2' : 0xBF, 'VK_OEM_3' : 0xC0, 'VK_OEM_4' : 0xDB, 'VK_OEM_5' : 0xDC,
'VK_OEM_6' : 0xDD, 'VK_OEM_7' : 0xDE, 'VK_OEM_8' : 0xDF, 'VK_OEM_102' : 0xE2, 'VK_PROCESSKEY' : 0xE5,
'VK_PACKET' : 0xE7}
#inverse mapping of keycodes
id_to_vk = dict([(v,k) for k,v in vk_to_id.items()])
#message constants to message names
msg_to_name = {WM_MOUSEMOVE : 'mouse move', WM_LBUTTONDOWN : 'mouse left down',
WM_LBUTTONUP : 'mouse left up', WM_LBUTTONDBLCLK : 'mouse left double',
WM_RBUTTONDOWN : 'mouse right down', WM_RBUTTONUP : 'mouse right up',
WM_RBUTTONDBLCLK : 'mouse right double', WM_MBUTTONDOWN : 'mouse middle down',
WM_MBUTTONUP : 'mouse middle up', WM_MBUTTONDBLCLK : 'mouse middle double',
WM_MOUSEWHEEL : 'mouse wheel', WM_KEYDOWN : 'key down',
WM_KEYUP : 'key up', WM_CHAR : 'key char', WM_DEADCHAR : 'key dead char',
WM_SYSKEYDOWN : 'key sys down', WM_SYSKEYUP : 'key sys up',
WM_SYSCHAR : 'key sys char', WM_SYSDEADCHAR : 'key sys dead char'}
def MsgToName(cls, msg):
'''
Class method. Converts a message value to message name.
@param msg: Keyboard or mouse event message
@type msg: integer
@return: Name of the event
@rtype: string
'''
return HookConstants.msg_to_name.get(msg)
def VKeyToID(cls, vkey):
'''
Class method. Converts a virtual keycode name to its value.
@param vkey: Virtual keycode name
@type vkey: string
@return: Virtual keycode value
@rtype: integer
'''
return HookConstants.vk_to_id.get(vkey)
def IDToName(cls, code):
'''
Class method. Gets the keycode name for the given value.
@param code: Virtual keycode value
@type code: integer
@return: Virtual keycode name
@rtype: string
'''
if (code >= 0x30 and code <= 0x39) or (code >= 0x41 and code <= 0x5A):
text = chr(code)
else:
text = HookConstants.id_to_vk.get(code)
if text is not None:
text = text[3:].title()
return text
MsgToName=classmethod(MsgToName)
IDToName=classmethod(IDToName)
VKeyToID=classmethod(VKeyToID)
class HookEvent(object):
'''
Holds information about a general hook event.
@ivar Message: Keyboard or mouse event message
@type Message: integer
@ivar Time: Specifies the elapsed time, in milliseconds, from the time the system was started to the time the event was created (that is, placed in the thread's message queue). See the MSDN documentation for the GetMessageTime function for more detail.
@type Time: integer
@ivar Window: Window handle of the foreground window at the time of the event
@type Window: integer
@ivar WindowName: Name of the foreground window at the time of the event
@type WindowName: string
'''
def __init__(self, msg, time, hwnd, window_name):
'''Initializes an event instance.'''
self.Message = msg
self.Time = time
self.Window = hwnd
self.WindowName = window_name
def GetMessageName(self):
'''
@return: Name of the event
@rtype: string
'''
return HookConstants.MsgToName(self.Message)
MessageName = property(fget=GetMessageName)
class MouseEvent(HookEvent):
'''
Holds information about a mouse event.
@ivar Position: Location of the mouse event on the screen
@type Position: 2-tuple of integer
@ivar Wheel: Positive if the wheel scrolls up, negative if down, zero otherwise
@type Wheel: integer
@ivar Injected: Was this event generated programmatically?
@type Injected: boolean
'''
def __init__(self, msg, x, y, data, flags, time, hwnd, window_name):
'''Initializes an instance of the class.'''
HookEvent.__init__(self, msg, time, hwnd, window_name)
self.Position = (x,y)
if data > 0: w = 1
elif data < 0: w = -1
else: w = 0
self.Wheel = w
self.Injected = flags & 0x01
class KeyboardEvent(HookEvent):
'''
Holds information about a keyboard event.
@ivar KeyID: Virtual key code
@type KeyID: integer
@ivar ScanCode: Scan code
@type ScanCode: integer
@ivar Ascii: ASCII character code, if one exists
@type Ascii: integer
'''
def __init__(self, msg, vk_code, scan_code, ascii, flags, time, hwnd, window_name):
'''Initializes an instance of the class.'''
HookEvent.__init__(self, msg, time, hwnd, window_name)
self.KeyID = vk_code
self.ScanCode = scan_code
self.Ascii = ascii
self.flags = flags
def GetKey(self):
'''
@return: Name of the virtual keycode
@rtype: string
'''
return HookConstants.IDToName(self.KeyID)
def IsExtended(self):
'''
@return: Is this an extended key?
@rtype: boolean
'''
return self.flags & 0x01
def IsInjected(self):
'''
@return: Was this event generated programmatically?
@rtype: boolean
'''
return self.flags & 0x10
def IsAlt(self):
'''
@return: Was the alt key depressed?
@rtype: boolean
'''
return self.flags & 0x20
def IsTransition(self):
'''
@return: Is this a transition from up to down or vice versa?
@rtype: boolean
'''
return self.flags & 0x80
Key = property(fget=GetKey)
Extended = property(fget=IsExtended)
Injected = property(fget=IsInjected)
Alt = property(fget=IsAlt)
Transition = property(fget=IsTransition)
class HookManager(object):
'''
Registers and manages callbacks for low level mouse and keyboard events.
@ivar mouse_funcs: Callbacks for mouse events
@type mouse_funcs: dictionary
@ivar keyboard_funcs: Callbacks for keyboard events
@type keyboard_funcs: dictionary
@ivar mouse_hook: Is a mouse hook set?
@type mouse_hook: boolean
@ivar keyboard_hook: Is a keyboard hook set?
@type keyboard_hook: boolean
'''
def __init__(self):
'''Initializes an instance by setting up an empty set of handlers.'''
self.mouse_funcs = {}
self.keyboard_funcs = {}
self.mouse_hook = False
self.keyboard_hook = False
def __del__(self):
'''Unhook all registered hooks.'''
self.UnhookMouse()
self.UnhookKeyboard()
def HookMouse(self):
'''Begins watching for mouse events.'''
cpyHook.cSetHook(HookConstants.WH_MOUSE_LL, self.MouseSwitch)
self.mouse_hook = True
def HookKeyboard(self):
'''Begins watching for keyboard events.'''
cpyHook.cSetHook(HookConstants.WH_KEYBOARD_LL, self.KeyboardSwitch)
self.keyboard_hook = True
def UnhookMouse(self):
'''Stops watching for mouse events.'''
if self.mouse_hook:
cpyHook.cUnhook(HookConstants.WH_MOUSE_LL)
self.mouse_hook = False
def UnhookKeyboard(self):
'''Stops watching for keyboard events.'''
if self.keyboard_hook:
cpyHook.cUnhook(HookConstants.WH_KEYBOARD_LL)
self.keyboard_hook = False
def MouseSwitch(self, msg, x, y, data, flags, time, hwnd, window_name):
'''
Passes a mouse event on to the appropriate handler if one is registered.
@param msg: Message value
@type msg: integer
@param x: x-coordinate of the mouse event
@type x: integer
@param y: y-coordinate of the mouse event
@type y: integer
@param data: Data associated with the mouse event (scroll information)
@type data: integer
@param flags: Flags associated with the mouse event (injected or not)
@type flags: integer
@param time: Seconds since the epoch when the even current
@type time: integer
@param hwnd: Window handle of the foreground window at the time of the event
@type hwnd: integer
'''
event = MouseEvent(msg, x, y, data, flags, time, hwnd, window_name)
func = self.mouse_funcs.get(msg)
if func:
return func(event)
else:
return True
def KeyboardSwitch(self, msg, vk_code, scan_code, ascii, flags, time, hwnd, win_name):
'''
Passes a keyboard event on to the appropriate handler if one is registered.
@param msg: Message value
@type msg: integer
@param vk_code: The virtual keycode of the key
@type vk_code: integer
@param scan_code: The scan code of the key
@type scan_code: integer
@param ascii: ASCII numeric value for the key if available
@type ascii: integer
@param flags: Flags associated with the key event (injected or not, extended key, etc.)
@type flags: integer
@param time: Time since the epoch of the key event
@type time: integer
@param hwnd: Window handle of the foreground window at the time of the event
@type hwnd: integer
'''
event = KeyboardEvent(msg, vk_code, scan_code, ascii, flags, time, hwnd, win_name)
func = self.keyboard_funcs.get(msg)
if func:
return func(event)
else:
return True
def SubscribeMouseMove(self, func):
'''
Registers the given function as the callback for this mouse event type. Use the
MouseMove property as a shortcut.
@param func: Callback function
@type func: callable
'''
if func is None:
self.disconnect(self.mouse_funcs, HookConstants.WM_MOUSEMOVE)
else:
self.connect(self.mouse_funcs, HookConstants.WM_MOUSEMOVE, func)
def SubscribeMouseLeftUp(self, func):
'''
Registers the given function as the callback for this mouse event type. Use the
MouseLeftUp property as a shortcut.
@param func: Callback function
@type func: callable
'''
if func is None:
self.disconnect(self.mouse_funcs, HookConstants.WM_LBUTTONUP)
else:
self.connect(self.mouse_funcs, HookConstants.WM_LBUTTONUP, func)
def SubscribeMouseLeftDown(self, func):
'''
Registers the given function as the callback for this mouse event type. Use the
MouseLeftDown property as a shortcut.
@param func: Callback function
@type func: callable
'''
if func is None:
self.disconnect(self.mouse_funcs, HookConstants.WM_LBUTTONDOWN)
else:
self.connect(self.mouse_funcs, HookConstants.WM_LBUTTONDOWN, func)
def SubscribeMouseLeftDbl(self, func):
'''
Registers the given function as the callback for this mouse event type. Use the
MouseLeftDbl property as a shortcut.
@param func: Callback function
@type func: callable
'''
if func is None:
self.disconnect(self.mouse_funcs, HookConstants.WM_LBUTTONDBLCLK)
else:
self.connect(self.mouse_funcs, HookConstants.WM_LBUTTONDBLCLK, func)
def SubscribeMouseRightUp(self, func):
'''
Registers the given function as the callback for this mouse event type. Use the
MouseRightUp property as a shortcut.
@param func: Callback function
@type func: callable
'''
if func is None:
self.disconnect(self.mouse_funcs, HookConstants.WM_RBUTTONUP)
else:
self.connect(self.mouse_funcs, HookConstants.WM_RBUTTONUP, func)
def SubscribeMouseRightDown(self, func):
'''
Registers the given function as the callback for this mouse event type. Use the
MouseRightDown property as a shortcut.
@param func: Callback function
@type func: callable
'''
if func is None:
self.disconnect(self.mouse_funcs, HookConstants.WM_RBUTTONDOWN)
else:
self.connect(self.mouse_funcs, HookConstants.WM_RBUTTONDOWN, func)
def SubscribeMouseRightDbl(self, func):
'''
Registers the given function as the callback for this mouse event type. Use the
MouseRightDbl property as a shortcut.
@param func: Callback function
@type func: callable
'''
if func is None:
self.disconnect(self.mouse_funcs, HookConstants.WM_RBUTTONDBLCLK)
else:
self.connect(self.mouse_funcs, HookConstants.WM_RBUTTONDBLCLK, func)
def SubscribeMouseMiddleUp(self, func):
'''
Registers the given function as the callback for this mouse event type. Use the
MouseMiddleUp property as a shortcut.
@param func: Callback function
@type func: callable
'''
if func is None:
self.disconnect(self.mouse_funcs, HookConstants.WM_MBUTTONUP)
else:
self.connect(self.mouse_funcs, HookConstants.WM_MBUTTONUP, func)
def SubscribeMouseMiddleDown(self, func):
'''
Registers the given function as the callback for this mouse event type. Use the
MouseMiddleDown property as a shortcut.
@param func: Callback function
@type func: callable
'''
if func is None:
self.disconnect(self.mouse_funcs, HookConstants.WM_MBUTTONDOWN)
else:
self.connect(self.mouse_funcs, HookConstants.WM_MBUTTONDOWN, func)
def SubscribeMouseMiddleDbl(self, func):
'''
Registers the given function as the callback for this mouse event type. Use the
MouseMiddleDbl property as a shortcut.
@param func: Callback function
@type func: callable
'''
if func is None:
self.disconnect(self.mouse_funcs, HookConstants.WM_MBUTTONDBLCLK)
else:
self.connect(self.mouse_funcs, HookConstants.WM_MBUTTONDBLCLK, func)
def SubscribeMouseWheel(self, func):
'''
Registers the given function as the callback for this mouse event type. Use the
MouseWheel property as a shortcut.
@param func: Callback function
@type func: callable
'''
if func is None:
self.disconnect(self.mouse_funcs, HookConstants.WM_MOUSEWHEEL)
else:
self.connect(self.mouse_funcs, HookConstants.WM_MOUSEWHEEL, func)
def SubscribeMouseAll(self, func):
'''
Registers the given function as the callback for all mouse events. Use the
MouseAll property as a shortcut.
@param func: Callback function
@type func: callable
'''
self.SubscribeMouseMove(func)
self.SubscribeMouseWheel(func)
self.SubscribeMouseAllButtons(func)
def SubscribeMouseAllButtons(self, func):
'''
Registers the given function as the callback for all mouse button events. Use the
MouseButtonAll property as a shortcut.
@param func: Callback function
@type func: callable
'''
self.SubscribeMouseAllButtonsDown(func)
self. SubscribeMouseAllButtonsUp(func)
self.SubscribeMouseAllButtonsDbl(func)
def SubscribeMouseAllButtonsDown(self, func):
'''
Registers the given function as the callback for all mouse button down events.
Use the MouseAllButtonsDown property as a shortcut.
@param func: Callback function
@type func: callable
'''
self.SubscribeMouseLeftDown(func)
self.SubscribeMouseRightDown(func)
self.SubscribeMouseMiddleDown(func)
def SubscribeMouseAllButtonsUp(self, func):
'''
Registers the given function as the callback for all mouse button up events.
Use the MouseAllButtonsUp property as a shortcut.
@param func: Callback function
@type func: callable
'''
self.SubscribeMouseLeftUp(func)
self.SubscribeMouseRightUp(func)
self.SubscribeMouseMiddleUp(func)
def SubscribeMouseAllButtonsDbl(self, func):
'''
Registers the given function as the callback for all mouse button double click
events. Use the MouseAllButtonsDbl property as a shortcut.
@param func: Callback function
@type func: callable
'''
self.SubscribeMouseLeftDbl(func)
self.SubscribeMouseRightDbl(func)
self.SubscribeMouseMiddleDbl(func)
def SubscribeKeyDown(self, func):
'''
Registers the given function as the callback for this keyboard event type.
Use the KeyDown property as a shortcut.
@param func: Callback function
@type func: callable
'''
if func is None:
self.disconnect(self.keyboard_funcs, HookConstants.WM_KEYDOWN)
self.disconnect(self.keyboard_funcs, HookConstants.WM_SYSKEYDOWN)
else:
self.connect(self.keyboard_funcs, HookConstants.WM_KEYDOWN, func)
self.connect(self.keyboard_funcs, HookConstants.WM_SYSKEYDOWN, func)
def SubscribeKeyUp(self, func):
'''
Registers the given function as the callback for this keyboard event type.
Use the KeyUp property as a shortcut.
@param func: Callback function
@type func: callable
'''
if func is None:
self.disconnect(self.keyboard_funcs, HookConstants.WM_KEYUP)
self.disconnect(self.keyboard_funcs, HookConstants.WM_SYSKEYUP)
else:
self.connect(self.keyboard_funcs, HookConstants.WM_KEYUP, func)
self.connect(self.keyboard_funcs, HookConstants.WM_SYSKEYUP, func)
def SubscribeKeyChar(self, func):
'''
Registers the given function as the callback for this keyboard event type.
Use the KeyChar property as a shortcut.
B{Note}: this is currently non-functional, no WM_*CHAR messages are
processed by the keyboard hook.
@param func: Callback function
@type func: callable
'''
if func is None:
self.disconnect(self.keyboard_funcs, HookConstants.WM_CHAR)
self.disconnect(self.keyboard_funcs, HookConstants.WM_DEADCHAR)
self.disconnect(self.keyboard_funcs, HookConstants.WM_SYSCHAR)
self.disconnect(self.keyboard_funcs, HookConstants.WM_SYSDEADCHAR)
else:
self.connect(self.keyboard_funcs, HookConstants.WM_CHAR, func)
self.connect(self.keyboard_funcs, HookConstants.WM_DEADCHAR, func)
self.connect(self.keyboard_funcs, HookConstants.WM_SYSCHAR, func)
self.connect(self.keyboard_funcs, HookConstants.WM_SYSDEADCHAR, func)
def SubscribeKeyAll(self, func):
'''
Registers the given function as the callback for all keyboard events.
Use the KeyAll property as a shortcut.
@param func: Callback function
@type func: callable
'''
self.SubscribeKeyDown(func)
self.SubscribeKeyUp(func)
self.SubscribeKeyChar(func)
MouseAll = property(fset=SubscribeMouseAll)
MouseAllButtons = property(fset=SubscribeMouseAllButtons)
MouseAllButtonsUp = property(fset=SubscribeMouseAllButtonsUp)
MouseAllButtonsDown = property(fset=SubscribeMouseAllButtonsDown)
MouseAllButtonsDbl = property(fset=SubscribeMouseAllButtonsDbl)
MouseWheel = property(fset=SubscribeMouseWheel)
MouseMove = property(fset=SubscribeMouseMove)
MouseLeftUp = property(fset=SubscribeMouseLeftUp)
MouseLeftDown = property(fset=SubscribeMouseLeftDown)
MouseLeftDbl = property(fset=SubscribeMouseLeftDbl)
MouseRightUp = property(fset=SubscribeMouseRightUp)
MouseRightDown = property(fset=SubscribeMouseRightDown)
MouseRightDbl = property(fset=SubscribeMouseRightDbl)
MouseMiddleUp = property(fset=SubscribeMouseMiddleUp)
MouseMiddleDown = property(fset=SubscribeMouseMiddleDown)
MouseMiddleDbl = property(fset=SubscribeMouseMiddleDbl)
KeyUp = property(fset=SubscribeKeyUp)
KeyDown = property(fset=SubscribeKeyDown)
KeyChar = property(fset=SubscribeKeyChar)
KeyAll = property(fset=SubscribeKeyAll)
def connect(self, switch, id, func):
'''
Registers a callback to the given function for the event with the given ID in the
provided dictionary. Internal use only.
@param switch: Collection of callbacks
@type switch: dictionary
@param id: Event type
@type id: integer
@param func: Callback function
@type func: callable
'''
switch[id] = func
def disconnect(self, switch, id):
'''
Unregisters a callback for the event with the given ID in the provided dictionary.
Internal use only.
@param switch: Collection of callbacks
@type switch: dictionary
@param id: Event type
@type id: integer
'''
try:
del switch[id]
except:
pass