mfc单文档对话框实时绘图解决办法
mfc单文档对话框实时绘图
之前发过的帖子,本来以为问题解决了,测试了好久发现运行30分钟,程序就会挂了。
我在对话框中绘图,使用了定时器,每隔100ms刷新一次,屏幕闪的快,而且运行半小时就挂了。下面是我的程序,麻烦帮忙解决下,谢谢指教!
void Dlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect rect;
CPen pen[2];//创建画笔
CPen *pOldPen;
//绘制背景
CWnd* pWnd = GetDlgItem(IDC_CURVE);
pWnd->GetClientRect(&rect);
CDC* pDC = pWnd->GetDC();
m_colBk = RGB(255,255,255);
rect.DeflateRect(1,1,1,1);
CBrush bkBrush(m_colBk);
pDC->FillRect(rect,&bkBrush);
//设置画笔
pen[0].CreatePen(PS_DASHDOTDOT,1,RGB(155,100,255));//创建双点划线画笔
pen[1].CreatePen(PS_SOLID,3,RGB(0,0,255));//创建实线画笔
//使用双点划线绘制坐标轴
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存储坐标位置
}
//创建txt文档
CStdioFile file;
file.Open(_T("D:\log.txt"),CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite|CFile::typeText);
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]));
//设定输出格式
CString str;
str.Format("Src X = %lf, Y = %lf, Dst X = %lf, Y = %lf\r\n",CPublic::v1[cnt], -(CPublic::v2[cnt]), CPublic::v1[cnt + 1], -(CPublic::v2[cnt + 1]));
file.WriteString(str); // 写入txt文档
//file.Close();
//printf("Src X = %u, Y = %u, Dst X = %u, Y = %u", CPublic::v1[cnt], -(CPublic::v2[cnt]), CPublic::v1[cnt + 1], -(CPublic::v2[cnt + 1]));
}
//恢复设备描述表中原有的笔
pDC->SelectObject(pOldPen);
//清除前360组的数据
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->ReleaseDC(pDC);
// Do not call CDialog::OnPaint() for painting messages
}
int Dlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
SetTimer(3,200,NULL);
return 0;
}
void Dlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CPublic::count++;
InvalidateRect (NULL, FALSE);
CDialog::OnTimer(nIDEvent);
}
//显示数据对话框
void Dlg::OnShow()
{
// TODO: Add your control notification handler code here
//创建非模态对话框显示数据
CAboutDlg *pAboutDlg;
pAboutDlg = new CAboutDlg();
之前发过的帖子,本来以为问题解决了,测试了好久发现运行30分钟,程序就会挂了。
我在对话框中绘图,使用了定时器,每隔100ms刷新一次,屏幕闪的快,而且运行半小时就挂了。下面是我的程序,麻烦帮忙解决下,谢谢指教!
void Dlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect rect;
CPen pen[2];//创建画笔
CPen *pOldPen;
//绘制背景
CWnd* pWnd = GetDlgItem(IDC_CURVE);
pWnd->GetClientRect(&rect);
CDC* pDC = pWnd->GetDC();
m_colBk = RGB(255,255,255);
rect.DeflateRect(1,1,1,1);
CBrush bkBrush(m_colBk);
pDC->FillRect(rect,&bkBrush);
//设置画笔
pen[0].CreatePen(PS_DASHDOTDOT,1,RGB(155,100,255));//创建双点划线画笔
pen[1].CreatePen(PS_SOLID,3,RGB(0,0,255));//创建实线画笔
//使用双点划线绘制坐标轴
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存储坐标位置
}
//创建txt文档
CStdioFile file;
file.Open(_T("D:\log.txt"),CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite|CFile::typeText);
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]));
//设定输出格式
CString str;
str.Format("Src X = %lf, Y = %lf, Dst X = %lf, Y = %lf\r\n",CPublic::v1[cnt], -(CPublic::v2[cnt]), CPublic::v1[cnt + 1], -(CPublic::v2[cnt + 1]));
file.WriteString(str); // 写入txt文档
//file.Close();
//printf("Src X = %u, Y = %u, Dst X = %u, Y = %u", CPublic::v1[cnt], -(CPublic::v2[cnt]), CPublic::v1[cnt + 1], -(CPublic::v2[cnt + 1]));
}
//恢复设备描述表中原有的笔
pDC->SelectObject(pOldPen);
//清除前360组的数据
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->ReleaseDC(pDC);
// Do not call CDialog::OnPaint() for painting messages
}
int Dlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
SetTimer(3,200,NULL);
return 0;
}
void Dlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CPublic::count++;
InvalidateRect (NULL, FALSE);
CDialog::OnTimer(nIDEvent);
}
//显示数据对话框
void Dlg::OnShow()
{
// TODO: Add your control notification handler code here
//创建非模态对话框显示数据
CAboutDlg *pAboutDlg;
pAboutDlg = new CAboutDlg();