MFC单文档图片框实时绘图解决办法
MFC单文档图片框实时绘图
我的工程师基于单文档的,想用图片框实时绘制曲线,采用定时器实现,但是绘制一定时间后就会报错,不知道原因在哪里?
vector里的数据会隔一段时间清除,下面是我的代码:
onpaint()中,
有会的路过帮帮忙,谢谢!
------解决方案--------------------
GDI资源泄露了吧?
pen[0].DeleteObject();
pen[1].DeleteObject();
你这些操作应该是失败返回了,都没有看到你SelectObject旧的PEN
------解决方案--------------------
1) CDC* pDC = pWnd->GetDC();
获得了dc为什么最后不释放dc呢
2) pen[0].DeleteObject();
pen[1].DeleteObject();
删除前需要还原dc的object
------解决方案--------------------
lz这个代码.............
1,在void Dlg::OnPaint() 给
CWnd* pWnd = GetDlgItem(IDC_CURVE); 绘图显然是不合适的,因为,pWnd 需要的绘画时,dlg不一定会收到WM_PAINT
2,绘画完毕不能再pWnd->InvalidateRect(&rect);
------解决方案--------------------
最后加一句:
pWnd->ReleaseDC(pDC);
------解决方案--------------------
对话框不弹出也未被隐藏的时候void Dlg::OnPaint()函数没有被执行,此时无法画图。要想在 对话框不弹出的时候也在绘图,还想把图形画到对话框上面,这不科学。因为CWnd*/CDC*/CRect等句均为NULL
------解决方案--------------------
做成非模态对对话框,m_XXXdlg.ShowWindow(SW_SHOW);//显示
m_XXXdlg.ShowWindow(SW_HIDE);//隐藏
我的工程师基于单文档的,想用图片框实时绘制曲线,采用定时器实现,但是绘制一定时间后就会报错,不知道原因在哪里?
vector里的数据会隔一段时间清除,下面是我的代码:
onpaint()中,
void Dlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect rect;
CPen pen[2];
//绘制背景
m_colBk = RGB(100,100,150);
CWnd* pWnd = GetDlgItem(IDC_CURVE);
rect.DeflateRect(1,1,1,1);
CBrush bkBrush(m_colBk);
pWnd->GetClientRect(&rect);
CDC* pDC = pWnd->GetDC();
pDC->FillRect(rect,&bkBrush);
pen[0].CreatePen(PS_DASHDOTDOT,1,RGB(155,0,255));//创建双点划线画笔
pen[1].CreatePen(PS_SOLID,3,RGB(0,0,255));//创建实线画笔
CPen *pOldPen;
//使用双点划线绘制坐标轴
pOldPen=pDC->SelectObject(&pen[0]);
//设置窗口坐标
pDC->SetMapMode(MM_ANISOTROPIC);
pDC->SetWindowExt(3000,3000); //设置窗口尺寸
pDC->SetViewportExt(rect.Width(),rect.Height()); //设置视口尺寸
pDC->SetWindowOrg(-100,-2800); //设置坐标原点
pDC->SetBkColor(RGB(255,255,100)); //设置背景色
//绘制坐标轴
for (int j = 0 ;j < 27 ;++j)
for (int i = 0 ;i < 27 ;++i)
{
CString str;
//t轴
//SYSTEMTIME st;
//GetLocalTime(&st);
//str.Format("-:-:-",st.wHour,st.wMinute,st.wSecond);
if(i*100 <= 2800)
{
pDC->MoveTo(i*100,-(100*j));
pDC->LineTo(100 + i*100,-(100*j));
}
//每隔72s改变一次时间轴
k = CPublic::v1.size()/360 + m_pCounter;
str.Format("%d", i*100*3/100 + 72*k);
pDC->TextOut(-10 + i*100,40,str);
pDC->TextOut(1500,120,"t/s");
//Z轴
if(j*100 >= -2800)
{
pDC->MoveTo(100*i,-(100*j));
pDC->LineTo(100*i,-(100 + 100*j));
}
str.Format("%d",i*100);
pDC->TextOut(-100,-(i*100)-40,str);
pDC->TextOut(-200,-1500,"z/mm");
}
//使用实线绘图
pDC->SelectObject(&pen[1]);
//保存坐标位置,为绘制曲线做准备(放在APP中只有显示数据之后才能绘图,达不到实时绘图的目的)
//CPublic::v1.push_back(CPublic::gstrStrOfGoodData[0]);
//测试绘制sin()曲线
vector<double>::size_type cnt;
if(CPublic::v1.size() < 361)
{
CPublic::v1.push_back(CPublic::count*100/15);//这里v1存储时间
CPublic::v2.push_back(500 + 500*sin(CPublic::count));//v2存储坐标位置
}
//
for (cnt = 0;cnt != CPublic::v1.size() - 1;++cnt)
{
pDC->MoveTo(CPublic::v1[cnt],-(CPublic::v2[cnt]));
pDC->LineTo(CPublic::v1[cnt + 1],-(CPublic::v2[cnt + 1]));
}
//清除前300组即1min的数据
if (CPublic::v1.size() > 360)
{
CPublic::v1.swap(vector<double>());//清除v1的存储空间即v1.size()为0
//int length = CPublic::v1.size();
CPublic::v2.swap(vector<double>());//清除v2的存储空间即v2.size()为0
CPublic::count = 0;//测试需要,时间轴数据未变化,用计数来实现
m_pCounter++;
UpdateData(FALSE);
}
//释放画笔
pen[0].DeleteObject();
pen[1].DeleteObject();
pWnd->InvalidateRect(&rect);
// Do not call CDialog::OnPaint() for painting messages
}
有会的路过帮帮忙,谢谢!
------解决方案--------------------
GDI资源泄露了吧?
pen[0].DeleteObject();
pen[1].DeleteObject();
你这些操作应该是失败返回了,都没有看到你SelectObject旧的PEN
------解决方案--------------------
1) CDC* pDC = pWnd->GetDC();
获得了dc为什么最后不释放dc呢
2) pen[0].DeleteObject();
pen[1].DeleteObject();
删除前需要还原dc的object
------解决方案--------------------
lz这个代码.............
1,在void Dlg::OnPaint() 给
CWnd* pWnd = GetDlgItem(IDC_CURVE); 绘图显然是不合适的,因为,pWnd 需要的绘画时,dlg不一定会收到WM_PAINT
2,绘画完毕不能再pWnd->InvalidateRect(&rect);
------解决方案--------------------
最后加一句:
pWnd->ReleaseDC(pDC);
------解决方案--------------------
对话框不弹出也未被隐藏的时候void Dlg::OnPaint()函数没有被执行,此时无法画图。要想在 对话框不弹出的时候也在绘图,还想把图形画到对话框上面,这不科学。因为CWnd*/CDC*/CRect等句均为NULL
------解决方案--------------------
做成非模态对对话框,m_XXXdlg.ShowWindow(SW_SHOW);//显示
m_XXXdlg.ShowWindow(SW_HIDE);//隐藏