使用windows api屏幕截图(支持多显示器)

#include <stdio.h>
#include <windows.h>
#include <iostream>
#include <vector>
#include <atlimage.h>
using namespace std;

#define ENTERFUNCTION printf("%s() >\n",__FUNCTION__);
#define LEAVEFUNCTION(iRtn) printf("%s() < iRtn = %d.\n",__FUNCTION__,iRtn);

// 定义错误
#define ERROR_PARAMETER 0x100
#define ERROR_SYSTEM	0x101

typedef enum
{
	BMP,
	JPG
}IMG_TYPE;

struct ALLMONITORINFO
{
	HMONITOR hMonitor;
	RECT rect;
	bool isPrimary;
};

BOOL CALLBACK MonitorEnumProc(__in HMONITOR hMonitor, __in HDC hdcMonitor, __in LPRECT lprcMonitor, __in LPARAM dwData)
{
	vector<ALLMONITORINFO>& infoArray = *reinterpret_cast<vector<ALLMONITORINFO>*>(dwData);
	ALLMONITORINFO monitorInfo;
	monitorInfo.hMonitor = hMonitor;
	monitorInfo.rect = *lprcMonitor;
	infoArray.push_back(monitorInfo);
	return TRUE;
}

void ScreenBMP(HWND hwnd, int left, int top, int width, int height,const char* path)
{
	// 获取指定窗口的句柄
	HDC sourceDC = GetWindowDC(hwnd);
	// 根据源DC获取创建兼容内存DC
	HDC memDC = ::CreateCompatibleDC(sourceDC);
	// 根据原DC创建兼容位图
	HBITMAP memBitmap;
	memBitmap = ::CreateCompatibleBitmap(sourceDC, width, height);
	// 将兼容位图写入内存DC
	SelectObject(memDC, memBitmap);
	// 截图
	BitBlt(memDC, 0, 0, width, height, sourceDC, left, top, SRCCOPY);
	
	BITMAP bmp;
	GetObject(memBitmap, sizeof(BITMAP), &bmp);
	FILE* fp;
	fopen_s(&fp, path, "w+b");
	BITMAPFILEHEADER bfh = { 0 };
	bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
	bfh.bfType = (WORD)0x4d42;
	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;
	fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);
	fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);
	byte* p = new byte[bmp.bmWidthBytes * bmp.bmHeight];
	GetDIBits(memDC, (HBITMAP)memBitmap, 0, height, p, (LPBITMAPINFO)&bih, DIB_RGB_COLORS);
	fwrite(p, 1, bmp.bmWidthBytes * bmp.bmHeight, fp);
	delete[]p;
	fclose(fp);
	DeleteObject(memBitmap);
	DeleteObject(memDC);
	ReleaseDC(hwnd, sourceDC);
}

void ScreenJPG(HWND hwnd, int left, int top, int width, int height, const char* path)
{
	// 获取指定窗口的句柄
	HDC sourceDC = GetWindowDC(hwnd);
	// 根据源DC获取创建兼容内存DC
	HDC memDC = ::CreateCompatibleDC(sourceDC);
	// 根据原DC创建兼容位图
	HBITMAP memBitmap;
	memBitmap = ::CreateCompatibleBitmap(sourceDC, width, height);
	// 将兼容位图写入内存DC
	SelectObject(memDC, memBitmap);
	// 截图
	BitBlt(memDC, 0, 0, width, height, sourceDC, left, top, SRCCOPY);

	CImage sImage;
	sImage.Attach(memBitmap);
	CString strPath;
	strPath.Format(_T("%s"), path);
	sImage.Save((LPCTSTR)strPath);
	DeleteObject(memBitmap);
	DeleteObject(memDC);
	ReleaseDC(hwnd, sourceDC);
}

/**
* @brief:抓取主屏幕的图像,并保存在指定目录
* @param path:图像保存目录
* @return int:0 OK,else failed.
*/
int CaptureMainScreen()
{
	int iRtn = 0;
	// param check
	ENTERFUNCTION
	do
	{
		HWND desktopHwnd = GetDesktopWindow();
		SetForegroundWindow(desktopHwnd);
		RECT deskRect;
		GetWindowRect(desktopHwnd, &deskRect);
		ScreenBMP(desktopHwnd, deskRect.left, deskRect.top, deskRect.right - deskRect.left, deskRect.bottom - deskRect.top, "c:/capture/mainScreen.bmp");
		ScreenJPG(desktopHwnd, deskRect.left, deskRect.top, deskRect.right - deskRect.left, deskRect.bottom - deskRect.top, "c:/capture/mainScreen.jpg");
	} while (0);
	LEAVEFUNCTION(iRtn);
	return iRtn;
}

int CaptureAllScreen()
{
	int iRtn = 0;
	HWND desktopHwnd = GetDesktopWindow();
	SetForegroundWindow(desktopHwnd);
	RECT deskRect;
	GetWindowRect(desktopHwnd, &deskRect);

	vector<ALLMONITORINFO> mInfo;
	mInfo.clear();
	mInfo.reserve(GetSystemMetrics(SM_CMONITORS));
	EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, reinterpret_cast<LPARAM>(&mInfo));

	int width = 0;
	int height = 0;
	int minleft = 0;
	int mintop = 0;
	int maxright = 0;
	int maxbottom = 0;
	for (int i = 0; i < mInfo.size(); i++)
	{
		if (minleft > mInfo[i].rect.left)
		{
			minleft = mInfo[i].rect.left;
		}
		if (mintop > mInfo[i].rect.top)
		{
			mintop = mInfo[i].rect.top;
		}
		if (maxright < mInfo[i].rect.right)
		{
			maxright = mInfo[i].rect.right;
		}
		if (maxbottom < mInfo[i].rect.bottom)
		{
			maxbottom = mInfo[i].rect.bottom;
		}
	}
	width = maxright - minleft;
	height = maxbottom - mintop;
	ScreenBMP(desktopHwnd, 0, 0, width, height, "c:/capture/desktop_all.bmp");
	return 0;
}

int main()
{
	int iRtn = 0;
	do
	{
		iRtn = CaptureMainScreen();
		iRtn = CaptureAllScreen();
	} while (0);
	return iRtn;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值