- 论坛徽章:
- 11
|
# coding=UTF-8
###############################################################################
# 自动化测试工具
# 模拟win32窗口行为
#
__author__ = "@nj"
# 版本号
__version__ = "$Revision: 1.0 $"
# 版权信息
__copyright__ = "Copyleft (c) 2001 li.rongqing"
__license__ = "Python"
###############################################################################
#系统模块
import time
import threading
import ctypes, ctypes.wintypes as _wintypes
import collections
#const NAME
import win32con
#new
win32con.WM_XBUTTONDOWN = 0x20B
win32con.WM_XBUTTONUP = 0x20C
win32con.WM_XBUTTONDBLCLK = 0x20D
win32con.WM_MOUSEHWHEEL = 0x20E
msgname = {
win32con.WM_MOUSEMOVE : 'WM_MOUSEMOVE ',
win32con.WM_MOUSEMOVE : 'WM_MOUSEMOVE ',
win32con.WM_LBUTTONDOWN : 'WM_LBUTTONDOWN ',
win32con.WM_LBUTTONUP : 'WM_LBUTTONUP ',
win32con.WM_LBUTTONDBLCLK : 'WM_LBUTTONDBLCLK',
win32con.WM_RBUTTONDOWN : 'WM_RBUTTONDOWN ',
win32con.WM_RBUTTONUP : 'WM_RBUTTONUP ',
win32con.WM_RBUTTONDBLCLK : 'WM_RBUTTONDBLCLK',
win32con.WM_MBUTTONDOWN : 'WM_MBUTTONDOWN ',
win32con.WM_MBUTTONUP : 'WM_MBUTTONUP ',
win32con.WM_MBUTTONDBLCLK : 'WM_MBUTTONDBLCLK',
win32con.WM_MOUSEWHEEL : 'WM_MOUSEWHEEL ',
win32con.WM_XBUTTONDOWN : 'WM_XBUTTONDOWN ',
win32con.WM_XBUTTONUP : 'WM_XBUTTONUP ',
win32con.WM_XBUTTONDBLCLK : 'WM_XBUTTONDBLCLK',
win32con.WM_MOUSEHWHEEL : 'WM_MOUSEHWHEEL ',
}
_user32 = ctypes.windll.user32
_kernel32 = ctypes.windll.kernel32
'''
封装 HOOK 函数 SetWindowsHookEx
'''
class win32hook:
def __init__(self,wh=None):
self._thread = None #线程
self._hookid = 0 #标识号
self.wh_xxx = wh #钩子类型
if not wh and hasattr(self, '_wh_type'):
self.wh_xxx = self._wh_type
return
#
def start(self):
if self._thread is None:
self._thread = threading.Thread(target=self.__hook_thread)
self._thread.start()
return
def stop(self):
if self._thread is None:
return
_user32.PostThreadMessageW(self._thread.ident,win32con.WM_QUIT,0,0)
self._thread.join()
self._thread = None
return
def __hook_thread(self):
LRESULT=ctypes.c_long
HOOKPROC = _wintypes.WINFUNCTYPE(LRESULT,
ctypes.c_int, _wintypes.WPARAM, _wintypes.LPARAM)
MouseHookFunc = HOOKPROC(self.__hook_func)
self._hookid = _user32.SetWindowsHookExW(
self.wh_xxx,
MouseHookFunc,
_kernel32.GetModuleHandleW(None),
0)
#print 'SetWindowsHookExW',self._hookid
if self._hookid == 0:
raise OSError("could not register keyboard hook")
msg = _wintypes.MSG()
while _user32.GetMessageW(ctypes.byref(msg),None,0,0):
_user32.TranslateMessage(byref(msg))
_user32.DispatchMessage(byref(msg))
pass
if _user32.UnhookWindowsHookEx(self._hookid)==0:
raise OSError("could not unregister key hook %s"%self._hookid)
self._hookid = 0
return
def __hook_func(self,nCode,wParam,lParam):
if nCode < win32con.HC_ACTION:
return _user32.CallNextHookEx(self._hookid,nCode,wParam,lParam)
if hasattr(self, '_hook_func'):
self._hook_func(nCode,wParam,lParam)
return _user32.CallNextHookEx(self._hookid,nCode,wParam,lParam)
wh2class = {}
@staticmethod
def register( cls):
print 'register',cls.__name__, cls._wh_type
win32hook.wh2class[ cls._wh_type] = cls
@staticmethod
def creator(wh_type):
cls = win32hook.wh2class[wh_type]
assert(wh_type == cls._wh_type)
print 'instance', cls.__name__, cls._wh_type
return cls
#这里是对参数进行解码的...
class MSLLHOOKSTRUCT(ctypes.Structure):
_fields_=[
#The x- and y-coordinates of the cursor, in screen coordinates.
('pt' , _wintypes.POINT),
# '''
# If the message is WM_MOUSEWHEEL,
# the high-order word of this member is the wheel delta.
# The low-order word is reserved.
# A positive value indicates that the wheel was rotated forward,
# away from the user;
# a negative value indicates that the wheel was rotated backward,
# toward the user.
# One wheel click is defined as WHEEL_DELTA, which is 120.
#
# If the message is WM_XBUTTONDOWN,
# WM_XBUTTONUP, WM_XBUTTONDBLCLK,
# WM_NCXBUTTONDOWN, WM_NCXBUTTONUP,
# or WM_NCXBUTTONDBLCLK,
# the high-order word specifies which X button was pressed or released,
# and the low-order word is reserved.
# This value can be one or more of the following values.
# Otherwise, mouseData is not used.
# Value Meaning
# XBUTTON1
# 0x0001 The first X button was pressed or released.
# XBUTTON2
# 0x0002 The second X button was pressed or release
# '''
('mouseData' ,_wintypes.DWORD),
#The event-injected flag. An application can use the following value to test the mouse flags.
# LLMHF_INJECTED 0x00000001 Test the event-injected flag.
('flags' ,_wintypes.DWORD),
#The time stamp for this message.
('time' ,_wintypes.DWORD),
#Additional information associated with the message.
('dwExtraInfo',_wintypes.DWORD),
]
class mousehook(win32hook):
_wh_type = win32con.WH_MOUSE_LL
def __init__(self):
win32hook.__init__(self, self._wh_type)
return
def _hook_func(self,nCode,wParam,lParam):
msll = MSLLHOOKSTRUCT.from_address(lParam)
print '%16s :pt=(% 4d,% 4d) mouseData=% 4d,flag=% 4d, %08X'%(
msgname[wParam],msll.pt.x,msll.pt.y,msll.mouseData,msll.flags,msll.dwExtraInfo)
win32hook.register(mousehook)
class KBDLLHOOKSTRUCT(ctypes.Structure):
_fields_=[
('vkCode' ,_wintypes.DWORD),
('scanCode' ,_wintypes.DWORD),
('flags' ,_wintypes.DWORD),
('time' ,_wintypes.DWORD),
('dwExtraInfo',_wintypes.DWORD),
]
class keybdhook(win32hook):
_wh_type = win32con.WH_KEYBOARD_LL
def __init__(self):
win32hook.__init__(self, None)#self._wh_type)
return
def _hook_func(self,nCode,wParam,lParam):
kbll = KBDLLHOOKSTRUCT.from_address(lParam)
#if not (kbd.flags&LLKHF_UP) and kbd.vkCode!=VK_RETURN:
KeyboardEvent = collections.namedtuple('KeyboardEvent',
['event_type', 'key_code','scan_code', 'alt_pressed', 'time'])
event_types = {
win32con.WM_KEYDOWN : 'key down ',
win32con.WM_KEYUP : 'key up ',
win32con.WM_SYSKEYDOWN : 'sys key down', # WM_SYSKEYDOWN, used for Alt key.
win32con.WM_SYSKEYUP : 'sys key up ', # WM_SYSKEYUP, used for Alt key.
}
event = KeyboardEvent(event_types[wParam], kbll.vkCode, kbll.scanCode, kbll.flags, kbll.dwExtraInfo)
print event
win32hook.register(keybdhook)
#过渡设计**
class hookmanager:
def __init__(self):
win32hook.__init__(self, None)#self._wh_type)
pass
def test(whtype):
m = win32hook.creator(whtype)()
m.start()
buf = ''
while buf!='quit':
buf=raw_input("Press quit Enter for quit ")
print "Sending quit message to hook thread"
m.stop()
print "done"
if __name__=='__main__':
test(win32con.WH_MOUSE_LL)
test(win32con.WH_KEYBOARD_LL)
|
|