按键精灵 python加强版

本文介绍了使用Python实现按键精灵的过程,重点在于程序的功能实现,虽然代码组织较为混乱。此外,提到了配置文件在实际应用中的重要性。
摘要由CSDN通过智能技术生成

主体程序,主要是一些功能的实现,具体应用需要自己写。
写的比较乱

import win32gui, win32api, win32con, win32ui
import time
from time import sleep
import random
from random import uniform
import logging
from logging import info, warning, error
from config import VK_CODE
import copy
import cv2 as cv
import traceback

# mode为test意为调试模式,real则为实际应用
# In 'test' mode, it will print some hidden info for Debug
mode = 'test'

# 模式图的存储路径
# The save path of pattern pics
pattern_path = 'yourpath\\'

# 设置logging的书写格式
# Setting logging configs
logging.basicConfig(
    level=logging.DEBUG,
    format=
    '%(lineno)d : %(asctime)s : %(levelname)s : %(funcName)s : %(message)s',
    filename='yourpath\\log{}.txt'.format(
        time.strftime('-%Y-%m-%d')),
    filemode='w')

# 用当前时间初始化随机数
# Set random seed
random.seed(time.time())


def Get_PosAndHwnd(hwnd=0, ClassName=None, TitleName=None):
    '''接受句柄、类名、标题名,返回第一个匹配的窗口位置和句柄。
        Accepts Handle, ClassName or TitleName of a window, returns the rect-pos of the first window that matches.
        
        Args:
            hwnd: 目标句柄 target handle.
            ClassName: 目标窗口类名 target ClassName.
            TitleName: 目标窗口标题 target TitleName.
        
        Returns: x1, y1, x2, y2, hwnd
            前四个参数描述窗口在显示器中的位置,hwnd为句柄。
            x1-y2 describes the pos of the window in screen, last arg is the handle.
    '''
    try:
        if hwnd == 0:
            hwnd = win32gui.FindWindow(ClassName, TitleName)
        x1, y1, x2, y2 = win32gui.GetWindowRect(hwnd)
        info('找到窗口,句柄:{},标题名:{},类名:{},坐标:{}'.format(
            hwnd, win32gui.GetWindowText(hwnd), win32gui.GetClassName(hwnd),
            (x1, y1, x2, y2)))
        return x1, y1, x2, y2, hwnd
    except:
        global mode
        if mode == 'test':
            traceback.print_exc()
        elif mode == 'real':
            error('Get_PosAndHwnd 出现错误')


def Activate_Hwnd(hwnd):
    '''激活指定句柄的窗口。每次转换时使用。
        Activates the window with the matching hwnd.

        Args:
            hwnd: 目标句柄 target handle.
        
        Returns:
            No return.
    '''
    try:
        win32gui.SendMessage(hwnd, win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)
        # WA_CLICKACTIVE为通过鼠标激活,WA_ACTIVE为鼠标以外的东西(如键盘)激活,WA_INACTIVE为取消激活
        # WA_CLICKACTIVE means activate by mouse, WA_ACTIVE means other equipments( like keyboard).WA_INACTIVE means inactivate it.
        info('激活句柄为 {} 标题为 {} 的窗口'.format(hwnd, win32gui.GetWindowText(hwnd)))
    except:
        global mode
        if mode == 'test':
            traceback.print_exc()
        elif mode == 'real':
            error('激活窗口 出现错误')


def LeftClick(hwnd, x1, y1, times='first', platform='PC'):
    '''左键单击(自带延时) Left Click the window (located by hwnd) once (with human-like delay). 

        Args:
            hwnd: 目标窗口的句柄 target hwnd. 
            x1, y1: 需要点击的坐标 target pos. 
            times: 'first'表示从其他窗口转过来点击,用于调用Activate_Hwnd(hwnd)。
                If 'first', means target window is inactive/unfocused, thus call Activate_Hwnd(hwnd). 
            platform: 目前无用。'PC'表示当前操作的是桌面版,不是安卓模拟器('AM')。
                Useless now. 'PC' means target window is PC, not Android manipulator ('AM').

        Returns:
            No return.
    '''
    try:
        if platform == 'PC':  # 对于桌面版 # for PC
            tmp_pos = win32api.MAKELONG(x1, y1)
        #elif flag == 'AM': # 对于模拟器 # for Android manipulator
        #click_pos = win32gui.ScreenToClient(hwnd, (x1, y1))
        # 注意坐标是整个窗口还是客户区的,用ScreenToClient转换 # switch between screen/client pos
        #tmp_pos = win32api.MAKELONG(click_pos[0], click_pos[1])
        if times == 'first':
            Activate_Hwnd(hwnd)
        win32gui.SendMessage(hwnd, win32con.WM_LBUTTONDOWN,
                             win32con.MK_LBUTTON, tmp_pos)
        # 鼠标点击格式为SendMessage(hWnd,WM_LBUTTONDOWN,fwKeys,MAKELONG(xPos,yPos));
        # fwKeys可以取:MK_CONTROL、MK_LBUTTON、MK_MBUTTON、MK_RBUTTON、MK_SHIFT等,多个值用|隔开
        sleep(uniform(0.05, 0.08))
        win32gui.SendMessage(hwnd, win32con.WM_LBUTTONUP, 0000, tmp_pos)
        # 抬起时有些电脑上fwKeys显示为0000,有些可能为MK_LBUTTON
        # Use spy++ for details
        sleep(uniform(0.07, 0.095))
        info('对句柄 {} 标题 {} 的坐标 {} 进行 左键单击 动作'.format(
            hwnd, win32gui.GetWindowText(hwnd), (x1, y1)))
    except:
        global mode
        if mode == 'test':
            traceback.print_exc()
        elif mode == 'real':
            error('左键单击 出现错误')


def LeftClick_sequence(hwnd, points, times='second', platform='PC'):
    '''左键依序单击(依次点击多个点) Click a sequence of points in order.

        Args: 
            hwnd: 目标窗口的句柄 target hwnd. 
            points: 需要点击的坐标 target points in the form like ((x1,y1),(x2,y2)...). 
            times: 'first'表示从其他窗口转过来点击,用于调用Activate_Hwnd(hwnd)。
                If 'first', means target window is inactive/unfocused, thus call Activate_Hwnd(hwnd). 
            platform: 目前无用。'PC'表示当前操作的是桌面版,不是安卓模拟器('AM')。
                Useless now. 'PC' means target window is PC, not Android manipulator ('AM').
        
        Returns:
            No return.
    '''
    try:
        if times == 'first':
            Activate_Hwnd(hwnd)
        for point in points:
            LeftClick(hwnd, point[0], point[1], 'second', platform)
        info('对句柄 {} 标题 {} 的坐标 {} 进行 左键依序单击 动作'.format(
            hwnd, win32gui.GetWindowText(hwnd), points))
    except:
        global mode
        if mode == 'test':
            traceback.print_exc()
        elif mode == 'real':
            error('左键单击 出现错误')


def LeftDoubleClick(hwnd, x1, y1, times='first', platform='PC'):
    '''左键同一位置双击 Click the same pos twice.

        Args:
            hwnd: 目标窗口的句柄 target hwnd. 
            x1, y1: 需要点击的坐标 target pos. 
            times: 'first'表示从其他窗口转过来点击,用于调用Activate_Hwnd(hwnd)。
                If 'first', means target window is inactive/unfocused, thus call Activate_Hwnd(hwnd). 
            platform: 目前无用。'PC'表示当前操作的是桌面版,不是安卓模拟器('AM')。
                Useless now. 'PC' means target window is PC, not Android manipulator ('AM').

        Returns:
            No return.
    '''
    try:
        if times == 'first':
            Activate_Hwnd(hwnd)
        info('左键同一位置双击--第一次点击')
        LeftClick(hwnd, x1, y1, 'second', platform)
        info('左键同一位置双击--第二次点击')
        LeftClick(hwnd, x1, y1, 'second', platform)
    except:
        global mode
        if mode == 'test':
            traceback.print_exc()
        elif mode == 'real':
            error('左键同一位置双击 出现错误')


def LeftDifDoubleClick_Rect(hwnd,
                            x1,
                            y1,
                            times='first',
                            platform='PC',
                            delta=(0, 4)):
    '''左键不同位置双击,范围为双正方形 Left click 2 pos, in a double-square-like area.
        _________
        |  ___  |
        | |   | |
        | |___| |
        |_______|
        (x1, y1) is at the center, (x2, y2) between the squares (borders included).

        Args:
            hwnd: 目标窗口的句柄 target hwnd. 
            x1, y1: 第一次点击的坐标 first pos to click. 
            times: 'first'表示从其他窗口转过来点击,用于调用Activate_Hwnd(hwnd)。
                If 'first', means target window is inactive/unfocused, thus call Activate_Hwnd(hwnd). 
            platform: 目前无用。'PC'表示当前操作的是桌面版,不是安卓模拟器('AM')。
                Useless now. 'PC' means target window is PC, not Android manipulator ('AM').
            delta: 第二个点的横坐标在x1+delta[0] 到 x1+delta[1]间(包括端点),纵坐标同样。
                x2 varies between x1+delta[0] to x1+delta[1], y2 the same (both ends included). 

        Returns:
            No return.
    '''
    try:
        if times == 'first':
            Activate_Hwnd(hwnd)
        info('左键正方形双击--第一次点击')
        LeftClick(hwnd, x1, y1, 'second', platform)
        point_list = []
        for delta_x in range(delta[0], delta[1] + 1):
            for delta_y in range(delta[0], delta[1] + 1):
                point_list.append((x1 + delta_x, y1 + delta_y))
                point_list.append((x1 + delta_x, y1 - delta_y))
                point_list.append((x1 - delta_x, y1 + delta_y))
                point_list.append((x1 - delta_x, y1 - delta_y))
        point_list = list(
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值