void CVEPView::SampleSetup()
{
do{
FlashCount++; //启动画黑白棋盘格图
drawpad.ShowWindow(TRUE);
drawpad.RunDraw();
//调用从A/D读取数据的线程
gm_pThread = AfxBeginThread(&Thread_IO_InData,NULL);
}while(FlashCount<FlashTotalCount);
//关闭闪烁棋盘格以及清零闪烁次数
drawpad.ShowWindow(FALSE);
FlashCount=0;
//数据保存,并把采样到的数据保存到txt文本文件中
CFile file("tempData.txt",CFile::modeCreate | CFile::modeWrite);
CString str="";
for(int i=0;i<CountReadData;i++)
{
str.Format("%f",firstdata[i]);
if(((i+1)!=0)&&((i+1)%10==0))
str=str+"\r\n";
else
str=str+',';
file.Write(str,str.GetLength());
}
file.Close();
AfxMessageBox("数据采样完成!");
//采样数据计数器清零
CountReadData=0;
}
UINT Thread_IO_InData(LPVOID pParam)//从A/D板读取数据的线程
{
CVEPView *pView = NULL;
CMainFrame *pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
pView = (CVEPView*) pFrame->GetActiveView();
//采样数据,采样的总时间长度等于闪烁的总次数乘以棋盘格时间频率的倒数;棋盘格时间频率的倒数等于0.5毫秒(采样率为2000次/秒)乘以PerSampleTotalCount
for(pView->PerSampleCount = 0; pView->PerSampleCount < pView->PerSampleTotalCount; pView->PerSampleCount++)
{
pView->SampleData();
pView->DelayTime(470);//进行延时,使读取每个数据的时间接近500毫秒(采样率2000次/秒)
} AfxEndThread(0);
return 0;
}
上面的CVEPView::SampleSetup()是我按下界面上一个按钮触发的函数,Thread_IO_InData(LPVOID pParam)是gm_pThread = AfxBeginThread(&Thread_IO_InData,NULL);这条语句所调用的线程,此线程完成工作为从A/D板读取数据。drawpad.RunDraw();调用了另一类的成员函数进行画黑白方格相间的图。
我的思路是:在do-while循环中,(1)先调用画图函数,画黑白棋盘格——(2)转到线程中读取数据——回到do-while中重复(1)(2)这两步操作,直到循环退出,将刚才所读取的数据保存成TXT文件。如果正常的话,看到的现象应该是黑白方格图在屏幕上闪烁若干次,然后结束,闪烁的时间间隔应该是相等的。黑白方格图在屏幕上停留的时间是线程运行的时间,也就是读取数据的时间,读取的数目固定,每次时间应该是相等的。我现在看到的现象是,黑白方格图前几次闪的特别快,后几次感觉还正常。单步调试时,发现线程好象正常、但有时又不正常!问题出在哪呢,大家能帮我分析一下吗,只要解决,分好商量!
{
do{
FlashCount++; //启动画黑白棋盘格图
drawpad.ShowWindow(TRUE);
drawpad.RunDraw();
//调用从A/D读取数据的线程
gm_pThread = AfxBeginThread(&Thread_IO_InData,NULL);
}while(FlashCount<FlashTotalCount);
//关闭闪烁棋盘格以及清零闪烁次数
drawpad.ShowWindow(FALSE);
FlashCount=0;
//数据保存,并把采样到的数据保存到txt文本文件中
CFile file("tempData.txt",CFile::modeCreate | CFile::modeWrite);
CString str="";
for(int i=0;i<CountReadData;i++)
{
str.Format("%f",firstdata[i]);
if(((i+1)!=0)&&((i+1)%10==0))
str=str+"\r\n";
else
str=str+',';
file.Write(str,str.GetLength());
}
file.Close();
AfxMessageBox("数据采样完成!");
//采样数据计数器清零
CountReadData=0;
}
UINT Thread_IO_InData(LPVOID pParam)//从A/D板读取数据的线程
{
CVEPView *pView = NULL;
CMainFrame *pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
pView = (CVEPView*) pFrame->GetActiveView();
//采样数据,采样的总时间长度等于闪烁的总次数乘以棋盘格时间频率的倒数;棋盘格时间频率的倒数等于0.5毫秒(采样率为2000次/秒)乘以PerSampleTotalCount
for(pView->PerSampleCount = 0; pView->PerSampleCount < pView->PerSampleTotalCount; pView->PerSampleCount++)
{
pView->SampleData();
pView->DelayTime(470);//进行延时,使读取每个数据的时间接近500毫秒(采样率2000次/秒)
} AfxEndThread(0);
return 0;
}
上面的CVEPView::SampleSetup()是我按下界面上一个按钮触发的函数,Thread_IO_InData(LPVOID pParam)是gm_pThread = AfxBeginThread(&Thread_IO_InData,NULL);这条语句所调用的线程,此线程完成工作为从A/D板读取数据。drawpad.RunDraw();调用了另一类的成员函数进行画黑白方格相间的图。
我的思路是:在do-while循环中,(1)先调用画图函数,画黑白棋盘格——(2)转到线程中读取数据——回到do-while中重复(1)(2)这两步操作,直到循环退出,将刚才所读取的数据保存成TXT文件。如果正常的话,看到的现象应该是黑白方格图在屏幕上闪烁若干次,然后结束,闪烁的时间间隔应该是相等的。黑白方格图在屏幕上停留的时间是线程运行的时间,也就是读取数据的时间,读取的数目固定,每次时间应该是相等的。我现在看到的现象是,黑白方格图前几次闪的特别快,后几次感觉还正常。单步调试时,发现线程好象正常、但有时又不正常!问题出在哪呢,大家能帮我分析一下吗,只要解决,分好商量!
void CDrawPad::RunDraw()
{
CPaintDC dc(this); // device context for painting
Invalidate();
//dc.SetMapMode(MM_HIMETRIC);//映射模式的设置
CDC *memDC = new CDC;
memDC->CreateCompatibleDC(&dc);
CBitmap *memBmp = new CBitmap;//内存绘图
CRect ClientRect;
GetClientRect(ClientRect);
memBmp->CreateCompatibleBitmap(&dc, ClientRect.Width(), ClientRect.Height());
CBitmap *pOldBmp = memDC->SelectObject(memBmp);
if((k%2)==0)
DrawElement(memDC, ClientRect, TRUE);//DrawElement()这个函数的代码,下面给出了
else
DrawElement(memDC, ClientRect, FALSE);
//把内存绘图拷贝到屏幕
dc.BitBlt(ClientRect.left, ClientRect.top, ClientRect.Width(), ClientRect.Height(),
memDC, 0, 0, SRCCOPY);
memDC->SelectObject(pOldBmp);
memDC->DeleteDC();
delete memDC;
memBmp->DeleteObject();
delete memBmp;
k++;
}
void CDrawPad::DrawElement(CDC *pDC, const CRect DrawRect, BOOL BlackFirst)//画黑白棋盘格图
{
if (!pDC)
return;
CBrush *pOldBrush = (CBrush*)pDC->SelectStockObject(WHITE_BRUSH);
CPen *pOldPen = (CPen*)pDC->SelectStockObject(NULL_PEN);
pDC->Rectangle(DrawRect);
pDC->SelectStockObject(BLACK_BRUSH);
CRect rcBlack(DrawRect.left, DrawRect.top, DrawRect.left + m_size0, DrawRect.top + m_size0);
if (!BlackFirst)
{
rcBlack.OffsetRect(m_size0, 0);
}
while (rcBlack.top < DrawRect.bottom)
{
while (rcBlack.left < DrawRect.right)
{
pDC->Rectangle(rcBlack);
rcBlack.OffsetRect(m_size0 + m_size0, 0);
}
rcBlack.left = DrawRect.left;
rcBlack.top += m_size0;
rcBlack.right = rcBlack.left + m_size0;
rcBlack.bottom = rcBlack.top + m_size0;
if (BlackFirst)
{
rcBlack.OffsetRect(m_size0, 0);
}
BlackFirst = !BlackFirst;
}
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush); //在屏幕中央画小红点部分
pDC->FillSolidRect(DrawRect.right/2-5, DrawRect.bottom/2-5, 10, 10, RGB(255,0,0) );
//画红点部分结束
ReleaseDC(pDC);
}
原来我放在void CDrawPad::RunDraw()中的代码是放在void CDrawPad::OnPaint()中的,除了Invalidate();这句。原来我是想在CVEPView::SampleSetup()中通过drawpad.Invalidate();触发画图的,结果出现不了黑白格子图交替出现的情况。别人告诉我:Invalidate触发重画只是发送WM_Paint消息,在此消息没有得到处理的时候,如果再有同样的消息到达,一律被抛弃。所以我就改成现在的情况了。我不知道还是不是Invalidate();的问题。谢谢大家了,欢迎给出意见!^-^
FlashCount++; //启动画黑白棋盘格图
drawpad.ShowWindow(TRUE);
drawpad.RunDraw();
//调用从A/D读取数据的线程
gm_pThread = AfxBeginThread(&Thread_IO_InData,NULL);
}while(FlashCount<FlashTotalCount);
//AfxBeginThread是开启一个新的线程,你这样调用的话,会同时开启多个线程,而且主线程并没有中断(没有等待读取数据完毕)。
//同时,在你的线程函数Thread_IO_InData中,你直接就调用pView->SampleData();
//所以,同时开了多个线程以后,每个线程都会调用pView->SampleData();然后才是延时。
//因此,最开始每次闪烁的间隔时间应该是创建新的线程,以及线程执行到pView->SampleData();
//以后的时间,后面的间隔时间就与Delay()的时间有关了,不过也不是Delay指定的时间
在do-while循环中,(1)先调用画图函数,画黑白棋盘格——(2)转到线程中读取数据——回到do-while中重复(1)(2)这两步操作,直到循环退出
//应该是画完棋盘以后,转到线程读取数据,这个时候应该是等待数据读取完毕?然后才重复前面的调用,还是不需要等待就开启线程读取新的数据?