代码
// An highlighted block
void GetScreenShot(void)
{
BITMAPFILEHEADER bfHeader;
BITMAPINFOHEADER biHeader;
BITMAPINFO bInfo;
HGDIOBJ hTempBitmap;
HBITMAP hBitmap;
BITMAP bAllDesktops;
HDC hDC, hMemDC;
LONG lWidth, lHeight;
BYTE *bBits = NULL;
HANDLE hHeap = GetProcessHeap();
DWORD cbBits, dwWritten = 0;
HANDLE hFile;
INT x = GetSystemMetrics(SM_XVIRTUALSCREEN);
INT y = GetSystemMetrics(SM_YVIRTUALSCREEN);
ZeroMemory(&bfHeader, sizeof(BITMAPFILEHEADER));
ZeroMemory(&biHeader, sizeof(BITMAPINFOHEADER));
ZeroMemory(&bInfo, sizeof(BITMAPINFO));
ZeroMemory(&bAllDesktops, sizeof(BITMAP));
hDC = GetDC(NULL);
hTempBitmap = GetCurrentObject(hDC, OBJ_BITMAP);
GetObjectW(hTempBitmap, sizeof(BITMAP), &bAllDesktops);
lWidth = bAllDesktops.bmWidth;
lHeight = bAllDesktops.bmHeight;
DeleteObject(hTempBitmap);
bfHeader.bfType = (WORD)('B' | ('M' << 8));
bfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
biHeader.biSize = sizeof(BITMAPINFOHEADER);
biHeader.biBitCount = 24;
biHeader.biCompression = BI_RGB;
biHeader.biPlanes = 1;
biHeader.biWidth = lWidth;
biHeader.biHeight = lHeight;
bInfo.bmiHeader = biHeader;
cbBits = (((24 * lWidth + 31)&~31) / 8) * lHeight;
hMemDC = CreateCompatibleDC(hDC);
hBitmap = CreateDIBSection(hDC, &bInfo, DIB_RGB_COLORS, (VOID **)&bBits, NULL, 0);
SelectObject(hMemDC, hBitmap);
BitBlt(hMemDC, 0, 0, lWidth, lHeight, hDC, x, y, SRCCOPY);
hFile = CreateFileW(L"screen.jpg", GENERIC_WRITE | GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hFile, &bfHeader, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
WriteFile(hFile, &biHeader, sizeof(BITMAPINFOHEADER), &dwWritten, NULL);
WriteFile(hFile, bBits, cbBits, &dwWritten, NULL);
CloseHandle(hFile);
DeleteDC(hMemDC);
ReleaseDC(NULL, hDC);
DeleteObject(hBitmap);
//return hBitmapToMat(hBitmap);
}
用到的相关函数
- HDC GetDC(
HWND hWnd
);
该函数用于返回特定窗体的区域或者是整个屏幕。当 hWnd 句柄为NULL时,返回整个屏幕。
- HGDIOBJ GetCurrentObject(
HDC hdc,
UINT type
);
该函数返回设备上下文对象的子对象的句柄。
其中 type 种类包括:
- PARAMETERS
Value Meaning - OBJ_BITMAP
Returns the current selected bitmap. - OBJ_BRUSH
Returns the current selected brush. - OBJ_COLORSPACE
Returns the current color space. - OBJ_FONT
Returns the current selected font. - OBJ_PAL
Returns the current selected palette. - OBJ_PEN
Returns the current selected pen.
可以看出 OBJ_BITMAP 可以返回设备上下文对应的BITMAP 对象。
- int GetObjectW(
HANDLE h,
int c,
LPVOID pv
);
该函数获取图形对象的相关信息。
在本示例中,该函数用于将对象句柄转换为 BITMAP 对象。
- HDC CreateCompatibleDC(
HDC hdc
);
该函数创建内存上下文。
- HBITMAP CreateDIBSection(
HDC hdc,
const BITMAPINFO *pbmi,
UINT usage,
VOID **ppvBits,
HANDLE hSection,
DWORD offset
);
该函数创建 一个DIB 对象容器,以便将bitmap 写入。
- HGDIOBJ SelectObject(
HDC hdc,
HGDIOBJ h
);
该函数用于将新创建的对象赋值到hdc 对象内。
- BOOL BitBlt(
HDC hdc,
int x,
int y,
int cx,
int cy,
HDC hdcSrc,
int x1,
int y1,
DWORD rop
);
从源对象将位图数据赋值到新创建的 HDC 对象中。
hdc 目标对象,hdcSrc 源对象。
总结
综上我们可以这样理解。 函数 GetDC 获得设备上下文(可以是窗口或者是整个屏幕),CreateCompatibleDC 创建一个内存上下文,CreateDIBSection 创建一个可访问的BITMAP容器。SelectObject 方法将容器绑定到内存上下文。BitBlt 方法将源设备上下文BITMAP数据赋值到新创建的内存上下文。 我们接下来就可以通过访问 hBitmap 来访问得到的图像数据。