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

最小化的窗口,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

DWM接口,关键字:DwmRegisterThumbnail,DwmUpdateThumbnailProperties

通过注入Dll + hook API(DwmRegisterThumbnail)的方式验证zoom进程,发现其就是用dwm捕获最小化窗口画面的。

在zoom的窗口选择界面,所有目标窗口的画面捕获和刷新 都是用的dwm,zoom每次调用dwmRegister 传入的dest HWND都是同一个句柄,且刚刚就是窗口选择界面的顶层窗口句柄,

目标窗口最小化和restore期间,zoom没有调用过dwmUnregister,应该是调用了dwmUpdate(尚未验证)。

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)
 在Excel 2007中,Microsoft重写了15年来未曾更新的图表引擎,但如果选择的图表类型不正确,将无助于传递要表达的信息。鉴于此,本书将介绍Excel 2007中全新的图表制作界面,更重要的是,将引导读者选择正确的图表类型并创建引人入胜的图表。通过阅读本书,读者将迅速创建出让观众发出惊叹的图表,并有效地表达信息。   全书分为14章和一个附录,包括如下内容:学习使用Excel 2007图表制作界面,掌握使用图形有效地表示数据的方式,根据要传达的信息选择正确的图表类型,学习可节省时间的解决方案,创建大多数人认为使用Excel无法创建的图表,使用数据透视图汇总数百万行数据,在不使用图表的情况下以图形方式显示数据,使用SmartArt图形绘制流程图和关系图,使用VBA创建图表,将数据绘制到地图中,将图表导出到网页或PowerPoint中,找出图表背后的谎言等。   本书语言简明清晰,内容实用,实例丰富,适合需要使用Excel制作图表的人员阅读。 第1章 Excel 2007图表简介 1 1.1 Excel 2007中的新图表特性 1 1.2 新的图表工具和菜单 2 1.2.1 使用“插入”选项卡来插入图表 3 1.2.2 使用“展开”图标来访问所有图表类型图库 3 1.2.3 理解图表缩略图图标 4 1.2.4 使用图库控件 6 1.3 创建图表 7 1.3.1 选择连续的数据到图表中 7 1.3.2 选择非连续的数据到图表中 7 1.3.3 使用“插入选项卡”图标创建图表 8 1.3.4 使用一次击键创建图表 9 1.4 使用图表 9 1.4.1 在当前工作表中移动图表 9 1.4.2 反转图表的系列(series)与类别(category) 11 1.4.3 使用“选择数据”来改变数据顺序 12 1.4.4 将左上角单元格留空 13 1.4.5 将图表移到另一个工作表中 14 1.5 使用“设计”选项卡自定义图表 15 1.5.1 选择图表布局 16 1.5.2 选择颜色方案 16 1.5.3 通过改变主题来修改颜色方案 17 1.6 创建自己的主题 18 1.6.1 从已有的主题中选择自定义主题的效果 18 1.6.2 理解RGB颜色码 19 1.6.3 将十六进制转换为RGB 20 1.6.4 查找互补色 20 1.6.5 指定主题的颜色 21 1.6.6 指定主题的字体 22 1.6.7 保存自定义的主题 22 1.6.8 在新文档中使用自定义的主题 23 1.6.9 与他人共享主题 23 1.7 下一步 24 第2章 定制图表 25 2.1 使用设置元素格式的工具 25 2.2 识别图表元素 26 2.2.1 图表标签与坐标轴 26 2.2.2 三维图表中的特殊元素 27 2.2.3 分析元素 28 2.3 设置图表元素格式 29 2.3.1 设置图表标题格式 29 2.3.2 设置坐标轴标题格式 31 2.3.3 设置图例格式 32 2.3.4 在图表中添加数据标签 34 2.3.5 在图表中添加数据表 36 2.3.6 设置坐标轴格式 37 2.3.7 网格线的显示与格式设置 43 2.3.8 设置绘图区格式 45 2.3.9 设置三维图表中的背景墙与基底的格式 48 2.3.10 控制三维图表的三维旋转 49 2.3.11 使用趋势线进行预测 51 2.3.12 在折线图或面积图中添加垂直线 53 2.3.13 添加涨/跌柱线到图表中 54 2.3.14 使用误差线显示可接受的偏差 55 2.4 设置数据系列的格式 55 2.5 使用“格式”选项卡 56 2.5.1 将文本转换为艺术字 56 2.5.2 使用形状样式图库 57 2.5.3 使用形状填充与形状效果 57 2.5.4 使用预设形状效果 58 2.6 使用剪贴画或形状替换数据标记 59 2.6.1 使用剪贴画作为数据标记 59 2.6.2 使用形状替换数据标记 60 2.7 下一步 61 第3章 创建显示趋势的图表 62 3.1 选择图表类型 62 3.2 理解基于日期的坐标轴与基于类别的坐标轴 65 3.2.1 将文本日期转换为日期 66 3.2.2 不被识别为日期的日期:数字年份 71 3.2.3 不被识别为日期的日期:1900年之前的日期 72 3.2.4 使用其他方法显示使用时间刻度的坐标轴 76 3.2.5 将日期转换为文本以添加装饰性图表元素 78 3.3 使用图表进行有效交流 81 3.3.1 使用有意义的长标题解释图表的含义 82 3.3.2 突出一列 85 3.3.3 用箭头取代柱形 86 3.3.4 添加另一个序列来突出图表的一部分 87 3.3.5 中途改变折线类型 88 3.4 在图表中添加自动趋势线 89 3.5 显示月销量及当年累积销量的趋势 90 3.6 理解堆积柱形图的缺点 91 3.7 在单个图表中显示很多趋势线的缺点 93 3.8 使用散点图显示趋势 94 3.9 下一步 95 第4章 创建显示差异的图表 96 4.1 比较实体 96 4.2 使用条形图比较数据项 96 4.2.1 增加另一列来显示时间的比较 98 4.2.2 分割条形以突出组分 99 4.3 比较组分 100 4.3.1 使用饼图 101 4.3.2 切换到百分比堆积柱形图 106 4.3.3 使用圆环图来比较两个饼图 107 4.3.4 处理饼图中的数据表示问题 108 4.4 使用瀑布图(waterfall)分解组分 114 4.5 下一步 116 第5章 创建显示关系的图表 117 5.1 在图表中比较两个变量 117 5.2 使用XY散点图绘制成对的数据点 118 5.2.1 在散点图中添加趋势线 118 5.2.2 在散点图中添加标签 120 5.2.3 用折线连接散点图中的点 121 5.2.4 在散点图中添加第二个系列 122 5.2.5 用散点图画图 123 5.3 使用图表来显示关系 123 5.3.1 使用散点图来测试相关性 124 5.3.2 使用成对的条形图来显示关系 126 5.3.3 使用成对的匹配图表 132 5.3.4 使用气泡图添加第三维 135 5.3.5 使用频数分布将成千上万的点分类 136 5.3.6 使用雷达图评估绩效 138 5.3.7 来自Gene Zelazny的一个图表 142 5.4 使用曲面图 145 5.4.1 使用竖坐标轴 146 5.4.2 通过三维旋转控制曲面图 146 5.5 下一步 147 第6章 创建股票分析图 148 6.1 股价图概述 148 6.1.1 折线图 148 6.1.2 OHLC图 149 6.1.3 烛柱(candlestick)图 149 6.2 获取股价数据 150 6.2.1 重排下载数据中的列 151 6.2.2 使用“调整后的收盘价”列来处理分股 151 6.3 创建折线图来显示收盘价 153 6.4 创建OHLC图 156 6.4.1 创建盘高-盘低-收盘图 156 6.4.2 创建OHLC图 159 6.4.3 在盘高-盘低-收盘图表中添加成交量 161 6.5 创建烛柱图 165 6.5.1 改变烛柱图的颜色 166 6.5.2 在烛柱图中添加成交量 166 6.5.3 手工创建包含成交量的烛柱图 167 6.6 使用Web连接创建实时图表 171 6.7 创建用于Dashboard的小图表 174 6.8 下一步 175 第7章 高级图表技巧 176 7.1 高级图表技巧工具箱 176 7.1.1 在单个图表中使用两种图表类型 176 7.1.2 将图表从一个工作表移到另一个工作表 177 7.1.3 使用形状来注释图表 178 7.1.4 使柱形与条形悬浮 180 7.1.5 使用虚构的xy系列给纵坐标轴加上标签 182 7.1.6 使用虚构的XY系列将几个图表显示在单个图表中 187 7.1.7 使用多个XY系列创建网格图(trellis chart) 191 7.2 创建动态图表 195 7.2.1 使用OFFSET函数指定特定区域 195 7.2.2 使用VLOOKUP或MATCH在表格中查找值 196 7.2.3 结合使用INDEX和MATCH函数 198 7.2.4 使用“有效性”下拉列表创建动态图表 199 7.2.5 在图表中使用动态区域 201 7.2.6 创建滚动图表 204 7.2.7 修改滚动条示例显示最近12个月 206 7.3 创建高级图表 206 7.3.1 温度计图表 206 7.3.2 基准图 207 7.3.3 增量图(delta chart) 208 7.4 使用Excel创建奇妙的图表 209 7.5 下一步 211 第8章 创建和使用数据透视图 212 8.1 Excel 2007数据透视表的新特性 212 8.2 决定先使用哪一个:表格还是图表 213 8.3 准备底层透视数据的规则 213 8.4 创建第一个数据透视图 214 8.4.1 更改图表类型及设置图表格式 216 8.4.2 在数据透视图中添加系列 216 8.5 通过数据透视表执行高级操作 217 8.6 筛选数据透视表 219 8.6.1 使用“报表筛选”进行筛选 219 8.6.2 将Excel 2007筛选条件用于轴字段和图例字段 220 8.7 为每个顾客创建图表 221 8.8 下一步 223 第9章 不使用图表的数据可视化表示法 224 9.1 在工作表单元格中创建图表 224 9.2 使用数据条创建单元格内的条形图 225 9.2.1 定制数据条 225 9.2.2 控制最小/最大数据条的长度 226 9.2.3 在部分单元格中显示数据条 228 9.3 使用色阶来突出极值 230 9.3.1 转换为单色数据条 230 9.3.2 排除色阶问题 231 9.4 使用图标集区分数据 232 9.4.1 建立图标集 232 9.4.2 让数字靠近图标 233 9.5 使用条件格式在工作表单元格中创建图表 234 9.6 使用REPT函数创建图表 237 9.7 使用滚动条控件创建图表 238 9.8 创建“茎叶”图表 240 9.8.1 创建将X作为叶的“茎叶”图表 241 9.8.2 使用长公式创建以数字作为叶的“茎叶”图表 242 9.8.3 使用排序和公式创建以数字作为叶的“茎叶”图表 243 9.9 下一步 244 第10章 使用Microsoft MapPoint将Excel 数据显示在地图中 245 10.1 绘制地理数据 245 10.2 在Excel中创建地图 246 10.3 在地图上使用图表 249 10.4 使用其他地图样式来显示数据 251 10.5 下一步 253 第11章 使用SmartArt图形和形状 254 11.1 理解SmartArt图形和形状 254 11.2 使用SmartArt 255 11.2.1 大多数SmartArt都有的元素 256 11.2.2 SmartArt类别简介 256 11.2.3 插入SmartArt 257 11.2.4 对SmartArt元素进行微观控制 260 11.2.5 在文本窗格中控制SmartArt形状 262 11.2.6 添加图像到SmartArt中 264 11.2.7 使用组织图时需要特别考虑的因素 265 11.2.8 使用受限制的SmartArt 267 11.3 为信息选择正确的布局 268 11.4 探索使用SmartArt图形的商业图表 268 11.4.1 使用“平衡”图来显示正/反决策 269 11.4.2 使用“向上箭头”来显示增长 269 11.4.3 使用“基本循环”布局显示重复的过程 269 11.4.4 使用“分离射线”图示显示公司与外部实体的关系 270 11.4.5 使用“表格列表”图示显示公司的部门 270 11.4.6 调整维恩图来显示关系 271 11.4.7 理解“标记的层次结构”图 272 11.4.8 使用其他SmartArt布局 273 11.5 使用形状显示单元格内容 273 11.5.1 处理形状 274 11.5.2 使用“任意多边形”形状创建自定义形状 275 11.6 使用艺术字显示有趣的标题 275 11.7 下一步 278 第12章 导出图表以便在 Excel外部使用 279 12.1 在PowerPoint或Word中显示Excel图表 279 12.1.1 将图表复制为链接到原工作簿链接的动态图表 280 12.1.2 将图表复制为与原工作簿拷贝链接的动态图表 281 12.1.3 将图表复制为图形 282 12.1.4 将图表粘贴为链接对象 283 12.1.5 在PowerPoint中创建图表,从Excel中复制数据 284 12.2 在网上展示图表 285 12.3 将图表导出为图形 286 12.3.1 使用VBA将图表导出为图像 286 12.3.2 使用Snag-it或OneNote捕获图表 286 12.3.3 将XPS转换为PDF 287 12.4 下一步 287 第13章 使用VBA创建图表 288 13.1 VBA简介 288 13.1.1 在Excel中启用VBA 289 13.1.2 在Excel中“开发工具”选项卡 289 13.1.3 Visual Basic编辑器 289 13.1.4 Visual Basic工具 290 13.1.5 宏录制器 291 13.1.6 理解面向对象的代码 291 13.2 学习VBA编程技巧 291 13.2.1 编写代码来处理任意大小的数据区域 292 13.2.2 使用超级变量(super-variable):对象变量 293 13.2.3 在引用对象时使用With和End With 294 13.2.4 续行 294 13.2.5 在代码中添加注释 294 13.3 针对Excel 2007的新图表特性进行编程 295 13.4 在VBA代码中引用图表和图表对象 295 13.5 创建图表 296 13.5.1 指定图表的大小和位置 296 13.5.2 引用特定的图表 297 13.6 录制“布局”和“设计”选项卡中的命令 299 13.6.1 指定内置的图表类型 299 13.6.2 指定模板图表类型 301 13.6.3 更改图表的布局或样式 301 13.7 使用SetElement模拟“布局”选项卡中的设置 303 13.8 使用VBA修改图表标题 308 13.9 模拟“格式”选项卡中的设置 308 13.10 自动化“设置数据系列格式”对话框中的设置 322 13.10.1 控制柱形图和条形图的系列间距和类别间距 323 13.10.2 将系列移到次要坐标轴上 324 13.10.3 旋转和分离圆形图表 325 13.10.4 控制复合饼图和复合条饼图 327 13.10.5 控制雷达图和曲面图 332 13.11 使用“监视”窗口查看对象的设置 333 13.12 将图表导出为图形 335 13.13 创建数据透视图 337 13.14 下一步 341 第14章 找出图表背后的谎言 342 14.1 使用透视进行欺骗 342 14.2 使用缩小的图表进行欺骗 343 14.3 使用刻度进行欺骗 344 14.4 由于Excel不配合导致的欺骗 344 14.5 通过模糊数据进行欺骗 345 14.6 有意使用图表进行欺骗 346 14.7 下一步 348 附录A 图表资源 349 A.1 其他图表资源 349 A.2 Gene Zelazny:商业图表制作大师 349 A.3 PowerFramework.com 349 A.4 Edward Tufte的书籍 350 A.5 图表制作教程网站 351 A.6 交互式培训 351 A.7 现场培训 352 A.8 有关图表制作的博客 352 A.9 视觉设计书店 352 A.10 专业图表设计师 353 A.11 图表制作工具和产品 353 Win32和UWP 在大多数情况下,Win32和UWP之间使用API​​的方式是相同的。 但是,有一些细微的差异。 GraphicsCapturePicker无法在Win32应用程序中推断您的窗口,因此您必须对QI表示并提供窗口的HWND。 Direct3D11CaptureFramePool需要DispatcherQueue ,与Composi
// handle: 当前窗口句柄 // hwnd: 要生成缩略图窗口,可以通过EnumWindows,FindWindow查找 // thumb: 生成的缩略图标识 if (DWMApi.DwmRegisterThumbnail(handle, hwnd, out IntPtr thumb) == 0) // 取窗口缩略图尺寸,下面画缩略图的时候可以根据取到的size对缩略图做等比缩放 DWMApi.DwmQueryThumbnailSourceSize(thumb, out System.Dr
您曾经是否好奇过DWM缩略图Windows 8和更高版本上动画/过渡时(Shell)为何如此平滑? 没有吗?好吧,有一件事是肯定的;他们没有使用像DwmRegisterThumbnailDwmUpdateThumbnailProperties这样的公共API 。 让我向您介绍…(鼓声) …最新的私有API,可以让您从选择的任何窗口中获取共享的Visual。 让我们开始吧! 注意:由于这些函数的调试符号已被剥离,因此我不得不猜测名称和类型,这听起来并不容易。 注意2:由于Windows 10的版本为20.
DWM是在Windows Vista后出现的操作系统窗口渲染程序,在中文化的系统中被描述为“桌面窗口管理器”,该进程随着系统一起启动,同时提供一些Api给其他程序进行调用。这里展示其中的一个功能——由窗口DWM订阅其他窗口缩略图,并由DWM绘制到请求的窗口上。 这一过程将使用以下四个API /// <summary> /// 向DWM管理器订阅某窗口缩略图 在视频会议中,有一个场景是屏幕分享,屏幕分享的时候要预览屏幕和窗口缩略图,然后选中对应缩略图窗口进行分享,本篇博客主要记录一下在 Windows 平台下面获取缩略图的一些方法,如果你有更好的方法欢迎交流 二、获取和显示缩略图 方法一:使用DwmUpdateThumbnailProperties 在指定窗口显示缩略图 可以参考即构科技的官方文档说明https://doc-zh.zego.im/zh/2365.html,他们注册缩略图的 API 也是需要将位置传进去,也就是说他们使用...
第一次写API的程序,做了一个类似SPY++雷达手的工具,可以捕捉鼠标当前的位置,句柄,类名等。图:软件下载地址:http://221.224.12.5:8080/sgs/CursorPlace/CursorPlace.rar源码地址:http://221.224.12.5:8080/sgs/CursorPlace/CursorPlace_source.rar开发工具:VS.Net 2003 转载...
捕获SDL2窗口画面并录制视频,你可以结合SDL2和FFmpeg库来实现。首先,你需要使用SDL2来创建窗口和渲染器,并在每一帧绘制完窗口内容后,将渲染器的像素数据复制到FFmpeg的AVFrame中。然后,你可以使用FFmpeg来编码并写入视频帧。 以下是一个简单的示例代码,展示了如何使用SDL2和FFmpeg来捕获窗口画面并录制视频: ```cpp extern "C" { #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavutil/imgutils.h> #include <SDL2/SDL.h> int main() { av_register_all(); // 初始化SDL2 SDL_Init(SDL_INIT_VIDEO); SDL_Window* window = SDL_CreateWindow("Capture Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0); SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 640, 480); // 创建FFmpeg相关的结构体 AVFormatContext* formatContext; avformat_alloc_output_context2(&formatContext, nullptr, nullptr, "output.mp4"); AVOutputFormat* outputFormat = formatContext->oformat; AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_H264); AVStream* stream = avformat_new_stream(formatContext, codec); AVCodecContext* codecContext = stream->codec; codecContext->codec_id = AV_CODEC_ID_H264; codecContext->codec_type = AVMEDIA_TYPE_VIDEO; codecContext->pix_fmt = AV_PIX_FMT_YUV420P; codecContext->width = 640; codecContext->height = 480; codecContext->time_base = AVRational{1, 25}; codecContext->bit_rate = 400000; avio_open(&formatContext->pb, "output.mp4", AVIO_FLAG_WRITE); avformat_write_header(formatContext, nullptr); AVFrame* frame = av_frame_alloc(); frame->format = codecContext->pix_fmt; frame->width = codecContext->width; frame->height = codecContext->height; av_frame_get_buffer(frame, 32); // 开始录制视频,逐帧写入 for (int i = 0; i < 250; ++i) { av_frame_make_writable(frame); // 渲染窗口内容到纹理 SDL_RenderClear(renderer); // 这里是你绘制窗口内容的代码 // ... SDL_UpdateTexture(texture, nullptr, nullptr, 0); SDL_RenderCopy(renderer, texture, nullptr, nullptr); SDL_RenderPresent(renderer); // 将纹理像素数据复制到AVFrame中 uint8_t* pixels = nullptr; int pitch = 0; SDL_LockTexture(texture, nullptr, reinterpret_cast<void**>(&pixels), &pitch); for (int y = 0; y < codecContext->height; ++y) { memcpy(frame->data[0] + y * frame->linesize[0], pixels + y * pitch, codecContext->width * 4); SDL_UnlockTexture(texture); // 编码并写入视频帧 AVPacket packet; av_init_packet(&packet); packet.data = nullptr; packet.size = 0; avcodec_send_frame(codecContext, frame); avcodec_receive_packet(codecContext, &packet); av_interleaved_write_frame(formatContext, &packet); av_packet_unref(&packet); av_write_trailer(formatContext); av_frame_free(&frame); avio_close(formatContext->pb); avformat_free_context(formatContext); // 释放SDL2资源 SDL_DestroyTexture(texture); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; 在上述示例代码中,我们使用SDL2创建了一个窗口和渲染器,并使用一个纹理来绘制窗口内容。然后,我们将纹理的像素数据复制到AVFrame中,并使用FFmpeg进行编码并写入视频帧。 请注意,上述代码只是一个简单的示例,你可能需要根据你的实际需求进行适当修改。另外,为了成功编译运行此代码,你需要安装SDL2和FFmpeg库,并将它们链接到你的项目中。 希望这个示例能对你有所帮助!如果你有任何疑问,请随时提出。祝你成功开发SDL2录制窗口画面的功能!
[code=cpp] // send video texture,触发信号量 通知video_thread线程可以取数据了 output_video_data(video, &frame, vframe_info.count); [/code] 是怎么触发信号量的 若干种窗口画面的捕获方法 还有我通过UpdateLayeredWindow这个回调的hWnd,如何知道这个是歌词窗口的句柄?kugou的歌词窗口是没有标题的