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/