c++ 截图GetWindowDC,并保存到文件夹下---手把手教

news2024/9/27 7:22:33

工作中遇到一个需求,需要在用户操作过后,需要截图来确认用户操作过后,真实的呈现结果,用来后期验证

直接上代码

直接使用,修改自己需要捕获的窗口名字就可以了


OnBnClickedBtUpimage(){
    CString strPathTmp;
	GetAppPath(strPathTmp);//获取当前程序的路径
	char    szpath[MAX_PATH] = {0};
	//控件大小和位置
	CRect r1;
	CoverCStringToChar(strPathTmp+_T("jietu.png"),szpath,MAX_PATH);
	//根据窗口名字获取窗口位置
	HWND hwnd=::FindWindow(NULL,_T("CarCps")); //后面一个参数是窗口名称
	::GetWindowRect(hwnd, r1);
	Screenbmp(hwnd, 0 ,0 , r1.Width(), r1.Height(),szpath);
} 

两个工具方法

​
获取工程安装路径
void GetAppPath(CString &path)
{
	TCHAR szPath[MAX_PATH] = {0};
	TCHAR szDrive[MAX_PATH] = {0};
	TCHAR szDir[MAX_PATH] = {0};
	TCHAR szFname[MAX_PATH] = {0};
	TCHAR szExt[MAX_PATH] = {0};
	//CString strPath;
	CString strDrive;
	CString strDir;
	GetModuleFileName(NULL,szPath,MAX_PATH);

	_wsplitpath(szPath,szDrive,szDir,szFname,szExt);
	strDrive.Format(_T("%s"),szDrive);
	strDir.Format(_T("%s"),szDir);
	path = strDrive + strDir;
}

//字符转换
int CoverCStringToChar(const CString &strsrc,char *szdet,int len)
{
	int n = strsrc.GetLength();
//获取宽字节字符的大小,大小是按字节计算的
	int lenByte = WideCharToMultiByte(CP_ACP, 0, strsrc, n, NULL, 0, NULL, NULL);
	if ((len - 1) < lenByte)
	{
		lenByte = len - 1;
	}
//宽字节编码转换成多字节编码
	WideCharToMultiByte(CP_ACP, 0, strsrc, n, szdet, lenByte, NULL, NULL); 

	return 0;
}

​

实际截图的方法

​
//输入目标窗口的句柄、左上角的位置以及截图的长宽和保存地址(左上角位置以目标窗口为基准)
void Screenbmp(HWND hwnd, int left, int top, int width, int height, CHAR* path){
	//1、获得指定窗口的dc(源dc)
	//注意GetWindowDC会把窗口的标题栏也同时截图,如果不需要窗口的标题就使用GetDC(hwnd)
	HDC sourceDC= GetWindowDC(hwnd);
	//2、根据源dc创建兼容内存DC
	HDC momDC;//内存DC
	momDC = ::CreateCompatibleDC(sourceDC);
	//3、根据源dc创建兼容位图
	HBITMAP memBitmap;
	memBitmap = ::CreateCompatibleBitmap(sourceDC, width, height);
	//4、将兼容位图写入内存dc
	SelectObject(momDC, memBitmap);
	//5、截图
	BitBlt(momDC, 0, 0, width, height, sourceDC, left, top, SRCCOPY);
	//6、以下代码保存截图信息到文件中
	//6.1获得位图信息
	BITMAP bmp;
	GetObject(memBitmap, sizeof(BITMAP), &bmp);
	//6.2图片保存路径和方式
	FILE* fp;
	fopen_s(&fp, path, "w+b");
	//6.3创建位图文件头
	//位图文件头设置默认值为0
	BITMAPFILEHEADER bfh = { 0 };
	//到位图数据的偏移量(此步骤固定,位图编译量即为位图文件头+位图信息头+调色板的大小,调色板设置为0)
	bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
	//文件总的大小
	bfh.bfSize = bfh.bfOffBits + bmp.bmWidthBytes * bmp.bmHeight;
	//bfType固定为BM,(WORD)0x4d42表示为BM
	bfh.bfType = (WORD)0x4d42;
	//6.4创建文件信息头
	//位图信息头,默认设置为0
	BITMAPINFOHEADER bih = { 0 };
	//每个像素字节大小
	bih.biBitCount = bmp.bmBitsPixel;
	bih.biCompression = BI_RGB;
	//高度
	bih.biHeight = bmp.bmHeight;
	bih.biPlanes = 1;
	bih.biSize = sizeof(BITMAPINFOHEADER);
	//图像数据大小
	bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;
	//宽度
	bih.biWidth = bmp.bmWidth;
	//6.5写入位图文件头
	fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);
	//6.6写入位图信息头
	fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);
	//6.7申请内存保存位图数据

	byte* p = new byte[bmp.bmWidthBytes * bmp.bmHeight];
	//6.8获取位图数据
	GetDIBits(momDC, (HBITMAP)memBitmap, 0, height, p,
		(LPBITMAPINFO)&bih, DIB_RGB_COLORS);

	//6.9写入位图数据        
	fwrite(p, 1, bmp.bmWidthBytes * bmp.bmHeight, fp);
	//6.10先删除开辟的内存,然后关闭文件
	delete[] p;
	fclose(fp);
	//7删除链接
	//7.1删除创建的位图
	DeleteObject(memBitmap);
	//7.2删除创建的兼容内存DC
	DeleteDC(momDC);
	//7.3#释放窗口DC
	ReleaseDC(hwnd, sourceDC);

}

​

//以下方法可用获取鼠标当前指向的控件,可以小到一个按钮控件
HWND GetCurPointedWindow()
{
    POINT point;
    BOOL ret = GetCursorPos(&point);
    if (ret) {
        HWND hwnd = WindowFromPoint(point);
        if (hwnd != nullptr && hwnd != INVALID_HANDLE_VALUE) {
            return hwnd;
        }
    }
    return nullptr;
}

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

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

相关文章

2024年 IT 行业就业情况能否回春?很多人说道…

我只能说可以&#xff0c;以前我是看不到的。但是鸿蒙全栈自研让我重新看到希望&#xff01; 2024年1月18日&#xff0c;华为鸿蒙千帆启航发布会。讲到HarmonyOS NEXT作为原生鸿蒙&#xff0c;其系统底座全栈自研&#xff0c;去掉了传统的AOSP 代码&#xff08;“Android 开放…

基于变异混合蛙跳算法的车间调度最优化matlab仿真,可以任意调整工件数和机器数,输出甘特图

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 车间调度问题&#xff08;JSSP&#xff09;描述 4.2 蛙跳算法&#xff08;SFLA&#xff09;基本原理 4.2.1 初始化 4.2.2 局部搜索 4.2.3 全局信息交换 4.2.4 变异策略 4.2.5 终止…

音乐证书通过率发布,市场对持有者需求旺盛

音乐证书的考试难度备受关注&#xff0c;通过率终于揭晓。据官方公布的数据&#xff0c;该证书的通过率相对较低&#xff0c;需要考生在音乐技能和表现方面有出色的表现。然而&#xff0c;持有音乐证书的人才在市场上需求旺盛&#xff0c;各种音乐机构和企业对其表现出强烈兴趣…

【AI视野·今日CV 计算机视觉论文速览 第288期】Thu, 11 Jan 2024

AI视野今日CS.CV 计算机视觉论文速览 Thu, 11 Jan 2024 Totally 50 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computer Vision Papers Towards Online Sign Language Recognition and Translation Authors Ronglai Zuo, Fangyun Wei, Brian Mak手语识别的目标…

MyBatis详解(2)-- mybatis配置文件

MyBatis详解&#xff08;2&#xff09; mybatis配置文件 mybatis配置文件 1.构建SqlSessionFactory的依据。 2.MyBatis最为核心的内容&#xff0c;对MyBatis的使用影响很大。 3.配置文件的层次顺序不能颠倒&#xff0c;一旦颠倒会出现异常。 < c o n f i g u r a t i o n…

【原创】linux为什么不是实时操作系统

文章目录 一、什么是实时操作系统&#xff08;RTOS&#xff09;&#xff1f;二、linux为什么不是实时操作系统&#xff1f;中断响应时间中断处理时间任务调度时间1、No Forced Preemption(Server)2、Voluntary Kernel Preemption(Desktop)3、Preemptible Kernel(Low-Latency De…

windows 下docker-compose 试玩 paperlsess

第一步安装&#xff1a;&#xff08;假设docker-compose已安装好&#xff09; 下载 docker-compose.yml &#xff0c;docker-compose.env: github下载地址 在docker-paperless.env增加环境变量,设置管理员账户信息&#xff1a; PAPERLESS_ADMIN_USER: admin PAPERLESS_ADMIN_P…

什么品牌洗地机最好?专业旗舰级洗地机推荐

作为一个打工族&#xff0c;很能理解大家对日常清洁繁琐的烦恼&#xff0c;尤其是在忙碌工作后难以有力气打扫卫生。这时候&#xff0c;洗地机就是解决问题的利器了。它不仅方便轻松&#xff0c;还能有效消菌杀毒&#xff0c;助力深度清洁。若你正在为选择哪款洗地机而烦恼&…

当软件开发具备了低代码的开发能力,难以想象会有多“香”

一、前言 低代码开发平台&#xff0c;一个号称能在几分钟的时间里开发出一套公司内部都可使用的应用系统开发工具。 很多人或许都隐隐听说过低代码&#xff0c;因为低代码不仅远名国外&#xff0c;国内的腾讯、阿里、华为、网易、百度等科技巨头也纷纷入局。 那么市面上都有哪些…

【复现】万户ezoffice协同管理平台 SQL注入漏洞_26

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 万户ezOFFICE协同管理平台分为企业版和政务版。 解决方案由五大应用、两个支撑平台组成&#xff0c;分别为知识管理、工作流程、沟…

1.8 万 Star!这款 Nginx 可视化配置工具太强了

NginxConfig简介 Nginx Config 是一个强大的 Nginx 配置文件生成器&#xff0c;号称配置 Nginx 服务器所需的唯一工具。 正因为 Nginx 功能强大&#xff0c;所以针对其各个功能的配置项会显得特别多&#xff0c;对于我们来说要记住那么多配置是一件十分头疼的事&#xff0c;甚…

Python环境下基于机器学习的NASA涡轮风扇发动机剩余使用寿命RUL预测

本例所用的数据集为C-MAPSS数据集&#xff0c;C-MAPSS数据集是美国NASA发布的涡轮风扇发动机数据集&#xff0c;其中包含不同工作条件和故障模式下涡轮风扇发动机多源性能的退化数据&#xff0c;共有 4 个子数据集&#xff0c;每个子集又可分为训练集、 测试集和RUL标签。其中&…

【Java并发】聊聊Future如何提升商品查询速度

java中可以通过new thread、实现runnable来进行实现线程。但是唯一的缺点是没有返回值、以及抛出异常&#xff0c;而callable就可以解决这个问题。通过配合使用futuretask来进行使用。 并且Future提供了对任务的操作&#xff0c;取消&#xff0c;查询是否完成&#xff0c;获取结…

XPath常用定位方式

1、通常定位元素有比较固定的八种定位方式&#xff0c;如下图&#xff1b; 2、平时可以通过浏览器右键进行获取定位方式&#xff0c;但是通常获取的元素无法准确定位或者太长这时就需要自己通过XPath语法来进行定位&#xff1b;目前我这边记录两种常用的定位方式&#xff0c;第…

【大数据】流处理基础概念(二):时间语义(处理时间、事件时间、水位线)

流处理基础概念&#xff08;一&#xff09;&#xff1a;Dataflow 编程基础、并行流处理流处理基础概念&#xff08;二&#xff09;&#xff1a;时间语义&#xff08;处理时间、事件时间、水位线&#xff09;流处理基础概念&#xff08;三&#xff09;&#xff1a;状态和一致性模…

10. Profile

1. 区分环境的配置 1.1. properties 配置 假设&#xff0c;一个应用的工作环境有&#xff1a;dev、test、prod 那么&#xff0c;我们可以添加 4 个配置文件&#xff1a; applcation.properties - 公共配置application-dev.properties - 开发环境配置application-test.proper…

电脑文件mfc140.dll丢失的解决方法指导,怎么快速修复mfc140.dll

mfc140.dll 文件的缺失是个普遍的问题&#xff0c;在日常使用中可能会时不时遇到。本文主要目的是详细介绍一旦遇到 mfc140.dll 文件缺失&#xff0c;应该如何进行下载和安装的步骤。不再赘言&#xff0c;下面就一起深入了解mfc140.dll丢失的解决方法指导。 一. mfc140.dll的作…

跟着pink老师前端入门教程-day09

二十二、定位 22.1 为什么需要定位 1. 某个元素可以自由的在一个盒子内移动位置&#xff0c;并且压住其他盒子 2. 当我们滚动窗口时&#xff0c;盒子是固定屏幕某个位置的 解决方法&#xff1a; 1. 浮动可以让多个块级盒子一行没有缝隙排列显示&#xff0c;经常用于横向排…

Spring Boot开发Spring Security

这里我对springboot不做过多描述&#xff0c;因为我觉得学这个的肯定掌握了springboot这些基础 导入核心依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring‐boot‐starter‐security</artifactId> </depen…

如何优雅的实现前端国际化?

JavaScript 中每个常见问题都有许多成熟的解决方案。当然&#xff0c;国际化 (i18n) 也不例外&#xff0c;有很多成熟的 JavaScript i18n 库可供选择&#xff0c;下面就来分享一些热门的前端国际化库&#xff01; i18next i18next 是一个用 JavaScript 编写的全面的国际化框架…