HRESULT OnDraw(ATL_DRAWINFO& di)//改用双缓冲绘制,消除闪烁
    {
        RECT& rc = *(RECT*)di.prcBounds;
        HDC& hdc = (HDC)di.hdcDraw;        // 将剪辑区域设置为 di.prcBounds 指定的矩形
        HRGN hRgnOld = NULL;
        if (GetClipRgn(hdc, hRgnOld) != 1)
            hRgnOld = NULL;
        bool bSelectOldRgn = false;        HRGN hRgnNew = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);        if (hRgnNew != NULL)
        {
            bSelectOldRgn = (SelectClipRgn(hdc, hRgnNew) != ERROR);
        }        //begin:
        static HDC hdcmem = NULL;
        static HBITMAP hbmp= NULL;
        static HBITMAP holdbmp=NULL;        int w = rc.right - rc.left;
        int h = rc.bottom - rc.top;        hdcmem = CreateCompatibleDC(hdc);
        hbmp = CreateCompatibleBitmap(hdc,w,h);
        holdbmp = (HBITMAP)SelectObject(hdcmem,(HGDIOBJ)hbmp);            
        
        //1:区域划分
        SetRect(&rtcaption,rc.left,rc.top,rc.right,rc.top + ncaption);
        SetRect(&rttop,rc.left+nleft ,rtcaption.bottom,rc.right-nright,rtcaption.bottom+ntop);
        SetRect(&rtleft,rc.left,rtcaption.bottom,rc.left+nleft,rc.bottom);
        SetRect(&rtright,rc.right- nright,rtleft.top,rc.right,rtleft.bottom);
        SetRect(&rtbottom,rtleft.right,rc.bottom-nbottom,rtright.left,rc.bottom);
        SetRect(&rtfill,rtleft.right ,rttop.bottom,rtright.left,rtbottom.top);
    
        //2:坐标系定义
        xyo.x = rtfill.left + 4;
        xyo.y = rtfill.bottom - 4;
        xyx.x = rtfill.right - 3;
        xyx.y = xyo.y; 
        xyy.x = xyo.x;
        xyy.y = rtfill.top + 3;            //3:画背景
        DrawBkGnd(hdcmem,rc);            //4:区域渲染m_clrBackColor
        DrawBorder(hdcmem,rc);        //5:标题绘制
        DrawTitle(hdcmem,rc);        //6:曲线辅助网格
        DrawGrid(hdcmem,rc);        //7:XY坐标轴和XY轴文本
        DrawXYName(hdcmem,rc);
        
        //8:曲线
        DrawCurve(hdcmem,rc);
        
        BitBlt(hdc,0,0,w,h,hdcmem,0,0,SRCCOPY);        SelectObject(hdcmem,(HGDIOBJ)holdbmp);
        DeleteObject(hbmp);
        ReleaseDC(hdcmem);
        //end.        if (bSelectOldRgn)
            SelectClipRgn(hdc, hRgnOld);        //DeleteObject(hRgnOld);
        DeleteObject(hRgnNew);        return S_OK;
    }

解决方案 »

  1.   


        void DrawBkGnd(HDC& hdc,RECT& rc)//画背景
        {
            COLORREF clbk;
            OleTranslateColor(m_clrBackColor,NULL,&clbk);
            
            HBRUSH hbr;
            hbr = CreateSolidBrush(clbk);        FillRect(hdc,&rc,hbr);        DeleteObject(hbr);
        }
        void DrawBorder(HDC& hdc,RECT& rc)//画四周边框
        {
            HBRUSH hbr;
            hbr = CreateSolidBrush(RGB(192,192,192));        FillRect(hdc,&rtcaption,hbr);
            FillRect(hdc,&rttop,hbr);
            FillRect(hdc,&rtleft,hbr);
            FillRect(hdc,&rtright,hbr);
            FillRect(hdc,&rtbottom,hbr);
            
            DeleteObject(hbr);
            
            COLORREF cl;
            OleTranslateColor(m_clrFillColor,NULL,&cl);
            
            hbr = CreateSolidBrush(cl);
            
            FillRect(hdc,&rtfill,hbr);
            
            DeleteObject(hbr);
        }
        void DrawTitle(HDC& hdc,RECT& rc)//画标题
        {
            USES_CONVERSION;        SetBkMode(hdc,1);//文字透明背景模式        COLORREF cltitle,clold;
            OleTranslateColor(m_CaptionColor,NULL,&cltitle);
            clold = SetTextColor(hdc,cltitle);
            
            HFONT hft,holdft;        hft = CreateFont(int((ncaption)*70/100),0,0,0,600,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"楷体_GB2312");    
            
            holdft = (HFONT)SelectObject(hdc,HGDIOBJ(hft));        DrawText(hdc,OLE2CT(m_bstrCaption),lstrlen(OLE2CT(m_bstrCaption)),&rtcaption,DT_CENTER|DT_SINGLELINE|DT_VCENTER);
            
            SelectObject(hdc,HGDIOBJ(holdft));
            DeleteObject(hft);        SetTextColor(hdc,clold);
        }
      

  2.   


        void DrawXYName(HDC& hdc,RECT& rc)//XY坐标轴和Y轴文本
        {
            USES_CONVERSION;        char str[12];
            RECT rttemp;
            COLORREF cltemp,clold;
            SIZE sz;        HPEN hpxy,hpold;
            HFONT hft,holdft;                int cx = xyx.x-xyo.x;
            int cy = xyo.y - xyy.y ;        OleTranslateColor(m_XYAxisColor,NULL,&cltemp);//XY轴及刻度Y文本        
            hpxy = CreatePen(PS_SOLID,m_LineWidth+1,cltemp);        
            hpold = (HPEN)SelectObject(hdc,(HGDIOBJ)hpxy);        //XY轴线
            MoveToEx(hdc,xyo.x ,xyo.y ,NULL);
            LineTo(hdc,xyx.x,xyx.y);
            MoveToEx(hdc,xyo.x ,xyo.y ,NULL);
            LineTo(hdc,xyy.x,xyy.y);        //刻度
            for(int i=0;i<m_XPrValue;++i)//x
            {
                MoveToEx(hdc,xyo.x + (i+1)*(cx)/m_XPrValue+1,xyo.y,NULL);
                LineTo(hdc,xyo.x + (i+1)*(cx)/m_XPrValue+1,xyo.y - 3);
            }
            for(int j=0;j<m_YPrValue;++j)//y
            {
                MoveToEx(hdc,xyo.x,xyo.y - (j+1)*(cy)/m_YPrValue, NULL);
                LineTo(hdc,xyo.x+ 3,xyo.y - (j+1)*(cy)/m_YPrValue);
            }        SelectObject(hdc,(HPEN)hpold);
            DeleteObject(hpxy);
            
            //XY轴文本
            hft = CreateFont(int((ntop)*85/100),0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"宋体_GB2312");
            if(!hft)
            {
                return;
            }
            holdft = (HFONT)SelectObject(hdc,HGDIOBJ(hft));        if(S_OK == OleTranslateColor(m_XYNameColor,NULL,&cltemp))
            {
                clold = SetTextColor(hdc,cltemp);
            }
            else
            {
                clold = SetTextColor(hdc,RGB(255,255,255));
            }        DrawText(hdc,OLE2CT(m_YName),lstrlen(OLE2CT(m_YName)),&rttop,DT_LEFT|DT_SINGLELINE|DT_VCENTER);        GetTextExtentPoint(hdc,OLE2CT(m_XName),lstrlen(OLE2CT(m_XName)),&sz);
            rttemp.left = rtbottom.right - 3*sz.cx/2;
            rttemp.bottom = rtbottom.bottom - 6;
            rttemp.top = rttemp.bottom - sz.cy;
            rttemp.right = rtbottom.right -6;
            DrawText(hdc,OLE2CT(m_XName),lstrlen(OLE2CT(m_XName)),&rttemp,DT_CENTER|DT_SINGLELINE|DT_VCENTER);
            
            SelectObject(hdc,HGDIOBJ(holdft));
            DeleteObject(hft);
        
            //Y轴刻度文本
            for(int j=0;j<m_YPrValue+1;++j)
            {
                if(j%m_YnShow == 0)
                {                    
                    wsprintf(str,"%d",j*m_YRange/m_YPrValue);
                    
                    GetTextExtentPoint(hdc,str,strlen(str),&sz); 
                    
                    rttemp.left = rtleft.left; 
                    rttemp.right =rtleft.right; 
                    rttemp.top = xyo.y - j*(cy)/m_YPrValue +sz.cy/2;
                    rttemp.bottom = xyo.y - j*(cy)/m_YPrValue -sz.cy/2;
                    
                    DrawText(hdc,str,strlen(str),&rttemp,
                        DT_RIGHT|DT_SINGLELINE|DT_VCENTER);
                }
            }            
            SetTextColor(hdc,clold);
        }
        void DrawXYAxis(HDC& hdc,RECT& rc)//画XY轴
        {
            
        }
        void DrawGrid(HDC& hdc,RECT& rc)//画辅助网格
        {        
            HPEN hpgrid,hpgridold;
            COLORREF grid;
            
            int cx = xyx.x-xyo.x;
            int cy = xyo.y - xyy.y;        if(S_OK == OleTranslateColor(m_GridLineColor,NULL,&grid))
            {
                hpgrid = CreatePen(PS_DOT,1,grid);
            }
            else
            {
                hpgrid = CreatePen(PS_DOT,1,RGB(255,255,255));
            }        if(hpgrid)
            {
                hpgridold = (HPEN)SelectObject(hdc,(HGDIOBJ)hpgrid);            for(int m=0;m<m_XPrValue;++m)//垂直线
                {
                    MoveToEx(hdc,xyo.x + (m+1)*(cx)/m_XPrValue ,xyo.y,NULL);
                    LineTo(hdc,xyo.x + (m+1)*(cx)/m_XPrValue ,xyy.y); 
                }
            
                for(int n=0;n<m_YPrValue;++n)//水平线
                {
                    MoveToEx(hdc,xyo.x,xyo.y - (n+1)*(cy)/m_YPrValue,NULL);  
                    LineTo(hdc,xyx.x,xyo.y - (n+1)*(cy)/m_YPrValue);
                }
            
                SelectObject(hdc,(HGDIOBJ)hpgridold);
                DeleteObject(hpgrid);
            }        
        }
      

  3.   


        void DrawCurve(HDC& hdc,RECT& rc)//画曲线
        {
            USES_CONVERSION;        char str[12];        
            COLORREF cltemp,clold;
            SIZE sz;
            RECT rttemp;
            
            HFONT hft,holdft;
            HPEN hpxy,hpold;            int cx = xyx.x-xyo.x;
            int cy = xyo.y - xyy.y;        hft = CreateFont((ntop)*85/100,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"宋体_GB2312");
            holdft = (HFONT)SelectObject(hdc,HGDIOBJ(hft));
            OleTranslateColor(m_XYNameColor,NULL,&cltemp);
            clold = SetTextColor(hdc,cltemp);        //本地时间
            SYSTEMTIME systm;
            GetLocalTime(&systm);
            char tm[60];
            if(m_bDynamic == VARIANT_TRUE)
            {
                wsprintf(tm,"Dynamic:%2d:%2d:%2d   count=%d",systm.wHour,systm.wMinute,systm.wSecond,count);
            
                DrawText(hdc,tm,lstrlen(tm),&rttop,DT_RIGHT|DT_SINGLELINE|DT_VCENTER);
            }
            SelectObject(hdc,HGDIOBJ(holdft));
            DeleteObject(hft);        //X轴刻度文本
            for(int k=0;k<m_XPrValue+1;++k)
            {
                if(k%m_XnShow == 0)
                {    
                    wsprintf(str,"%d",k*m_XRange/m_XPrValue);
                    
                    GetTextExtentPoint(hdc,str,strlen(str),&sz); 
                    
                    rttemp.left = xyo.x + (k)*(cx)/m_XPrValue+1 - sz.cx/2; 
                    rttemp.right =xyo.x + (k)*(cx)/m_XPrValue+1 + sz.cx/2;
                    rttemp.top = rtbottom.top;
                    rttemp.bottom =rtbottom.bottom;
            
                    DrawText(hdc,str,strlen(str),&rttemp,
                        DT_CENTER|DT_SINGLELINE|DT_TOP);
                }
            }            
            SetTextColor(hdc,clold);
                
            //:去掉无用点
            int vptcount=0;
            for(int d=0;d<m_XPrValue*m_XnDots;++d)
            {
               if(m_xypt[d].x == 1)
               {
                      ++vptcount;
               }
            }        POINT pt[256];// = new POINT[vptcount];
            int nptcount = 0;
            for(int r=0;r<m_XPrValue*m_XnDots;++r)
            {
               if(m_xypt[r].x == 1)
               {
                   pt[nptcount].x = r;
                   pt[nptcount].y = m_xypt[r].y;
                   ++nptcount;
               }
            }        for(int k=0;k<vptcount;++k)
            {
                pt[k].x = xyo.x + pt[k].x*(xyx.x - xyo.x)/(m_XPrValue*m_XnDots);
                pt[k].y = xyo.y - pt[k].y*(xyo.y - xyy.y)/m_YRange;
            }
                
            if(S_OK == OleTranslateColor(m_LineColor,NULL,&cltemp))
            {
                hpxy = CreatePen(PS_SOLID,m_LineWidth,cltemp);                
            }
            else
            {
                hpxy = CreatePen(PS_SOLID,m_LineWidth,RGB(255,255,255));              
            }
                
            hpold = (HPEN)SelectObject(hdc,(HGDIOBJ)hpxy);
            
            Polyline(hdc,pt,vptcount);            
            
            SelectObject(hdc,(HGDIOBJ)hpold);
            DeleteObject(hpxy);        //delete []pt;
        }
      

  4.   

    只能自己对应的new delete检查
      

  5.   

    谢谢,后面的函数别看,就看OnDraw()
    即使把里面DrawX都注释掉还是漏,
      

  6.   

    改成这样测试了一下,没有问题HRESULT OnDraw(HWND& hwnd, HDC& hdc, RECT& rc)//改用双缓冲绘制,消除闪烁
    {
    //    RECT& rc = *(RECT*)di.prcBounds;
    //    HDC& hdc = (HDC)di.hdcDraw;    // 将剪辑区域设置为 di.prcBounds 指定的矩形
        HRGN hRgnOld = NULL;
        if (GetClipRgn(hdc, hRgnOld) != 1)
            hRgnOld = NULL;
        bool bSelectOldRgn = false;
        
        HRGN hRgnNew = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
        
        if (hRgnNew != NULL)
        {
            bSelectOldRgn = (SelectClipRgn(hdc, hRgnNew) != ERROR);
        }
        
        //begin:
        static HDC hdcmem = NULL;
        static HBITMAP hbmp= NULL;
        static HBITMAP holdbmp=NULL;
        
        int w = rc.right - rc.left;
        int h = rc.bottom - rc.top;
        
        hdcmem = CreateCompatibleDC(hdc);
        hbmp = CreateCompatibleBitmap(hdc,w,h);
        holdbmp = (HBITMAP)SelectObject(hdcmem,(HGDIOBJ)hbmp);            
        
        
        
        
        BitBlt(hdc,0,0,w,h,hdcmem,0,0,SRCCOPY);
        
        ::SelectObject(hdcmem,(HGDIOBJ)holdbmp);
        ::DeleteObject(hbmp);
        ::ReleaseDC(hwnd,hdcmem);
        //end.
        
        if (bSelectOldRgn)
            SelectClipRgn(hdc, hRgnOld);
        
        //DeleteObject(hRgnOld);
        DeleteObject(hRgnNew);
        
        return S_OK;
    }