Pywin32提供了很多访问windows的API。较重要的三个模块就是win32api、win32gui和win32con。通过这些API,我们可以获取windows窗口的相关信息,并可以简单操作这些窗口,由于windows各个版本的不同,有些获取方式会有些不同,甚至获取不到,还需要借助spy++这类的工具。
DC在pywin32中是一个重要概念。windows不允许程序直接访问硬件,所有的操作都需要通过一个设备上下文环境。屏幕上的每个窗口都对应一个DC。DC相当于一个视频缓冲区,对这个缓冲区的操作,会表现在这个缓冲区对应的屏幕窗口上。除了窗口对应的DC外,还可以自己创建DC,然后在创建的DC上面建立数据拷贝到窗口的DC上,就相当于刷新窗口的DC。
Pywin32安装
这个模块没有中文文档,有chm版的英文文档
pip install pywin32
github地址:https://github.com/mhammond/pywin32
常用方法介绍
1.win32gui.FindWindow(None, u"窗口的title")
根据窗口的标题去找这个窗口的句柄,句柄是唯一的,找到第一个符合的名字就结束,句柄之后我们就可以操作这个窗口了
2.win32gui.FindWindowEx(父句柄, None, 'Frame Notification Bar', None)
获取父句柄下第一个窗口类为Frame Notification Bar控件的句柄
3.win32gui.GetWindowText(句柄)
获取此窗口的标题
4.win32gui.GetWindowRect(句柄)
根据句柄获取窗口左上角和右下角坐标
5.win32gui.BringWindowToTop(句柄)
将这个窗口放置最前
6.win32gui.SetForegroundWindow(wnd)
将这个窗口激活并放至最前
7.win32api.keybd_event(VK_CODE, 0, win32con.KEYEVENTF_KEYUP, 0)
按键功能,这个VK_CODE就是windows对应的按键或字符的16进制代码,比如:
'enter': 0x0D, 'shift': 0x10, 'ctrl': 0x11, 'alt': 0x12,
win32con.KEYEVENTF_KEYUP是按下后抬起的动作,win32con.KEYEVENTF_KEYDOWN是按下的动作
8.win32api.GetCurrentProcessId()
获取当前的进程ID
9.win32api.GetCurrentThreadId()
获取当前的线程ID
10.win32gui.PostMessage(句柄, win32con.WM_CLOSE, 0, 0)
关闭此句柄的窗口
11.win32con.MOUSEEVENTF_LEFTDOWN 鼠标左键按下
win32con.MOUSEEVENTF_LEFTUP 鼠标左键抬起 win32con.MOUSEEVENTF_RIGHTDOWN 鼠标右键按下
win32con.MOUSEEVENTF_RIGHTUP 鼠标右键抬起
这个一般要和win32api.keybd_event搭配使用
12.win32gui.GetClassName(句柄)
获取句柄的类名
使用
ctrl+v操作
def press_ctrlv(*args):
for arg in args:
win32api.keybd_event(VK_CODE, 0, 0, 0)
time.sleep(.05)
for arg in args:
win32api.keybd_event(VK_CODE, 0, win32con.KEYEVENTF_KEYUP, 0)
time.sleep(.05)
点击操作
def click(句柄):
win32gui.PostMessage(句柄, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, 0)
win32gui.PostMessage(句柄, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, 0)
截图操作
import win32gui,win32ui,win32con
def get_windows(windowsname,filename):
# 获取窗口句柄
handle = win32gui.FindWindow(None,windowsname)
# 将窗口放在前台,并激活该窗口(窗口不能最小化)
win32gui.SetForegroundWindow(handle)
# 获取窗口DC
hdDC = win32gui.GetWindowDC(handle)
# 根据句柄创建一个DC
newhdDC = win32ui.CreateDCFromHandle(hdDC)
# 创建一个兼容设备内存的DC
saveDC = newhdDC.CreateCompatibleDC()
# 创建bitmap保存图片
saveBitmap = win32ui.CreateBitmap()
# 获取窗口的位置信息
left, top, right, bottom = win32gui.GetWindowRect(handle)
# 窗口长宽
width = right - left
height = bottom - top
# bitmap初始化
saveBitmap.CreateCompatibleBitmap(newhdDC, width, height)
saveDC.SelectObject(saveBitmap)
saveDC.BitBlt((0, 0), (width, height), newhdDC, (0, 0), win32con.SRCCOPY)
saveBitmap.SaveBitmapFile(saveDC, filename)
获取句柄
通过遍历所有窗口的句柄,然后找到自己想要的窗口句柄。
import win32gui
hwnd_title = dict()
def get_all_hwnd(hwnd, mouse):
if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
hwnd_title.update({hwnd: win32gui.GetWindowText(hwnd)})
win32gui.EnumWindows(get_all_hwnd, 0)
for h, t in hwnd_title.items():
if t is not "":
print(h, t)
打开文档输入helloworld并保存关闭
import time
import win32gui,win32con
import keyboardEmulation as ke
def get_windows(windowsname,filename):
# 获取窗口句柄
hwnd = win32gui.FindWindow(None,windowsname)
# 将窗口放在前台,并激活该窗口
win32gui.SetForegroundWindow(hwnd)
# helloworld每个字母对应的windows下的16进制code
scancodes = [0x23, 0x12, 0x26, 0x26, 0x18, 0x11, 0x18, 0x13, 0x26, 0x20, 0x2a]
for code in scancodes:
ke.key_press(code)
# 保存
ke.key_down(0x1d)
ke.key_down(0x1f)
ke.key_up(0x1d)
ke.key_up(0x1f)
# 关闭窗口
time.sleep(1);
win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)
本文链接:http://nix.pub/article/pywin32/