Exemple #1
0
 def postClick(hwnd,
               x,
               y,
               flag=MouseFlag.LeftButton,
               clicktype=MouseClickType.SingleClick):
     """在目标窗口通过PostMessage的方式产生鼠标点击的动作
     
     :param hwnd: 目标窗口句柄
     :type hwnd: 整数
     :param x: 屏幕x坐标
     :type x: 整数  
     :param y: 屏幕y坐标
     :type y: 整数
     :param flag: 鼠标键类型 
     :type flag: 枚举类型, MouseFlag.LeftButton|MouseFlag.MiddleButton|MouseFlag.RightButton
     :param clicktype: 鼠标键点击方式
     :type clicktype: 枚举类型, MouseClickType.SingleClick | MouseClickType.DoubleClick
     """
     sleep_time = (win32gui.GetDoubleClickTime() / 1000.0 +
                   0.05) - (time.time() - Mouse._last_click_time)
     if sleep_time > 0:
         time.sleep(sleep_time)
     keystate = 0
     if win32api.GetAsyncKeyState(win32con.VK_CONTROL) & 0x8000 != 0:
         keystate = keystate | win32con.MK_CONTROL
     if win32api.GetAsyncKeyState(win32con.VK_SHIFT) & 0x8000 != 0:
         keystate = keystate | win32con.MK_SHIFT
     win32api.SetCursorPos((x, y))
     c_x, c_y = win32gui.ScreenToClient(hwnd, (x, y))
     if clicktype == MouseClickType.SingleClick:
         try:
             win32gui.PostMessage(hwnd, win32con.WM_NULL, 0, 0)
             win32gui.PostMessage(hwnd, _mouse_msg_param[flag][0],
                                  _mouse_msg_param[flag][2] | keystate,
                                  (c_y << 16) | c_x)
             win32gui.PostMessage(hwnd, _mouse_msg_param[flag][1],
                                  0 | keystate, (c_y << 16) | (c_x))
         except win32gui.error as e:
             if e.winerror == winerror.ERROR_INVALID_WINDOW_HANDLE:  #无效窗口句柄,有些窗口post第一个消息后就会消失
                 pass
             else:
                 raise e
     else:
         win32gui.PostMessage(hwnd, _mouse_msg_param[flag][0],
                              _mouse_msg_param[flag][2] | keystate,
                              (c_y << 16) | c_x)
         win32gui.PostMessage(hwnd, _mouse_msg_param[flag][1], 0 | keystate,
                              (c_y << 16) | (c_x))
         time.sleep(0.1)
         win32gui.PostMessage(hwnd, _mouse_msg_param[flag][3],
                              _mouse_msg_param[flag][2] | keystate,
                              (c_y << 16) | c_x)
         win32gui.PostMessage(hwnd, _mouse_msg_param[flag][1], 0 | keystate,
                              (c_y << 16) | (c_x))
     Mouse._last_click_time = time.time()
Exemple #2
0
 def notify(self, hwnd, msg, wparam, lparam):
     # Double click is actually 1 single click followed
     # by a double-click event, no way to differentiate
     # So we need a timed callback to cancel
     if lparam == win32con.WM_LBUTTONDBLCLK:
         self.execute_menu_option(self.default_menu_index + self.FIRST_ID)
         self.stop_click_timer()
     elif lparam == win32con.WM_RBUTTONUP:
         self.show_menu()
     elif lparam == win32con.WM_LBUTTONDOWN:
         # Wrapper of win32api, timeout is in ms
         # We need to wait at least untill what user has defined as double click
         self.stop_click_timer()
         self.click_timer = timer.set_timer(win32gui.GetDoubleClickTime() * 2, self.click)
     return True
Exemple #3
0
    def _perform_click_input(
        button="left",
        coords=(None, None),
        double=False,
        button_down=True,
        button_up=True,
        wheel_dist=0,
        pressed="",
        key_down=True,
        key_up=True,
    ):
        """Perform a click action using SendInput

        All the *click_input() and *mouse_input() methods use this function.

        Thanks to a bug report from Tomas Walch (twalch) on sourceforge and code
        seen at http://msdn.microsoft.com/en-us/magazine/cc164126.aspx this
        function now always works the same way whether the mouse buttons are
        swapped or not.

        For example if you send a right click to Notepad.Edit - it will always
        bring up a popup menu rather than 'clicking' it.
        """

        # Handle if the mouse buttons are swapped
        if win32functions.GetSystemMetrics(win32defines.SM_SWAPBUTTON):
            if button.lower() == 'left':
                button = 'right'
            elif button.lower() == 'right':
                button = 'left'

        events = []
        if button.lower() == 'left':
            events.append(win32defines.MOUSEEVENTF_MOVE)
            if button_down:
                events.append(win32defines.MOUSEEVENTF_LEFTDOWN)
            if button_up:
                events.append(win32defines.MOUSEEVENTF_LEFTUP)
        elif button.lower() == 'right':
            if button_down:
                events.append(win32defines.MOUSEEVENTF_RIGHTDOWN)
            if button_up:
                events.append(win32defines.MOUSEEVENTF_RIGHTUP)
        elif button.lower() == 'middle':
            if button_down:
                events.append(win32defines.MOUSEEVENTF_MIDDLEDOWN)
            if button_up:
                events.append(win32defines.MOUSEEVENTF_MIDDLEUP)
        elif button.lower() == 'move':
            events.append(win32defines.MOUSEEVENTF_MOVE)
            events.append(win32defines.MOUSEEVENTF_ABSOLUTE)
        elif button.lower() == 'x':
            if button_down:
                events.append(win32defines.MOUSEEVENTF_XDOWN)
            if button_up:
                events.append(win32defines.MOUSEEVENTF_XUP)

        if button.lower() == 'wheel':
            events.append(win32defines.MOUSEEVENTF_WHEEL)

        # if we were asked to double click (and we are doing a full click
        # not just up or down.
        if double and button_down and button_up:
            events *= 2

        if button_down and (button.lower() not in ['move', 'wheel']):
            # wait while previous click is not affecting our current click
            while 0 < win32api.GetTickCount() - win32api.GetLastInputInfo(
            ) < win32gui.GetDoubleClickTime():
                time.sleep(Timings.after_clickinput_wait)

        # set the cursor position
        win32api.SetCursorPos((coords[0], coords[1]))
        time.sleep(Timings.after_setcursorpos_wait)
        if win32api.GetCursorPos() != (coords[0], coords[1]):
            win32api.SetCursorPos((coords[0], coords[1]))
            time.sleep(Timings.after_setcursorpos_wait)

        keyboard_keys = pressed.lower().split()
        if ('control' in keyboard_keys) and key_down:
            SendKeys.VirtualKeyAction(SendKeys.VK_CONTROL, up=False).Run()
        if ('shift' in keyboard_keys) and key_down:
            SendKeys.VirtualKeyAction(SendKeys.VK_SHIFT, up=False).Run()
        if ('alt' in keyboard_keys) and key_down:
            SendKeys.VirtualKeyAction(SendKeys.VK_MENU, up=False).Run()

        dw_flags = 0
        for event in events:
            dw_flags |= event

        dw_data = 0
        if button.lower() == 'wheel':
            wheel_dist = wheel_dist * 120
            dw_data = wheel_dist

        if button.lower() == 'move':
            x_res = win32functions.GetSystemMetrics(win32defines.SM_CXSCREEN)
            y_res = win32functions.GetSystemMetrics(win32defines.SM_CYSCREEN)
            x_coord = int(float(coords[0]) * (65535. / float(x_res - 1)))
            y_coord = int(float(coords[1]) * (65535. / float(y_res - 1)))
            win32api.mouse_event(dw_flags, x_coord, y_coord, dw_data)
        else:
            for event in events:
                if event == win32defines.MOUSEEVENTF_MOVE:
                    x_res = win32functions.GetSystemMetrics(
                        win32defines.SM_CXSCREEN)
                    y_res = win32functions.GetSystemMetrics(
                        win32defines.SM_CYSCREEN)
                    x_coord = int(
                        float(coords[0]) * (65535. / float(x_res - 1)))
                    y_coord = int(
                        float(coords[1]) * (65535. / float(y_res - 1)))
                    win32api.mouse_event(
                        win32defines.MOUSEEVENTF_MOVE
                        | win32defines.MOUSEEVENTF_ABSOLUTE, x_coord, y_coord,
                        dw_data)
                else:
                    win32api.mouse_event(
                        event | win32defines.MOUSEEVENTF_ABSOLUTE, coords[0],
                        coords[1], dw_data)

        time.sleep(Timings.after_clickinput_wait)

        if ('control' in keyboard_keys) and key_up:
            SendKeys.VirtualKeyAction(SendKeys.VK_CONTROL, down=False).Run()
        if ('shift' in keyboard_keys) and key_up:
            SendKeys.VirtualKeyAction(SendKeys.VK_SHIFT, down=False).Run()
        if ('alt' in keyboard_keys) and key_up:
            SendKeys.VirtualKeyAction(SendKeys.VK_MENU, down=False).Run()
Exemple #4
0
def get_double_click_time():
    try:
        return win32gui.GetDoubleClickTime()
    except Exception as e:
        log.warn("failed to get double click time: %s", e)
        return 0
Exemple #5
0
def mouse_single_click():
    """单击鼠标"""
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
    time.sleep(win32gui.GetDoubleClickTime() / 1000 / 4)
Exemple #6
0
    0x2e: 'delete',
    0x24: 'home',
    0x23: 'end',
    0x21: 'page_up',
    0x22: 'page_down',
    0x25: 'left_arrow',
    0x27: 'right_arrow',
    0x26: 'up_arrow',
    0x28: 'down_arrow',
}

win_button_flags = wc.MK_LBUTTON | wc.MK_MBUTTON | wc.MK_RBUTTON
win_prev_key_state = 1 << 30

win_last_mouse_down = None
win_dbl_time = gui.GetDoubleClickTime() / 1000.0  # 0.25
win_dbl_xdist = api.GetSystemMetrics(wc.SM_CXDOUBLECLK)
win_dbl_ydist = api.GetSystemMetrics(wc.SM_CYDOUBLECLK)


def win_message_to_event(message, target=None):
    hwnd, msg, wParam, lParam, milliseconds, gpos = message
    kind, button = win_message_map[msg]
    time = milliseconds / 1000.0
    if kind == 'mouse_move' and wParam & win_button_flags <> 0:
        kind = 'mouse_drag'
    if target:
        lpos = target.global_to_local(gpos)
    else:
        lpos = gpos
    event = Event()