欢迎访问宙启技术站
智能推送

使用python中的shell32()函数实现系统鼠标和键盘的模拟

发布时间:2023-12-29 03:59:06

在Python中,可以使用ctypes模块来调用shell32库中的函数来模拟系统鼠标和键盘操作。以下是一个示例,展示如何使用ctypes模块来调用shell32库中的函数来模拟点击鼠标和输入键盘。

import ctypes
import time

# 定义常量
MOUSEEVENTF_MOVE = 0x0001  # 移动鼠标
MOUSEEVENTF_LEFTDOWN = 0x0002  # 鼠标左键按下
MOUSEEVENTF_LEFTUP = 0x0004  # 鼠标左键松开
MOUSEEVENTF_RIGHTDOWN = 0x0008  # 鼠标右键按下
MOUSEEVENTF_RIGHTUP = 0x0010  # 鼠标右键松开
MOUSEEVENTF_MIDDLEDOWN = 0x0020  # 鼠标中键按下
MOUSEEVENTF_MIDDLEUP = 0x0040  # 鼠标中键松开
MOUSEEVENTF_WHEEL = 0x0800  # 滚动鼠标
KEYEVENTF_KEYUP = 0x0002  # 键盘松开

# 定义结构体
class INPUT(ctypes.Structure):
    _fields_ = [
        ("type", ctypes.c_ulong),
        ("union", ctypes.POINTER(ctypes.c_ulong))
    ]

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

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

class MouseInput(ctypes.Structure):
    _fields_ = [
        ("dx", ctypes.c_long),
        ("dy", ctypes.c_long),
        ("mouseData", ctypes.c_ulong),
        ("dwFlags", ctypes.c_ulong),
        ("time", ctypes.c_ulong),
        ("dwExtraInfo", ctypes.POINTER(ctypes.c_ulong))
    ]

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

# 定义函数
def click_mouse(x, y):
    # 创建INPUT结构体的实例
    inp = INPUT()
    inp.type = ctypes.c_ulong(0)
    inp.union.mi.dx = ctypes.c_ulong(int(x * (65536 / ctypes.windll.user32.GetSystemMetrics(0)) + 1))
    inp.union.mi.dy = ctypes.c_ulong(int(y * (65536 / ctypes.windll.user32.GetSystemMetrics(1)) + 1))
    inp.union.mi.mouseData = ctypes.c_ulong(0)
    inp.union.mi.dwFlags = ctypes.c_ulong(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP)
    inp.union.mi.time = ctypes.c_ulong(0)
    inp.union.mi.dwExtraInfo = ctypes.POINTER(ctypes.c_ulong)(0)

    # 发送鼠标事件
    ctypes.windll.user32.SendInput(1, ctypes.pointer(inp), ctypes.sizeof(INPUT))

def press_key(key_code):
    # 创建INPUT结构体的实例
    inp = INPUT()
    inp.type = ctypes.c_ulong(1)
    inp.union.ki.wVk = ctypes.c_ushort(key_code)
    inp.union.ki.wScan = ctypes.c_ushort(0)
    inp.union.ki.dwFlags = ctypes.c_ulong(0)
    inp.union.ki.time = ctypes.c_ulong(0)
    inp.union.ki.dwExtraInfo = ctypes.POINTER(ctypes.c_ulong)(0)

    # 发送键盘事件
    ctypes.windll.user32.SendInput(1, ctypes.pointer(inp), ctypes.sizeof(INPUT))

def release_key(key_code):
    # 创建INPUT结构体的实例
    inp = INPUT()
    inp.type = ctypes.c_ulong(1)
    inp.union.ki.wVk = ctypes.c_ushort(key_code)
    inp.union.ki.wScan = ctypes.c_ushort(0)
    inp.union.ki.dwFlags = ctypes.c_ulong(KEYEVENTF_KEYUP)
    inp.union.ki.time = ctypes.c_ulong(0)
    inp.union.ki.dwExtraInfo = ctypes.POINTER(ctypes.c_ulong)(0)

    # 发送键盘松开事件
    ctypes.windll.user32.SendInput(1, ctypes.pointer(inp), ctypes.sizeof(INPUT))

# 示例:模拟点击鼠标和输入键盘
time.sleep(2)  # 等待2秒钟
click_mouse(500, 500)  # 在屏幕中央点击鼠标
time.sleep(1)  # 等待1秒钟
press_key(0x41)  # 按下"A"键
time.sleep(1)  # 等待1秒钟
release_key(0x41)  # 松开"A"键

上述代码首先导入了ctypes模块,并定义了一些常量和结构体,以及点击鼠标和键盘操作的函数。然后,通过调用ctypes模块中的windll.user32.SendInput函数来模拟点击鼠标和输入键盘。

在示例中,使用click_mouse函数模拟鼠标在屏幕中央点击的操作。然后等待1秒钟,使用press_key函数按下"A"键,并再次等待1秒钟,最后使用release_key函数松开"A"键。