http://xa.ctfs.ftn.qq.com/ftn_handler/aed4b06542eeb5599e02542be5668942fefe25c6691aac7ebcfb382e162fa4d72e040eaea614bbeb052826063239e2fee4509adf17669e764b1d487baf00a598/?fname=DBBTest_459.zip&k=7939393472b0c7c635ba131310370a165b0d5d0701015a5f140e5f04041a0c0000001456530001140e005c050503005f085d5805363c387d7b7b6d514543164350493909&fr=00&&txf_fid=61bf336297f2787e7d0db0a7aa0b92f6b3035679&xffz=309083个dc(其中2个是内存dc)第一个dc上不断的绘制 圆, 第二个是贴一张图, 第二个拷贝到第一个的中间,最后把第一个dc拷贝第3个dc(即:
设备dc上 ,结果失败了)源码已经上传 CRect rt;
this->GetClientRect(&rt); // 为屏幕DC创建兼容的内存DC
if(!m_dcMemory.CreateCompatibleDC(NULL))
{
::PostQuitMessage(0);
} // 创建位图
m_Bmp.CreateCompatibleBitmap(&m_dcMemory, rt.Width(), rt.Height()); // 相当于选择画布
::SelectObject(m_dcMemory.GetSafeHdc(), m_Bmp);

HBITMAP hBitmap=(HBITMAP)LoadImage(0,"c:\\1.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

//第三个dc
CDC* pDc=GetDC();
m_dcMemory2.CreateCompatibleDC(pDc);
m_dcMemory2.SelectObject((HGDIOBJ)hBitmap);
ReleaseDC(pDc);
//另外一段代码////////////////////////////////////////// CRect rt;
this->GetClientRect(&rt); m_dcMemory.FillSolidRect(&rt, RGB(255,255,255)); // 白色填充, 注意,这次是画在内存设备环境上 // 画圆
for(int i = 0; i < rt.Width() - 1; i+= 16)
{
for(int j = 0; j < rt.Height() - 1; j+= 16)
{
m_dcMemory.Ellipse(i, j, i + m_nRadius, j + m_nRadius);
}
} m_dcMemory.BitBlt(rt.Width()/4,rt.Height()/4,rt.Width()/2,rt.Height()/2,&m_dcMemory2, 0,0,SRCCOPY);
Invalidate();
//第3段代码
///////////////////////////////////////void CDBBTestView::OnDraw(CDC* pDC)
{
CDBBTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CRect rc;
GetClientRect(&rc);
if(m_bStart)
{
pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &m_dcMemory, 0, 0, SRCCOPY); }
else
{ pDC->FillSolidRect(&rc,RGB(255,255,255)); }}

解决方案 »

  1.   

    http://hzsrc.ctfs.ftn.qq.com/ftn_handler/f8039d6407e542c9b5dd688e62c50473e34727702a339ae79a74dfc6ae0c4d7cb2804183c708cc367c7c0b16bd2935265d5623db4299f9e7624da5b53f50b82f/?fname=1.bmp&k=08636235abc3f79d3ee0481245300a4d0053010654560a521f075600001d0c5a03574f0c5b08004f5653540007060e0601560006633538531c010f45630d&fr=00&&txf_fid=d0511f80578e477d7c8b11ef02b42777008237d4&xffz=3148856图片到这里下载,不好意思了啊,没有发图片,图片比较大,所以存网络硬盘里吧
      

  2.   

    // 创建位图
    m_Bmp.CreateCompatibleBitmap(pDC, rt.Width(), rt.Height());
    不是:
    m_dcMemory !!!
      

  3.   

    m_Bmp.CreateCompatibleBitmap(&m_dcMemory, rt.Width(), rt.Height()); 
    这样产生的位图是 黑白的。
    你试试:
    m_dcMemory.FillSolidRect(&rt, RGB(255,128,128));// 除了白色,其他都是黑色。
      

  4.   

    另外:
    BOOL CDBBTestView::OnEraseBkgnd(CDC* pDC) 
    {
    // TODO: Add your message handler code here and/or call default
    return TRUE;
    return CView::OnEraseBkgnd(pDC);
    }
      

  5.   

    // 初始化和双缓冲相关的要素
    void CDBBTestView::InitialDBB()
    {
    CRect rt;
    this->GetClientRect(&rt); CDC* pDc=GetDC(); // 为屏幕DC创建兼容的内存DC
    if(!m_dcMemory.CreateCompatibleDC(pDc))
    {
    ReleaseDC(pDc);
    ::PostQuitMessage(0);
    } // 创建兼容位图
    m_Bmp.CreateCompatibleBitmap(pDc, rt.Width(), rt.Height());
    m_dcMemory.SelectObject((HGDIOBJ)m_Bmp); //没有返回旧的
    //第三个dc HBITMAP hBitmap=(HBITMAP)LoadImage(0,"c:\\1.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
    m_dcMemory2.CreateCompatibleDC(pDc);
    m_dcMemory2.SelectObject((HGDIOBJ)hBitmap); //没有返回旧的
    ReleaseDC(pDc);}看了一下CBitmap的基类CGidObject的析构函数似乎是有自动删除该gdi对象的功能。widnows程序设计一书提到:先还旧gdi对象,再释放dc. 如果gdi是create的,那么还旧的gdi对象后,还要删除create出来的gdi对象和释放dc.
    现在好了,所有都是析构函数负责。问题:析构函数能够正确的保存删除?要正确删除,必须:安装一定的顺序。
    目标:1个位图需要deleteobject,一个dc需要deletedc.     
      

  6.   

    sdk版本:
    HDC hMemoDc, hMemDoc2; //内存dc, dc2HBTIMAP hMemoBitmap, hOldMemobitmap, hOldMemobitmap2;case WM_CREATE://创建兼容dc、位图
    HDC hDC=getdc(hwnd);hMemoDc=CreateCompatibleDC(hDC);
    hMemoBitmap=createcompatbileBitmap(hDc,rt.width,,);hOldMemobitmap=selectobject(hMemoDc, hMemoBitmap); //记录旧位图// 同理,保存第3个dc中的旧位图hOldMemobitmap2=selectobject(hMemoDc2, hMemoBitmap); //记录旧位图ReleaseDc(hwnd,hdc);
    case WM_DESTROY://返回旧位图
    SelectObject(hMemoDC,hOldMemobitmap); //教还旧位图
    SelectObject(hMemoDC2,hOldMemobitmap2); //教还旧位图//删除兼容位图,这个位图是create出来的
    DelteObject(hwnd,hMemoBitmap);
    //删除2个dc,这2个dc都是create出来的
    DeleteDc(hwnd,hMemoDc);
    DeleteDc(hwnd,hMemoDc2);没泄露了吧
      

  7.   

    有没有GDI资源泄露,自己用任务管理器看看GDI资源是否是自增不减?
      

  8.   

    有一个 CS_OWNDC 就是为了这个目的。
      

  9.   

    关于‘CS_OWNDC’
    请参考我的:
    "定制控件(旋转立方体).rar" 0 分
      

  10.   


    请按下面代码修改
    void CDBBTestView::InitialDBB()
    {
    CRect rt;
    this->GetClientRect(&rt);
    CDC *pDC=GetDC();
    // 为屏幕DC创建兼容的内存DC
    if(!m_dcMemory.CreateCompatibleDC(pDC))
    {
    ::PostQuitMessage(0);
    } // 创建位图
    m_Bmp.CreateCompatibleBitmap(pDC, rt.Width(), rt.Height()); // 相当于选择画布
    m_dcMemory.SelectObject(m_Bmp);
    //::SelectObject(m_dcMemory.GetSafeHdc(), m_Bmp);

    HBITMAP hBitmap=(HBITMAP)LoadImage(0,"D:\\my\\Picture_2012_12_28_15_21_16.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); //第三个dc
    m_dcMemory2.CreateCompatibleDC(pDC);
    m_dcMemory2.SelectObject((HGDIOBJ)hBitmap);
    ReleaseDC(pDC);
    }
    我电脑测试OK,中间可以显示BMP图片内容