主体程序,主要是一些功能的实现,具体应用需要自己写。
写的比较乱
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(