Win32を使用して現在の画面のスクリーンショットを撮るにはどうすればよいですか?
// get the device context of the screen
HDC hScreenDC = CreateDC("DISPLAY", NULL, NULL, NULL);
// and a device context to put it in
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
int width = GetDeviceCaps(hScreenDC, HORZRES);
int height = GetDeviceCaps(hScreenDC, VERTRES);
// maybe worth checking these are positive values
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
// get a new bitmap
HBITMAP hOldBitmap = (HBITMAP) SelectObject(hMemoryDC, hBitmap);
BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);
hBitmap = (HBITMAP) SelectObject(hMemoryDC, hOldBitmap);
// clean up
DeleteDC(hMemoryDC);
DeleteDC(hScreenDC);
// now your image is held in hBitmap. You can save it or do whatever with it
GetDC(NULL);
を使用して、画面全体に対してDC)を取得します。CreateCompatibleDC
を使用して、画面DCと互換性のあるDCと互換性があります。CreateCompatibleBitmap
を使用して、画面と互換性のあるビットマップを作成しますDC結果を保持します。SelectObject
を使用して、互換DCに互換ビットマップを選択します。BitBlt
を使用して、画面からDCと互換性のあるDCにコピーします。SelectObject
を使用して、互換性のあるDCから互換性のあるビットマップを選択解除します。DeleteDC
を使用して、互換性のあるDCを削除します。互換性のあるビットマップを作成するときは、互換性のあるDCではなく、画面DCとの互換性が必要です。
例えば:
HDC dcScreen = GetDC(0);
HDC dcTarget = CreateCompatibleDC(dcScreen);
HBITMAP bmpTarget = CreateCompatibleBitmap(dcScreen);
HGDIOBJ oldBmp = SelectObject(dcTarget, bmpTarget);
BitBlt(dcTarget, 0, 0, cx, cy, dcDesktop, x, y, SRCCOPY | CAPTUREBLT);
SelectObject(dcTarget, oldBmp);
DeleteDC(dcTarget);
ReleaseDC(dcScreen);
もう1つの重要な部分は、仮想スクリーン全体のサイズと場所を取得することです。
int x = GetSystemMetrics(SM_XVIRTUALSCREEN); //left (e.g. -1024)
int y = GetSystemMetrics(SM_YVIRTUALSCREEN); //top (e.g. -34)
int cx = GetSystemMetrics(SM_CXVIRTUALSCREEN); //entire width (e.g. 2704)
int cy = GetSystemMetrics(SM_CYVIRTUALSCREEN); //entire height (e.g. 1050)
void GetScreenShot(void)
{
int x1, y1, x2, y2, w, h;
// get screen dimensions
x1 = GetSystemMetrics(SM_XVIRTUALSCREEN);
y1 = GetSystemMetrics(SM_YVIRTUALSCREEN);
x2 = GetSystemMetrics(SM_CXVIRTUALSCREEN);
y2 = GetSystemMetrics(SM_CYVIRTUALSCREEN);
w = x2 - x1;
h = y2 - y1;
// copy screen to bitmap
HDC hScreen = GetDC(NULL);
HDC hDC = CreateCompatibleDC(hScreen);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, w, h);
HGDIOBJ old_obj = SelectObject(hDC, hBitmap);
BOOL bRet = BitBlt(hDC, 0, 0, w, h, hScreen, x1, y1, SRCCOPY);
// save bitmap to clipboard
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBitmap);
CloseClipboard();
// clean up
SelectObject(hDC, old_obj);
DeleteDC(hDC);
ReleaseDC(NULL, hScreen);
DeleteObject(hBitmap);
}
任意のHWNDをDC(渡すことを試すことができます)するための、MSDNサンプル Captureing a Image ) GetDesktopWindowからこれへの出力)しかし、これがVista/Windows 7の新しいデスクトップコンポジターでどの程度うまく機能するかはわかりません。
Windows APIを使用して、現在のウィンドウステーションですべてのモニターの生の24ビットロスレスビットマップを保存するための完全なコード:
BOOL WINAPI SaveBitmap(WCHAR *wPath)
{
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;
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, 0, 0, SRCCOPY);
hFile = CreateFileW(wPath, 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 TRUE;
}