Thread: Trying to take lots of screenshots, program crashes.

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    76

    Trying to take lots of screenshots, program crashes.

    No matter how I structure my main function, I can't run l1see() more than 65 times before I get a false return because CreateCompatibleBitmap returned 0. Can anyone help me explain this problem, and make it so I can run l1see() in an infinite loop, with less than 20 milliseconds of manual sleep/sdl_delay time between each one?

    Code:
    #include <windows.h>
    #include <iostream>
    #include <winable.h>
    #include <fstream>
    #include <sstream>
    #include <SDL.h>
    #include <math.h>
    
    using namespace std;
    
    string istr(int in)
    {
           stringstream tmp;
           tmp<<in;
           return tmp.str();
    }
    
    struct simple_rgb
    {
           unsigned char r,g,b;
           string rgbstr(){return istr((unsigned int)r)+":"+istr((unsigned int)g)+":"+istr((unsigned int)b);};
    };
    
    struct extended_rgb
    {
           simple_rgb *pixels;
           int width,height;
           bool alloced;
           void alloc(){delete pixels; pixels = new simple_rgb[width*height]; alloced = true;};
           extended_rgb(){alloced = false;width=1;height=1;};
    };
    
    extended_rgb view;
    
    int sdloutputmsoffsetstatic = 0;
    
    void output(string out)
    {
           fstream err("general.log",ios::out|ios::app);
           err<<SDL_GetTicks()-sdloutputmsoffsetstatic<<"ms : "<<out<<"\n";
           err.close();
    }
    
    int sw=0,sh=0;
    
    bool l1see()
    {
    
         // 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) {
    		output("hbmscreen");return false;}
     
    	// Select the bitmaps into the compatible DC. 
     
    	if (!SelectObject(hdcCompatible, hbmScreen)) {
    		output("Bitmap selection");return false;}
    
     
    		 //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)) 
    				   {
    			output("screen blt failed");return false;}
     			
        BITMAP bmp; 
        PBITMAPINFO pbmi; 
        WORD    cClrBits; 
    
        // Retrieve the bitmap color format, width, and height. 
        if (!GetObject(hbmScreen, sizeof(BITMAP), (LPSTR)&bmp)) {
     		output("getobject");return false;}
     		
        // 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; 
         			
        BITMAPFILEHEADER hdr;       // bitmap file-header 
        PBITMAPINFOHEADER pbih;     // bitmap info-header 
        LPBYTE lpBits;              // memory pointer 
        
        pbih = (PBITMAPINFOHEADER) pbmi; 
        lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
        if (!lpBits) {
     
    		 output("global alloc");return false;}
    		 
        // Retrieve the color table (RGBQUAD array) and the bits 
        // (array of palette indices) from the DIB. 
        if (!GetDIBits(hdcScreen, hbmScreen, 0, (WORD) pbih->biHeight, lpBits, pbmi, 
            DIB_RGB_COLORS)) {
        output("getdibits");return false;}
    
        char *lptest;
        lptest = (char*)lpBits;
        
        int pixoffset = 0;
        
        
        view.width =  bmp.bmWidth;
        view.height = bmp.bmHeight;
        if(!view.alloced)
             view.alloc();
         
         sw = bmp.bmWidth;
         sh = bmp.bmHeight;
         
              for(int i = 0; i<bmp.bmHeight; i++)
              {
                   
              for(int z = 0; z<bmp.bmWidth; z++)
              {                              
            
                      unsigned char rgb[3];
                      rgb[0] = lptest[pixoffset];
                      rgb[1] = lptest[pixoffset+1];
                      rgb[2] = lptest[pixoffset+2];
                      
                      view.pixels[((bmp.bmHeight-i)*bmp.bmWidth)+(bmp.bmWidth-z)].r = rgb[2];
                      view.pixels[((bmp.bmHeight-i)*bmp.bmWidth)+(bmp.bmWidth-z)].g = rgb[1];
                      view.pixels[((bmp.bmHeight-i)*bmp.bmWidth)+(bmp.bmWidth-z)].b = rgb[0];
                      
                      pixoffset += 4;
              }
              
    
              
              }
        
        DeleteDC(hdcScreen);
        DeleteDC(hdcCompatible);
        GlobalFree((HGLOBAL)lpBits);
        GlobalFree(lpBits);
        delete lpBits;
        delete hdcScreen;
        delete hdcCompatible;
        delete lptest;
        
        
        return true;
        
        
    }
    
    void sendkey(unsigned char key)
    {
        KEYBDINPUT  kb = {0};
        INPUT       Input = {0};
        kb.wVk  = key;
        Input.type  = INPUT_KEYBOARD;
        Input.ki  = kb;
        SendInput(1, &Input, sizeof(Input));
    }
    
    struct uint2{unsigned int a,b;string tostr(){return istr(a)+":"+istr(b);};};
    struct uint3{unsigned int a,b,c;string tostr(){return istr(a)+":"+istr(b)+":"+istr(c);};};
    struct uint4{unsigned int a,b,c,d;string tostr(){return istr(a)+":"+istr(b)+":"+istr(c)+":"+istr(d);};};
    
    int postoarray(int x,int y){return (y*sw)+x;}
    
    uint2 arraytopos(int in)
    {
          uint2 ret;
          float f1 = in/sw;
          float f2 = floor(f1);
          int f3 = (int)f2;
    
          ret.b = f3;
          ret.a = in-(f3*sw);
    
          return ret;
    }
    
    uint3 postocolor(int x,int y)
    {
          if(postoarray(x,y) > 0 && postoarray(x,y) < sw*sh)
          {
                uint3 ret;
                ret.a = view.pixels[postoarray(x,y)].r;
                ret.b = view.pixels[postoarray(x,y)].g;
                ret.c = view.pixels[postoarray(x,y)].b;
                return ret;
          }
    }
    
    int main(int argc, char *argv[])
    {       
    
        //FreeConsole();
        remove("general.log");
            
        sdloutputmsoffsetstatic = SDL_GetTicks();
        output("Starting program.");
        
        l1see();
        
        bool processedpixels[sw*sh];
        
        output("Starting round 1...");
        
        int a = 0;
        for(int i = 0; i<30; i++)
        {
        a++;
        if(l1see())
        output(istr(a));
        else break;
        }
        
        Sleep(1500);SDL_Delay(1500);
        output("Starting round 2...");
        
        a = 0;
        for(int i = 0; i<30; i++)
        {
        a++;
        if(l1see())
        output(istr(a));
        else break;
        }
        
        Sleep(1500);SDL_Delay(1500);
        output("Starting round 3...");
        
        a = 0;
        for(int i = 0; i<30; i++)
        {
        a++;
        if(l1see())
        output(istr(a));
        else break;
        }
         
        output("Ending program.");
        return 0;
    }
    Last edited by azjherben; 09-25-2010 at 12:16 PM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    GlobalFree(lpBits);
    delete lpBits;
    delete hdcScreen;
    delete hdcCompatible;
    delete lptest;
    Why are you using delete on things that were not allocated with new ?

    You're lucky you got to 65. It could have easily blown up on the first pass.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 02-12-2010, 08:02 PM
  2. Program crashes any ideas
    By auryc in forum C Programming
    Replies: 6
    Last Post: 11-25-2009, 06:50 AM
  3. funcion runs 14 times, then program crashes
    By happyclown in forum C Programming
    Replies: 9
    Last Post: 03-03-2009, 11:58 PM
  4. program crashes on closure.
    By ssjnamek in forum C++ Programming
    Replies: 7
    Last Post: 09-26-2005, 04:55 PM
  5. Program crashes...help Needed!!
    By butterfly in forum C++ Programming
    Replies: 4
    Last Post: 05-31-2002, 11:22 AM