抓屏示例

以下示例程序功能为:抓取整个屏幕并保存为D:\\1234.bmp
#include <windows.h>
#include <iostream>

using namespace std;

//
// 抓取屏幕图像存入DDB位图
//
HBITMAP CaptureScreenToDDB()
{
	HDC hdcScreen = NULL;
	HDC hdcMem = NULL;
	HBITMAP hBitmap = NULL;
	HBITMAP hOldBitmap = NULL;
	int xScreenRes = 0;
	int yScreenRes = 0;

	// 创建屏幕设备描述表
	hdcScreen = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);

	// 获取屏幕分辨率
	xScreenRes = ::GetDeviceCaps(hdcScreen, HORZRES);
	yScreenRes = ::GetDeviceCaps(hdcScreen, VERTRES);

	// 创建位图并拷贝屏幕至位图
	hdcMem = ::CreateCompatibleDC(hdcScreen);
	hBitmap = ::CreateCompatibleBitmap(hdcScreen, xScreenRes, yScreenRes);
	hOldBitmap = (HBITMAP)::SelectObject(hdcMem, hBitmap);
	::BitBlt(hdcMem, 0, 0, xScreenRes, yScreenRes, hdcScreen, 0, 0, SRCCOPY);
	hBitmap = (HBITMAP)::SelectObject(hdcMem, hOldBitmap);

	// 释放资源
	::DeleteDC(hdcMem);
	::DeleteDC(hdcScreen);

	return hBitmap;
}

//
// 保存DDB位图成本地DIB位图文件
//
int SaveDDBToFile(HBITMAP hBitmap, HDC hdc, TCHAR name[])
{
	// 获取位图信息
	BITMAP bm;
	::GetObject(hBitmap, sizeof(bm), &bm);

	// 计算位图文件每个字节所占的bit数
	int iBitsPixel = bm.bmBitsPixel * bm.bmPlanes;
	if (iBitsPixel < 24)
		return -1;

	// 位图信息头结构 
	BITMAPINFOHEADER bmih = { 0 };
	bmih.biSize = sizeof(bmih);
	bmih.biWidth = bm.bmWidth;
	bmih.biHeight = bm.bmHeight;
	bmih.biPlanes = 1;
	bmih.biBitCount = iBitsPixel;
	bmih.biCompression = BI_RGB;
	bmih.biSizeImage = 0;
	bmih.biXPelsPerMeter = 0;
	bmih.biYPelsPerMeter = 0;
	bmih.biClrUsed = 0;
	bmih.biClrImportant = 0;

	// 调色板
	DWORD dwPaletteSize = 0;

	// 创建DIB位图内容
	DWORD dwSize = ((bm.bmWidth * iBitsPixel + 31) / 32) * 4 * bm.bmHeight;
	DWORD dwDIBSize = sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwSize;
	LPVOID lpDIB = ::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, dwDIBSize);
	LPBITMAPINFOHEADER lpbmih = (LPBITMAPINFOHEADER)lpDIB;
	*lpbmih = bmih;
	::GetDIBits(hdc, hBitmap, 0, bm.bmHeight, (char*)lpDIB + sizeof(BITMAPINFOHEADER) + dwPaletteSize,
		(PBITMAPINFO)lpbmih, DIB_RGB_COLORS);
	
	// 位图文件头
	BITMAPFILEHEADER bmfh;
	bmfh.bfType = 0x4d42;
	bmfh.bfSize = sizeof(BITMAPFILEHEADER) + dwDIBSize;
	bmfh.bfReserved1 = 0;
	bmfh.bfReserved2 = 0;
	bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize;

	// 创建.bmp文件并保存
	HANDLE hFile = ::CreateFile(name,
		GENERIC_WRITE,
		0,
		NULL,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if (INVALID_HANDLE_VALUE == hFile)
		return GetLastError();

	DWORD dwWritten = 0;
	::WriteFile(hFile, &bmfh, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
	::WriteFile(hFile, lpDIB, dwDIBSize, &dwWritten, NULL);

	::HeapFree(::GetProcessHeap(), 0, lpDIB);
	::CloseHandle(hFile);

	return 0;
}

int main()
{
	HDC hdcScreen = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
	HBITMAP hBitmapScreen = CaptureScreenToDDB();
	if (hBitmapScreen == NULL)
	{
		cout << "CaptureScreenToDDB() failed." << endl;
		return -1;
	}
	TCHAR name[] = TEXT("d:\\1234.bmp");

	cout << SaveDDBToFile(hBitmapScreen, hdcScreen, name) << endl;

	cout << "Hello Kitty" << endl;
	system("pause");
}

你可能感兴趣的:(C++,抓屏)