在调用GDI函数时,一般来说,调用CreateXX后要调用DeleteXX,调用GetXX后要调用ReleaseXX,否则会有句柄未释放,这样进程中的句柄数将越来越多,最后导致非法操作之类的错误。你的程序中,最后应该调用MemDC.DeleteDC\pDC->ReleaseDC.

解决方案 »

  1.   

    那你还不如添加一个全程内存设备CDC m_dcMem变量以及一个全程位图变量CBitmap m_bitmap,
    在视的构造函数中初始化装载位图.
    m_bitmap.LoadBitmap(IDB_BITMAP0);
    然后读取位图信息
    m_Bitmap.GetObject(sizeof(BM),&BM);
    在视的OnInitialUpdate()中初始化m_dcMem.
    CClientDC dc(this);
    m_dcMem.CreateCompatibleDC(&dc);在真正的显示函数中再调用
    pDC->StretchBlt();
      

  2.   

    pDC->DeleteDC();不可以吗?
      

  3.   

    申请的DC指针指向的DC并没有被释放,
      

  4.   

    用我们头的话来说90%以上的VC Bug是内存问题
    因为往往不提示你错了,等到运行一段时间才出问题。这种最难办了,索性编译不通过到好
      

  5.   

    创建一个内存设备类.代码如下.
    class cMemDC : public CDC 
    {
    private:
    CBitmap* m_bitmap;
    CBitmap* m_oldBitmap;
    CDC* m_pDC;
    CRect m_rcBounds;
    public:
    cMemDC(CDC* pDC, const CRect& rcBounds, long BackColor = RGB(255,255,255)) : 
          CDC(), m_oldBitmap(NULL), m_pDC(pDC), m_rcBounds(rcBounds)
       {
    CreateCompatibleDC(pDC);
    m_bitmap = new CBitmap;
    m_bitmap->CreateCompatibleBitmap(pDC, rcBounds.Width(), rcBounds.Height());
    CBrush *pBack = new CBrush(BackColor);
          FillRect(m_rcBounds, pBack);
          delete pBack;
          m_oldBitmap = SelectObject(m_bitmap);
    //m_pDC = pDC;
    //m_rcBounds = rcBounds;
       } ~cMemDC() 
       {
    //m_pDC->BitBlt(m_rcBounds.left, m_rcBounds.top, m_rcBounds.Width(), m_rcBounds.Height(), 
    // this, m_rcBounds.left, m_rcBounds.top, SRCCOPY);
    SelectObject(m_oldBitmap);
    if (m_bitmap != NULL) delete m_bitmap;
       }

       cMemDC* operator->() {return this;}
    };
      

  6.   

    现在改为:
    CDC *pDC;
    pDC=GetDC();
    CClientDC ClientDC(this);
    ConArray(0);
    AddBkBitmap();
    MemDC.Detach();
    m_Bitmap.Detach();
    m_Bitmap.LoadBitmap(StockList(m_NextStockCode));
    m_Bitmap.GetObject(sizeof(BM),&BM);
    MemDC.CreateCompatibleDC(&ClientDC);
    MemDC.SelectObject(m_Bitmap);
    DeleteObject(ClientDC);
    ConArray(1);
    pDC->BitBlt
    (cur_x,
    cur_y,
    BM.bmWidth,
    BM.bmHeight,
    &MemDC,
    0,
    0,
    SRCCOPY);
    ReleaseDC(pDC);
    其中memdc bitmap BM 均为全局变量
    但是调用的IDB_BITMAPXXX是不同的图片
    但是现在还是不行呀?
      

  7.   

    连续导入bitmap图片
    其中memdc和m_bitmap是全局的
    问题可能出在:
    MemDC.Detach();
    m_Bitmap.Detach(); 具体应该怎么改?
    谢了!
      

  8.   

    这里的Detach()函数我觉得你可以不使用.让系统自动为你进行内存管理.
      

  9.   

    删掉Detach()函数程序直接就死了呀
    问题到底在哪里?
    现在可以肯定程序死亡和这段程序有关.
      

  10.   

    MemDC.SelectObject(m_Bitmap);
    必须保存返回的BITMAP,m_Bitmap用完后先把保存的BITMAP选回去,然后再释放MemDC,否则就会出现资源漏洞。
    另外如果是反复、循环调用含CDC及图形对象的函数,函数最好用SDK编写,如果非用SDK不可,也要自己手工调用DeleteObject、DeleteDC、ReleaseDC等释放函数,原因是:MFC封装的对象都是在析构函数中调用这些函数,但是临时性的MFC对象只有在OnIdle函数中才会被删除。如果程序始终处于忙状态,没有时间调用OnIdle,资源就会得不到释放的机会。
      

  11.   

    这个问题我遇倒过,不要频繁调用createcompatiabledc函数,可以在加载位图时调用一次,
    然后显示时只调用bitblt,如果不这样即使调用deleteobject,deletedc等函数,时间一长
    就会出现非法错误。
      

  12.   

    我觉得mmhhj()说的有道理。
    问题肯定出在位图的创建和对象的删除上面。
    但是程序要求频繁的加载位图
    可不可以用别的函数呢?
    memdc bitmap bm都是全局的变量
    位图资源IDB_BITMAP0到IDB_BITMAP30
    调用位图非常频繁
    具体有没有什么办法可以解决?
      

  13.   

    是不是只显示IDB_BITMAP0到IDB_BITMAP30
    31个位图,如果是,开一个位图数组好了
    我是这样作的,位图显示我自己定义了一个cdib类,比如30个位图定义
    cdib dib[30];
    初始化:
    dib[i].load("..");
    显示:
    dib.show(x,y);
      

  14.   

    现在想出了一个办法
    就像其它游戏似的,导入一张大的bmp图片
    根据不通图像的位置,确定坐标,导入图片
    这样就避免了多次读图的操作,就不会非法程序了
    呵呵