这是VC的另一种方式:
1 在类内声明成员函数,这个函数做为线程的入口函数:
static UINT ReceiveThread(void *param);
2 线程入口函数的实现:
UINT CTestDlg::ReceiveThread(void *param)
{
CTestDlg *dlg=(CTestDlg*)param;
CListBox *box=(CListBox *)dlg->GetDlgItem(IDC_LIST_INFO);
VCI_CAN_OBJ frameinfo[50];
VCI_ERR_INFO errinfo;
int len=1;
int i=0;
CString str,tmpstr;
while(1)
{
Sleep(1);
if(dlg->m_connect==0)
break;
len=VCI_Receive(dlg->m_devtype,dlg->m_devind,dlg->m_cannum,frameinfo,50,200);
if(len<=0)
{
//注意:如果没有读到数据则必须调用此函数来读取出当前的错误码,
//千万不能省略这一步(即使你可能不想知道错误码是什么)
VCI_ReadErrInfo(dlg->m_devtype,dlg->m_devind,dlg->m_cannum,&errinfo);
}
else
{
for(i=0;i<len;i++)
{
str="<-[属性]:";
if(frameinfo[i].TimeFlag==0)
tmpstr="时间标识:无 ";
else
tmpstr.Format("时间标识:%08x ",frameinfo[i].TimeStamp);
str+=tmpstr;
tmpstr.Format("帧ID:%08x ",frameinfo[i].ID);
str+=tmpstr;
str+="帧格式:";
if(frameinfo[i].RemoteFlag==0)
tmpstr="数据帧 ";
else
tmpstr="远程帧 ";
str+=tmpstr;
str+="帧类型:";
if(frameinfo[i].ExternFlag==0)
tmpstr="标准帧 ";
else
tmpstr="扩展帧 ";
str+=tmpstr;
box->InsertString(box->GetCount(),str);
if(frameinfo[i].RemoteFlag==0)
{
str="<-[数据]:";
if(frameinfo[i].DataLen>8)
frameinfo[i].DataLen=8;
for(int j=0;j<frameinfo[i].DataLen;j++)
{
tmpstr.Format("%02x ",frameinfo[i].Data[j]);
str+=tmpstr;
}
//EnterCriticalSection(&(dlg->m_Section));
//LeaveCriticalSection(&(dlg->m_Section));
box->InsertString(box->GetCount(),str);
}
}
box->SetCurSel(box->GetCount()-1);
}
}
return 0;
}
3 在程序的初始化或适当位置启动线程:
void CTestDlg::OnButtonConnect()
{
// TODO: Add your control notification handler code here
if(m_connect==1)
{
m_connect=0;
Sleep(500);
GetDlgItem(IDC_BUTTON_CONNECT)->SetWindowText("连接");
VCI_CloseDevice(m_devtype,m_devind);
return;
}
VCI_INIT_CONFIG init_config;
int index,filtertype,mode,cannum;
CString strcode,strmask,strtiming0,strtiming1,strtmp;
char szcode[20],szmask[20],sztiming0[20],sztiming1[20];
unsigned char sztmp[4];
DWORD code,mask,timing0,timing1;
UpdateData(true);
index=m_ComboIndex.GetCurSel(); //设备索引号
filtertype=m_ComboFilterType.GetCurSel(); //滤波方式
mode=m_ComboMode.GetCurSel(); //模式
cannum=m_ComboCANInd.GetCurSel(); //第几路CAN
strcode=m_EditCode; //验收码
strmask=m_EditMask; //屏蔽码
strtiming0=m_EditTiming0; //定时器0
strtiming1=m_EditTiming1; //定时器1
UpdateData(false);
//验收码和屏蔽码转化为固定8个字符宽度
strtmp=strcode;
strcode.Format("%08s",strtmp);
strtmp=strmask;
strmask.Format("%08s",strtmp);
//定时器转化为固件两个字符宽度
strtmp=strtiming0;
strtiming0.Format("%02s",strtmp);
strtmp=strtiming1;
strtiming1.Format("%02s",strtmp);
strcpy(szcode,(LPCTSTR)strcode);
strcpy(szmask,(LPCTSTR)strmask);
strcpy(sztiming0,(LPCTSTR)strtiming0);
strcpy(sztiming1,(LPCTSTR)strtiming1);
if(strtodata((unsigned char*)szcode,sztmp,4,0)!=0)
{
MessageBox("验收码数据格式不对!","警告",MB_OK|MB_ICONQUESTION);
return;
}
code=(((DWORD)sztmp[0])<<24)+(((DWORD)sztmp[1])<<16)+(((DWORD)sztmp[2])<<8)+
((DWORD)sztmp[3]);
if(strtodata((unsigned char*)szmask,sztmp,4,0)!=0)
{
MessageBox("屏蔽码数据格式不对!","警告",MB_OK|MB_ICONQUESTION);
return;
}
mask=(((DWORD)sztmp[0])<<24)+(((DWORD)sztmp[1])<<16)+(((DWORD)sztmp[2])<<8)+
((DWORD)sztmp[3]);
if(strtodata((unsigned char*)sztiming0,sztmp,1,0)!=0)
{
MessageBox("定时器0数据格式不对!","警告",MB_OK|MB_ICONQUESTION);
return;
}
timing0=((DWORD)sztmp[0]);
if(strtodata((unsigned char*)sztiming1,sztmp,1,0)!=0)
{
MessageBox("定时器1数据格式不对!","警告",MB_OK|MB_ICONQUESTION);
return;
}
timing1=((DWORD)sztmp[0]);
init_config.AccCode=code; //验收码
init_config.AccMask=mask; //屏蔽码
init_config.Filter=filtertype; //过滤方式
init_config.Mode=mode; //模式
init_config.Timing0=timing0; //定时器0
init_config.Timing1=timing1; //定时器1
//打开设备
if(VCI_OpenDevice(m_devtype,index,0)!=STATUS_OK)
{
MessageBox("打开设备失败!","警告",MB_OK|MB_ICONQUESTION);
return;
}
//初始化CAN
if(VCI_InitCAN(m_devtype,index,cannum,&init_config)!=STATUS_OK)
{
MessageBox("初始化CAN失败!","警告",MB_OK|MB_ICONQUESTION);
VCI_CloseDevice(m_devtype,index);
return;
}
m_connect=1;
m_devind=index;
m_cannum=cannum;
GetDlgItem(IDC_BUTTON_CONNECT)->SetWindowText("断开");
//启动线程
AfxBeginThread(ReceiveThread,this);
}
如此即可实现VC的线程方法.