捕获最小化窗口的缩略图画面

news2024/10/1 5:31:09

关键字:

capture minimized window

window thumbnail

IsIconic 

==================== 问题背景 ======================

最小化的窗口,API GetClientRect 返回的窗口尺寸是0x0,故无法通过GetDC+BitBlt捕获到窗口画面。

但是 Agora/zoom/tencentMeeting 都可以拿到最小化窗口的缩略图。经确认这个程序并没有注入任何dll到目标窗口,且也没有临时显示最小化了的目标窗口。

如果用SHOW_RESTORE恢复最小化了的目标窗口,目标窗口是会收到WM_MOVE消息的,测试Agora/zoom/tencent抓最小化窗口的缩略图时,最小化的窗口并没有收到这个消息,事实上,目标窗口没有收到任何窗口消息。

小记:

  1. agora zoom 腾讯会议 在目标窗口最小化时, 都可以拿到窗口缩略图
  2. 拿到的该缩略图,画面和任务栏鼠标悬停时显示的缩略图一致(该缩略图并不是实时的,而是窗口最小化时刻的画面)
  3. 获取缩略图时,目标窗口没有收到任何窗口消息(SPY)
  4. 开始捕获窗口后,这几个视频会议软件 均可以恢复最小化了的窗口(即使目标窗口是管理员权限启动)

==================== 可用的方法 ====================

方法1(不推荐!)

WS_EX_LAYERED, SetLayeredWindowAttributes

方法2:

DWM接口,关键字:DwmRegisterThumbnail,DwmUpdateThumbnailProperties

方法3:

WGC接口,关键字:GraphicsCapturePicker.PickSingleItemAsync (是系统提供的子进程界面)

GitHub - robmikh/Win32CaptureSample: A simple sample using the Windows.Graphics.Capture APIs in a Win32 application.

================ DWM接口 ========================

关键字:

DWM(桌面窗口管理器)API , 可以实现获取目标窗口的缩略图(即使目标窗口是最小化)

DWM API应用之缩略图_老狼主的博客-CSDN博客_c++ dwm api

DWM API应用之缩略图 - CodeAntenna

Windows 使用 DuiLib 显示屏幕和窗口缩略图_12194415的技术博客_51CTO博客

DwmRegisterThumbnail function (dwmapi.h) - Win32 apps | Microsoft Learn

DwmUpdateThumbnailProperties function (dwmapi.h) - Win32 apps | Microsoft Learn

DwmUnregisterThumbnail function (dwmapi.h) - Win32 apps | Microsoft Learn

注意:

1. 一旦用DwmRegisterThumbnail和DwmUpdateThumbnail,绑定了缩略图关系后,只要不调用DwmUnregister,源窗口的画面就会被系统持续自动更新到目标窗口,不需要手动去刷新画面。

2. 一旦源窗口销毁了,目标窗口上的画面也就没有了(系统会自动清空)

3. 源窗口和目标窗口 都必须是顶层窗口,且目标窗口必须是当前进程的窗口

4. UWP窗口的源窗口句柄,需要设置为parent host句柄(EnumWindows的回调形参HWND就是parent句柄)

#include <dwmapi.h>
#pragma comment(lib,"Dwmapi.lib")

HRESULT RegisterThumbWindow(HWND hWndSrc, HWND hWndDst)
{
    HTHUMBNAIL thumbnail = NULL;
    HRESULT hr = DwmRegisterThumbnail(hWndDst, hWndSrc, &thumbnail);
        if (FAILED(hr))
        return hr; // 如果窗口句柄不存在 或传入了非顶层窗口的句柄 此处会出错

    RECT dest;
        GetClientRect(hWndDst, &dest);

    DWM_THUMBNAIL_PROPERTIES dskThumbProps;
    dskThumbProps.dwFlags = DWM_TNP_RECTDESTINATION | DWM_TNP_VISIBLE | DWM_TNP_SOURCECLIENTAREAONLY |DWM_TNP_OPACITY; // 标识哪些字段已经设置了有效值
    dskThumbProps.fSourceClientAreaOnly = FALSE;
    dskThumbProps.fVisible = TRUE;
    dskThumbProps.rcDestination = dest;
    dskThumbProps.opacity = 255;

    hr = DwmUpdateThumbnailProperties(thumbnail, &dskThumbProps);
        if (FAILED(hr))
        OutputDebugStringA("error");

        // DwmUnregisterThumbnail(thumbnail);
        return hr;
}

void CMFCApplication4Dlg::OnBnClickedButton1()
{
        // 要把缩略图显示在这个窗口 注意:根据MSDN这个窗口必须是顶层窗口,否则返回错误E_INVALIDARG
        // 注意 这个句柄 必须是【当前进程】的窗口句柄
    HWND hwndDestination = m_hWnd; 
    
        // 想捕获的源窗口 这个句柄也必须是顶层窗口句柄,UWP窗口在此处需要设置为parent host句柄
        HWND hwndSource = (HWND)0X004E0286; 
       
        RegisterThumbWindow(hwndSource, hwndDestination);
}

===================== WGC接口 =====================

GitHub - walker-WSH/Win32CaptureSample: A simple sample using the Windows.Graphics.Capture APIs in a Win32 application.

这个项目,点击按钮“Open Picker”, 会弹出一个窗口 用来显示所有窗口 包含最小化窗口的缩略图。

但是这个弹出窗口是系统的,主程序退出后 这个窗口都还在。如果捕获窗口利用的是WGC技术,则可以完全复用系统的这个picker窗口。

这个弹出的子窗口,实际上是系统提供的独立进程:

================= WS_EX_LAYERED ===================

技术点:临时把窗口显示出来(SW_RESTORE),捕获到一帧窗口画面后,再把窗口恢复最小化。

显示窗口之前,需要做如下准备:

1. 给目标窗口增加扩展属性 WS_EX_LAYERED(增加了这个属性 才可以设置窗口透明度)。

2. 用API设置窗口的透明度为透明 (让用户感知不到窗口被显示了)SetLayeredWindowAttributes / GetLayeredWindowAttributes。

3. 临时关闭系统的最大化和最小化的动画效果 animation(否则临时restore最小化的窗口时 系统有动画效果 被用户感知)。

恢复了最小化的窗口 抓取到窗口画面后,再恢复以上几个属性(有些窗口可能之前就有透明度,要注意保存以前的值)

注意:

以上操作,如果是UWP窗口,需要设置的HWND对象是外层的host窗口。

TODO:

尚未验证过如果目标窗口是管理员权限进程的,如下API设置layered透明度是否还能成功?

HWND hWnd = 0;
    if (pTemp->pObject->bIsUWP) {
        hWnd = pTemp->pObject->hParent; // 如果是UWP窗口 需要使用host窗口
    } else {
        hWnd = pTemp->pObject->hActual;
    }

    if (IsWindow(hWnd)) {
        if (IsIconic(hWnd)) {
            ModifyStyleEx2(hWnd, 0, WS_EX_LAYERED); // 增加了这个属性 才可以设置半透明
            SetLayeredWindowAttributes(hWnd, 0, 155, LWA_ALPHA); // 设置整个窗口透明
                        // TODO: 临时关闭系统的最大化和最小化的动画效果
            ShowWindow(hWnd, SW_RESTORE);                        // 显示窗口

            // TODO: capture window video

            // TODO: 移除layered属性,恢复最小化状态。
            // 注意:需要确认之前是否有layer属性,以及对应透明度。GetLayeredWindowAttributes
            ShowWindow(hWnd, SW_MINIMIZE);
        }
    }

备注:

显示最小化窗口时,如果目标窗口是管理员权限运行,而自己的进程不是,则使用ShowWindow则会收到last error = 5。此时想显示最小化的目标窗口,应该用如下两种方法之一。

// 方法1 
// [此功能不适用于一般用途。它可能会在后续版本的 Windows 中更改或不可用。]
// 根据微软注释 这个API不建议使用了。
SwitchToThisWindow(hWnd, TRUE) 


// 方法2 (推荐使用)
PostMessage(hWnd, WM_SYSCOMMAND, (WPARAM)SC_RESTORE, 0)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/352965.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python自动化必不可少的测试框架 — pytest

Python在测试圈的应用非常广泛&#xff0c;特别是在自动化测试以及测试开发的领域&#xff0c;其中在自动化测试中我们常用的测试框架是uniitest和pytest&#xff0c;本文将带领大家搭建以及熟悉pytest的使用。 既然有unittest那么为什么还要用pytest呢&#xff1f; 这是因为…

会议论文分享-Security22-状态感知符号执行

Ferry: State-Aware Symbolic Execution for Exploring State-Dependent Program Paths1.引言2.问题陈述与分析2.1.实现状态感知符号执行的挑战2.2.真实程序的特征2.3.Ferry的模型2.3.1.程序状态的定义2.3.2.状态描述变量的特征3.Design3.1.Overview of Ferry3.2.状态描述变量识…

CISCN(Web Ezpentest)GC、序列化、case when

目录 REGEXP的一个点&#xff08;正则&#xff09; like&#xff08;默认不区分大小写&#xff09; 当禁用了空格 regexp&#xff0c;like的区分大小写的使用方法 [CISCN 2022 初赛]ezpentest 卡点 2022 HFCTF babysql 最近又学到了一道新知识&#xff0c;case when的错…

Python|每日一练|排序|递归|链表|字符串|数组|动态规划|哈希表|单选记录:K 个一组翻转链表|括号生成|无重复字符的最长子串

1、K 个一组翻转链表&#xff08;递归&#xff0c;链表&#xff09; 给你一个链表&#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回翻转后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。 如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩…

kafka安装及使用

目录 1.单机部署 1.下载安装包 2.启动zookeeper服务 3.启动kafka broker服务 2.集群部署 1.下载安装包 2.修改zookeeper配置 3.修改kafka配置 4.在3台机器上启动zookepper 5.在3台机器上启动kafka 6.检查是否启动OK 3.使用 1.创建topic 2.查看kafka topic分区数 …

OpenFaaS介绍

FaaS 云计算时代出现了大量XaaS形式的概念&#xff0c;从IaaS(Infrastructure as a Service)、PaaS(Platform as a Service)、SaaS(Software as a Service)到容器云引领的CaaS(Containers as a Service)&#xff0c;再到火热的微服务架构&#xff0c;它们都在试着将各种软、硬…

通过Prowork每日自动提醒待处理工作任务

对于中小团队来说&#xff0c;由于不需要繁琐的流程和高频的异地沟通&#xff0c;需要一款更适合中小团队的日程和项目管理工具。而Prowork就是这样一款敏捷高效的协同平台。Prowork与以往各种项目管理⼯具最⼤的不同在于&#xff0c;其弱化流程和弱化权限的特性&#xff0c;不…

ES6基础规范

1.变量声明const和let 我们都是知道在ES6以前&#xff0c;var关键字声明变量。无论声明在何处&#xff0c;都会被视为声明在函数的最顶部(不在函数内即在全局作用域的最顶部)。这就是函数变量提升例如: 下图左侧其实相当于右侧: 所以不用关心bool是否为true or false。实际上…

小知识点:Mac M1/M2 VMware Fusion 安装 Centos 7.9(ARM 64 版本)

最近换了 Mac M2 芯片的笔记本&#xff0c;用原来的 Centos 镜像安装虚拟机直接报错 “无法打开此虚拟机的电源&#xff0c;因为它需要使用 X86 计算机架构&#xff0c;而该架构与此 Arm 计算机架构主机不兼容。” 安装流程前置一、下载镜像二、安装虚拟机三、配置静态 IP四、安…

UVa 225 Golygons 黄金图形 暴力搜索 剪枝 状态判断

题目链接&#xff1a;Golygons 题目描述&#xff1a; 给定nnn和kkk个障碍物的坐标&#xff0c;你需要走nnn次&#xff0c;第一次走一个单位距离&#xff0c;第二次走二个单位距离&#xff0c;…&#xff0c;第nnn次走nnn个单位距离。走得过程中不能穿过或者到达障碍物所在的点&…

数据分析与SAS学习笔记6

数据集整理&#xff1a; 目的&#xff1a;对数据集中的数据进行预处理&#xff0c;使数据更适合统计分析过程对数据格式的要求&#xff1b; 常见整理要求&#xff1a; 1&#xff09;建立新的变量&#xff0c;衍生变量&#xff0c;删除某些原变量&#xff1b; 2&#xff09;…

Jira Server一年后“停服” 中国用户如何减损失降影响

近日Jira官方再次表示&#xff1a;在“2024年2月15日之后&#xff0c;用户所使用的 Server 版本的安全漏洞将不再有官方的修复方案&#xff0c;产品的 Bug 也不再被修复。在支持日期结束后&#xff0c;Atlassian 和Marketplace 合作伙伴将不再为任何问题、安全更新或关键漏洞的…

spring-web DispatcherServlet 源码分析

说明 本文基于 jdk 8, spring-framework 5.2.x 编写。author JellyfishMIX - github / blog.jellyfishmix.comLICENSE GPL-2.0 DispatcherServlet 的继承实现层次 关注点应放在 Servlet, GenericServlet, HttpServlet, HttpServletBean, FrameworkServlet, DispatcherServle…

关于Ubuntu20.04文件系统思考

文章目录问题产生Ubuntu文件系统中普通用户可读写地址Ubuntu文件系统Ubuntu文件系统详解一级目录二级目录查找Ubuntu中软件安装位置Ubuntu修改文件权限问题产生 使用electron框架开发桌面端跨平台软件时&#xff0c;当开发完成的程序部署到Ubuntu上&#xff0c;系统无法产生日…

推荐3款远程办公软件

一款好用的远程办公软件能够大大的提高我们的办公效率&#xff0c;在这篇文章中&#xff0c;我们将为您推荐几款常见又好用的远程办公软件&#xff0c;以帮助您能更加高效的远程办公。电脑远程办公软件有很多&#xff0c;本文主要从团队沟通软件、视频会议软件、远程控制软件等…

距离不是拦截我们前进的主因,与社科院杜兰金融硕士一起奔赴山海

最近有咨询社科院杜兰金融管理硕士项目的同学反馈他在西安&#xff0c;读研来北京上课太远了。一直在纠结要不要申请&#xff0c;其实距离不是问题&#xff0c;相向而行才是关键。在项目就读的同学好多也是来自外地&#xff0c;他们克服了种种困难来到项目学习&#xff0c;就是…

kubernetes教程 --service详解

Service 介绍 在kubernetes中&#xff0c;pod是应用程序的载体&#xff0c;我们可以通过pod的ip来访问应用程序&#xff0c;但是pod的ip地址不是固定的&#xff0c;这也就意味着不方便直接采用pod的ip对服务进行访问。 为了解决这个问题&#xff0c;kubernetes提供了Service…

行业分析| 智能无人自助设备

智能无人自助设备运用二维码技术、音视频通信技术和AI智能技术等相结合&#xff0c;提供了无人超市、自动售货机、智能快递柜等。当下很多商业地区或社区&#xff0c;都放置了智能无人自助设备&#xff0c;不仅可以为商家节省时间和精力、提升运营环境&#xff0c;也可以为众多…

宽刈幅干涉雷达高度计SWOT(Surface Water and Ocean Topography)卫星进展(待完善)

> 以下信息搬运自SWOT官方网站等部分文献资料&#xff0c;如有侵权请联系&#xff1a;sunmingzhismz163.com > 排版、参考文献、部分章节待完善 > 2023.02.17.22:00 初稿概况 2022年12月16日地表水与海洋地形卫星SWOT (Surface Water and Ocean Topography)在加利福尼…

SpringCloud(一)注册中心

注册中心eureka服务端客户端负载均衡nacos服务端客户端nacos分级存储模型配置集群属性nacos环境隔离-namespace临时实例和非临时实例Eureka和Nacos的异同负载均衡策略饥饿加载eureka 服务端 依赖 <!-- eureka注册中心服务端依赖--><dependencies><depe…