开发者

Screen capture code produces black bitmap

I need to add the ability to take a screenshot of the entire screen, not just the current window. The following code produces a bmp file with the correct dimensions, but the image is completely black. What am I doing wrong?

void CaptureScreen(LPCTSTR lpszFilePathName)
{
      BITMAPFILEHEADER   bmfHeader;
      BITMAPINFO                *pbminfo;
      HBITMAP                   hBmp;
      FILE                      *oFile;
      HDC      screen;
   HDC      memDC;
   int      sHeight;  
   int      sWidth;   
      LPBYTE     pBuff;
   BITMAP     bmp;
   WORD      cClrBits; 
   RECT      rcClient;


   screen = GetDC(0);
   memDC = CreateCompatibleDC(screen);

   sHeight = GetDeviceCaps(screen, VERTRES);
   sWidth = GetDeviceCaps(screen, HORZRES);

   //GetObject(screen, sizeof(BITMAP), &bmp);

   hBmp    = CreateCompatibleBitmap ( screen, sWidth, sHeight );

   // Retrieve the bitmap color format, width, and height.  
 GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp) ;

    // Convert the color format to a count of bits.  
    cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); 
    if (cClrBits == 1) 
        cClrBits = 1; 
    else if (cClrBits bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
    pbminfo->bmiHeader.biWidth = bmp.bmWidth; 
    pbminfo->bmiHeader.biHeight = bmp.bmHeight; 
    pbminfo->bmiHeader.biPlanes = bmp.bmPlanes; 
    pbminfo->bmiHeader.biBitCount = bmp.bmBitsPixel; 
    if (cClrBits bmiHeader.biClrUsed = (1bmiHeader.biCompression = BI_RGB; 

    // Compute the number of bytes in the array of color  
    // indices and store the result in biSizeImage.  
    // The width must be DWORD aligned unless the bitmap is RLE 
    // compressed. 
    pbminfo->bmiHeader.biSizeImage = ((pbminfo->bmiHeader.biWidth * cClrBits +31) & ~31) /8
                                  * pbminfo->bmiHeader.biHeight; 
    // Set biClrImportant to 0, indicating that all of the  
    // device colors are important.  
     pbminfo->bmiHeader.biClrImportant = 0; 

  CreateBMPFile(lpszFilePathName, pbminfo, hBmp, memDC);
}

void CreateBMPFile(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; 
 int lines;

    pbih = (PBITMAPINFOHEADER) pbi; 
    lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);

    // Retrieve the color table (RGBQUAD array) and the bits  
    // (array of palette indices) from the DIB.  
    lines = GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi, 
        DIB_RGB_COLORS);

    // Create the .BMP file.  
    hf = CreateFile(pszFile, 
                   GENERIC_READ | GENERIC_WRITE, 
                   (DWORD) 0, 
                开发者_开发百科    NULL, 
                   CREATE_ALWAYS, 
                   FILE_ATTRIBUTE_NORMAL, 
                   (HANDLE) NULL); 

    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.  
    WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), 
        (LPDWORD) &dwTmp,  NULL);

    // Copy the BITMAPINFOHEADER and RGBQUAD array into the file.  
    WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) 
                  + pbih->biClrUsed * sizeof (RGBQUAD), 
                  (LPDWORD) &dwTmp, ( NULL));

    // Copy the array of color indices into the .BMP file.  
    dwTotal = cb = pbih->biSizeImage; 
    hp = lpBits; 
    WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL);
    // Close the .BMP file.  
 CloseHandle(hf);
    // Free memory.  
    GlobalFree((HGLOBAL)lpBits);
}



All the CaptureScreen function does is create a compatible bitmap the same size as the screen and then write it out to disk, so you're seeing the default contents of the bitmap (black). To capture the screen you need to create a compatible DC, select the bitmap you made into it and blit from one DC to the other. Then you need to unselect your target bitmap before you start writing the file.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜