簡體   English   中英

python win32api MOUSEEVENTF_MOVE 未按預期工作

[英]python win32api MOUSEEVENTF_MOVE not working as expected

這是代碼

# set mouse position to absolute position 674, 499
win32api.SetCursorPos((674, 499))
# add 100 to current x position which will be 674 + 100 = 774
# will not change y position it will be 499 
win32api.mouse_event(win32con.MOUSEEVENTF_MOVE, 100 ,0)
# print the position
print(f'The final position is {win32api.GetCursorPos()}')

我在循環中運行了一段時間的代碼,這是 output:

The final position is (864, 499)
The final position is (983, 499)
The final position is (984, 499)
The final position is (983, 499)
The final position is (984, 499)
The final position is (983, 499)
The final position is (983, 499)
The final position is (984, 499)
The final position is (983, 499)
The final position is (984, 499)
The final position is (983, 499)
The final position is (983, 499)
The final position is (984, 499)
The final position is (983, 499)
The final position is (984, 499)
The final position is (983, 499)
The final position is (864, 499)
The final position is (864, 499)
The final position is (882, 499)
The final position is (864, 499)
The final position is (984, 499)

在腳本運行中,我沒有移動鼠標(腳本運行期間我的手沒有握住鼠標)

在我的理解中,output 永遠是(774, 499),但它給了我一個毫無預兆的驚喜,是因為我對方法的理解錯誤還是與其他事情有關? 請幫忙。 謝謝你們。

[MS.Docs]:mouse_event function (winuser.h)其中指出:

注意此 function 已被取代。 請改用SendInput

還包含有關如何在備注部分傳遞這些值的詳細信息。

選項(相對於當前位置移動鼠標):

  1. 由於您已經在使用GetCursorPos / SetCursorPos ,您可以:

    • 獲取當前 position

    • 添加增量

    • 設置新 position

    從我所關心的情況來看,這是最有意義的

  2. 使用發送輸入 但是PyWin32沒有包裝它,所以你需要通過CTypes調用它,但這需要一些更深入的知識( CPython內部, ZA05B798442A1AF567F798BC01樣板代碼)和EBA01。 [SO]:如何使用 ctypes 將 SendInput function 包裝到 python就是這樣

  3. 使用其他第3方模塊。 使用[PyPI]: pynput ,您可以在幾行代碼中完成此操作。 可能PyWinAuto是另一個候選者

  4. 繼續向mouse_event方向挖掘(盡管我認為這毫無意義)

代碼00.py

#!/usr/bin/env python

import msvcrt
import random
import sys
import time

import win32con as wcon
import win32api as wapi
import win32gui as wgui


def transform_relative(val, tres0, tres1, acc, speed):
    ret = val
    val = abs(val)
    if val > tres0 and acc:
        ret *= 2
    if val > tres1 and acc == 2:
        ret *= 2
    return round(ret * speed / 10)


def set_pos_mouse_event(x, y, absolute_coordinates=True):
    flags = wcon.MOUSEEVENTF_MOVE
    if absolute_coordinates: 
        flags |= wcon.MOUSEEVENTF_ABSOLUTE
        normx = round(x * 0xFFFF / (wapi.GetSystemMetrics(wcon.SM_CXSCREEN) - 1))
        normy = round(y * 0xFFFF / (wapi.GetSystemMetrics(wcon.SM_CYSCREEN) - 1))
    else:  # @TODO - cfati: Not working yet!!!
        tres0, tres1, acc = wgui.SystemParametersInfo(wcon.SPI_GETMOUSE)
        speed = wgui.SystemParametersInfo(wcon.SPI_GETMOUSESPEED)
        #print(tres0, tres1, acc, speed)
        normx = transform_relative(x, tres0, tres1, acc, speed)
        normy = transform_relative(y, tres0, tres1, acc, speed)
    print(f"Move with: ({x}, {y}) ({normx}, {normy})")
    wapi.mouse_event(flags, normx, normy)


def set_pos_cursor_pos(x, y, absolute_coordinates=True):
    print(f"Move with: ({x}, {y})")
    if absolute_coordinates:
        wapi.SetCursorPos((x, y))
    else:
        curx, cury = wapi.GetCursorPos()
        wapi.SetCursorPos((curx + x, cury + y))


def main(*argv):
    maxx = wapi.GetSystemMetrics(wcon.SM_CXSCREEN) - 1
    maxy = wapi.GetSystemMetrics(wcon.SM_CYSCREEN) - 1
    #print(maxx, maxy)
    abs_coords = 0
    set_pos = set_pos_cursor_pos
    #set_pos = set_pos_mouse_event
    print(f"Using function: {set_pos.__name__}")
    print(f"Absolute coordinates: {'True' if abs_coords else 'False'}")
    print(f"Start position: {wapi.GetCursorPos()}")
    while not msvcrt.kbhit():
        print()
        #set_pos_mouse_event(100, 100, 1)
        #print(f"{wapi.GetCursorPos()}")
        x = random.randint(0, maxx)
        y = random.randint(0, maxy)
        if not abs_coords:
            curx, cury = wapi.GetCursorPos()
            x -= curx
            y -= cury
        set_pos(x, y, absolute_coordinates=abs_coords)
        print(f"Final position: {wapi.GetCursorPos()}")
        time.sleep(0.5)


if __name__ == "__main__":
    print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
                                                   64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    rc = main(*sys.argv[1:])
    print("\nDone.")
    sys.exit(rc)

備注

  • 我選擇了#1。 ( set_pos_cursor_pos )。 它工作正常

  • 我也嘗試了#4。 ( set_pos_mouse_event )

    • 我只能完成一半( MOUSEEVENTF_ABSOLUTE )。 我嘗試通過執行URL (在transform_relative中)中的步驟來完成另一半(您感興趣),但它不起作用
  • 我選擇概念清晰而不是常識(性能)。 一些API (例如GetSystemMetrics )是從多次執行的函數中調用的。 這是沒有意義的,對於生產代碼,它們應該只被調用一次(在開始時),並且返回的值作為 arguments 傳遞給需要它們的 function

Output (2 個有效的變體):

 [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q073428381]> "e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts\python.exe"./code00.py Python 3.9.9 (tags/v3.9.9:ccb0e6a, Nov 15 2021, 18:08:50) [MSC v.1929 64 bit (AMD64)] 064bit on win32 Using function: set_pos_cursor_pos Absolute coordinates: False Start position: (583, 610) Move with: (-461, 103) Final position: (122, 713) Move with: (44, -324) Final position: (166, 389) Move with: (1153, 418) Final position: (1319, 807) Move with: (390, 118) Final position: (1709, 925) Move with: (-860, 127) Final position: (849, 1052) Move with: (127, -202) Final position: (976, 850) Move with: (-84, -605) Final position: (892, 245) Move with: (86, 330) Final position: (978, 575) Move with: (-167, 170) Final position: (811, 745) Move with: (-63, -233) Final position: (748, 512) Done. [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q073428381]> "e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts\python.exe"./code00.py Python 3.9.9 (tags/v3.9.9:ccb0e6a, Nov 15 2021, 18:08:50) [MSC v.1929 64 bit (AMD64)] 064bit on win32 Using function: set_pos_mouse_event Absolute coordinates: True Start position: (748, 512) Move with: (1076, 803) (36746, 48772) Final position: (1076, 803) Move with: (1435, 572) (49006, 34741) Final position: (1435, 572) Move with: (197, 820) (6728, 49804) Final position: (197, 820) Move with: (1153, 522) (39376, 31705) Final position: (197, 820) Move with: (12, 29) (410, 1761) Final position: (12, 29) Move with: (150, 176) (5123, 10690) Final position: (150, 176) Move with: (882, 37) (30121, 2247) Final position: (882, 37) Move with: (582, 195) (19876, 11844) Final position: (582, 195) Move with: (1066, 810) (36405, 49197) Final position: (1066, 810) Move with: (1888, 487) (64476, 29579) Final position: (1888, 487) Done.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM