吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 903|回复: 49
上一主题 下一主题
收起左侧

[Python 原创] 使用python实现程序最小化截图

  [复制链接]
跳转到指定楼层
楼主
18834161486 发表于 2024-11-13 21:34 回帖奖励
简单介绍一下这个功能,像程序最小化之后,用鼠标移动到下面的图表会出现一个缩略图,就是通过这样方式来实现最小化截图。但是测试后发现最小化后缩略图不会发生变化,所以有点鸡肋。
然后放到后台测试了一下延迟,发现还是蛮快的,所以就发出来供大家参考学习,开发出更多用法。

[Python] 纯文本查看 复制代码
import ctypesimport time
import win32api
import win32con
import win32gui
from ctypes import wintypes

# Windows API 常量
DWM_TNP_RECTDESTINATION = 0x00000001
DWM_TNP_VISIBLE = 0x00000008
DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010


# 定义 RECT 结构体
class RECT(ctypes.Structure):
    _fields_ = [("left", wintypes.LONG),
                ("top", wintypes.LONG),
                ("right", wintypes.LONG),
                ("bottom", wintypes.LONG)]


# DWM_THUMBNAIL_PROPERTIES 结构体
class DWM_THUMBNAIL_PROPERTIES(ctypes.Structure):
    _fields_ = [("dwFlags", wintypes.DWORD),
                ("rcDestination", RECT),
                ("fVisible", wintypes.BOOL),
                ("fSourceClientAreaOnly", wintypes.BOOL),
                ("opacity", wintypes.UINT)]


# 定义 HRESULT 类型
HRESULT = ctypes.c_int

# DWM API 函数声明
DWM_API = ctypes.windll.dwmapi

# DwmRegisterThumbnail 函数声明
DWM_API.DwmRegisterThumbnail.argtypes = [wintypes.HWND, wintypes.HWND, ctypes.POINTER(wintypes.HANDLE)]
DWM_API.DwmRegisterThumbnail.restype = HRESULT  # 使用 c_int 来表示 HRESULT

# DwmUpdateThumbnailProperties 函数声明
DWM_API.DwmUpdateThumbnailProperties.argtypes = [wintypes.HANDLE, ctypes.POINTER(DWM_THUMBNAIL_PROPERTIES)]
DWM_API.DwmUpdateThumbnailProperties.restype = HRESULT


# 定义窗口回调函数
def wnd_proc(hwnd, msg, w_param, l_param):
    if msg == win32con.WM_CLOSE:
        win32gui.DestroyWindow(hwnd)
        # DWM_API.DwmUnregisterThumbnail(hwnd)
    return win32gui.DefWindowProc(hwnd, msg, w_param, l_param)


# 创建窗口函数
def create_window(window_title, w, h):
    wc = win32gui.WNDCLASS()
    wc.lpfnWndProc = wnd_proc
    wc.lpszClassName = window_title
    wc.hInstance = win32api.GetModuleHandle(None)
    class_atom = win32gui.RegisterClass(wc)

    hwnd = win32gui.CreateWindow(
        class_atom,  # 窗口类的标识符
        window_title,  # 窗口标题
        win32con.WS_OVERLAPPEDWINDOW,  # 窗口样式
        0, 0,  # 窗口位置
        w + 50, h + 50,  # 窗口大小
        0,  # 父窗口句柄
        0,  # 菜单句柄
        wc.hInstance,  # 实例句柄
        None  # 额外的参数
    )

    return hwnd


def mapping_window(target_hwnd, source_hwnd, draw_position):
    thumbnail = wintypes.HANDLE()

    # 注册缩略图
    result = DWM_API.DwmRegisterThumbnail(target_hwnd, source_hwnd, ctypes.byref(thumbnail))
    if result != 0:  # 如果 DwmRegisterThumbnail 返回非 0,表示失败
        print("未获取到缩略图")
        return

    # 设置缩略图属性
    thumb_props = DWM_THUMBNAIL_PROPERTIES()
    thumb_props.dwFlags = DWM_TNP_RECTDESTINATION
    thumb_props.rcDestination = draw_position
    thumb_props.fVisible = True
    thumb_props.fSourceClientAreaOnly = False
    thumb_props.opacity = (255 * 70) // 100  # 设置透明度为 70%

    # 更新缩略图属性
    DWM_API.DwmUpdateThumbnailProperties(thumbnail, ctypes.byref(thumb_props))

    print("缩略图已映射到目标窗口")


def get_window_normal_size(hwnd):
    # 获取窗口的位置信息和状态
    placement = win32gui.GetWindowPlacement(hwnd)
    print(placement)

    # 获取窗口正常状态下的尺寸
    rect = placement[4]  # rcNormalPosition: (left, top, right, bottom)

    # 计算宽度和高度
    width = rect[2] - rect[0]
    height = rect[3] - rect[1]

    return width, height


# 获取源窗口的句柄
source_hwnd = 198072  # 这里填写需要截图的窗口的句柄
width, height = get_window_normal_size(source_hwnd)
print(width, height)

# 创建目标窗口
target_window_title = "Target Window"  # 目标窗口的标题
target_hwnd = create_window(target_window_title, width, height)

# 显示目标窗口
win32gui.ShowWindow(target_hwnd, win32con.SW_SHOWNORMAL)
win32gui.UpdateWindow(target_hwnd)

# 定义绘制位置(你可以根据需要调整)
draw_position = RECT()
draw_position.left = 0
draw_position.top = 0
draw_position.right = draw_position.left + width
draw_position.bottom = draw_position.top + height

# 调用映射窗口函数
mapping_window(target_hwnd, source_hwnd, draw_position)

# 运行消息循环以保持窗口显示
while True:
    win32gui.PumpMessages()
    time.sleep(0.1)

免费评分

参与人数 5吾爱币 +3 热心值 +4 收起 理由
fkdzk + 1 我很赞同!
limuziz + 1 + 1 太牛了
hehehero + 1 谢谢@Thanks!
Elowen1127 + 1 谢谢@Thanks!
laozhang4201 + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
52zct 发表于 2024-11-14 09:33
本帖最后由 52zct 于 2024-11-14 09:40 编辑
52zct 发表于 2024-11-14 09:11
测试了一下,像是实时投屏

[Python] 纯文本查看 复制代码
import ctypes
[/quote]


[mw_shl_code=python,true]
import win32gui

def enum_windows_callback(hwnd, windows):
    if win32gui.IsWindowVisible(hwnd):
        windows.append((hwnd, win32gui.GetWindowText(hwnd)))

def get_all_window_titles():
    windows = []
    win32gui.EnumWindows(enum_windows_callback, windows)
    return windows

def write_window_info_to_file(windows, filename="窗口信息.txt"):
    with open(filename, 'w', encoding='utf-8') as file:
        for hwnd, title in windows:
            file.write(f"HWND: {hwnd}, Title: {title}\n")

def main():
    # 获取所有窗口的标题
    all_windows = get_all_window_titles()

    # 定义文件名
    filename = "窗口信息.txt"

    # 将窗口信息写入文件
    write_window_info_to_file(all_windows, filename)

    # 打印消息
    print(f"窗口信息已写入到 {filename}")

if __name__ == "__main__":
    main()


上面是检测窗口的代码
下面这个是读取config.ini进行窗口映射的代码
[Python] 纯文本查看 复制代码
import ctypes
import time
import win32api
import win32con
import win32gui
from ctypes import wintypes

# Windows API 常量
DWM_TNP_RECTDESTINATION = 0x00000001
DWM_TNP_VISIBLE = 0x00000008
DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010

# 定义 RECT 结构体
class RECT(ctypes.Structure):
    _fields_ = [("left", wintypes.LONG),
                ("top", wintypes.LONG),
                ("right", wintypes.LONG),
                ("bottom", wintypes.LONG)]

# DWM_THUMBNAIL_PROPERTIES 结构体
class DWM_THUMBNAIL_PROPERTIES(ctypes.Structure):
    _fields_ = [("dwFlags", wintypes.DWORD),
                ("rcDestination", RECT),
                ("fVisible", wintypes.BOOL),
                ("fSourceClientAreaOnly", wintypes.BOOL),
                ("opacity", wintypes.UINT)]

# 定义 HRESULT 类型
HRESULT = ctypes.c_int

# DWM API 函数声明
DWM_API = ctypes.windll.dwmapi

# DwmRegisterThumbnail 函数声明
DWM_API.DwmRegisterThumbnail.argtypes = [wintypes.HWND, wintypes.HWND, ctypes.POINTER(wintypes.HANDLE)]
DWM_API.DwmRegisterThumbnail.restype = HRESULT  # 使用 c_int 来表示 HRESULT

# DwmUpdateThumbnailProperties 函数声明
DWM_API.DwmUpdateThumbnailProperties.argtypes = [wintypes.HANDLE, ctypes.POINTER(DWM_THUMBNAIL_PROPERTIES)]
DWM_API.DwmUpdateThumbnailProperties.restype = HRESULT

# 定义窗口回调函数
def wnd_proc(hwnd, msg, w_param, l_param):
    if msg == win32con.WM_CLOSE:
        win32gui.DestroyWindow(hwnd)
        # DWM_API.DwmUnregisterThumbnail(hwnd)
    return win32gui.DefWindowProc(hwnd, msg, w_param, l_param)

# 创建窗口函数
def create_window(window_title, w, h):
    wc = win32gui.WNDCLASS()
    wc.lpfnWndProc = wnd_proc
    wc.lpszClassName = window_title
    wc.hInstance = win32api.GetModuleHandle(None)
    class_atom = win32gui.RegisterClass(wc)

    hwnd = win32gui.CreateWindow(
        class_atom,  # 窗口类的标识符
        window_title,  # 窗口标题
        win32con.WS_OVERLAPPEDWINDOW,  # 窗口样式
        0, 0,  # 窗口位置
        w + 50, h + 50,  # 窗口大小
        0,  # 父窗口句柄
        0,  # 菜单句柄
        wc.hInstance,  # 实例句柄
        None  # 额外的参数
    )

    return hwnd

def mapping_window(target_hwnd, source_hwnd, draw_position):
    thumbnail = wintypes.HANDLE()

    # 注册缩略图
    result = DWM_API.DwmRegisterThumbnail(target_hwnd, source_hwnd, ctypes.byref(thumbnail))
    if result != 0:  # 如果 DwmRegisterThumbnail 返回非 0,表示失败
        print("未获取到缩略图")
        return

    # 设置缩略图属性
    thumb_props = DWM_THUMBNAIL_PROPERTIES()
    thumb_props.dwFlags = DWM_TNP_RECTDESTINATION
    thumb_props.rcDestination = draw_position
    thumb_props.fVisible = True
    thumb_props.fSourceClientAreaOnly = False
    thumb_props.opacity = (255 * 70) // 100  # 设置透明度为 70%

    # 更新缩略图属性
    DWM_API.DwmUpdateThumbnailProperties(thumbnail, ctypes.byref(thumb_props))

    print("缩略图已映射到目标窗口")

def get_window_normal_size(hwnd):
    if not win32gui.IsWindow(hwnd):
        print("窗口已关闭或不存在")
        return None, None

    # 获取窗口的位置信息和状态
    placement = win32gui.GetWindowPlacement(hwnd)
    print(f"Placement: {placement}")

    # 获取窗口正常状态下的尺寸
    rect = placement[4]  # rcNormalPosition: (left, top, right, bottom)

    # 计算宽度和高度
    width = rect[2] - rect[0]
    height = rect[3] - rect[1]

    return width, height

# 从 config.txt 文件中读取窗口标题
def read_config():
    try:
        with open('config.ini', 'r') as file:
            window_title = file.readline().strip()
            return window_title
    except FileNotFoundError:
        print("config.ini 文件未找到")
        return None

# 主程序逻辑
window_title = read_config()
if window_title:
    source_hwnd = win32gui.FindWindow(None, window_title)  # 替换为实际的窗口标题
    if not win32gui.IsWindow(source_hwnd):
        print("未找到指定的窗口")
    else:
        width, height = get_window_normal_size(source_hwnd)
        if width is not None and height is not None:
            print(f"窗口尺寸: {width} x {height}")

            # 创建目标窗口
            target_window_title = "Target Window"  # 目标窗口的标题
            target_hwnd = create_window(target_window_title, width, height)

            # 显示目标窗口
            win32gui.ShowWindow(target_hwnd, win32con.SW_SHOWNORMAL)
            win32gui.UpdateWindow(target_hwnd)

            # 定义绘制位置(你可以根据需要调整)
            draw_position = RECT()
            draw_position.left = 0
            draw_position.top = 0
            draw_position.right = draw_position.left + width
            draw_position.bottom = draw_position.top + height

            # 调用映射窗口函数
            mapping_window(target_hwnd, source_hwnd, draw_position)

            # 运行消息循环以保持窗口显示
            while True:
                win32gui.PumpMessages()
                time.sleep(0.1)
else:
    print("未从 config.txt 中读取到窗口标题")


最后只需要自己创建一个config,ini存放提取出来的窗口标题即可
推荐
52zct 发表于 2024-11-14 09:11
测试了一下,像是实时投屏

[Python] 纯文本查看 复制代码
import ctypes
import time
import win32api
import win32con
import win32gui
from ctypes import wintypes
 
# Windows API 常量
DWM_TNP_RECTDESTINATION = 0x00000001
DWM_TNP_VISIBLE = 0x00000008
DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010
 
 
# 定义 RECT 结构体
class RECT(ctypes.Structure):
    _fields_ = [("left", wintypes.LONG),
                ("top", wintypes.LONG),
                ("right", wintypes.LONG),
                ("bottom", wintypes.LONG)]
 
 
# DWM_THUMBNAIL_PROPERTIES 结构体
class DWM_THUMBNAIL_PROPERTIES(ctypes.Structure):
    _fields_ = [("dwFlags", wintypes.DWORD),
                ("rcDestination", RECT),
                ("fVisible", wintypes.BOOL),
                ("fSourceClientAreaOnly", wintypes.BOOL),
                ("opacity", wintypes.UINT)]
 
 
# 定义 HRESULT 类型
HRESULT = ctypes.c_int
 
# DWM API 函数声明
DWM_API = ctypes.windll.dwmapi
 
# DwmRegisterThumbnail 函数声明
DWM_API.DwmRegisterThumbnail.argtypes = [wintypes.HWND, wintypes.HWND, ctypes.POINTER(wintypes.HANDLE)]
DWM_API.DwmRegisterThumbnail.restype = HRESULT  # 使用 c_int 来表示 HRESULT
 
# DwmUpdateThumbnailProperties 函数声明
DWM_API.DwmUpdateThumbnailProperties.argtypes = [wintypes.HANDLE, ctypes.POINTER(DWM_THUMBNAIL_PROPERTIES)]
DWM_API.DwmUpdateThumbnailProperties.restype = HRESULT
 
 
# 定义窗口回调函数
def wnd_proc(hwnd, msg, w_param, l_param):
    if msg == win32con.WM_CLOSE:
        win32gui.DestroyWindow(hwnd)
        # DWM_API.DwmUnregisterThumbnail(hwnd)
    return win32gui.DefWindowProc(hwnd, msg, w_param, l_param)
 
 
# 创建窗口函数
def create_window(window_title, w, h):
    wc = win32gui.WNDCLASS()
    wc.lpfnWndProc = wnd_proc
    wc.lpszClassName = window_title
    wc.hInstance = win32api.GetModuleHandle(None)
    class_atom = win32gui.RegisterClass(wc)
 
    hwnd = win32gui.CreateWindow(
        class_atom,  # 窗口类的标识符
        window_title,  # 窗口标题
        win32con.WS_OVERLAPPEDWINDOW,  # 窗口样式
        0, 0,  # 窗口位置
        w + 50, h + 50,  # 窗口大小
        0,  # 父窗口句柄
        0,  # 菜单句柄
        wc.hInstance,  # 实例句柄
        None  # 额外的参数
    )
 
    return hwnd
 
 
def mapping_window(target_hwnd, source_hwnd, draw_position):
    thumbnail = wintypes.HANDLE()
 
    # 注册缩略图
    result = DWM_API.DwmRegisterThumbnail(target_hwnd, source_hwnd, ctypes.byref(thumbnail))
    if result != 0:  # 如果 DwmRegisterThumbnail 返回非 0,表示失败
        print("未获取到缩略图")
        return
 
    # 设置缩略图属性
    thumb_props = DWM_THUMBNAIL_PROPERTIES()
    thumb_props.dwFlags = DWM_TNP_RECTDESTINATION
    thumb_props.rcDestination = draw_position
    thumb_props.fVisible = True
    thumb_props.fSourceClientAreaOnly = False
    thumb_props.opacity = (255 * 70) // 100  # 设置透明度为 70%
 
    # 更新缩略图属性
    DWM_API.DwmUpdateThumbnailProperties(thumbnail, ctypes.byref(thumb_props))
 
    print("缩略图已映射到目标窗口")
 
 
def get_window_normal_size(hwnd):
    # 获取窗口的位置信息和状态
    placement = win32gui.GetWindowPlacement(hwnd)
    print(placement)
 
    # 获取窗口正常状态下的尺寸
    rect = placement[4]  # rcNormalPosition: (left, top, right, bottom)
 
    # 计算宽度和高度
    width = rect[2] - rect[0]
    height = rect[3] - rect[1]
 
    return width, height
 
 
# 获取源窗口的句柄
source_hwnd = 198072  # 这里填写需要截图的窗口的句柄
width, height = get_window_normal_size(source_hwnd)
print(width, height)
 
# 创建目标窗口
target_window_title = "Target Window"  # 目标窗口的标题
target_hwnd = create_window(target_window_title, width, height)
 
# 显示目标窗口
win32gui.ShowWindow(target_hwnd, win32con.SW_SHOWNORMAL)
win32gui.UpdateWindow(target_hwnd)
 
# 定义绘制位置(你可以根据需要调整)
draw_position = RECT()
draw_position.left = 0
draw_position.top = 0
draw_position.right = draw_position.left + width
draw_position.bottom = draw_position.top + height
 
# 调用映射窗口函数
mapping_window(target_hwnd, source_hwnd, draw_position)
 
# 运行消息循环以保持窗口显示
while True:
    win32gui.PumpMessages()
    time.sleep(0.1)

免费评分

参与人数 1吾爱币 +1 收起 理由
hehehero + 1 我很赞同!

查看全部评分

沙发
LinuxK 发表于 2024-11-13 21:54
3#
Onaking 发表于 2024-11-13 22:30
好用好用
4#
Yhuo 发表于 2024-11-13 22:44
不错,有意思
5#
oy1313277oy 发表于 2024-11-13 22:45
感谢分亨,学习了
6#
likemebee 发表于 2024-11-13 23:09
有点意思,学习了~~
7#
Lanthanum 发表于 2024-11-13 23:30
感谢分享
8#
pyjiujiu 发表于 2024-11-13 23:37
谢分享,测试下,确实如楼主所说,截取播放器 会和播放器一起播放,但最小化播放 就是静止的。

看来需要先激活窗口再截图不可
9#
tannium 发表于 2024-11-13 23:48
支持一下
10#
BrutusScipio 发表于 2024-11-14 00:28
最小化后截取程序界面吗?描述看不出具体用途,可以加个演示
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 14:57

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表