DaniWeb IT Discussion Community

DaniWeb IT Discussion Community (http://www.daniweb.com/forums/index.php)
-   C++ (http://www.daniweb.com/forums/forum8.html)
-   -   Screen Capture Program (http://www.daniweb.com/forums/thread189901.html)

kashmir323 May 1st, 2009 4:58 pm
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;
}

William Hemsworth May 1st, 2009 6:23 pm
Re: Screen Capture Program
 
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.

kashmir323 May 1st, 2009 7:31 pm
Re: Screen Capture Program
 
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.

William Hemsworth May 1st, 2009 8:19 pm
Re: Screen Capture Program
 
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.

kashmir323 May 1st, 2009 9:46 pm
Re: Screen Capture Program
 
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:
Quote:

"LRSscreenshooter - Release" uses an invalid compiler. Skipping...
Nothing to be done.
Any idea what is wrong? And im building this in CodeBlocks 8.02.

thefly Oct 28th, 2009 5:06 am
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!

ithelp Oct 28th, 2009 5:08 am
Quote:

Originally Posted by thefly (Post 1029452)
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 ?

thefly Oct 28th, 2009 5:16 am
Quote:

Originally Posted by ithelp (Post 1029454)
What OS are you using ?

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


All times are GMT -4. The time now is 12:44 pm.

Forum system based on vBulletin Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
©2003 - 2009 DaniWeb® LLC