源码如下 代码貌似是把客户区的图像保存为位图  但我看不懂  求解答
还有貌似一定要在ondraw里边进行重绘 图像才会被保存 为什么?
有没有更好易懂的代码 要交作业 用于画图板 谢谢
BOOL CEditorDoc::SaveBmp(LPCTSTR lpszPathName) // Save bitmap file
{
CDC dcMemSave;
dcMemSave.CreateCompatibleDC(NULL);
dcMemSave.SelectObject(&m_bmpSave); CDC dcMem;
dcMem.CreateCompatibleDC(NULL);
dcMem.SelectObject(&m_bmpBuf); CBitmap bmp;
bmp.CreateCompatibleBitmap(&dcMemSave, m_CanvasRect.Width(), m_CanvasRect.Height()); CDC dcMemTemp;
dcMemTemp.CreateCompatibleDC(NULL);
CBitmap* pOldBmp = dcMemTemp.SelectObject(&bmp);
dcMemTemp.BitBlt(0, 0, m_CanvasRect.Width(), m_CanvasRect.Height(), &dcMemSave, 0, 0, SRCCOPY); if (m_isSelected)
{
CDC dcMemSelect;
dcMemSelect.CreateCompatibleDC(NULL);
dcMemSelect.SelectObject(&m_bmpSelect);

dcMemTemp.BitBlt(m_SelectRect.left, m_SelectRect.top, m_SelectRect.Width(), m_SelectRect.Height(), &dcMemSelect, 0, 0, SRCCOPY);
}
if (m_MouseDownTime > 0)
{
dcMemTemp.BitBlt(0, 0, m_CanvasRect.Width(), m_CanvasRect.Height(), &dcMem, 0, 0, SRCCOPY);
} bmp.GetBitmap(&(m_bmpInfo));
DWORD size = m_bmpInfo.bmWidthBytes * m_bmpInfo.bmHeight;
LPSTR lpData = (LPSTR)GlobalAllocPtr(GPTR, size); BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih; bih.biBitCount = m_bmpInfo.bmBitsPixel;
bih.biClrImportant = 0;
bih.biClrUsed = 0;
bih.biCompression = 0;
bih.biHeight = m_bmpInfo.bmHeight;
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = size;
bih.biWidth = m_bmpInfo.bmWidth;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
GetDIBits(dcMemTemp, bmp, 0, bih.biHeight, lpData, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
// m_bmpTemp.GetBitmapBits(size,lpData);
bfh.bfReserved1 = bfh.bfReserved2 = 0;
bfh.bfType = ((WORD)('M'<< 8)|'B');
bfh.bfSize = 54 + size;
bfh.bfOffBits = 54; CFile bf;
if(bf.Open(lpszPathName, CFile::modeCreate | CFile::modeWrite))
{
bf.Write(&bfh, sizeof(BITMAPFILEHEADER));
bf.Write(&bih, sizeof(BITMAPINFOHEADER));
bf.Write(lpData, size);
bf.Close(); SetModifiedFlag(FALSE);
}
GlobalFreePtr(lpData);

dcMemTemp.SelectObject(pOldBmp);
bmp.DeleteObject();
m_Saved = TRUE; return TRUE;
}

解决方案 »

  1.   

    你看一下这段代码:
    int CCopyScreenDlg::BitMapToFile(HBITMAP hBitmap, LPSTR FileName)
    {
    HDC hdc;
    int ibits;//当前显示模式下每个像素所占字节数
    WORD  wbitsCount;//位图中每个像素所占字节数。
    DWORD dwpalettelsize=0;//调色板大小
    DWORD dwbmdibitsize,dwdibsize,dwwritten;
    BITMAP bitmap;
    BITMAPFILEHEADER bmfhdr;
    BITMAPINFOHEADER bi;
    LPBITMAPINFOHEADER lpbi;
    HANDLE fh,fdib,hpal,holdpal=NULL;
    CString work;
    hdc=CreateDC("display",NULL,NULL,NULL);
    ibits=::GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES);
    if(ibits<=1)
    wbitsCount=1;
    if(ibits<=4)
    wbitsCount=4;
    if(ibits<=8)
    wbitsCount=8;
    if(ibits<=16)
    wbitsCount=16;
    if(ibits<=24)
    wbitsCount=24;
    else 
    wbitsCount=32;
    //以上代码中ibits返回的显示模式下,每个像素所占的位数,wbitsCount是位图上每个像素所占的位数。
    if(wbitsCount<=8)
    dwpalettelsize=(1<<wbitsCount)*sizeof(RGBQUAD);
    GetObject(hBitmap,sizeof(BITMAP),(void *)&bitmap);//得到BITMAP的信息,这是一个BITMAP结构。
    bi.biSize=sizeof(BITMAPINFOHEADER);
    bi.biWidth=bitmap.bmWidth;
    bi.biHeight=bitmap.bmHeight;
    bi.biPlanes=1;
    bi.biBitCount=wbitsCount;
    bi.biClrImportant=0;
    bi.biClrUsed=0;
    bi.biCompression=BI_RGB;
    bi.biSizeImage=0;
    bi.biYPelsPerMeter=0;
    bi.biXPelsPerMeter=0;
    dwbmdibitsize=((bitmap.bmWidth*wbitsCount+31)/8)*bitmap.bmHeight;
    fdib=GlobalAlloc(GHND,dwbmdibitsize+dwpalettelsize+sizeof(BITMAPINFOHEADER));
    lpbi=(LPBITMAPINFOHEADER)::GlobalLock(fdib);
    *lpbi=bi;//将bi中的数据写入分配的内存中。
    //处理调色板
    hpal=::GetStockObject(DEFAULT_PALETTE);
    if(hpal)
    {
    hdc=::GetDC(NULL);
    holdpal=::SelectPalette(hdc,(HPALETTE)hpal,false);
    ::RealizePalette(hdc);
    }
    GetDIBits(hdc,hBitmap,0,(UINT)bitmap.bmHeight,(LPSTR)lpbi+sizeof(BITMAPINFOHEADER)+dwpalettelsize,(BITMAPINFO *)lpbi,DIB_RGB_COLORS);
    if(holdpal)
    {
    ::SelectPalette(hdc,(HPALETTE)holdpal,true);
    ::RealizePalette(hdc);
    ::ReleaseDC(NULL,hdc);
    }
    //创建文件
    fh=CreateFile(FileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
    if(fh==INVALID_HANDLE_VALUE)
    return FALSE;
    bmfhdr.bfType=0x4d42;
    dwdibsize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwbmdibitsize+dwpalettelsize;
    bmfhdr.bfSize=dwdibsize;
    bmfhdr.bfReserved1=0;
    bmfhdr.bfReserved2=0;
    bmfhdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+dwpalettelsize;
    ::WriteFile(fh,(LPSTR)&bmfhdr,sizeof(BITMAPFILEHEADER),&dwwritten,NULL);
    ::WriteFile(fh,(LPSTR)lpbi,dwdibsize,&dwwritten,NULL);
    ::GlobalUnlock(fdib);
    ::GlobalFree(fdib);
    ::CloseHandle(fh);
    return TRUE;
    }
      

  2.   

    楼上啊 你的貌似是截图啊 我是想将客户区画的东西存为位图
    ====================
    你看了没有啊?上面的是将根据HBITMAP句柄保存为BMP文件啊,
    int CCopyScreenDlg::BitMapToFile(HBITMAP hBitmap, LPSTR FileName)
    两个参数一个句柄,一个文件名,前面那个CCopyScreenDlg是我以前一个工程的对话框名字,你去掉就是了。
      

  3.   

    CImage可以很方便的存取~
    就算是Bitmap的,转到CImage里save一下就可以了~
      

  4.   

    CDC memDC;
    CRect range;
    CBitmap srcImage,*oldImage;
    CPalette *palette=NULL;
    BITMAP info;
    srcImage.CreateCompatibleBitmap(&dc,News_MaxWidth,NEWS_HEIGHT);//MoveWidth
    oldImage=memDC.SelectObject(&srcImage);//选择画布
    memDC.BitBlt(0,0,News_MaxWidth,NEWS_HEIGHT,&ChildViewDC,0,0,SRCCOPY);//MoveWidth
    memDC.SelectObject(oldImage);
    srcImage.GetBitmap(&info);
    if(info.bmPlanes*info.bmBitsPixel<=8)
    palette=dc.GetCurrentPalette();
    MY_CDIB *Arrbmp1;
    Arrbmp1=new MY_CDIB(srcImage,palette);
    lpszPathName=WorkDirectory+"*.bmp";
    //----------------------------------------
    CString StrNewPath,StrTempTitle;
    CFileDialog  myNewFile(FALSE,"*.bmp",lpszPathName,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"bmp Files (*.bmp)|*.bmp||",this);
    if(myNewFile.DoModal()==IDOK)
    {
    m_BMP_StrPath=myNewFile.GetPathName();
    m_BMP_StrTitle=myNewFile.GetFileName();
    int nLen=m_BMP_StrPath.GetLength();
    char* bmpFileName=new char[nLen];
    bmpFileName=m_BMP_StrPath.GetBuffer(0);
    Arrbmp1->SaveFile(bmpFileName);
    int aa=Arrbmp1->Width();
    CDialog::OnOK();
    }
    else
    {
    CDialog::OnCancel();
    }