954,173 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Screen Capture Program

I am creating this simple program that will capture screen shots. I want to make it so the name of the image that is saved is what the user enters into a text field before the picture is taken. and if at all possible is there a way to make this window pop up above the game screen when a key combination is pressed?

thanks! this is the code i have so far btw.

#include<iostream>
#include<windows.h>
using namespace std;

inline int GetFilePointer(HANDLE FileHandle){
	return SetFilePointer(FileHandle, 0, 0, FILE_CURRENT);
}

bool SaveBMPFile(char *filename, HBITMAP bitmap, HDC bitmapDC, int width, int height){
	bool Success=0;
	HDC SurfDC=NULL;
	HBITMAP OffscrBmp=NULL;
	HDC OffscrDC=NULL;
	LPBITMAPINFO lpbi=NULL;
	LPVOID lpvBits=NULL;
	HANDLE BmpFile=INVALID_HANDLE_VALUE;
	BITMAPFILEHEADER bmfh;
	if ((OffscrBmp = CreateCompatibleBitmap(bitmapDC, width, height)) == NULL)
		return 0;
	if ((OffscrDC = CreateCompatibleDC(bitmapDC)) == NULL)
		return 0;
	HBITMAP OldBmp = (HBITMAP)SelectObject(OffscrDC, OffscrBmp);
	BitBlt(OffscrDC, 0, 0, width, height, bitmapDC, 0, 0, SRCCOPY);
	if ((lpbi = (LPBITMAPINFO)(new char[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)])) == NULL)
		return 0;
	ZeroMemory(&lpbi->bmiHeader, sizeof(BITMAPINFOHEADER));
	lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	SelectObject(OffscrDC, OldBmp);
	if (!GetDIBits(OffscrDC, OffscrBmp, 0, height, NULL, lpbi, DIB_RGB_COLORS))
		return 0;
	if ((lpvBits = new char[lpbi->bmiHeader.biSizeImage]) == NULL)
		return 0;
	if (!GetDIBits(OffscrDC, OffscrBmp, 0, height, lpvBits, lpbi, DIB_RGB_COLORS))
		return 0;
	if ((BmpFile = CreateFile(filename,
						GENERIC_WRITE,
						0, NULL,
						CREATE_ALWAYS,
						FILE_ATTRIBUTE_NORMAL,
						NULL)) == INVALID_HANDLE_VALUE)
		return 0;
	DWORD Written;
	bmfh.bfType = 19778;
	bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
	if (!WriteFile(BmpFile, &bmfh, sizeof(bmfh), &Written, NULL))
		return 0;
	if (Written < sizeof(bmfh))
		return 0;
	if (!WriteFile(BmpFile, &lpbi->bmiHeader, sizeof(BITMAPINFOHEADER), &Written, NULL))
		return 0;
	if (Written < sizeof(BITMAPINFOHEADER))
		return 0;
	int PalEntries;
	if (lpbi->bmiHeader.biCompression == BI_BITFIELDS)
		PalEntries = 3;
	else PalEntries = (lpbi->bmiHeader.biBitCount <= 8) ?
					  (int)(1 << lpbi->bmiHeader.biBitCount) : 0;
	if(lpbi->bmiHeader.biClrUsed)
	PalEntries = lpbi->bmiHeader.biClrUsed;
	if(PalEntries){
	if (!WriteFile(BmpFile, &lpbi->bmiColors, PalEntries * sizeof(RGBQUAD), &Written, NULL))
		return 0;
		if (Written < PalEntries * sizeof(RGBQUAD))
			return 0;
	}
	bmfh.bfOffBits = GetFilePointer(BmpFile);
	if (!WriteFile(BmpFile, lpvBits, lpbi->bmiHeader.biSizeImage, &Written, NULL))
		return 0;
	if (Written < lpbi->bmiHeader.biSizeImage)
		return 0;
	bmfh.bfSize = GetFilePointer(BmpFile);
	SetFilePointer(BmpFile, 0, 0, FILE_BEGIN);
	if (!WriteFile(BmpFile, &bmfh, sizeof(bmfh), &Written, NULL))
		return 0;
	if (Written < sizeof(bmfh))
		return 0;
	return 1;
}
bool ScreenCapture(int x, int y, int width, int height, char *filename){
	HDC hDc = CreateCompatibleDC(0);
	HBITMAP hBmp = CreateCompatibleBitmap(GetDC(0), width, height);
	SelectObject(hDc, hBmp);
	BitBlt(hDc, 0, 0, width, height, GetDC(0), x, y, SRCCOPY);
	bool ret = SaveBMPFile(filename, hBmp, hDc, width, height);
	DeleteObject(hBmp);
	return ret;
}

int main() {
	int x1 = 0;
	int y1 = 0;
	int x2 = GetSystemMetrics(SM_CXSCREEN);
	int y2 = GetSystemMetrics(SM_CYSCREEN);
	ScreenCapture(x1, y1, x2 - x1, y2 - y1, "rename_me_before_upload.bmp");
	cin.ignore();
	return 0;
}
kashmir323
Light Poster
28 posts since Jan 2008
Reputation Points: 31
Solved Threads: 0
 

If all you want to do is let allow the user to input the bitmap name, use std::cin to get the name, and strcat ".bmp" on the end. Change your main code like this:

int main() {
  int x1 = 0;
  int y1 = 0;
  int x2 = GetSystemMetrics(SM_CXSCREEN);
  int y2 = GetSystemMetrics(SM_CYSCREEN);

  char bmp_name[100];
  cin.getline( bmp_name, 96 );
  strcat( bmp_name, ".bmp" );


  ScreenCapture(x1, y1, x2 - x1, y2 - y1, bmp_name);

  cin.ignore();
  return 0;
}


>if at all possible is there a way to make this window pop up above the game screen when a key combination is pressed?
Not quite sure what you mean by this.

William Hemsworth
Posting Virtuoso
1,591 posts since Mar 2008
Reputation Points: 1,429
Solved Threads: 129
 

Since this program is a anti-cheat parameter for the league, the picture wont be needed till once the player is in game. so once in game i would like the players to push lets say Shift+Alt+S to bring up the console app over top the game. Then once the picture is taken and saved then push Shift+Alt+S to minimize the console behind the top screen again.

kashmir323
Light Poster
28 posts since Jan 2008
Reputation Points: 31
Solved Threads: 0
 

Okay, that's tricky but possible. In this small example, I check to see if those keys are down. If they are down, it will toggle the windows visibility. I tried using windows hooks to give this example, but I couldn't set the hook without having a hInstance, so I tried this alternative method which works on console windows.

#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <iostream>
using namespace std;

int main() {
  bool visible = false;
  ShowWindow( GetConsoleWindow(), SW_HIDE );

  for ( ; ; ) {

    if ( GetAsyncKeyState( VK_SHIFT ) &&
         GetAsyncKeyState( VK_MENU ) &&
         GetAsyncKeyState( VkKeyScanA('s') ) )
    {
      if ( visible )
        ShowWindow( GetConsoleWindow(), SW_HIDE );
      else
        ShowWindow( GetConsoleWindow(), SW_SHOW );

      visible = !visible;
      Sleep( 500 );
    }

    Sleep( 100 );
  }

  cin.ignore();
}


Whether or notShowWindow will be enough to bring the console window in front of the game, I don't know, but that would be the next stage if the above doesn't work.

Hope this helps.

Code tags don't seem to work correctly, and can't get the C++ syntax, not sure why.

William Hemsworth
Posting Virtuoso
1,591 posts since Mar 2008
Reputation Points: 1,429
Solved Threads: 129
 

Alright. So i havent compiled any programs for a while and im compiling this using the Microsoft Visual C++ Toolkit 2003. When i click build it gives me an error saying:
"LRSscreenshooter - Release" uses an invalid compiler. Skipping...
Nothing to be done.

Any idea what is wrong? And im building this in CodeBlocks 8.02.

kashmir323
Light Poster
28 posts since Jan 2008
Reputation Points: 31
Solved Threads: 0
 

Hello,

I'm trying to use the code in the first post to capture a smaller area than the whole screen. I have a point that is at the center of the area I need to capture. In my main() function I call ScreenCapture(xPos - 25, yPos - 25, 50, 50, "image.bmp"), where xPos is the x-position of the center and yPos is the y-position of the center point.

Everything is running OK, but the saved image is black. It has the right size, but it's black. What am I doing wrong?

Thanx!

thefly
Newbie Poster
2 posts since Oct 2009
Reputation Points: 10
Solved Threads: 0
 

Hello,

I'm trying to use the code in the first post to capture a smaller area than the whole screen. I have a point that is at the center of the area I need to capture. In my main() function I call ScreenCapture(xPos - 25, yPos - 25, 50, 50, "image.bmp"), where xPos is the x-position of the center and yPos is the y-position of the center point.

Everything is running OK, but the saved image is black. It has the right size, but it's black. What am I doing wrong?

Thanx!


What OS are you using ?

ithelp
Nearly a Posting Maven
Banned
2,230 posts since May 2006
Reputation Points: 769
Solved Threads: 128
 
What OS are you using ?

Windows Vista 32bit. Capturing the whole screen works well. I get normal screen shot.

thefly
Newbie Poster
2 posts since Oct 2009
Reputation Points: 10
Solved Threads: 0
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You