Jump to content
  • Advertisement
Sign in to follow this  
Jareds411

Taking a screenshot

This topic is 5150 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

Advertisement
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
I don't want to take a screenshot of a specific program. I want to take a screenshot of the entire screen as the user sees it from the winapi.

Share this post


Link to post
Share on other sites
I've been looking for a couple days, and I'm not really understanding what they're saying. I'd really appreciate it if someone could post the barebones code to take a screenshot.

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
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!