微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

脚本知道用户何时点击鼠标导致死锁

如何解决脚本知道用户何时点击鼠标导致死锁

我正在尝试编写一个脚本,该脚本会在用户单击鼠标后调整游戏中的视图,并在释放鼠标后停止调整。为了启用/禁用我的脚本,我使用了 keyboard.Listener 中的 pynput。要知道用户何时单击鼠标,我尝试使用 mouse.Listener,但它给我带来了一些问题,所以我切换到 pyWinhook.Hookmanager,我可以使用键绑定来挂钩/取消挂钩。

def left_down(event):
    move(10,-10,10,0.15)
    return True

hm = pyWinhook.HookManager() 
hm.SubscribeMouseLeftDown(left_down)

def on_key_press(key):

    if (key==keyboard.Key.f8):
        try:
            global hm
            hm.HookMouse()
        except MyException as e:
            print('Exception: '.format(e.args[0]))

    elif (key==keyboard.Key.f9):
        hm.UnhookMouse()
        
    elif (key==keyboard.Key.f10):
        hm.UnhookMouse() 
        key_listener.stop()                  


with keyboard.Listener(on_press=on_key_press) as key_listener:
    key_listener.join() 
  

一切正常,直到我尝试使用模拟游戏中鼠标移动的代码来实现它。据我了解,钩子管理器在调用使用 win32api

工作的移动函数时会产生死锁
PUL = ctypes.POINTER(ctypes.c_ulong)


class KeyBdInput(ctypes.Structure):
    _fields_ = [("wVk",ctypes.c_ushort),("wScan",("dwFlags",ctypes.c_ulong),("time",("dwExtraInfo",PUL)]


class HardwareInput(ctypes.Structure):
    _fields_ = [("uMsg",("wParamL",ctypes.c_short),("wParamH",ctypes.c_ushort)]


class MouseInput(ctypes.Structure):
    _fields_ = [("dx",ctypes.c_long),("dy",("mouseData",PUL)]

class Input_I(ctypes.Union):
    _fields_ = [("ki",KeyBdInput),("mi",MouseInput),("hi",HardwareInput)]

class Input(ctypes.Structure):
    _fields_ = [("type",("ii",Input_I)]


def move(steps,x=None,y=None,duration=0.25,vertical=False):
    x = int(x)
    y = int(y)

    coordinates = _interpolate_mouse_movement(
        start_windows_coordinates=(0,0),end_windows_coordinates=(x,y)
    )

    
    for x,y in coordinates:
        if (vertical):
            x = 0
        extra = ctypes.c_ulong(0)
        ii_ = Input_I()
        ii_.mi = MouseInput(x,y,0x0001,ctypes.pointer(extra))
        x = Input(ctypes.c_ulong(0),ii_)
        ctypes.windll.user32.sendinput(1,ctypes.pointer(x),ctypes.sizeof(x))

        time.sleep(duration / len(coordinates))


def _to_windows_coordinates(x=0,y=0):
    display_width = win32api.GetSystemMetrics(0)
    display_height = win32api.GetSystemMetrics(1)

    windows_x = (x * 65535) // display_width
    windows_y = (y * 65535) // display_height

    return windows_x,windows_y
    
def _interpolate_mouse_movement(start_windows_coordinates,end_windows_coordinates,steps=10):
    x_coordinates = [start_windows_coordinates[0],end_windows_coordinates[0]]
    y_coordinates = [start_windows_coordinates[1],end_windows_coordinates[1]]

    if x_coordinates[0] == x_coordinates[1]:
        x_coordinates[1] += 1

    if y_coordinates[0] == y_coordinates[1]:
        y_coordinates[1] += 1

    interpolation_func = scipy.interpolate.interp1d(x_coordinates,y_coordinates)    
    intermediate_x_coordinates = np.linspace(start_windows_coordinates[0],end_windows_coordinates[0],steps + 1)[1:]
    
    coordinates = list(map(lambda x: (int(round(x)),int(interpolation_func(x))),intermediate_x_coordinates))
    
    return coordinates

一个问题是,我不知道如何创建一个功能,如果只在按下鼠标时应用给定的一系列移动,当鼠标松开时,整个周期应该重置。

能否请您帮我解决这些问题,或者根据整个想法提供不同的方法

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。