BOOL Capture(HWND hWnd,RECT pircRect,CString picstrFilename,int piiSerial)
{
HBITMAP hDesktopCompatibleBitmap=NULL;
HDC hDesktopCompatibleDC=NULL;
HDC hDesktopDC=NULL;
HWND hDesktopWnd=NULL;

hDesktopWnd=GetDesktopWindow();
hDesktopDC=GetDC(hDesktopWnd);
hDesktopCompatibleDC=CreateCompatibleDC(hDesktopDC);
hDesktopCompatibleBitmap=CreateCompatibleBitmap(hDesktopDC,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
SelectObject(hDesktopCompatibleDC,hDesktopCompatibleBitmap); BitBlt(hDesktopCompatibleDC,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),hDesktopDC,0,0,SRCCOPY); BITMAPINFO bi;
void *         pBits=NULL;
int  nWidth=GetSystemMetrics(SM_CXSCREEN);
int  nHeight=GetSystemMetrics(SM_CYSCREEN);
ZeroMemory(&bi,sizeof(bi));
bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
bi.bmiHeader.biHeight=nHeight;
bi.bmiHeader.biWidth=nWidth;
bi.bmiHeader.biPlanes=1;
bi.bmiHeader.biBitCount=24;
bi.bmiHeader.biCompression=BI_RGB;
bi.bmiHeader.biSizeImage=3*nWidth * nHeight;
HDC hBmpFileDC=CreateCompatibleDC(hDesktopCompatibleDC);
HBITMAP hBmpFileBitmap=CreateDIBSection(hDesktopCompatibleDC,&bi,DIB_RGB_COLORS,&pBits,NULL,0);
SelectObject(hBmpFileDC,hBmpFileBitmap);
BitBlt(hBmpFileDC,0,0,nWidth,nHeight,hDesktopCompatibleDC,0,0,SRCCOPY);// if(piiSerial > 140)
{
HANDLE hFile = CreateFile(picstrFilename,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile!=INVALID_HANDLE_VALUE)
{
DWORD dwRet=0;
BITMAPFILEHEADER bmfHeader;
ZeroMemory(&bmfHeader,sizeof(bmfHeader));
bmfHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
bmfHeader.bfSize=bi.bmiHeader.biSizeImage+bmfHeader.bfOffBits;
bmfHeader.bfType='MB';

WriteFile(hFile,&bmfHeader,sizeof(bmfHeader),&dwRet,NULL);
WriteFile(hFile,&bi.bmiHeader,sizeof(bi.bmiHeader),&dwRet,NULL);
WriteFile(hFile,pBits,bi.bmiHeader.biSizeImage,&dwRet,NULL);
CloseHandle(hFile);
}
}
DeleteDC(hBmpFileDC);
DeleteObject(hBmpFileBitmap); return TRUE;
}是抓屏的.
这个函数在一个循环里调用两百次.抓出来的前三四十个图是正确的.
后面的BMP文件即是黑屏了.但是能正常打开,和正常的图片大小一样.请问错在哪儿?谢谢!

解决方案 »

  1.   

    DeleteObject(hDesktopCompatibleBitmap);
      

  2.   

    bi.bmiHeader.biSizeImage=3*nWidth * nHeight好象不对吧?
    DWORD  dwBytesPerLine  =  (((lpbi->biWidth*lpbi->biBitCount+7)/8)+3)/4*4;  
    bi.bmiHeader.biSizeImage =    dwBytesPerLine*lpbi->biHeight
      

  3.   

    内存泄露,hDesktopCompatibleBitmap
      

  4.   

    参考:
    void CCaptureDlg::SaveBmp()
    {
    CDC dc;
    dc.CreateDC("DISPLAY",NULL,NULL,NULL);
    CBitmap bm;
    int Width=GetSystemMetrics(SM_CXSCREEN);
    int Height=GetSystemMetrics(SM_CYSCREEN);
    bm.CreateCompatibleBitmap(&dc,Width,Height);
    CDC tdc;
    tdc.CreateCompatibleDC(&dc);
    CBitmap*pOld=tdc.SelectObject(&bm);
    tdc.BitBlt(0,0,Width,Height,&dc,0,0,SRCCOPY);
    tdc.SelectObject(pOld);
    BITMAP btm;
    bm.GetBitmap(&btm);
    DWORD size=btm.bmWidthBytes*btm.bmHeight;
    LPSTR lpData=(LPSTR)GlobalAllocPtr(GPTR,size);
    /////////////////////////////////////////////
    BITMAPINFOHEADER bih;
    bih.biBitCount=btm.bmBitsPixel;
    bih.biClrImportant=0;
    bih.biClrUsed=0;
    bih.biCompression=0;
    bih.biHeight=btm.bmHeight;
    bih.biPlanes=1;
    bih.biSize=sizeof(BITMAPINFOHEADER);
    bih.biSizeImage=size;
    bih.biWidth=btm.bmWidth;
    bih.biXPelsPerMeter=0;
    bih.biYPelsPerMeter=0;
    ///////////////////////////////////
    GetDIBits(dc,bm,0,bih.biHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);
    // bm.GetBitmapBits(size,lpData); //此函数在处理5-5-5模式的16位色下会出现颜色混乱
    //////////////////////////////
    static int filecount=0;
    CString name;
    name.Format("pict%04d.bmp",filecount++);
    name=m_Path+name;
    BITMAPFILEHEADER bfh;
    bfh.bfReserved1=bfh.bfReserved2=0;
    bfh.bfType=((WORD)('M'<< 8)|'B');
    bfh.bfSize=54+size;
    bfh.bfOffBits=54;
    CFile bf;
    if(bf.Open(name,CFile::modeCreate|CFile::modeWrite)){
    bf.WriteHuge(&bfh,sizeof(BITMAPFILEHEADER));
    bf.WriteHuge(&bih,sizeof(BITMAPINFOHEADER));
    bf.WriteHuge(lpData,size);
    bf.Close();
    nCount++;
    }
    GlobalFreePtr(lpData);
    if(nCount==1)
    m_Number.Format("%d picture captured.",nCount);
    else
    m_Number.Format("%d pictures captured.",nCount);
    UpdateData(FALSE);
    }
      

  5.   

    ReleaseDC(hDesktopWnd,hDesktopDC);
    但你在循环中抓屏??即便没有内存泄漏或是GDI泄漏的问题,你的显卡处理及总线处理得过来不?