MFC程序老是运行一段时间后自动卡死,重启。并且自动卡死重启的时间总是大约在3分钟左右
MFC程序总是运行一段时间后自动卡死,重启。并且自动卡死重启的时间总是大约在3分钟左右
我做的是一个光谱仪的显示界面,为了防止界面闪烁,使用了双缓存技术。因为每隔固定时间(例如10ms要求数据刷新),所以主要程序是在定时器中完成的,主要就是使用了位图CBitmap,创建与显示的编辑框相兼容的Dc,并在位图中绘图,绘图完成后将位图显示在编辑框中。定时器的函数如下;
我做的是一个光谱仪的显示界面,为了防止界面闪烁,使用了双缓存技术。因为每隔固定时间(例如10ms要求数据刷新),所以主要程序是在定时器中完成的,主要就是使用了位图CBitmap,创建与显示的编辑框相兼容的Dc,并在位图中绘图,绘图完成后将位图显示在编辑框中。定时器的函数如下;
void CMy427eveningDlg::OnTimer(UINT_PTR nIDEvent)
{
//******************************************************************************//
if(true==m_Isthefirsttime)//第一次执行计数器的时候将data中添加MAXPOINT个数,防止后面访问data时溢出
{
for(int i=0;i<MAXPOINT;++i)
{
data.push_back(f_cos(m_Count+data.size())); //f_cos()是要绘制的函数曲线
}
m_Isthefirsttime=false; //data是一个deque<float>的数组,存储将被显示的数据点坐标y轴
}
if (true==m_stoportiming)
{
if (m_Xnunbers==m_NewXnum)//默认m_NewXnum等于100
{
data.pop_front();
++m_Count;
data.push_back(f_cos(m_Count+data.size()));
}
else if(m_NewXnum > m_Xnunbers)
{
for (int i=0;i<m_NewXnum-m_Xnunbers;++i)
data.push_back(f_cos(m_Count+data.size()));
}
else if (m_NewXnum<m_Xnunbers)
{
for (int i=0;i<m_Xnunbers-m_NewXnum;++i)
{ data.pop_front();
++m_Count;
}
}
}
m_Xnunbers=m_NewXnum;
//********************************************************************************//以上程序段主要实现显示界面的横轴分辨率可调
//**********************************************************************************m_NewXnum是整个界面这一次会绘制的点数///**********************************************************************************m_Xnunbers是整个界面上一次会绘制的点数
if(1== nIDEvent ) ////////定时器的标志为1
{
CRect rc;
CClientDC *pDC=(CClientDC *)GetDlgItem(IDC_drawplace)->GetDC(); //获取绘图框的设备上下文dc
GetDlgItem(IDC_drawplace)-> GetClientRect(rc); //获取绘图框的大小
CRect m_rec(rc);
////////双缓冲技术中的两个重要变量
CDC pMemDC; //在内存画图的DC和存在内存中的位图
pMemDC.CreateCompatibleDC(pDC);
CBitmap membitmap;
membitmap.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height()); //将此Dc和内存中的位图相关联
pMemDC.SelectObject(&membitmap);
// CBrush *pbrush=pDC->GetCurrentBrush(); //将位图的背景设为白色
CBrush pbrush(RGB(0,100,100));
pMemDC.FillRect(rc,&pbrush); //改变位图背景颜色,如果不变的话显示的背景将为黑色,极其难看
////////////************************************************
rc.DeflateRect(rc.Width()/20,rc.Height()/20); //矩形内缩函数
int gridXnums=20,gridYnums=5;
int dx=rc.Width()/gridXnums;
int dy=rc.Height()/gridYnums;
CPen gridPen(0,0,RGB(0,0,0));
//////////////////////////////////////绘制网格线
//所有一切跟绘图有关的句柄,在内存位图中实施进行的都应该是用pMemDC来完成,而不是使用编辑框的pDC
CRect gridRect(rc.left,rc.top,rc.left+dx*gridXnums,rc.top+dy*gridYnums);
CPen *oldPen=pDC->SelectObject(&gridPen);
for(int i=0;i<=gridXnums;i++) //画网格线条X轴
{
pMemDC.MoveTo(gridRect.left+i*dx,gridRect.bottom);
pMemDC.LineTo(gridRect.left+i*dx,gridRect.top);
}
for(int i=0;i<=gridYnums;i++) //画网格线条Y轴
{
pMemDC.MoveTo(gridRect.left,gridRect.top+i*dy);
pMemDC.LineTo(gridRect.right,gridRect.top+i*dy);
}
pMemDC.SelectObject(oldPen);
gridPen.Detach();
gridPen.CreatePen(PS_SOLID,3,RGB(255,255,255));
pMemDC.SelectObject(&gridPen);
////////////////////////////////////////////
//绘制坐标轴和刻度线
// 绘制坐标轴
pMemDC.MoveTo(gridRect.left,gridRect.top-20);
// 垂直轴
pMemDC.LineTo(gridRect.left,gridRect.bottom);
// 水平轴
pMemDC.LineTo(gridRect.right+20,gridRect.bottom);
// 写X轴刻度值
for(int i=0;i<=10;++i)
{
//str.Format(_T("%d"),m_Min+i*m_Interval);
m_str.Format(_T("%.2lf"),(m_Count+i*MAXPOINT/10/m_waveresolution)*Period);
pMemDC.TextOut(rc.left+2*i*dx-3,rc.bottom+3,m_str); //加3为经验值,无实际意义
}
//写y轴刻度值
for(int i=0;i<=5;++i)
{
//str.Format(_T("%d"),m_Min+i*m_Interval);
m_str.Format(_T("%.0lf"),10*i*m_rangeresolution+m_ref); //注意此处由于m_rangeresolution是float类型,所以转化的时候一定要转化为lf类型的,为了省去小数点后的数字,采用%.0lf的格式化输出
pMemDC.TextOut(rc.left-10,rc.bottom-dy*i-10,m_str); //减10为经验值,无实际意义
}
m_str.Format(_T("%d"),m_Count);
pMemDC.TextOut(rc.left-10,rc.bottom+10,m_str); //用文本框输出现在已经被弹出的数据
// 绘制Y轴箭头
pMemDC.MoveTo(gridRect.left-5,gridRect.top-20+5);
pMemDC.LineTo(gridRect.left,gridRect.top-20);
pMemDC.LineTo(gridRect.left+5,gridRect.top-20+5);
// 绘制X轴箭头
pMemDC.MoveTo(gridRect.right+20-5,gridRect.bottom-5);
pMemDC.LineTo(gridRect.right+20,gridRect.bottom);
pMemDC.LineTo(gridRect.right+20-5,gridRect.bottom+5);
gridPen.Detach();
//str.Format(_T("%d"),m_Max);