实现了一个window下对窗体操作的类,实现的功能如:移动窗体、获取窗体位置和大小、截取窗体图片、坐标转换等。

直接上代码:

# coding=utf-8
import win32con
import win32api
import win32gui
import win32ui
from ctypes import *
from ctypes import wintypes GetForegroundWindow = windll.user32.GetForegroundWindow
GetWindowRect = windll.user32.GetWindowRect
SetForegroundWindow = windll.user32.SetForegroundWindow
GetWindowText = windll.user32.GetWindowTextA
MoveWindow = windll.user32.MoveWindow
EnumWindows = windll.user32.EnumWindows class RECT(Structure):
_fields_ = [
('left', c_long),
('top', c_long),
('right', c_long),
('bottom', c_long)
] class POINT(Structure):
_fields_ = [
('x', c_long),
('y', c_long),
] class FormControl(object):
def __init__(self):
self.win_hd = None
self.win_title = '' def bindActiveWindow(self):
"""
函数功能:获取当前焦点所在窗口
"""
self.win_hd = GetForegroundWindow() def bindWindowByName(self, win_name):
"""
函数功能:根据窗体名获取窗体句柄
"""
self.win_title = win_name
pro_fun_type = CFUNCTYPE(c_bool, c_int, c_long)
pro_fun_p = pro_fun_type(self.EnumWindowsProc)
EnumWindows(pro_fun_p, None) def getWinRect(self):
"""
函数功能:获取窗体的位置和大小
"""
if self.win_hd is None:
return None
rect=RECT()
GetWindowRect(self.win_hd,byref(rect))
return rect def toScreenPos(self, x,y):
"""
函数功能:将窗体内部坐标转换为相对于显示屏的绝对坐标
"""
#未指定窗口,则结束函数
if self.win_hd is None:
return None
rect=self.getWinRect()
#指定的坐标不在窗体内,则结束函数
if x < 0 or y < 0 or x > rect.right or y > rect.bottom:
return None
pos = POINT()
pos.x = x + rect.left
pos.y = y + rect.top
return pos def toWindowPos(self,x,y):
"""
函数功能:将绝对坐标转换成相对于窗体内部坐标
"""
if self.win_hd is None:
return None
rect = self.getWinRect()
pos = POINT()
pos.x = x - rect.left
pos.y = y - rect.top
# 指定的坐标不在窗体内,则结束函数
if pos.x < 0 or pos.y < 0 or pos.x > rect.right or pos.y > rect.bottom:
return None
return pos def WindowActive(self):
"""
函数功能:将窗体置前
"""
if self.win_hd is None:
return None
SetForegroundWindow(self.win_hd) def getHWND(self):
return self.win_hd def getWinTitle(self):
"""
函数功能:获取窗体的标题
"""
if self.win_hd is None:
return None
buffer = create_string_buffer(255,'\0')
GetWindowText(self.win_hd,buffer,255)
value=buffer.value.decode('gbk')
return value def MoveTo(self,x,y):
"""
函数功能:移动窗体到指定坐标位置
"""
if self.win_hd is None:
return None
rect = self.getWinRect()
MoveWindow(self.win_hd,x,y,rect.right-rect.left,rect.bottom-rect.top,True) def WinCapture(self,path,x,y,w,h):
"""
函数功能:抓取窗体截图,并保存到文件
参 数:path 保存路径
x 截取起始x坐标(窗体内相对坐标)
y 截取起始y坐标(窗体内相对坐标)
w 截取宽度,为0则取窗体宽度
h 截取长度,为0则取窗体高度
"""
if self.win_hd is None:
return None
rect = self.getWinRect()
if w == 0:
w = rect.right - rect.left
if h == 0:
h = rect.bottom - rect.top
if x < 0 or y < 0 or (x+w) > rect.right or (y+h) > rect.bottom:
return None
self.Capture(self.win_hd,path,x,y,w,h,0) def WinCapture_Mem(self,x,y,w,h):
"""
函数功能:抓取窗体截图,并返回图像内存数据
参 数:
x 截取起始x坐标(窗体内相对坐标)
y 截取起始y坐标(窗体内相对坐标)
w 截取宽度,为0则取窗体宽度
h 截取长度,为0则取窗体高度
"""
if self.win_hd is None:
return None
rect = self.getWinRect()
if w == 0:
w = rect.right - rect.left
if h == 0:
h = rect.bottom - rect.top
if x < 0 or y < 0 or (x+w) > rect.right or (y+h) > rect.bottom:
return None
return self.Capture(self.win_hd,'',x,y,w,h,1) def Capture(self, hd, path, x, y, w, h, mode):
"""
函数功能:截图
参 数:hd 截取的窗口句柄
path 保存路径
x 截取起始x坐标(窗体内相对坐标)
y 截取起始y坐标(窗体内相对坐标)
w 截取宽度,为0则取窗体宽度
h 截取长度,为0则取窗体高度
mode 保存模式 0:保存为图片,1:返回图像字节数据
"""
# 根据窗口句柄获取窗口的设备上下文
hwndDC = win32gui.GetWindowDC(self.win_hd)
# 根据窗口的DC获取memDC
srcdc = win32ui.CreateDCFromHandle(hwndDC)
# memDC创建可兼容的DC
saveDC = srcdc.CreateCompatibleDC()
# 创建bigmap准备保存图片
saveBitMap = win32ui.CreateBitmap()
# 为bitmap开辟空间
saveBitMap.CreateCompatibleBitmap(srcdc, w, h)
# 高度saveDC,将截图保存到saveBitmap中
saveDC.SelectObject(saveBitMap)
# 截取从左上角(0,0)长宽为(w,h)的图片
saveDC.BitBlt((0, 0), (w, h), srcdc, (x, y), win32con.SRCCOPY)
if mode == 0:
saveBitMap.SaveBitmapFile(saveDC, path)
else:
signedIntsArray = saveBitMap.GetBitmapBits(True)
return signedIntsArray
# 释放内存
srcdc.DeleteDC()
saveDC.DeleteDC()
win32gui.ReleaseDC(self.win_hd,hwndDC)
win32gui.DeleteObject(saveBitMap.GetHandle()) def EnumWindowsProc(self,hwnd, lParam):
buffer = create_string_buffer(255,'\0')
GetWindowText(hwnd,buffer,255)
value=buffer.value.decode('gbk')
if value == self.win_title:
self.win_hd = hwnd
print(self.win_hd)
return False
return True

测试代码:

import FormApi
import time if __name__== '__main__':
time.sleep(2)
form=FormApi.FormControl()
form.bindActiveWindow()
rect=form.getWinRect()
print("坐标:(x:%d,y:%d),大小:(width:%d,height:%d)" % (rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top))
time.sleep(2)
form.WinCapture(r'c:\1.bmp',0,0,200,200)

Python窗体操作函数的更多相关文章

  1. Python文件操作函数os.open、io.open、内置函数open之间的关系

    Python提供了多种文件操作方式,这里简单介绍os.open.io.open.内置函数open之间的关系: 一.内置函数open和io.open实际上是同一个函数,后者是前者的别名: 二.os.op ...

  2. Python基础操作-函数

    本节内容 1. 函数基本语法及特性2. 参数与局部变量3. 返回值4.递归5.高阶函数 1.函数基本语法及特性函数是什么? 函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,具 ...

  3. Python 文件操作函数

    这个博客是 Building powerful image classification models using very little data 的前期准备,用于把图片数据按照教程指示放到规定的文 ...

  4. python——列表操作函数和方法

    1.添加新元素 1.1 append()函数 描述:append() 方法用于在列表末尾添加新的对象. 语法:list.append(obj) 参数:obj -- 添加到列表末尾的对象. 返回值:该方 ...

  5. Python 字符串操作函数一

    #-*- coding:utf-8 -*- strword = "i will fly with you , fly on the sky ." #find print(strwo ...

  6. python——字符串操作函数

    字符串 join() map() split() rsplit() splitlines() partiton() rpartition() upper() lower() swapcase() ca ...

  7. Python 字符串操作函数二

    #-*- coding:utf-8 -*- line = "l want watch movie with you ." print(line.center(50)) print( ...

  8. Python文件操作与函数目录

    文件操作 python文件操作 函数 Python函数学习——初步认识 Python函数学习——作用域与嵌套函数 Python函数学习——匿名函数 python内置函数 Python函数学习——递归 ...

  9. python 集合、函数和文件操作

    1.set集合 set集合是一个无序.不可重复.可嵌套的序列,基本功能是进行成员关系测试和删除重复元素,可以使用大括号({})或者 set()函数创建集合,注意:创建一个空集合必须用 set() 而不 ...

随机推荐

  1. Docker网络配置、Docker部署分布式项目

    目标 1.Docker网络配置 2.Docker部署SpringCloud项目 Docker网络配置 Docker网络模式介绍 Docker在创建容器时有四种网络模式:bridge/host/cont ...

  2. final和static语句

    final关键字 final的概念 关键字final,final的意思为最终,不可变.final是个修饰符,它可以用来修饰类,类的成员,以及局部变量.不能修饰构造方法. final的特点 当final ...

  3. vim文本编辑器——删除、复制、剪切、更改某一个字符、替换、撤销、关键字搜索

    1.删除: (1)删除光标所在处的字符: 如上图所示:点击一次x键只能删除一个字符. (2)删除光标所在处后的n个字符(nx): 删除前: 输入6x: (3)删除光标所在的行(dd): 删除前: 输入 ...

  4. 如何把Eclipse项目迁移到AndroidStudio(如何把项目导入安卓)--这我很困惑

    学习android对我来说,就是兴趣,所以我以自己的兴趣写出的文章,希望各位多多支持!多多点赞,评论讨论加关注. 大佬必备功能. 把Eclipse项目迁移到AndroidStudio 现在就叫你如何把 ...

  5. MYSQL避免重复插入记录的三种方法

      方案一:使用ignore关键字 如果是用主键primary或者唯一索引unique区分了记录的唯一性,避免重复插入记录可以使用: insert ignore into table_name(ema ...

  6. 区间DP复习

    区间DP复习 (难度排序:(A,B),(F,G,E,D,H,I,K),(C),(J,L)) 这是一个基本全在bzoj上的复习专题 没有什么可以说的,都是一些基本的dp思想 A [BZOJ1996] [ ...

  7. ubuntu笔记2-误删dpkg的/var/lib/dpkg/info文件夹

    由于误删了dpkg的/var/lib/dpkg/info文件夹,导致安装文件的时候报错 错误提示:E: Sub-process /usr/bin/dpkg returned an error code ...

  8. 如何保证MQ的顺序性?比如Kafka

    三.如何保证消息的顺序性 1. rabbitmq 拆分多个queue,每个queue一个consumer,就是多一些queue而已,确实是麻烦点:或者就一个queue但是对应一个consumer,然后 ...

  9. c++字符串输入格式总结

    最近的几次笔试中,常常遇到一些输入的问题.下面说明一下几种情况. 1. 第一种就是常见的,输入数字序列,用空格分隔开,直到回车结束.这个之前一开始遇到的时候都是利用getline直接作为字符读入一行处 ...

  10. 转录因子 | transcription factor | 从入门到精通

    研究可以做得很浅,查查genecard数据库,从数据库里找找motif,用工具跑跑target gene,构建一下基因调控网络GRN. 研究也可以做得很深,了解一个物种里面有哪些transcripti ...