1

I'm making a screenshot utility for personal use and I want to add in bounding box screenshots. I want to be able to press insert on the 2 corners of the area and then grab the screenshot.

The issue is that I can't get the keyboard and mouse events to work with each other. I can't seem to get the mouse position.

This is what I have so far:

from PIL import ImageGrab
import time
import pythoncom, pyHook

mospos = None

def OnMouseEvent(event):
    print 'MessageName:',event.MessageName
    print 'Message:',event.Message
    print 'Position:',event.Position
    print '---'
    mospos = event.Position
    return True

def OnKeyboardEvent(event):
    print 'KeyID:', event.KeyID#Show KeyID of keypress
    if(event.KeyID == 44):#Prntscr
        print 'Print Screen'
        im = ImageGrab.grabclipboard()
        im.save('img'+time.strftime("%d-%m-%y_%H-%M-%S")+'.png','PNG')#save with Day-Month-Year_Hour-Minute_Second format
    if(event.KeyID == 45):#insert
        print mospos

    return True# return True to pass the event to other handlers


hm = pyHook.HookManager()# create a hook manager
hm.KeyDown = OnKeyboardEvent# watch for all key events
hm.MouseAll = OnMouseEvent
hm.HookKeyboard()# set the hook
hm.HookMouse()
pythoncom.PumpMessages()# wait forever

mospos never changes from 'None' even after I cause mouse events.

How do I get the mouse position from the keyboard event handler?

p.s. I'm eternally sorry if this doesn't make sense.

Margamel
  • 11
  • 4

1 Answers1

1

Your problem is that mospos is not used as a global variable in your code.

In OnMouseEvent, when you set mospos to event.position, you just set a local variable, incidentally named mospos. It is not the same variable!

You have to explicitly declare that in OnMouseEvent, mospos is to be treated as a global variable, using the global keyword.

def OnMouseEvent(event):
    global mospos
    mospos = event.Position
    return True

That way, you will be able to read the current mouse position in OnKeyboardEvent.

Here is what your OnKeyboardEvent callback may look like, with yet another global variable used to store one corner of the area (grab screen on second insert press):

def OnKeyboardEvent(event):
    global origin
    if(event.KeyID == 45):  # insert
        if origin is None:
            origin = mospos
        else:
            bbox = (min(origin[0], mospos[0]), 
                    min(origin[1], mospos[1]), 
                    max(origin[0], mospos[0]), 
                    max(origin[1], mospos[1]))
            im = ImageGrab.grab(bbox)
            im.save('img'+time.strftime("%d-%m-%y_%H-%M-%S")+'.png','PNG')  # save with Day-Month-Year_Hour-Minute_Second format
            origin = None
    return True 

Note however that it may be overkill to use a mouseHook just to get the cursor position when you press a given key.

Another solution would be to use call GetCursorInfo() from win32gui in your keyboard hook.

flags, hcursor, mospos = win32gui.GetCursorInfo()