代码之家  ›  专栏  ›  技术社区  ›  Wade Tandy

屏幕捕获代码生成黑色位图

  •  0
  • Wade Tandy  · 技术社区  · 16 年前

    我需要增加的能力,采取整个屏幕截图,而不仅仅是当前的窗口。下面的代码生成具有正确尺寸的bmp文件,但图像是完全黑色的。我做错了什么?

    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);
    }
    
    
    
    1 回复  |  直到 16 年前
        1
  •  3
  •   Stewart    16 年前

    CaptureScreen函数所做的只是创建一个与屏幕大小相同的兼容位图,然后将其写入磁盘,这样您就可以看到位图的默认内容(黑色)。要捕获需要创建兼容DC的屏幕,请选择制作到其中的位图,然后从一个DC到另一个DC进行blit。然后,在开始写入文件之前,需要取消选择目标位图。