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();的问题。谢谢大家了,欢迎给出意见!^-^
因此:
CPaintDC dc(this); // device context for painting
Invalidate();
可以改成:
CDC *pDC = GetDC();最后不要忘了:
ReleaseDC(pDC);
所有的绘图操作都在m_DCMem上进行,
更新的话只要绘图完成后调用InvalidDate()函数(函数名记不清了,好像是这个),让它触发CDrawPad的OnPaint()消息函数,
在OnPaint()函数中加入:
//把内存绘图拷贝到屏幕
dc.BitBlt(ClientRect.left, ClientRect.top, ClientRect.Width(), ClientRect.Height(),
m_DCMem, 0, 0, SRCCOPY);
Good Luck!
FlashCount++; //启动画黑白棋盘格图
drawpad.ShowWindow(TRUE);
drawpad.RunDraw();
//调用从A/D读取数据的线程
gm_pThread = AfxBeginThread(&Thread_IO_InData,NULL);
}while(FlashCount<FlashTotalCount);这里启动了多少线程哦? FlashCount<FlashTotalCount 循环多少次? 太多的启动线程是个问题
多问一句? 你的目的是重现下棋过程吗?
FlashCount++; //启动画黑白棋盘格图
drawpad.ShowWindow(TRUE);
drawpad.RunDraw();
//调用从A/D读取数据的线程
gm_pThread = AfxBeginThread(&Thread_IO_InData,NULL);
}while(FlashCount<FlashTotalCount);
============================
这里我不是很明白,你一下子创建了那么多的线程(FlashTotalCount-FlashCount个线程)为什么呢?你虽然在线程中进行了500ms的睡眠,但是线程基本上是同时创建的,所以说数据基本上是同时到达,这不符合你的“进行延时,使读取每个数据的时间接近500毫秒(采样率2000次/秒)”的要求了啊?!