Как захватить часть экрана и сохранить его в BMP?

Возможный дубликат:как сделать скриншот экрана с win32 в С++?

В настоящее время я пытаюсь создать приложение, которое сохранит часть экрана в bmp. Я нашел BitBlt, но я действительно не знаю, что с ним делать. Я попытался найти ответы на некоторые вопросы, но я до сих пор не нашел пояснения, используя С++.

Итак, в основном я хочу эту функцию:

bool capturePartScreen(int x, int y, int w int, h, string dest){
 //Capture part of screen according to coordinates, width and height.
 //Save that captured image as a bmp to dest.
 //Return true if success, false if failure
}

BitBlt:

BOOL BitBlt(
 __in HDC hdcDest,
 __in int nXDest,
 __in int nYDest,
 //The three above are the ones I don't understand!
 __in int nWidth,
 __in int nHeight,
 __in HDC hdcSrc,
 __in int nXSrc,
 __in int nYSrc,
 __in DWORD dwRop
);

Каким должен быть hdc и как я могу получить bmp?

2 ответа

Потребовалось некоторое время, но теперь у меня наконец появился функционал script.

Требования:

#include <iostream>
#include <ole2.h>
#include </ole2.h></iostream>

Также вы можете (?) добавить в свой компоновщик ole32, oleaut32 и uuid.

screenCapturePart:

bool screenCapturePart(int x, int y, int w, int h, LPCSTR fname){
 HDC hdcSource = GetDC(NULL);
 HDC hdcMemory = CreateCompatibleDC(hdcSource);
 int capX = GetDeviceCaps(hdcSource, HORZRES);
 int capY = GetDeviceCaps(hdcSource, VERTRES);
 HBITMAP hBitmap = CreateCompatibleBitmap(hdcSource, w, h);
 HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMemory, hBitmap);
 BitBlt(hdcMemory, 0, 0, w, h, hdcSource, x, y, SRCCOPY);
 hBitmap = (HBITMAP)SelectObject(hdcMemory, hBitmapOld);
 DeleteDC(hdcSource);
 DeleteDC(hdcMemory);
 HPALETTE hpal = NULL;
 if(saveBitmap(fname, hBitmap, hpal)) return true;
 return false;
}

saveBitmap:

bool saveBitmap(LPCSTR filename, HBITMAP bmp, HPALETTE pal)
{
 bool result = false;
 PICTDESC pd;
 pd.cbSizeofstruct = sizeof(PICTDESC);
 pd.picType = PICTYPE_BITMAP;
 pd.bmp.hbitmap = bmp;
 pd.bmp.hpal = pal;
 LPPICTURE picture;
 HRESULT res = OleCreatePictureIndirect(&pd, IID_IPicture, false,
 reinterpret_cast<void**>(&picture));
 if (!SUCCEEDED(res))
 return false;
 LPSTREAM stream;
 res = CreateStreamOnHGlobal(0, true, &stream);
 if (!SUCCEEDED(res))
 {
 picture->Release();
 return false;
 }
 LONG bytes_streamed;
 res = picture->SaveAsFile(stream, true, &bytes_streamed);
 HANDLE file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, 0,
 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
 if (!SUCCEEDED(res) || !file)
 {
 stream->Release();
 picture->Release();
 return false;
 }
 HGLOBAL mem = 0;
 GetHGlobalFromStream(stream, &mem);
 LPVOID data = GlobalLock(mem);
 DWORD bytes_written;
 result = !!WriteFile(file, data, bytes_streamed, &bytes_written, 0);
 result &= (bytes_written == static_cast<dword>(bytes_streamed));
 GlobalUnlock(mem);
 CloseHandle(file);
 stream->Release();
 picture->Release();
 return result;
}
</dword></void**>


Вы можете использовать GetDC(NULL), чтобы получить контекст устройства для всего экрана, а затем использовать его с BitBlt в качестве контекста исходного устройства.

Что касается остальной части того, что делать:

Создание растрового изображения (Windows)

Растровое хранилище (Windows)

licensed under cc by-sa 3.0 with attribution.