在学长的强烈要求下,本来想用qt写一个截图程序,但是这个截图程序不符合学长的项目要求,于是转手学了一波windows api。虽然还是对windows api有点云里雾里,但还是摸索出来了。
有几个问题

  1. 第一是有些窗口的截图是黑色的
  2. 第二是截出来的窗口的显示大小有些问题
  3. 第三是只能截出现在桌面的窗口(包括被挡住的窗口),但是不包括最小化的窗口
    如果有大佬知道怎么做,一定要教教我啊,谢谢!

#include "stdio.h"

#include "windows.h"

/************************************************************************/

/* hBitmap    为刚才的屏幕位图句柄

/* lpFileName 为需要保存的位图文件名

/************************************************************************/

int SaveBitmapToFile(HBITMAP hBitmap, LPSTR lpFileName)

{

	HDC            hDC; //设备描述表

	int            iBits;//当前显示分辨率下每个像素所占字节数

	WORD           wBitCount;//位图中每个像素所占字节数    

	DWORD          dwPaletteSize = 0;//定义调色板大小

	DWORD          dwBmBitsSize;//位图中像素字节大小

	DWORD          dwDIBSize;// 位图文件大小

	DWORD          dwWritten;//写入文件字节数

	BITMAP         Bitmap;//位图结构

	BITMAPFILEHEADER   bmfHdr;   //位图属性结构   

	BITMAPINFOHEADER   bi;       //位图文件头结构

	LPBITMAPINFOHEADER lpbi;     //位图信息头结构     指向位图信息头结构

	HANDLE          fh;//定义文件句柄

	HANDLE            hDib;//分配内存句柄

	HANDLE            hPal;//分配内存句柄

	HANDLE          hOldPal = NULL;//调色板句柄  



	//计算位图文件每个像素所占字节数   

	hDC = CreateDC("DISPLAY", NULL, NULL, NULL);

	iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);

	DeleteDC(hDC);



	if (iBits <= 1)

		wBitCount = 1;

	else if (iBits <= 4)

		wBitCount = 4;

	else if (iBits <= 8)

		wBitCount = 8;

	else if (iBits <= 24)

		wBitCount = 24;

	else if (iBits <= 32)

		wBitCount = 24;





	//计算调色板大小   

	if (wBitCount <= 8)

		dwPaletteSize = (1 << wBitCount) *sizeof(RGBQUAD);







	//设置位图信息头结构   

	GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);

	bi.biSize = sizeof(BITMAPINFOHEADER);

	bi.biWidth = Bitmap.bmWidth;

	bi.biHeight = Bitmap.bmHeight;

	bi.biPlanes = 1;

	bi.biBitCount = wBitCount;

	bi.biCompression = BI_RGB;

	bi.biSizeImage = 0;

	bi.biXPelsPerMeter = 0;

	bi.biYPelsPerMeter = 0;

	bi.biClrUsed = 0;

	bi.biClrImportant = 0;

	dwBmBitsSize = ((Bitmap.bmWidth *wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;



	//为位图内容分配内存   

	hDib = GlobalAlloc(GHND, dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));

	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);

	if (lpbi == NULL)

	{

		return 0;

	}



	*lpbi = bi;

	// 处理调色板

	hPal = GetStockObject(DEFAULT_PALETTE);

	if (hPal)

	{

		hDC = GetDC(NULL);

		hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE);

		RealizePalette(hDC);

	}

	// 获取该调色板下新的像素值   

	GetDIBits(hDC, hBitmap, 0, (UINT)Bitmap.bmHeight,

		(LPSTR)lpbi + sizeof(BITMAPINFOHEADER) + dwPaletteSize,

		(LPBITMAPINFO)lpbi, DIB_RGB_COLORS);

	//恢复调色板      

	if (hOldPal)

	{

		SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);

		RealizePalette(hDC);

		ReleaseDC(NULL, hDC);

	}

	//创建位图文件       

	fh = CreateFile(lpFileName, GENERIC_WRITE,

		0, NULL, CREATE_ALWAYS,

		FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);



	if (fh == INVALID_HANDLE_VALUE)

		return FALSE;



	// 设置位图文件头   

	bmfHdr.bfType = 0x4D42;  // "BM"   

	dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;

	bmfHdr.bfSize = dwDIBSize;

	bmfHdr.bfReserved1 = 0;

	bmfHdr.bfReserved2 = 0;

	bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;



	// 写入位图文件头   

	WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);



	// 写入位图文件其余内容   

	WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);



	//清除      

	GlobalUnlock(hDib);

	GlobalFree(hDib);

	CloseHandle(fh);



	return 1;

}

HBITMAP   GetCaptureBmp()

{

	HDC     hDC;

	HDC     MemDC;

	BYTE*   Data;

	HBITMAP   hBmp;

	BITMAPINFO   bi;

	HWND hq = FindWindow(NULL, "网易云音乐");
	hDC = GetWindowDC(hq);
	RECT rect;
	GetWindowRect(hq, &rect);
	int w = rect.right - rect.left, h = rect.bottom - rect.top;

	memset(&bi, 0, sizeof(bi));

	bi.bmiHeader.biSize = sizeof(BITMAPINFO);

	bi.bmiHeader.biWidth = w*1.235;

	bi.bmiHeader.biHeight = h*1.225;

	bi.bmiHeader.biPlanes = 1;

	bi.bmiHeader.biBitCount = 24;



	

	MemDC = CreateCompatibleDC(hDC);

	hBmp = CreateDIBSection(MemDC, &bi, DIB_RGB_COLORS, (void**)&Data, NULL, 0);

	SelectObject(MemDC, hBmp);

	BitBlt(MemDC, 1, 1, w*GetSystemMetrics(SM_CXSCREEN) / GetDeviceCaps(hDC, HORZSIZE), h*GetSystemMetrics(SM_CYSCREEN) / GetDeviceCaps(hDC, VERTSIZE), hDC, 9, 9, SRCCOPY);

	ReleaseDC(NULL, hDC);

	DeleteDC(MemDC);

	return   hBmp;

}


void main()

{

	HBITMAP   hBmp;

	hBmp = GetCaptureBmp();

	SaveBitmapToFile(hBmp, "D:\\11.bmp");

}