2010-11-24 20 views
4

ctypes.windll.user32.mouse_event(3,0,0,0,0)ctypes的mouse_events

我用鼠標位置瞎搞,並偶然發現這行從我的理解模擬鼠標單擊。有沒有人有類似的文檔(如右鍵單擊等)?

回答

9

我有一個包裝鼠標管理的小類。

import win32gui, win32api, win32con, ctypes 

class Mouse: 
    """It simulates the mouse""" 
    MOUSEEVENTF_MOVE = 0x0001 # mouse move 
    MOUSEEVENTF_LEFTDOWN = 0x0002 # left button down 
    MOUSEEVENTF_LEFTUP = 0x0004 # left button up 
    MOUSEEVENTF_RIGHTDOWN = 0x0008 # right button down 
    MOUSEEVENTF_RIGHTUP = 0x0010 # right button up 
    MOUSEEVENTF_MIDDLEDOWN = 0x0020 # middle button down 
    MOUSEEVENTF_MIDDLEUP = 0x0040 # middle button up 
    MOUSEEVENTF_WHEEL = 0x0800 # wheel button rolled 
    MOUSEEVENTF_ABSOLUTE = 0x8000 # absolute move 
    SM_CXSCREEN = 0 
    SM_CYSCREEN = 1 

    def _do_event(self, flags, x_pos, y_pos, data, extra_info): 
     """generate a mouse event""" 
     x_calc = 65536L * x_pos/ctypes.windll.user32.GetSystemMetrics(self.SM_CXSCREEN) + 1 
     y_calc = 65536L * y_pos/ctypes.windll.user32.GetSystemMetrics(self.SM_CYSCREEN) + 1 
     return ctypes.windll.user32.mouse_event(flags, x_calc, y_calc, data, extra_info) 

    def _get_button_value(self, button_name, button_up=False): 
     """convert the name of the button into the corresponding value""" 
     buttons = 0 
     if button_name.find("right") >= 0: 
      buttons = self.MOUSEEVENTF_RIGHTDOWN 
     if button_name.find("left") >= 0: 
      buttons = buttons + self.MOUSEEVENTF_LEFTDOWN 
     if button_name.find("middle") >= 0: 
      buttons = buttons + self.MOUSEEVENTF_MIDDLEDOWN 
     if button_up: 
      buttons = buttons << 1 
     return buttons 

    def move_mouse(self, pos): 
     """move the mouse to the specified coordinates""" 
     (x, y) = pos 
     old_pos = self.get_position() 
     x = x if (x != -1) else old_pos[0] 
     y = y if (y != -1) else old_pos[1]  
     self._do_event(self.MOUSEEVENTF_MOVE + self.MOUSEEVENTF_ABSOLUTE, x, y, 0, 0) 

    def press_button(self, pos=(-1, -1), button_name="left", button_up=False): 
     """push a button of the mouse""" 
     self.move_mouse(pos) 
     self._do_event(self.get_button_value(button_name, button_up), 0, 0, 0, 0) 

    def click(self, pos=(-1, -1), button_name= "left"): 
     """Click at the specified placed""" 
     self.move_mouse(pos) 
     self._do_event(self._get_button_value(button_name, False)+self._get_button_value(button_name, True), 0, 0, 0, 0) 

    def double_click (self, pos=(-1, -1), button_name="left"): 
     """Double click at the specifed placed""" 
     for i in xrange(2): 
      self.click(pos, button_name) 

    def get_position(self): 
     """get mouse position""" 
     return win32api.GetCursorPos() 

這裏是一個小例子:

import time 
mouse = Mouse() 
mouse.click((20, 10), "left") 
time.sleep(2.0) 

mouse.click((100, 100), "right") 

我希望它能幫助

+0

如果您只使用`win32api`查詢鼠標位置,[您可以在ctypes中執行此操作](http://pastebin.com/P2SYvZYc)。 – DuckPuncher 2016-04-01 20:10:35

+1

_do_event的部分不起作用,65536L返回錯誤。 – 2016-05-13 15:38:52

4

這是http://blog.lazynice.net/?p=63

腳本每分鐘檢測一次窗口的不活動狀態。如果不活動超過5分鐘,它只是發送一個鼠標事件來移動鼠標,所以屏幕保護程序可能認爲它來自用戶輸入,然後重置計時器。只需設置不活動持續時間少於屏幕保護程序的等待時間,然後運行!

from ctypes import Structure, windll, c_uint, sizeof, byref 
import time 

class LASTINPUTINFO(Structure): 
    _fields_ = [('cbSize', c_uint), ('dwTime', c_uint)] 

def get_idle_duration(): 
    lastInputInfo = LASTINPUTINFO() 
    lastInputInfo.cbSize = sizeof(lastInputInfo) 
    windll.user32.GetLastInputInfo(byref(lastInputInfo)) 
    millis = windll.kernel32.GetTickCount() – lastInputInfo.dwTime 
    return millis/1000.0 

while True: 
    d = get_idle_duration() 
    if d > 60 * 5: 
     windll.user32.mouse_event(1, 1, 1, 0, 0) 
    time.sleep(60)