CBarChart使用时踩到的一个显示位图异常的坑

CBarChart源码下载:  https://www.codeproject.com/Articles/17105/CBarChart?msg=3210667#xx3210667xx

修改过的CBarChart源码: https://download.csdn.net/download/u010096608/10879033

问题: 再调用下面的函数来调用显示图表时,调用次数多了后,会出现图表区域无法显示的问题

void ShowBarChart(int *hours,int n,bool bClass)
{
    CRect rcClient;
    CString strTemp;
    GetClientRect(&rcClient);
    int crl = 1;
    if (!m_chart.Create(CRect(crl, crl, rcClient.Width()-crl, rcClient.Height() - crl), this, 1000 ))
    {
        if (!m_chart.GetSafeHwnd())
        {
            AfxMessageBox(_T("不能创建图表控件!"));
            return;
        }
        m_chart.Reset();
        m_chart.SetAutoScale(FALSE);
    }
    m_chart.SetAutoScale(TRUE);
    m_chart.SetTitle(_T("生 产 数 据 分 时 段 显 示"));
    m_chart.SetBKColor(RGB(255, 255, 240));
    m_chart.ShowTooltip(TRUE);

    for (int i=0;i<DATA_ITEM_COUNT-1;i++)
    {
        if (!bClass)
            strTemp.Format(_T("%d时"),8+i);
        else
            strTemp.Format(_T("%d时"),(20+i)%24);
        m_chart.AddBar(hours[i],strTemp,RGB(130,235,250));
    }
    if (!bClass)
        strTemp.Format(_T("%d时"),8+DATA_ITEM_COUNT);
    else
        strTemp.Format(_T("%d时"),(20+DATA_ITEM_COUNT)%24);
    m_chart.AddBar(hours[DATA_ITEM_COUNT-1],strTemp,RGB(130,235,250),TRUE);
}

 

正常情况下的显示: 

  

点击多次查询,不停调用ShowBarChart()后,出现异常: 

   

 

解决:   经过跟踪调试,发现问题是出现在了BarChart的ReSet()函数上。Reset()函数如下:

  

// Removes all bars, and forces the chart to be redrawn.
void CBarChart::Reset()
{
    m_bars.RemoveAll();
    m_rctMemPic = CRect(0, 0, 0, 0);

    CClientDC dc(this);
    RedrawChart(&dc);
}

Reset主要删除数据和重设位图,而我在reset后进行AddBar操作,添加数据并显示柱状图,AddBar函数如下: 

// Adds a bar to the chart
// Parameters:
//                udValue : Value of the bar
//                szLabel : Label of the bar, will be shown under the bar
//                color    : Color of the bar. This color will be used to create a gradient.
//                bRepaint: If set to TRUE, forces the chart to show changes on the screen
//                          Default is set to false. It is recommended to set it to true just
//                          For last Add bar of the chart, so the chart won't be forced to
//                          Show changes every time a single bar is added.

void CBarChart::AddBar(double udValue, CString szLabel, COLORREF color, BOOL bRepaint)
{
    m_bars.AddBar(udValue, szLabel, color);

    if (bRepaint)
    {
        CClientDC dc(this);
        RedrawChart(&dc);

        Invalidate();
    }
}

AddBar主要添加数据和重设位图以及显示。问题就出在RedrawChart()中,RedrawChart()函数如下:

  

void CBarChart::RedrawChart(CDC* pDC)
{
    if (!m_dcMem.GetSafeHdc())
    {
        m_dcMem.CreateCompatibleDC(pDC);
    }

    // Deselect and destroy old bitmap, and create a new one
    ResetBitmap(pDC);

    Refresh();
}

可以看到,RedrawChart中进行了删除位图和创建新位图,并刷新,刷新是调用Invalidate()函数, 但是对于Invalidate()函数,只有在函数运行完后才会发送WM_PAINT消息,然后窗口才会重绘。

   因此,Reset函数中在删除位图和创建新位图后,并没有能够实现刷新窗口 并显示位图,而是在AddBar中又一次删除 位图和创建新位图,然后才能够重绘窗口显示位图。 这样容易出现 保存位图的DC资源异常的问题,导致后面显示都是一片黑色。 

  解决方法是不要在Addbar前面调用Reset函数,只需删除旧的数据旧可以了。更新后的代码 如下: 

 

void ShowBarChart(int *hours,int n,bool bClass)
{
    CRect rcClient;
    CString strTemp;
    GetClientRect(&rcClient);
    int crl = 1;
    if (!m_chart.Create(CRect(crl, crl, rcClient.Width()-crl, rcClient.Height() - crl), this, 1000 ))
    {
        if (!m_chart.GetSafeHwnd())
        {
            AfxMessageBox(_T("不能创建图表控件!"));
            return;
        }
        //m_chart.Reset();//用reset后再addbar,只会执行一次重绘
        m_chart.SetAutoScale(FALSE);
    }
    m_chart.RemoveAll();
    m_chart.SetAutoScale(TRUE);
    m_chart.SetTitle(_T("生 产 数 据 分 时 段 显 示"));
    m_chart.SetBKColor(RGB(255, 255, 240));
    m_chart.ShowTooltip(TRUE);

    for (int i=0;i<DATA_ITEM_COUNT-1;i++)
    {
        if (!bClass)
            strTemp.Format(_T("%d时"),8+i);
        else
            strTemp.Format(_T("%d时"),(20+i)%24);
        m_chart.AddBar(hours[i],strTemp,RGB(130,235,250));
    }
    if (!bClass)
        strTemp.Format(_T("%d时"),8+DATA_ITEM_COUNT);
    else
        strTemp.Format(_T("%d时"),(20+DATA_ITEM_COUNT)%24);
    m_chart.AddBar(hours[DATA_ITEM_COUNT-1],strTemp,RGB(130,235,250),TRUE);
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值