问题
Possible Duplicate:
how to make screen screenshot with win32 in c++?
I am currently trying to create an application that saved a portion of the screen to a bmp. I have found BitBlt but I really don't know what to do with it. I have tried searching for some answers but I still haven't found a clarifying one using C++.
So, basically I want this function:
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
);
What should that hdc be and how do I obtain the bmp?
回答1:
It took a while, but I have now finally ended up with a functioning script.
Requirements:
#include <iostream>
#include <ole2.h>
#include <olectl.h>
Also you might(?) have to add ole32, oleaut32 and uuid to your linker.
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;
}
回答2:
You can use GetDC(NULL)
to get the device context for the entire screen, then use that with BitBlt
as the source device context.
As for the rest of what to do:
Bitmap Creation (Windows)
Bitmap Storage (Windows)
来源:https://stackoverflow.com/questions/9524393/how-to-capture-part-of-the-screen-and-save-it-to-a-bmp