我把那位大哥的代码用到了这里,编译可通过,可是执行的时候却出错误,请各位多多指导!!菜鸟有礼了.
HBITMAP CMultimediaDoc::CopyScreenToBitmap(LPRECT lpRect)
 //lpRect 代表选定区域
{
    HDC hScrDC,hMemDC;      
 // 屏幕和内存设备描述表
    HBITMAP hBitmap,hOldBitmap;   
 // 位图句柄
    int nX,nY,nX2,nY2;      
// 选定区域坐标
    int nWidth,nHeight;      
// 位图宽度和高度
    int xScrn,yScrn;         
// 屏幕分辨率
   // 确保选定区域不为空矩形
    if (IsRectEmpty(lpRect))
    return NULL;
   //为屏幕创建设备描述表
 CDC pDC=AfxGetMainWnd()->GetDC();
    hScrDC = pDC.GetSafeHdc();
   //hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
   //为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = ::CreateCompatibleDC(hScrDC);
   // 获得选定区域坐标
   nX = lpRect->left;
   nY = lpRect->top;
   nX2 = lpRect->right;
   nY2 = lpRect->bottom;
   // 获得屏幕分辨率
   xScrn = GetDeviceCaps(hScrDC, HORZRES);
   yScrn = GetDeviceCaps(hScrDC, VERTRES);
   //确保选定区域是可见的
   if (nX < 0)
      nX = 0;
   if (nY < 0)
      nY = 0;
   if (nX2 > xScrn)
      nX2 = xScrn;
   if (nY2 > yScrn)
      nY2 = yScrn;
    nWidth = nX2 - nX;
    nHeight = nY2 - nY;
  // 创建一个与屏幕设备描述表兼容的位图    hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
   // 把新位图选到内存设备描述表中   hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);   // 把屏幕设备描述表拷贝到内存设备描述表中   BitBlt(hMemDC,0,0,nWidth, nHeight,hScrDC, nX, nY, SRCCOPY);   //得到屏幕位图的句柄   hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);   //清除    DeleteDC(hScrDC);   DeleteDC(hMemDC);   // 返回位图句柄   return hBitmap;}int CMultimediaDoc::SaveBitmapToFile(HBITMAP hBitmap , LPCTSTR lpFileName) //hBitmap 为刚才的屏幕位图句柄{      //lpFileName 为位图文件名
    HDC  hDC;         
    //设备描述表
    int  iBits;      
  //当前显示分辨率下每个像素所占字节数
WORD  wBitCount;   
    //位图中每个像素所占字节数
 //定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数
DWORD  dwPaletteSize=0,
dwBmBitsSize,
dwDIBSize, 
dwWritten; BITMAP Bitmap;        
//位图属性结构
BITMAPFILEHEADER   bmfHdr;        
//位图文件头结构
    BITMAPINFOHEADER   bi;            
//位图信息头结构 
LPBITMAPINFOHEADER lpbi;          
//指向位图信息头结构
    HANDLE  fh, hDib;HPALETTE hOldPal=NULL, hPal;
//定义文件,分配内存句柄,调色板句柄
//计算位图文件每个像素所占字节数
    hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
    iBits = GetDeviceCaps(hDC, BITSPIXEL) * 
    GetDeviceCaps(hDC, PLANES);
    DeleteDC(hDC);
   if (iBits <= 1)      wBitCount = 1;   else if (iBits <= 4)      wBitCount = 4;   else if (iBits <= 8)      wBitCount = 8;   else if (iBits <= 24)      wBitCount = 24;   //计算调色板大小   if (wBitCount <= 8)      dwPaletteSize = (1 <<  wBitCount)*sizeof(RGBQUAD);
     
   //设置位图信息头结构   GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);   bi.biSize            = sizeof(BITMAPINFOHEADER);   bi.biWidth           = Bitmap.bmWidth;   bi.biHeight          = Bitmap.bmHeight;   bi.biPlanes          = 1;   bi.biBitCount         = wBitCount;   bi.biCompression      = BI_RGB;   bi.biSizeImage        = 0;   bi.biXPelsPerMeter     = 0;   bi.biYPelsPerMeter     = 0;   bi.biClrUsed         = 0;   bi.biClrImportant      = 0;dwBmBitsSize = ((Bitmap.bmWidth*wBitCount+31)/32)*4*Bitmap.bmHeight ;
   //为位图内容分配内存   hDib=GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);   *lpbi = bi;   // 处理调色板      hPal =(HPALETTE) GetStockObject(DEFAULT_PALETTE);   if (hPal)   {      hDC  = GetDC(NULL);      hOldPal = SelectPalette(hDC, hPal, FALSE);      RealizePalette(hDC);   }   // 获取该调色板下新的像素值   GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,  (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)    +dwPaletteSize,  (BITMAPINFO*)    lpbi, DIB_RGB_COLORS);   //恢复调色板      if (hOldPal)   {
      SelectPalette(hDC, hOldPal, TRUE);
      RealizePalette(hDC);
      ReleaseDC(NULL, hDC);
   }   //创建位图文件    fh = CreateFile(lpFileName, GENERIC_WRITE, 
                0, NULL, CREATE_ALWAYS,
                FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_SEQUENTIAL_SCAN, NULL);
                
   if (fh == INVALID_HANDLE_VALUE)      return FALSE;   // 设置位图文件头   bmfHdr.bfType = 0x4D42;  // "BM"   dwDIBSize = sizeof(BITMAPFILEHEADER)            + sizeof(BITMAPINFOHEADER)         + dwPaletteSize + dwBmBitsSize;     bmfHdr.bfSize = dwDIBSize;   bmfHdr.bfReserved1 = 0;   bmfHdr.bfReserved2 = 0;   bmfHdr.bfOffBits = (DWORD)sizeof   (BITMAPFILEHEADER)       + (DWORD)sizeof(BITMAPINFOHEADER)     + dwPaletteSize;   // 写入位图文件头WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);   // 写入位图文件其余内容   WriteFile(fh, (LPSTR)lpbi, dwDIBSize,    &dwWritten, NULL);   //清除      GlobalUnlock(hDib);   GlobalFree(hDib);   CloseHandle(fh);
   return 0;}BOOL CMultimediaDoc::OnSaveDocument(LPCTSTR lpszPathName) 
{
// TODO: Add your specialized code here and/or call the base class
// HBITMAP CopyScreenToBitmap(LPRECT lpRect)
LPRECT lpRect;
lpRect->left=20;
lpRect->top=20;
lpRect->right=400;
lpRect->bottom=300;
    HBITMAP map=CopyScreenToBitmap(lpRect);
SaveBitmapToFile(map,lpszPathName);
                     
return CDocument::OnSaveDocument(lpszPathName);
}

解决方案 »

  1.   

    保存一个HBITMAP或者CBitmap到指定文件,参考下面的代码:
    =========================================================int 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 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 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;
    }BOOL CImageBmp::SaveFile(const char * pFileName)
    {
        return SaveAsBmp(pFileName);
    }BITMAPINFO * BitmapToDIB(HPALETTE hPal,            // palette for color conversion
                             HBITMAP  hBmp,            // DDB for convert
                             int nBitCount, int nCompression)    // 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 = GetDC(NULL); // screen DC
        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);    ReleaseDC(NULL, hDC);    return (BITMAPINFO *) pDIB;
    }
    HBITMAP CaptureWindow(HWND hWnd)
    {
        RECT wnd;    if ( ! GetWindowRect(hWnd, & wnd) )
            return NULL;    HDC hDC = GetWindowDC(hWnd);    HBITMAP hBmp = CreateCompatibleBitmap(hDC, wnd.right - wnd.left, wnd.bottom - wnd.top);    if ( hBmp )
        {
            HDC hMemDC   = CreateCompatibleDC(hDC);
            HGDIOBJ hOld = SelectObject(hMemDC, hBmp);        BitBlt(hMemDC, 0, 0, wnd.right - wnd.left, wnd.bottom - wnd.top, 
                hDC, 0, 0, SRCCOPY);        SelectObject(hMemDC, hOld);
            DeleteObject(hMemDC);
        }
        
        ReleaseDC(hWnd, hDC);    return hBmp;
    }void SaveWindowToFile(HWND hWnd, const char *filename, int nBitCount, int nCompression)
    {
        HBITMAP hBmp = CaptureWindow(hWnd);    if(hBmp)
        {
            BITMAPINFO * pDIB = BitmapToDIB(NULL, hBmp, nBitCount, nCompression);
            if(pDIB)
            {
                SaveDIBToBmp(filename, pDIB, NULL);
                delete [](BYTE *) pDIB;
            }
            DeleteObject(hBmp);
        }
    }