Skip to content

Commit

Permalink
Added __init__ file
Browse files Browse the repository at this point in the history
Updated  AA example to work with wx namespace
Added support for allowing/disallowing event propagation
  • Loading branch information
parente committed Sep 13, 2004
1 parent 1ed9cf1 commit a5a2cfd
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 75 deletions.
8 changes: 6 additions & 2 deletions HookManager.py
Expand Up @@ -250,7 +250,9 @@ def MouseSwitch(self, msg, x, y, data, flags, time, hwnd, window_name):
event = MouseEvent(msg, x, y, data, flags, time, hwnd, window_name)
func = self.mouse_funcs.get(msg)
if func:
func(event)
return func(event)
else:
return True

def KeyboardSwitch(self, msg, vk_code, scan_code, flags, time, hwnd, win_name):
'''Pass a keyboard event on to the appropriate handler if one is registered.
Expand All @@ -272,7 +274,9 @@ def KeyboardSwitch(self, msg, vk_code, scan_code, flags, time, hwnd, win_name):
event = KeyboardEvent(msg, vk_code, scan_code, flags, time, hwnd, win_name)
func = self.keyboard_funcs.get(msg)
if func:
func(event)
return func(event)
else:
return True

def SubscribeMouseMove(self, func):
if func is None:
Expand Down
1 change: 1 addition & 0 deletions __init__.py
@@ -0,0 +1 @@
from HookManager import *
32 changes: 9 additions & 23 deletions aa hook.py
@@ -1,31 +1,19 @@
from wxPython.wx import *
from pyHookManager import *
import wx
import pyHook
from pyAA import *

EVT_GET_AO_ID = wxNewId()
def EVT_GET_AO(win, func):
win.Connect(-1, -1, EVT_GET_AO_ID, func)

class evtGetAO(wxPyEvent):
def __init__(self, event, type):
wxPyEvent.__init__(self)
self.SetEventType(EVT_GET_AO_ID)
self.HookEvent = event
self.Type = type

class myFrame(wxFrame):
class myFrame(wx.Frame):
def __init__(self):
wxFrame.__init__(self, None, -1, 'My Frame')
wx.Frame.__init__(self, None, -1, 'My Frame')

self.hm = HookManager()
self.hm = pyHook.HookManager()
self.hm.MouseAllButtonsDown = self.OnMouseEvent
self.hm.KeyDown = self.OnKeyboardEvent

self.hm.HookMouse()
self.hm.HookKeyboard()

EVT_CLOSE(self, self.OnClose)
EVT_GET_AO(self, self.OnGetAO)
wx.EVT_CLOSE(self, self.OnClose)

def OnGetAO(self, event):
if event.Type == 'keyboard':
Expand Down Expand Up @@ -73,21 +61,19 @@ def OnGetAO(self, event):
print

def OnMouseEvent(self, event):
#wxPostEvent(self, evtGetAO(event, 'mouse'))
event.Type = 'mouse'
wxCallAfter(self.OnGetAO, event)
wx.CallAfter(self.OnGetAO, event)

def OnKeyboardEvent(self, event):
#wxPostEvent(self, evtGetAO(event, 'keyboard'))
event.Type = 'keyboard'
wxCallAfter(self.OnGetAO, event)
wx.CallAfter(self.OnGetAO, event)

def OnClose(self, event):
del self.hm
self.Destroy()

if __name__ == '__main__':
app = wxPySimpleApp(0)
app = wx.PySimpleApp(0)
frame = myFrame()
app.SetTopWindow(frame)
frame.Show()
Expand Down
93 changes: 48 additions & 45 deletions cpyHook.i
Expand Up @@ -5,23 +5,19 @@
#define _WIN32_WINNT 0x400
#include "windows.h"

//#pragma data_seg(".GLOBALS")
PyObject* callback_funcs[WH_MAX];
HHOOK hHooks[WH_MAX];
PyInterpreterState *save_interp = NULL;
//#pragma data_seg()
%}

%typemap(python, in) PyObject *pyfunc {
if (!PyCallable_Check($input)) {
PyErr_SetString(PyExc_TypeError, "Need a callable object!");
PyErr_SetString(PyExc_TypeError, "Need a callable object");
return NULL;
}
$1 = $input;
}

%init %{ save_interp = PyThreadState_Get()->interp;

%init %{
//set the arrays to NULL
for(i=0; i < WH_MAX; i++) {
callback_funcs[i] = NULL;
Expand All @@ -32,60 +28,69 @@
%wrapper %{
LRESULT CALLBACK cLLKeyboardCallback(int code, WPARAM wParam, LPARAM lParam) {
PyObject *arglist, *r;
PyThreadState *prev_state, *new_state;
PKBDLLHOOKSTRUCT kbd; HWND hwnd;
PKBDLLHOOKSTRUCT kbd;
HWND hwnd;
PSTR win_name = NULL;
static int win_len;
static long result;
long pass = 1;
PyGILState_STATE gil;

// get the GIL
gil = PyGILState_Ensure();


// cast to a keyboard event struct
kbd = (PKBDLLHOOKSTRUCT)lParam;
// get the current foreground window (might not be the real window that received the event)
hwnd = GetForegroundWindow();

//grab the window name if possible
// grab the window name if possible
win_len = GetWindowTextLength(hwnd);
if(win_len > 0) {
win_name = (PSTR) malloc(sizeof(char) * win_len + 1);
GetWindowText(hwnd, win_name, win_len + 1);
}

//pass the message on to the Python function
PyEval_AcquireLock();
new_state = PyThreadState_New(save_interp);
prev_state = PyThreadState_Swap(new_state);

// pass the message on to the Python function
arglist = Py_BuildValue("(iiiiiiz)", wParam, kbd->vkCode, kbd->scanCode,
kbd->flags, kbd->time, hwnd, win_name);
r = PyEval_CallObject(callback_funcs[WH_KEYBOARD_LL], arglist);
r = PyObject_CallObject(callback_funcs[WH_KEYBOARD_LL], arglist);

if(r == NULL) {
// check if we should pass the event on or not
if(r == NULL)
PyErr_Print();
}
else
pass = PyInt_AsLong(r);

Py_XDECREF(r);
Py_DECREF(arglist);
// release the GIL
PyGILState_Release(gil);

new_state = PyThreadState_Swap(prev_state);
PyThreadState_Clear(new_state);
PyEval_ReleaseLock();
PyThreadState_Delete(new_state);

//free the memory for the window name
// free the memory for the window name
if(win_name != NULL)
free(win_name);
//now pass the message onto the next hook in Windows
result = CallNextHookEx(hHooks[WH_KEYBOARD_LL], code, wParam, lParam);


// decide whether or not to call the next hook
if(code < 0 || pass)
result = CallNextHookEx(hHooks[WH_KEYBOARD_LL], code, wParam, lParam);
else
result = 42;
return result;
}

LRESULT CALLBACK cLLMouseCallback(int code, WPARAM wParam, LPARAM lParam) {
PyObject *arglist, *r;
PyThreadState *prev_state, *new_state;
PMSLLHOOKSTRUCT ms; HWND hwnd;
PMSLLHOOKSTRUCT ms;
HWND hwnd;
PSTR win_name = NULL;
static int win_len;
static long result;
long pass = 1;
PyGILState_STATE gil;

// get the GIL
gil = PyGILState_Ensure();

//pass the message on to the Python function
ms = (PMSLLHOOKSTRUCT)lParam;
Expand All @@ -98,33 +103,31 @@
GetWindowText(hwnd, win_name, win_len + 1);
}

PyEval_AcquireLock();
new_state = PyThreadState_New(save_interp);
prev_state = PyThreadState_Swap(new_state);

//build the argument list to the callback function
arglist = Py_BuildValue("(iiiiiiiz)", wParam, ms->pt.x, ms->pt.y, ms->mouseData,
ms->flags, ms->time, hwnd, win_name);
r = PyEval_CallObject(callback_funcs[WH_MOUSE_LL], arglist);

if(r == NULL) {
r = PyObject_CallObject(callback_funcs[WH_MOUSE_LL], arglist);

// check if we should pass the event on or not
if(r == NULL)
PyErr_Print();
}
else
pass = PyInt_AsLong(r);

Py_XDECREF(r);
Py_DECREF(arglist);
// release the GIL
PyGILState_Release(gil);

new_state = PyThreadState_Swap(prev_state);
PyThreadState_Clear(new_state);
PyEval_ReleaseLock();
PyThreadState_Delete(new_state);
//free the memory for the window name
if(win_name != NULL)
free(win_name);

//now pass the message onto the next hook in Windows
result = CallNextHookEx(hHooks[WH_MOUSE_LL], code, wParam, lParam);


// decide whether or not to call the next hook
if(code < 0 || pass)
result = CallNextHookEx(hHooks[WH_MOUSE_LL], code, wParam, lParam);
else
result = 42;
return result;
}

Expand Down
15 changes: 13 additions & 2 deletions example.py
@@ -1,14 +1,17 @@
import wx
from pyHook.HookManager import *
import pyHook

class myFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, 'My Frame')

self.hm = HookManager()
# create the hook mananger
self.hm = pyHook.HookManager()
# register two callbacks
self.hm.MouseAllButtonsDown = self.OnMouseEvent
self.hm.KeyDown = self.OnKeyboardEvent

# hook into the mouse and keyboard events
self.hm.HookMouse()
self.hm.HookKeyboard()

Expand All @@ -24,6 +27,10 @@ def OnMouseEvent(self, event):
print 'Wheel:',event.Wheel
print 'Injected:',event.Injected
print '---'

# return True to pass the event to other handlers
# return False to stop the event from propagating
return True

def OnKeyboardEvent(self, event):
print 'MessageName:',event.MessageName
Expand All @@ -39,6 +46,10 @@ def OnKeyboardEvent(self, event):
print 'Alt', event.Alt
print 'Transition', event.Transition
print '---'

# return True to pass the event to other handlers
# return False to stop the event from propagating
return True

def OnClose(self, event):
del self.hm
Expand Down
7 changes: 4 additions & 3 deletions setup.py
Expand Up @@ -23,7 +23,7 @@
doclines = __doc__.split('\n')

setup(name='pyHook',
version='1.2',
version='1.3',
author='Peter Parente',
author_email='parente@cs.unc.edu',
url='http://www.cs.unc.edu/~parente',
Expand All @@ -34,6 +34,7 @@
classifiers = filter(None, classifiers.split('\n')),
long_description = ' '.join(doclines[2:]),
packages = ['pyHook'],
ext_modules = [Extension('pyHook._cpyHook', ['pyHook/cpyHook.i'], libraries=libs)],
data_files=[('Lib/site-packages/pyHook', ['pyHook/LICENSE.txt'])]
package_dir = {'pyHook' : ""},
ext_modules = [Extension('pyHook._cpyHook', ['cpyHook.i'], libraries=libs)],
data_files=[('Lib/site-packages/pyHook', ['LICENSE.txt'])]
)

0 comments on commit a5a2cfd

Please sign in to comment.