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

发布时间:2024年01月24日

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

直接上代码

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


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;
}

文章来源:https://blog.csdn.net/Super_Jadroid/article/details/135829857
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。