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;
}

Recommended Answers

All 7 Replies

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.

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.

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

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.

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!

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 ?

What OS are you using ?

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

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.