Sign in to follow this  

Taking a screenshot

This topic is 4840 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Quote:
Original post by Jareds411
How do I take a screenshot in c++ and save it to a specified file? Thanks. :D


You can't take a screenshot via standard C++ code, as C++ has no standard way of rendering. Do you mean how to take a screenshot in a 3D API, like OpenGL, or Direct3D? If so, I suggest that you search google with "OpenGL" (or "Direct3D"), "C++" and "screenshot" as keywords, and you should be able to find information.

Otherwise, if you want to take a screenshot of a running program, you're going to have to check into the win32 API. See MSDN.

Share this post


Link to post
Share on other sites
you sir are in luck, but it's mostly a lot of sloppy msdn code. i haven't had a chance to work it down into a tight function yet.

#include <windows.h>

void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi,
HBITMAP hBMP, HDC hDC);
PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp);

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
// Create a normal DC and a memory DC for the entire screen. The
// normal DC provides a "snapshot" of the screen contents. The
// memory DC keeps a copy of this "snapshot" in the associated
// bitmap.

HDC hdcScreen = CreateDC("DISPLAY", NULL, NULL, NULL);
HDC hdcCompatible = CreateCompatibleDC(hdcScreen);

// Create a compatible bitmap for hdcScreen.

HBITMAP hbmScreen = CreateCompatibleBitmap(hdcScreen,
GetDeviceCaps(hdcScreen, HORZRES),
GetDeviceCaps(hdcScreen, VERTRES));

if (hbmScreen == 0)
MessageBox(NULL, "hbmScreen", "Error", MB_OK);

// Select the bitmaps into the compatible DC.

if (!SelectObject(hdcCompatible, hbmScreen))
MessageBox(NULL, "Compatible Bitmap Selection", "Error", MB_OK);

//Copy color data for the entire display into a
//bitmap that is selected into a compatible DC.
if (!BitBlt(hdcCompatible,
0,0,
GetDeviceCaps(hdcScreen, HORZRES), GetDeviceCaps(hdcScreen, VERTRES),
hdcScreen,
0,0,
SRCCOPY))
MessageBox(NULL, "Screen to Compat Blt Failed", "Error", MB_OK);

PBITMAPINFO pBitmapInfo = CreateBitmapInfoStruct(hbmScreen);
CreateBMPFile(NULL, "test.bmp", pBitmapInfo,
hbmScreen, hdcScreen);
return 0;
}



PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp)
{
BITMAP bmp;
PBITMAPINFO pbmi;
WORD cClrBits;

// Retrieve the bitmap color format, width, and height.
if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp))
MessageBox(NULL, "error", "Error", MB_OK);

// Convert the color format to a count of bits.
cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
if (cClrBits == 1)
cClrBits = 1;
else if (cClrBits <= 4)
cClrBits = 4;
else if (cClrBits <= 8)
cClrBits = 8;
else if (cClrBits <= 16)
cClrBits = 16;
else if (cClrBits <= 24)
cClrBits = 24;
else cClrBits = 32;

// Allocate memory for the BITMAPINFO structure. (This structure
// contains a BITMAPINFOHEADER structure and an array of RGBQUAD
// data structures.)

if (cClrBits != 24)
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * (1<< cClrBits));

// There is no RGBQUAD array for the 24-bit-per-pixel format.

else
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER));

// Initialize the fields in the BITMAPINFO structure.

pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = bmp.bmWidth;
pbmi->bmiHeader.biHeight = bmp.bmHeight;
pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
if (cClrBits < 24)
pbmi->bmiHeader.biClrUsed = (1<<cClrBits);

// If the bitmap is not compressed, set the BI_RGB flag.
pbmi->bmiHeader.biCompression = BI_RGB;

// Compute the number of bytes in the array of color
// indices and store the result in biSizeImage.
// For Windows NT, the width must be DWORD aligned unless
// the bitmap is RLE compressed. This example shows this.
// For Windows 95/98/Me, the width must be WORD aligned unless the
// bitmap is RLE compressed.
pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8
* pbmi->bmiHeader.biHeight;
// Set biClrImportant to 0, indicating that all of the
// device colors are important.
pbmi->bmiHeader.biClrImportant = 0;
return pbmi;
}

void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi,
HBITMAP hBMP, HDC hDC)
{
HANDLE hf; // file handle
BITMAPFILEHEADER hdr; // bitmap file-header
PBITMAPINFOHEADER pbih; // bitmap info-header
LPBYTE lpBits; // memory pointer
DWORD dwTotal; // total count of bytes
DWORD cb; // incremental count of bytes
BYTE *hp; // byte pointer
DWORD dwTmp;

pbih = (PBITMAPINFOHEADER) pbi;
lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);

if (!lpBits)

MessageBox(NULL, "GlobalAlloc", "Error", MB_OK);

// Retrieve the color table (RGBQUAD array) and the bits
// (array of palette indices) from the DIB.
if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi,
DIB_RGB_COLORS))
{

MessageBox(NULL, "GetDIBits", "Error", MB_OK);
}

// Create the .BMP file.
hf = CreateFile(pszFile,
GENERIC_READ | GENERIC_WRITE,
(DWORD) 0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if (hf == INVALID_HANDLE_VALUE)

MessageBox(NULL, "CreateFile", "Error", MB_OK);
hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M"
// Compute the size of the entire file.
hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +
pbih->biSize + pbih->biClrUsed
* sizeof(RGBQUAD) + pbih->biSizeImage);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;

// Compute the offset to the array of color indices.
hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +
pbih->biSize + pbih->biClrUsed
* sizeof (RGBQUAD);

// Copy the BITMAPFILEHEADER into the .BMP file.
if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER),
(LPDWORD) &dwTmp, NULL))
{
MessageBox(NULL, "error", "Error", MB_OK);
}

// Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER)
+ pbih->biClrUsed * sizeof (RGBQUAD),
(LPDWORD) &dwTmp, ( NULL)))
MessageBox(NULL, "error", "Error", MB_OK);

// Copy the array of color indices into the .BMP file.
dwTotal = cb = pbih->biSizeImage;
hp = lpBits;
if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL))
MessageBox(NULL, "error", "Error", MB_OK);

// Close the .BMP file.
if (!CloseHandle(hf))
MessageBox(NULL, "error", "Error", MB_OK);

// Free memory.
GlobalFree((HGLOBAL)lpBits);
}



may not clear anything up, but it will get the job done.

Share this post


Link to post
Share on other sites
I tried to compile that under Dev-C++ and got this error message:

C:\DOCUME~1\JAREDJ~1\LOCALS~1\Temp\ccYDdaaa.o: In function `CreateBitmapInfoStruct(HBITMAP__ *)':
//c/docume~1/jaredj~1/desktop/screen~1.cpp:56: undefined reference to `GetObjectA@12'
C:\DOCUME~1\JAREDJ~1\LOCALS~1\Temp\ccYDdaaa.o: In function `CreateBMPFile(HWND__ *, char *, tagBITMAPINFO *, HBITMAP__ *, HDC__ *)':
//c/docume~1/jaredj~1/desktop/screen~1.cpp:137: undefined reference to `GetDIBits@28'
C:\DOCUME~1\JAREDJ~1\LOCALS~1\Temp\ccYDdaaa.o: In function `WinMain':
//c/docume~1/jaredj~1/desktop/screen~1.cpp:14: undefined reference to `CreateDCA@16'
//c/docume~1/jaredj~1/desktop/screen~1.cpp:15: undefined reference to `CreateCompatibleDC@4'
//c/docume~1/jaredj~1/desktop/screen~1.cpp:19: undefined reference to `GetDeviceCaps@8'
//c/docume~1/jaredj~1/desktop/screen~1.cpp:19: undefined reference to `GetDeviceCaps@8'
//c/docume~1/jaredj~1/desktop/screen~1.cpp:19: undefined reference to `CreateCompatibleBitmap@12'
//c/docume~1/jaredj~1/desktop/screen~1.cpp:28: undefined reference to `SelectObject@8'
//c/docume~1/jaredj~1/desktop/screen~1.cpp:38: undefined reference to `GetDeviceCaps@8'
//c/docume~1/jaredj~1/desktop/screen~1.cpp:38: undefined reference to `GetDeviceCaps@8'
//c/docume~1/jaredj~1/desktop/screen~1.cpp:38: undefined reference to `BitBlt@36'

Share this post


Link to post
Share on other sites
Quote:
Original post by Charles Hwang
It seems you dont' have DX setup properly for the use of those functions? I'm know you use DevC++ though (by the errors) and that's beyond my expertise.

No DX! He needs to link GDI32.lib (gdi32.a in Dev-C++?).

Share this post


Link to post
Share on other sites

This topic is 4840 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this