Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中选择屏幕创建位图时出现黑色图像+;_C++_Winapi_Screenshot_Bmp - Fatal编程技术网

C++ 在C+中选择屏幕创建位图时出现黑色图像+;

C++ 在C+中选择屏幕创建位图时出现黑色图像+;,c++,winapi,screenshot,bmp,C++,Winapi,Screenshot,Bmp,我正在尝试获取桌面选定区域的屏幕截图 我遇到的问题是输出(.bmp文件)是黑色的 我获取了createBitMapInfo();和CreateBMPFile();从…起其余的都是我从网上截取的弗兰肯斯坦 下面是我的代码目前的样子: #include <windows.h> #include <iostream> #include <fstream> #include <string> using namespace std; PBITMAPINF

我正在尝试获取桌面选定区域的屏幕截图

我遇到的问题是输出(.bmp文件)是黑色的

我获取了createBitMapInfo();和CreateBMPFile();从…起其余的都是我从网上截取的弗兰肯斯坦

下面是我的代码目前的样子:

#include <windows.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp)
{ 
    BITMAP bmp; 
    PBITMAPINFO pbmi; 
    WORD    cClrBits; 

    // Retrieve the bitmap color format, width, and height.  
    if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp)) 
        cout << "ERROR:1";

    // 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 these formats: 24-bit-per-pixel or 32-bit-per-pixel 

     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.  
    // The width must be DWORD 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; 
     return pbmi; 
 } 

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; 

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

    if (!lpBits) 
         cout << "ERROR:2"; 

    // Retrieve the color table (RGBQUAD array) and the bits  
    // (array of palette indices) from the DIB.  
    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); 
    if (hf == INVALID_HANDLE_VALUE) 
        cout << "ERROR:4"; 
    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.  
    if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), 
        (LPDWORD) &dwTmp,  NULL)) 
    {
       cout << "ERROR:5";
    }

    // Copy the BITMAPINFOHEADER and RGBQUAD array into the file.  
    if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) 
                  + pbih->biClrUsed * sizeof (RGBQUAD), 
                  (LPDWORD) &dwTmp, ( NULL)))
        cout << "ERROR:6";

    // Copy the array of color indices into the .BMP file.  
    dwTotal = cb = pbih->biSizeImage; 
    hp = lpBits; 
    if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) 
           cout << "ERROR:7";

    // Close the .BMP file.  
     if (!CloseHandle(hf)) 
           cout << "ERROR:8"; 

    // Free memory.  
    GlobalFree((HGLOBAL)lpBits);
}

void getBit(string name) {
    int nX = 300;
    int nX2 = 600;
    int nY = 300;
    int nY2 = 700;
     HDC hScrDC  =  GetDC(NULL); 
     HDC hMemDC  =  CreateCompatibleDC(hScrDC);
     int nWidth  =  nX2  -  nX; 
     int nHeight  =  nY2  -  nY; 
     HBITMAP hBitmap  =  CreateCompatibleBitmap(hScrDC,  nWidth,  nHeight); 
     HBITMAP hOldBitmap  =  (HBITMAP)SelectObject(hMemDC,  hBitmap); 

     BitBlt(hMemDC,  0,  0,  nWidth,  nHeight, 
     hScrDC,  nX,  nY,  SRCCOPY); 
     hBitmap  =  (HBITMAP)SelectObject(hMemDC,  hOldBitmap); 
     DeleteDC(hScrDC); 
     DeleteDC(hMemDC); 
    // now your image is held in hBitmap. You can save it or do whatever with it
    PBITMAPINFO pbi = CreateBitmapInfoStruct(hBitmap);
    //File name
    LPTSTR path = L"test.bmp";
    CreateBMPFile(path,pbi,hBitmap,hMemDC);
}

void main(void) {
    getBit("SAVE");
    cout << "Done";
    int wait;
    cin >> wait;
}
#包括
#包括
#包括
#包括
使用名称空间std;
PBITMAPINFO CreateBitMapInfo结构(HBITMAP hBmp)
{ 
位图bmp;
PBITMAPINFO pbmi;
字cClrBits;
//检索位图颜色格式、宽度和高度。
if(!GetObject(hBmp、sizeof(位图)、(LPSTR)和bmp))
cout bmiHeader.biclrued=(1bmiHeader.biSizeImage=((pbmi->bmiHeader.biWidth*cClrBits+31)和~31)/8
*pbmi->bmi header.biHeight;
//将biClrImportant设置为0,表示所有
//设备颜色很重要。
pbmi->bmiHeader.biClrImportant=0;
返回pbmi;
} 
void CreateBMPFile(LPTSTR pszFile、PBITMAPINFO pbi、,
HBITMAP hBMP,HDC HDC)
{ 
HANDLE hf;//文件句柄
BITMAPFILEHEADER hdr;//位图文件头
PBITMAPINFOHEADER pbih;//位图信息头
LPBYTE lpBits;//内存指针
DWORD dwTotal;//字节总数
DWORD cb;//字节的增量计数
BYTE*hp;//字节指针
DWORD dwTmp;
pbih=(PBITMAPINFOHEADER)pbi;
lpBits=(LPBYTE)GlobalAlloc(GMEM_固定,pbih->biSizeImage);
if(!lpBits)
cout-biHeight、lpBits、pbi、,
DIB_RGB_颜色);
//创建.BMP文件。
hf=创建文件(pszFile,
一般的读,一般的写,
(德沃德)0,
无效的
永远创造你,
文件\u属性\u正常,
(句柄)NULL);
if(hf==无效的句柄值)
cout biSize+pbih->biClrUsed
*sizeof(RGBQUAD)+pbih->biSizeImage;
hdr.bfReserved1=0;
hdr.bfserved2=0;
//计算颜色索引数组的偏移量。
hdr.bOffBits=(DWORD)大小(BITMAPFILEHEADER)+
pbih->biSize+pbih->BICLRUSE
*sizeof(RGBguad);
//将BITMAPFILEHEADER复制到.BMP文件中。
如果(!WriteFile(hf,(LPVOID)&hdr,sizeof(BITMAPFILEHEADER),
(LPDWORD)和dwTmp,空)
{
cout biClrUsed*sizeof(RGBQUAD),
(LPDWORD)和dwTmp(NULL)))
cout-biSizeImage;
hp=lpbit;
if(!WriteFile(hf,(LPSTR)hp,(int)cb,(LPDWORD)和dwTmp,NULL))

cout最大的问题是,
GetDIBits
失败,因为您正在将句柄传递给已删除的内存上下文,而不是传递给有效的设备上下文。如果您解决了这个问题,它就会工作

调试时,最好检查所有返回值

我注意到的其他事情:

  • 您不应该删除hSrcDC,因为您没有创建它。请使用
    ReleaseDC
    ,它是
    GetDC
    的配套工具
  • 考虑在
    BitBlt
    调用中使用
    CAPTUREBLT

  • 如果我在getBit例程结束时移动他的DeleteDC函数,这对我也很有效。我尝试使用ReleaseDC,但这个函数有两个参数:ReleaseDC(u in_opt HWND HWND,u in HDC HDC);但是,在他的代码中,他没有声明任何HWND变量,所以我像那样传递了NULL,结果成功了。ReleaseDC(NULL,hScrDC);ReleaseDC(NULL,hMemDC);在他的情况下使用它是否合适?@ForceMagic:ReleaseDC用于返回您通过GetDC获得的DC。如果您需要整个屏幕的DC,则GetDC接受HWND或NULL。由于他使用NULL调用GetDC,因此调用ReleaseDC(NULL,hSrcDC)是合适的.但hMemDC来自CreateCompatibleDC调用,因此DeleteDC适用于该调用。