none
hrgn对象调用DeleteObject后GDI对象数量在不断增长 RRS feed

  • 问题

  • 最近编写VC++代码,遇到了很奇怪的问题.我几万次调用CreateRectRgn,用完调用DeleteObject删除后,任务列表里面GDI对象数量没有变小,达到了10000,导致画图发黑失败.不知道怎么解决.多次测试发现调用CreateRectRgn产生HRGN区域对象后,任务列表GDI对象数量增加一个,调用DeleteObject后GDI对象数量没有减1.怎么回事?急死了.请专家解答,非常感谢!!!

    2019年11月18日 9:03

全部回复

  • 你好

    感谢你在这里发帖。

    >>任务列表GDI对象数量增加一个

    你的GDI对象存储在什么数据结构中的,DeleteObject删除GDI资源之后又是怎么删除数据结构中的GDI对象的,这个方便说下吗?或者有什么相关的代码可以展示一下,这将会帮助我们更快地解决你的问题。

    Best Regards,

    Suarez Zhou


    如果您对Visual Studio 或Microsoft Azure相关产品感兴趣,请点击此链接,或扫描以下二维码注册获取相关信息。


    2019年11月19日 2:17
  • 非常感谢.

    它们是HRGN对象,有的是局部变量方式,有的是全局变量方式.局部变量用完在函数里面就删除了,全局变量方式在软件运行结束时删除.删除时调用DeleteObject函数GDI对象数量没有减少.我试着用CreatePen,DeleteObject很管用.

    下面是相关代码.因为是循环操作,GDI对象句柄增加非常快.调了DeleteObject没有效果.

    ////提取区域信息
    int CSortPos::getAreaInfo(ELEINFO* p,int iStatIndex,
                              BOOL bNeedMaskColor,
                              COLORREF* prgbMaskColor,
                              int iMCArrLen,
                              HRGN* phX0,
                              RANGE* pRange,
                              HWND hWndScrollBar,
                              
                              
                              int& iResult)
    {
        int iRet = 0;
        //4 提供...
        HDC hdcwnd = GetDC(m_hWnd);//!!later直接赋值
        HDC hdcmem = ::CreateCompatibleDC(hdcwnd);
        //5 调用系统函数处理
        int iWndDirection = getWndDirection(m_hWnd);
        if(iWndDirection == 3)
        {
        
            iRet = GetRgnX0_v2(p->arrhbmpBMP[iStatIndex],
                p->arriPicAreaWidth_Ori[iStatIndex], p->arriPicAreaHeight_Ori[iStatIndex],
                bNeedMaskColor,
                prgbMaskColor,
                iMCArrLen,
                phX0,
                hdcmem,
                &pRange->x,&pRange->y, &pRange->width_hor_bak,&pRange->height_ver_bak,
                &pRange->x0_lastline,&pRange->x1_lastline
                //..
                );

                p->arrstAreaInfo_Ori[1][iStatIndex].iXPicOffset = -(0 - pRange->x);
                p->arrstAreaInfo_Ori[1][iStatIndex].iYPicOffset = -(0 - pRange->y);

    #if 1 //later...
            {
        
            

                int iPicNewWidth = p->arriPicAreaWidth_Ori[iStatIndex];// += (0 - pRange->x);
                int iPicNewHeight = p->arriPicAreaHeight_Ori[iStatIndex];// += (0 - pRange->y);

                //
                int x0_bigger = (pRange->x <= pRange->x0_lastline) ? (pRange->x) : pRange->x0_lastline;
                //int y0_bigger = (pRange->y <= pRange->y0_lastline) ? (pRange->y) : pRange->y0_lastline;
                int y0_bigger = pRange->y;

                x0_bigger += pRange->width_hor_bak;
                y0_bigger += pRange->height_ver_bak;

            
                HRGN hrgn_right = ::CreateRectRgn(x0_bigger,0,iPicNewWidth,iPicNewHeight);
                CombineRgn(*phX0,*phX0,hrgn_right,RGN_DIFF);

                //HRGN hrgn_bottom = ::CreateRectRgn(0,y0_bigger,iPicNewWidth,iPicNewHeight);
                HRGN hrgn_bottom = ::CreateRectRgn(x0_bigger,y0_bigger,iPicNewWidth,iPicNewHeight);
                CombineRgn(*phX0,*phX0,hrgn_bottom,RGN_DIFF);

                DeleteObject(hrgn_right);
                DeleteObject(hrgn_bottom);

            }
    #endif
            pRange->y0_lastline = pRange->y1_lastline = (pRange->height_ver_bak + pRange->y)-1;
            
            
            p->arrstAreaInfo_Ori[1][iStatIndex].hArea = *phX0;
            p->arrstAreaInfo_Ori[1][iStatIndex].iXOffset = pRange->x;
            p->arrstAreaInfo_Ori[1][iStatIndex].iYOffset = pRange->y;
            p->arrstAreaInfo_Ori[1][iStatIndex].iAreaHeight_Ori = pRange->height_ver_bak;
            p->arrstAreaInfo_Ori[1][iStatIndex].iAreaWidth_Ori = pRange->width_hor_bak;
            
            p->arrstAreaInfo_Ori[1][iStatIndex].bFilter = bNeedMaskColor;
            p->arrstAreaInfo_Ori[1][iStatIndex].arrrgbFilter[0] = prgbMaskColor[0];
            p->arrstAreaInfo_Ori[1][iStatIndex].iarrrgbFilterLen = iMCArrLen;
            //p->arrstAreaInfo_Ori[1][iStatIndex].bResize = ;//later...
            //p->arrstAreaInfo_Ori[1][iStatIndex]. = pRange->;
            
            //最下面两点 竖直
            //    POINT arrptMaxBottom[2];
            //最右面两点 水平
            //    POINT arrptMaxRight[2];
            
            p->arrstAreaInfo_Ori[1][iStatIndex].arrptMaxBottom_Ori[0].x = pRange->x0_lastline;
            p->arrstAreaInfo_Ori[1][iStatIndex].arrptMaxBottom_Ori[1].x = pRange->x1_lastline;
            p->arrstAreaInfo_Ori[1][iStatIndex].arrptMaxBottom_Ori[0].y = pRange->y0_lastline;
            p->arrstAreaInfo_Ori[1][iStatIndex].arrptMaxBottom_Ori[1].y = pRange->y1_lastline;
            //p->arrstAreaInfo_Ori[1][iStatIndex]. = pRange->x0_lastline;
        }
        else
            {
        
            iRet = GetRgnX0_h2(p->arrhbmpBMP[iStatIndex],
                p->arriPicAreaWidth_Ori[iStatIndex], p->arriPicAreaHeight_Ori[iStatIndex],
                bNeedMaskColor,
                prgbMaskColor,
                iMCArrLen,
                phX0,
                hdcmem,
                &pRange->x,&pRange->y, &pRange->width_hor_bak,&pRange->height_ver_bak,
                &pRange->y0_lastline,&pRange->y1_lastline
                //..
                );

                p->arrstAreaInfo_Ori[1][iStatIndex].iXPicOffset = -(0 - pRange->x);
                p->arrstAreaInfo_Ori[1][iStatIndex].iYPicOffset = -(0 - pRange->y);

    #if 1 //later...
            {
        
            

                int iPicNewWidth = p->arriPicAreaWidth_Ori[iStatIndex];// += (0 - pRange->x);
                int iPicNewHeight = p->arriPicAreaHeight_Ori[iStatIndex];// += (0 - pRange->y);

                //!!!
                //int x0_bigger = (pRange->x <= pRange->x0_lastline) ? (pRange->x) : pRange->x0_lastline;
                int x0_bigger = pRange->x;
                int y0_bigger = (pRange->y <= pRange->y0_lastline) ? (pRange->y) : pRange->y0_lastline;

                x0_bigger += pRange->width_hor_bak;
                y0_bigger += pRange->height_ver_bak;

            
                HRGN hrgn_right = ::CreateRectRgn(x0_bigger,0,iPicNewWidth,iPicNewHeight);
                CombineRgn(*phX0,*phX0,hrgn_right,RGN_DIFF);

                //HRGN hrgn_bottom = ::CreateRectRgn(0,y0_bigger,iPicNewWidth,iPicNewHeight);
                HRGN hrgn_bottom = ::CreateRectRgn(x0_bigger,y0_bigger,iPicNewWidth,iPicNewHeight);
                CombineRgn(*phX0,*phX0,hrgn_bottom,RGN_DIFF);

                DeleteObject(hrgn_right);
                DeleteObject(hrgn_bottom);

            }
    #endif
            pRange->x0_lastline = pRange->x1_lastline = (pRange->width_hor_bak + pRange->x)-1;
            
            
            p->arrstAreaInfo_Ori[1][iStatIndex].hArea = *phX0;
            p->arrstAreaInfo_Ori[1][iStatIndex].iXOffset = pRange->x;
            p->arrstAreaInfo_Ori[1][iStatIndex].iYOffset = pRange->y;
            p->arrstAreaInfo_Ori[1][iStatIndex].iAreaHeight_Ori = pRange->height_ver_bak;
            p->arrstAreaInfo_Ori[1][iStatIndex].iAreaWidth_Ori = pRange->width_hor_bak;
            
            p->arrstAreaInfo_Ori[1][iStatIndex].bFilter = bNeedMaskColor;
            p->arrstAreaInfo_Ori[1][iStatIndex].arrrgbFilter[0] = prgbMaskColor[0];
            p->arrstAreaInfo_Ori[1][iStatIndex].iarrrgbFilterLen = iMCArrLen;
            //p->arrstAreaInfo_Ori[1][iStatIndex].bResize = ;//later...
            //p->arrstAreaInfo_Ori[1][iStatIndex]. = pRange->;
            
            //最下面两点 竖直
            //    POINT arrptMaxBottom[2];
            //最右面两点 水平
            //    POINT arrptMaxRight[2];
            
            p->arrstAreaInfo_Ori[1][iStatIndex].arrptMaxRight_Ori[0].x = pRange->x0_lastline;
            p->arrstAreaInfo_Ori[1][iStatIndex].arrptMaxRight_Ori[1].x = pRange->x1_lastline;
            p->arrstAreaInfo_Ori[1][iStatIndex].arrptMaxRight_Ori[0].y = pRange->y0_lastline;
            p->arrstAreaInfo_Ori[1][iStatIndex].arrptMaxRight_Ori[1].y = pRange->y1_lastline;
            //p->arrstAreaInfo_Ori[1][iStatIndex]. = pRange->x0_lastline;
        }
        
        
        pRange->width_hor_cur = pRange->width_hor_bak;
        pRange->height_ver_cur = pRange->height_ver_bak;
        
        
        
        iRet = DeleteDC(hdcmem);
        if(!iRet)
        {
            TRACE("DeleteDC ERROR5.\n");
        }
        iRet = ReleaseDC(hWndScrollBar,hdcwnd);
        
        if(!iRet)
        {
            TRACE("ReleaseDC not ok.\n");
        }
        else     if(1==iRet)
        {
    //        TRACE("ReleaseDC is ok.\n");
        }
        
        //here. later


        return iRet;
        
        }
       

    下面是代码所在位置.

    https://pan.baidu.com/s/1BPw0NoNqc9OFbkImQ9pkRQ

    请运行后,点击  加入N条记录按钮, 然后拖拉右侧滚动条,打开任务管理器,点击菜单  查看  选择列 勾选 GDI对象,会看到

    GDI对象不断增加,我调了DeleteObject不管用.烦死了.




    2019年11月19日 6:59
  • CombineRgn产生的区域*phX0哪里删除过?没看到删除的代码。




    Visual C++ MVP

    2019年11月25日 20:45
    版主
  • 非常感谢.

    这是提取不规则图片信息的代码,在外层删除的.下面盘里有细致的展示.

    https://pan.baidu.com/s/1BPw0NoNqc9OFbkImQ9pkRQ

    疑惑只有不断增加,调用删除GDI数量不见减少.非常怪异.区域一般都是用完就删掉了.区域API里面为什么没有增加删除一个点的功能?为什么没有清空区域的功能?

    下面这段代码能出现释放不掉的现象.

     

                                                                                                                                                                                 void ftest()

    {

    #define MAXNUM (10)

    HRGN hp[MAXNUM] = {0};
    #if 1

            // TODO: code your application's behavior here.
            for(int i=0;i<MAXNUM;i++)
            {
                HRGN h = (HRGN)0;
    #if 0
                ::Sleep(1);
    #endif

                h = CreateRectRgn(1,2,3,4+i%10);

                hp[i] = h;

               

            }

            for( i=0;i<MAXNUM;i++)
            {



    #if 1
                DeleteObject(hp[i]);
    #endif


            }

    #endif

    }



    非常感激


    2019年11月27日 5:23