我最近遇到一个很烦人的问题?我在SDI 工程中 CView 类中定义了  一个 CDC 对象 ,和一个CBitmap 对象;然后再 我用 兼容DC BOOL CRGYView::OnEraseBkgnd(CDC* pDC)中创建!程序在运行 3~5分钟后崩溃 啦 ,提示 创建位图失败,内存不足 ? 
为仕么?我没有 new 和delete 动态创建其他东西啊?BOOL CRGYView::OnEraseBkgnd(CDC* pDC)
{
   //这个函数中创建 了兼容DC ,和兼容 CBitmap ;     if(!memDC.m_hDC && m_bInitial)// 初始化调用一次
{
CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
CString str,sreg;
//memDC.DeleteDC();
//memBmp.DeleteTempMap();
//memBmp.DeleteObject();
memDC.CreateCompatibleDC(pDC);
CRect cur;
GetClientRect(&cur);
CMainFrame *pFrm=(CMainFrame*)AfxGetApp()->m_pMainWnd;
//pFrm->GetClientRect(&cur);
//str="Cur= ";

GetWindowRect(&cur);
memBmp.CreateCompatibleBitmap(pDC,cur.Width(),cur.Height());
//memBmp.LoadBitmap(IDB_BITMAP2);
BITMAP bmp;
memBmp.GetBitmap(&bmp);
memDC.SelectObject(&memBmp);
//memDC.FillSolidRect(cur,pDC->GetBkColor());//
memDC.BitBlt(0, 0, cur.Width(), cur.Height(), pDC, 0, 0, SRCCOPY);
}
if(FALSE==m_bInitial)
{
if(m_bToolBarDesign)
{
OnDesignDraw(1,&memDC);
}
m_bInitial=TRUE;
return CView::OnEraseBkgnd(pDC);// 填充背景,没有这一句的话 客户群就是透明的?
                                                  //  不知 有仕么好的方法?
}
         else
         {
CPen pen;
                  memDC.Rectangle();                  、、、、、、、、、
                  //  在兼容DC 中 绘制图形!
         }}最后 在 
void CRGYView::OnDraw(CDC* pDC)
{
       //  这个函数中输出拷贝 图形;
       pDC->BitBlt(0, 0, cur.Width(), cur.Height(), &memDC, 0, 0, SRCCOPY);        pFrm->m_sRectTip=str;
pDC->TextOut(10,10,str);
CFont font;
font.CreatePointFont(300,"@System");
CFont *pOldFont=pDC->SelectObject(&font);        //。。
        //绘制其他图形 。}

解决方案 »

  1.   

    你的GDI资源使用完了以后没有及时释放
      

  2.   

    问题是我没有 new ,啊!没有创建 GDI 资源 ,只是局部 GDI 资源 ,函数执行完了就会自动释放吧!我上面的代码 有哪里不对 ? 请大家指出?
      

  3.   

    CreateCompatibleBitmap
    CreateCompatibleD
    这两个都是创建
      

  4.   

    没有局部 GDI 资源 之说
      

  5.   

    CreateCompatibleDC用完后需要DeleteDC,还有类似的CreateCompatibleBitmap等都需要释放,必须的。
    楼主散分吧。
      

  6.   

    1.OnEraseBkgnd()里面直接返回TRUE然后把绘制的代码放到OnDraw()里面2.
    资源使用完毕后要释放,如1楼7楼所述
      

  7.   


    放心,等我 结贴一定 散 分 !我上面的  CreateCompatibleDC,和 CreateCompatibleBitmap() 是初始化 只调用一次,不会调用第二次啊!就是在OnDraw ()函数中 ,
    用 pDC->BitBlt(0, 0, cur.Width(), cur.Height(), &memDC, 0, 0, SRCCOPY);把 memDC 1:1 拷贝到 输出 DC 啊!这种重复 拷贝,也能出错么?
      

  8.   

    很少看到有在OnEraseBkgnd里创建局部DC资源的,应采用8楼的方法,在每次OnDraw里重新创建兼容DC,最后pDC->BitBlt,用完记得释放兼容DC;另外CreatePointFont后也需要DeleteObject.
      

  9.   

    哦,谢谢楼上, 你的意思不要添加 OnEraseBkgnd()这个消息函数么?在Ondraw 函数中创建兼容DC ,那么程序还是会处理WM_ERASEBKGND消息的,会察除背景,这样屏会闪吧!我要是在 OnEraseBkgnd()函数中 直接返回 TRUE ,就看到程序的客户区(View类)是透明的!
     
      

  10.   

    OnEraseBkgnd   你以为这个函数只调用一次??
      

  11.   

    在Ondraw 函数中创建兼容DC 进行双缓存贴图。
    在OnEraseBkgnd中直接return TRUE,不让其擦除背景。
      

  12.   


    不行啊, 在 OnEraseBkgnd中直接return TRUE 的结果是 View 的背景变成了透明色了,能看到窗口背后的东西?你信你试试!
      

  13.   


    就算初始化没东西画上去,那为仕么, 我设置了初始化标志,第一次调用 
    OnEraseBkgnd()
    {
        if(m_bInit==FALSE)
         {
         return CView::OnEraseBkgnd();//第一次返回基类的察除背景函数,
          m_bInit=TRUE;                  // 背景启动后就是白色的,但是当我
         }                               // 拖动边框拉大的时候,发现,
          return TRUE;                 // 超出初始化大小的视图背景是黑色的?这怎么解释?}
      

  14.   

    if(!memDC.m_hDC && m_bInitial)// 初始化调用一次应该是:
    if(!memDC.m_hDC && !m_bInitial)或者
    if(!(memDC.m_hDC && m_bInitial))
      

  15.   

    是不是没有DeleteObjet() ?