下面是我做的一个位图程序,它能够对当前可视部分进行抓屏保存,但是我改了很长时间始终无法使它对客户区的其他图形进行保存,基类是CScrollView,望高手指点!
//
int CBittestView::GetDIBPixelSize(const BITMAPINFOHEADER &bmih)
{
    if ( bmih.biSizeImage )
        return bmih.biSizeImage;
    else
        return ( bmih.biWidth * bmih.biBitCount + 31 ) / 32 * 4 * bmih.biPlanes * abs(bmih.biHeight);
}
//
int CBittestView::GetDIBColorCount(const BITMAPINFOHEADER & bmih)
{
    if ( bmih.biBitCount <= 8 )
        if ( bmih.biClrUsed )
            return bmih.biClrUsed;
        else
            return 1 << bmih.biBitCount;
else if ( bmih.biCompression==BI_BITFIELDS )
return 3 + bmih.biClrUsed;
else
return bmih.biClrUsed;
}
//
BOOL CBittestView::SaveDIBToBmp(const char* pFileName, const BITMAPINFO *pBMI, const BYTE *pBits)
{
    if(pFileName==NULL)
{
        return FALSE;
    }
    HANDLE handle = CreateFile(pFileName, GENERIC_WRITE, FILE_SHARE_READ, 
        NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if(handle == INVALID_HANDLE_VALUE)
{
        return FALSE;
    }
    BITMAPFILEHEADER bmFH;
    int nHeadSize = sizeof(BITMAPINFOHEADER) + 
sizeof(RGBQUAD) * GetDIBColorCount(pBMI->bmiHeader);
    bmFH.bfType      = 0x4D42;
    bmFH.bfSize      = nHeadSize + GetDIBPixelSize(pBMI->bmiHeader);
    bmFH.bfReserved1 = 0;
    bmFH.bfReserved2 = 0;
    bmFH.bfOffBits   = nHeadSize + sizeof(BITMAPFILEHEADER);
    DWORD dwRead = 0;
    WriteFile(handle, & bmFH, sizeof(bmFH), & dwRead, NULL);
    if(pBits==NULL) // packed DIB
        pBits = (BYTE *) pBMI + nHeadSize;
    WriteFile(handle, pBMI,  nHeadSize,& dwRead, NULL);
    WriteFile(handle, pBits, GetDIBPixelSize(pBMI->bmiHeader), & dwRead, NULL);
    CloseHandle(handle);
    return TRUE;
}
//
BITMAPINFO* CBittestView::BitmapToDIB(HPALETTE hPal,            // palette for color conversion
                         HBITMAP  hBmp,            // DDB for convert
                         int nBitCount, int nCompression,CDC *pDC)    // format wanted
{
    typedef struct
    {
        BITMAPINFOHEADER bmiHeader;
        RGBQUAD              bmiColors[256+3];
    }    DIBINFO;
    BITMAP  ddbinfo;
    DIBINFO dibinfo;
    // retrieve DDB information
    if ( GetObject(hBmp, sizeof(BITMAP), & ddbinfo)==0 )
        return NULL;
    // fill out BITMAPINFOHEADER based on size and required format
    memset(&dibinfo, 0, sizeof(dibinfo));
    dibinfo.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
    dibinfo.bmiHeader.biWidth       = ddbinfo.bmWidth;
    dibinfo.bmiHeader.biHeight      = ddbinfo.bmHeight;
    dibinfo.bmiHeader.biPlanes      = 1;
    dibinfo.bmiHeader.biBitCount    = nBitCount;
    dibinfo.bmiHeader.biCompression = nCompression;
   
HDC hDC =::GetWindowDC(NULL); // screen DC
 // HDC hDC=pDC->GetSafeHdc(); 
    HGDIOBJ hpalOld;
    if ( hPal )
        hpalOld = SelectPalette(hDC, hPal, FALSE);
    else
        hpalOld = NULL;
    // query GDI for image size
    GetDIBits(hDC, hBmp, 0, ddbinfo.bmHeight, NULL, (BITMAPINFO *) & dibinfo, DIB_RGB_COLORS);
    int nInfoSize  = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * GetDIBColorCount(dibinfo.bmiHeader);
    int nTotalSize = nInfoSize + GetDIBPixelSize(dibinfo.bmiHeader);
    BYTE * pDIB = new BYTE[nTotalSize];
    if ( pDIB )
    {
        memcpy(pDIB, & dibinfo, nInfoSize);
        if ( ddbinfo.bmHeight != GetDIBits(hDC, hBmp, 0, ddbinfo.bmHeight, pDIB + nInfoSize, (BITMAPINFO *) pDIB, DIB_RGB_COLORS) )
        {          
delete [] pDIB;
pDIB = NULL;
        }
    }
    if ( hpalOld )
        SelectObject(hDC, hpalOld);
    DeleteDC(hDC);
    return (BITMAPINFO *) pDIB;
}
//
HBITMAP CBittestView::CaptureWindow(CDC *pDC)
{
  // HDC hDC = pDC->m_hDC;
   HDC hDC = pDC->GetSafeHdc();
   HBITMAP hBmp = CreateCompatibleBitmap(hDC,bitmappoint.x,bitmappoint.y);
 if ( hBmp )
    {
        HDC hMemDC   = CreateCompatibleDC(hDC);
        HGDIOBJ hOld = SelectObject(hMemDC, hBmp);
        BitBlt(hMemDC, 0, 0,this->GetTotalSize().cx, this->GetTotalSize().cy, 
            hDC, 0, 0, SRCCOPY);
        SelectObject(hMemDC, hOld);
        DeleteObject(hMemDC);
    }
    DeleteDC(hDC);
return hBmp;
}
//
void CBittestView::SaveWindowToFile(CDC *pDC,const char *filename,int nBitCount,int nCompression)
{
HBITMAP hBmp=CaptureWindow(pDC);
    if(hBmp)
    {
        BITMAPINFO *pDIB = (BITMAPINFO*)BitmapToDIB(NULL, hBmp, nBitCount, nCompression,pDC);
if(pDIB)
        {
SaveDIBToBmp(filename, pDIB, NULL);
delete [](BYTE *) pDIB;
        }
        DeleteObject(hBmp);
    }
}
//void CBittestView::bitmapsave(CDC *pDC)
{
CRect rect;
GetClientRect(&rect);
bitmappoint.x=rect.Width();
bitmappoint.y=rect.Height();
TCHAR szFilters[]=_T("BMP位图(*.bmp)|*.bmp|所有文件(*.*)|*.*|");
CString filename;
CFileDialog dlg(false,_T("BMP"),_T("*.BMP"),OFN_HIDEREADONLY,szFilters);
if(dlg.DoModal()==IDOK)
{
filename=dlg.GetPathName();
SaveWindowToFile(pDC,filename,32,0);
}
}