串口(CComPort)

/*************************************************************************************************
*                       
*        模块名称:多线程串口通讯类(MultiThread Com class)       
*        编制人(author): liu_sir   
*        创建日期(date): 2003.4.20 -4.30
*        修改日前      : 2004.6.01 -6.14      
*        当前版本(Version) :v1.2
*        主要类说明(Main class):
*             CComPort 串口类  内聚合一个CSerialPort类用于串口的操作
*                      接收模式说明(Receive Mode):
*                     1.ManualReceiveByQuery,  //手动查询接收
*                   2.ManualReceiveByConst,  //定数接收(按照一定数量接收)
*                   3.AutoReceiveBySignal,   //信号自动接收
*                        4.AutoReceiveByBreak,    //自动中断接收
*                     推荐使用:1或3
*       CReadComThread 串口读线程类  和CComPort关联起来进行操作
*      
*
***************************************************************************************************/
#pragma once
//接收函数
#ifndef COMPORT_H
#define COMPORT_H

typedef void (* FOnReceiveData)(LPVOID,void*,DWORD);
typedef void (* FOnComBreak)(LPVOID,DWORD,COMSTAT stat);


#include "serialport.h"
// CComPort 命令目标
namespace LsComm{

class CReadComThread;

class CComPort
{
public:
 enum ReceiveMode
 {
  ManualReceiveByQuery,  //手动查询接收
  ManualReceiveByConst,  //定数接收
  AutoReceiveBySignal,   //信号自动接收
        AutoReceiveByBreak,    //自动中断接收
 };
    //Enums
 enum FlowControl
 {
  NoFlowControl,
  CtsRtsFlowControl,
  CtsDtrFlowControl,
  DsrRtsFlowControl,
  DsrDtrFlowControl,
  XonXoffFlowControl
 };

 enum Parity
 {   
  EvenParity,
  MarkParity,
  NoParity,
  OddParity,
  SpaceParity
 };

 enum StopBits
 {
  OneStopBit,
  OnePointFiveStopBits,
  TwoStopBits
 };

 CComPort();
 virtual ~CComPort();


   //1.打开,关闭串口函数
 bool Open(int nPort,ReceiveMode mode=AutoReceiveBySignal, DWORD dwBaud = 9600, Parity parity = NoParity, BYTE DataBits = 8,
    StopBits stopbits = OneStopBit, FlowControl fc = NoFlowControl);
    void Close();

    //2.设置接收函数,中断处理函数
 void SetReceiveFunc(FOnReceiveData pfnOnReceiveData,LPVOID pSender);
    void SetBreakHandleFunc(FOnComBreak pfnOnComBreak);

 //3.获取自身参数
 int GetCurPortNum() { return this->m_CurPortNum;  }
 CSerialPort* GetSerialPort();
 HANDLE GetCloseHandle();
 ReceiveMode GetReceiveMode();

    //4.(线程类)通知接收处理函数    
 void ReceiveData(void* pBuf,DWORD InBufferCount);//线程调用的接收函数
 void ComBreak(DWORD dwMask);

 //6.输入,输出函数--返回实际个数
 DWORD GetInBufferCount();
 DWORD GetInput(void* pBuf,DWORD Count,DWORD dwMilliseconds=1000);
 DWORD Output(void* pBuf,DWORD Count);
 bool IsOverlapped() { return m_IsOverlapped; }
protected:
 CSerialPort* m_pPort;                           //内含串口类
 CReadComThread* m_pReadThread;                  //读串口线程

 LPVOID m_pSender;                               //保存的父窗体指针
 int m_CurPortNum;                               //当前端口号
    FOnReceiveData m_pfnOnReceiveData;              //接收信号函数
 FOnComBreak    m_pfnOnComBreak;                 //串口事件处理函数
    ReceiveMode    m_RecvMode;                      //接收模式

 HANDLE         m_hWriteEvent;                    //写事件
 OVERLAPPED     m_WriteOverlapped;                //写重叠结构

 bool m_IsOverlapped;                            //是否重叠结构;
private:
    HANDLE m_hCloseEvent; //E: A event handle to close thread  //Chinese:结束线程事件

public:
 // //当前串口是否打开
 bool IsOpen(void);
protected:
 // 当前串口是否打开
 bool m_bIsOpen;
};

//DWORD WINAPI ThreadFunc(LPVOID  lpParam ); //线程调用函数

class CReadComThread
{
public:
    /*1.构造与系构函数
 */
 CReadComThread();
    virtual ~CReadComThread();         
   
 /* 2.创建,结束,复位
 */
    void Create();                         //创建线程
    void Terminate();                      //结束线程
    void Resume();                         //复位
 bool IsTerminated() {return this->m_IsTerminated; }
    
 /*3.绑定串口,异步读取
 */
 void BandSerialPort(CComPort* pPort);  //绑定串口
 DWORD ReadInput(void* pBuf,DWORD Count,DWORD dwMilliseconds);//异步读取输入

 friend DWORD WINAPI ThreadFunc(LPVOID  lpParam );
protected:
 DWORD dwThreadId;//线程号 
    bool IsClose;
    /*4.设置异步读取事件,异步中断事件以及处理事件
 */
 bool SetReadEvent(OVERLAPPED& overlapped);//设置启动读事件
 bool HandleReadEvent(OVERLAPPED& overlapped);//处理读事件
    bool HandleData(); //处理读取数据
   
 bool SetBreakEvent(DWORD& dwMask);//设置串口中断事件,通过DWMask参数的改变返回监听状态
 bool HandleBreakEvent(DWORD dwMask);//处理串口中断事件

 /*5.手动模式,信号模式,中断模式执行线程
 */
 void ExecuteByAutoSignalRecvMode();
 void ExecuteByAutoBreakRecvMode();
 void ExecuteByManualQueryRecvMode();
 void ExecuteByManualConstRecvMode();
    void Execute(void);                    //线程执行
  
private:
 HANDLE m_hThread;           //线程句柄
 CComPort* m_pPort;          //关联串口指针

    byte  m_InputBuffer[2048];  //接收缓冲区
 byte* m_pBuffer;            //实际的内存
 DWORD m_InBufferCount;      //接收个数

 OVERLAPPED m_ReadOverlapped;     //读取重叠结构
 OVERLAPPED m_BreakOverlapped;    //串口中断事件结构
   
 bool m_IsTerminated;            //是否结束线程

};

}

#endif

 

// ComPort.cpp : 实现文件
//

#include "stdafx.h"
#include "ComPort.h"


namespace LsComm{

// CComPort

CComPort::CComPort()
: m_bIsOpen(false)
{
 this->m_pfnOnReceiveData = NULL;
    this->m_pfnOnComBreak =NULL;
 this->m_pPort = NULL;
 this->m_pReadThread = NULL;
 ::ZeroMemory(&this->m_WriteOverlapped,sizeof(this->m_WriteOverlapped));
    this->m_hWriteEvent = NULL;
 this->m_bIsOpen = false;
}

CComPort::~CComPort()
{
 if(this->m_pPort)
 {
  if(this->m_pPort->IsOpen())
  {
     this->Close();
  }
 }

 if(this->m_pPort)
 {
    delete this->m_pPort;
    this->m_pPort = NULL;
 }
}


// CComPort 成员函数

// //当前串口是否打开
bool CComPort::IsOpen(void)
{
 return this->m_bIsOpen;
}

bool CComPort::Open(int nPort,ReceiveMode mode, DWORD dwBaud, Parity parity, BYTE DataBits,
            StopBits stopbits,FlowControl fc)
{  
 //1.新建串口
 if(this->m_pPort)
  delete this->m_pPort;
 this->m_pPort = new CSerialPort();
    this->m_bIsOpen = false;
 //2.判断收发模式
 if(mode==ReceiveMode::ManualReceiveByQuery)
 {
    this->m_IsOverlapped  = false;
 }
 else
 {
    this->m_IsOverlapped  = true;
 }
    this->m_RecvMode = mode;
   
 //3.转换参数,打开串口
 int index;
 index=parity-CComPort::EvenParity;
 CSerialPort::Parity spParity=(CSerialPort::Parity)(CSerialPort::EvenParity+index);
 index=stopbits-CComPort::OneStopBit;
 CSerialPort::StopBits spStopbits=(CSerialPort::StopBits)(CSerialPort::OneStopBit+index);
    index=fc-CComPort::NoFlowControl;
 CSerialPort::FlowControl spFC=(CSerialPort::FlowControl)(CSerialPort::NoFlowControl+index) ;
  
 try    
 {
  this->m_pPort->Open(nPort,dwBaud,spParity,DataBits,spStopbits,spFC,m_IsOverlapped);
 }
 catch(CSerialException* pE)
 {
    //AfxMessageBox(pE->GetErrorMessage());
    pE->Delete();
    return false;
 }

 //it is important!!
 COMMTIMEOUTS timeouts;
 this->m_pPort->GetTimeouts(timeouts);
    timeouts.ReadIntervalTimeout=100;
 //timeouts.WriteTotalTimeoutConstant = 1000;
 this->m_pPort->SetTimeouts(timeouts);

 this->m_pPort->Purge(PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
 this->m_pPort->Setup(4096,4096);     

 this->m_CurPortNum = nPort;
   //创建关闭事件
 this->m_hCloseEvent = CreateEvent(NULL,true,false,NULL);
 if(this->m_hCloseEvent==NULL)
 {
    return false;
 }
 //4.创建线程类
 this->m_pReadThread = new CReadComThread();
 this->m_pReadThread->BandSerialPort(this);
 this->m_pReadThread->Create();
 this->m_pReadThread->Resume();

 if(this->IsOverlapped())
 {
      
    this->m_hWriteEvent = ::CreateEvent(NULL,true,false,NULL);
       if(this->m_hCloseEvent==NULL)
     return false;
       this->m_WriteOverlapped.hEvent = this->m_hWriteEvent;
 }
 this->m_bIsOpen = true;
 return true;
}

void CComPort::Close()
{
 //1.串口
 if(this->m_pPort==NULL)
  return;
 if(!this->m_pPort->IsOpen())
  return;
    //2.事件
 ::SetEvent(this->m_hCloseEvent);//通知关闭系统
    Sleep(1000);
 //3.结束读线程
 try
 {
      this->m_pReadThread->Terminate();  
      delete this->m_pReadThread;
      this->m_pReadThread = NULL;
 }
 catch(char e[150])
 {
  ::AfxMessageBox(e);
 }
  
   //4.结束关闭线程
   ::CloseHandle(this->m_hCloseEvent);
   this->m_pPort->Close();
  
   //5.结束写事件
   if(this->m_hWriteEvent)
   {
    ::CloseHandle(this->m_hWriteEvent);
    this->m_hWriteEvent = NULL;
   }
   //6.释放串口对象
 if(this->m_pPort)
 {
  delete this->m_pPort;
     this->m_pPort = NULL;
 }
}

void CComPort::ReceiveData(void* pBuf,DWORD InBufferCount)
{
   if(this->m_pfnOnReceiveData)
   this->m_pfnOnReceiveData(this->m_pSender,pBuf,InBufferCount);
}

void CComPort::SetReceiveFunc(FOnReceiveData pfnOnReceiveData,LPVOID pSender)
{
   this->m_pfnOnReceiveData = pfnOnReceiveData;
   this->m_pSender = pSender;
}

void CComPort::ComBreak(DWORD dwMask)
{
   if(this->m_pfnOnComBreak)
   {
    COMSTAT stat;
    this->m_pPort->GetStatus(stat);
       this->m_pfnOnComBreak(this->m_pPort,dwMask,stat);
   }
}

void CComPort::SetBreakHandleFunc(FOnComBreak pfnOnComBreak)
{
   this->m_pfnOnComBreak = pfnOnComBreak;
}

 

CComPort::ReceiveMode CComPort::GetReceiveMode()
{
 return this->m_RecvMode;
}

DWORD CComPort::GetInBufferCount()
{
    if(this->IsOverlapped())
 {
  ::AfxMessageBox("this methord is only used for ManualQueryMode!");
  return 0;
 }
 COMSTAT stat;
   ::ZeroMemory(&stat,sizeof(stat));
   this->m_pPort->GetStatus(stat);
   return stat.cbInQue;
}


DWORD CComPort::GetInput(void* pBuf,DWORD Count,DWORD dwMilliseconds)
{  
 //不能在自动模式下getinput
 if(this->GetReceiveMode()==CComPort::AutoReceiveByBreak||
  this->GetReceiveMode()==CComPort::AutoReceiveBySignal)
 {
  ::AfxMessageBox("Can't use GetInput methord in this mode!");
  return 0;
 }

 if(this->IsOverlapped())
 {
     ASSERT(this->m_pReadThread);
     DWORD dwBytes = this->m_pReadThread->ReadInput(pBuf,Count,dwMilliseconds); 
        this->m_pPort->TerminateOutstandingReads(); 
  return dwBytes;
 }
 else
    return this->m_pPort->Read(pBuf,Count); 
}

DWORD CComPort::Output(void* pBuf,DWORD Count)
{  
    DWORD dwWriteBytes=0;
 if(this->IsOverlapped())//异步模式
 {
    this->m_pPort->Write(pBuf,Count,this->m_WriteOverlapped);
    if(WaitForSingleObject(this->m_WriteOverlapped.hEvent,INFINITE)==WAIT_OBJECT_0)
  {
      this->m_pPort->GetOverlappedResult(this->m_WriteOverlapped,dwWriteBytes,false);
  }
 }
 else
 {
       /*for(DWORD i=0;i<Count;i++)
    {
      dwWriteBytes+= this->m_pPort->Write(pBuf,1);
    } //for use in win98
    */
    dwWriteBytes = this->m_pPort->Write(pBuf,Count);
 }
 return dwWriteBytes;
}

 CSerialPort* CComPort::GetSerialPort()
{
 ASSERT(m_pPort);
 return m_pPort;
}
HANDLE CComPort::GetCloseHandle()
{
 ASSERT(this->m_hCloseEvent);
 return this->m_hCloseEvent;
}

//CReadComThread

CReadComThread::CReadComThread()
{
 this->m_hThread = NULL;
 this->m_pPort = NULL;
 this->IsClose =false;
 ::ZeroMemory(&this->m_BreakOverlapped,sizeof(this->m_BreakOverlapped));
 ::ZeroMemory(&this->m_ReadOverlapped,sizeof(this->m_ReadOverlapped));
 
 memset(this->m_InputBuffer,0,2048);
}

CReadComThread::~CReadComThread()
{
 this->m_hThread = NULL;
}


// CReadComThread 成员函数
bool CReadComThread::SetReadEvent(OVERLAPPED& overlapped)
{
 BeginSet:
 memset(this->m_InputBuffer,0,2048);
 if(this->m_pPort->GetSerialPort()->Read(this->m_InputBuffer,2048,overlapped,&this->m_InBufferCount))
 {
    if(!this->HandleData())
     return  false;
    ::ResetEvent(this->m_ReadOverlapped.hEvent); 
    goto BeginSet;
 }
    DWORD error=::GetLastError();
 if(error==ERROR_IO_PENDING)
 { return true; }
 else
 { return false; }

}


bool CReadComThread::HandleData() //处理读取数据
{
   if(this->m_InBufferCount>0)
   {
      this->m_pBuffer = new byte[this->m_InBufferCount];
   for(int i=0;i<(int)this->m_InBufferCount;i++)
   {
       this->m_pBuffer[i] = this->m_InputBuffer[i]; 
   }
      //this->m_pSerialPort-> 
   this->m_pPort->ReceiveData(this->m_pBuffer,this->m_InBufferCount);  
   delete[] this->m_pBuffer;
   }
   return true;
}


bool CReadComThread::HandleReadEvent(OVERLAPPED& overlapped)
{
 if(this->m_pPort->GetSerialPort()->GetOverlappedResult(overlapped,this->m_InBufferCount,false))
 {
    return this->HandleData();
 }

 DWORD dwError = ::GetLastError();
 if(dwError==ERROR_INVALID_HANDLE)
  return false;
 else
  return true;
}

bool CReadComThread::SetBreakEvent(DWORD& dwMask )
{
SetBegin:
   if(this->m_pPort->GetSerialPort()->WaitEvent(dwMask,this->m_BreakOverlapped))
   {
      if(!this->HandleBreakEvent(dwMask))
    return false;
   goto SetBegin;
   }

    DWORD error=::GetLastError();
 if(error==ERROR_IO_PENDING)
 { return true; }
 else
 { return false; }
}

bool CReadComThread::HandleBreakEvent(DWORD dwMask)
{
   DWORD dwReadBytes;
   bool successed=
      this->m_pPort->GetSerialPort()->GetOverlappedResult(this->m_BreakOverlapped,dwReadBytes,false);
   if(successed)
   {
    this->m_pPort->ComBreak(dwMask); //调用处理过程
    return true;
   }
   return false;
}

void CReadComThread::Execute()
{

 if(this->m_pPort->GetReceiveMode()==CComPort::ManualReceiveByQuery)
 {
    this->ExecuteByManualQueryRecvMode();
 }
 else if(this->m_pPort->GetReceiveMode()==CComPort::ManualReceiveByConst)
 {
       this->ExecuteByManualConstRecvMode();  
 }
 else if(this->m_pPort->GetReceiveMode()==CComPort::AutoReceiveBySignal)
 {
    this->ExecuteByAutoSignalRecvMode();
 }
 else//中断模式
 {
       this->ExecuteByAutoBreakRecvMode();
 }

}
void CReadComThread::ExecuteByAutoSignalRecvMode()
{
 DWORD dwMask=0;
 HANDLE WaitHandles[3]; //监听事件数组
 DWORD dwSignaledHandle;
 //DWORD dwStoredFlags = EV_ERR | EV_RLSD | EV_RING;
    DWORD dwStoredFlags = EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING |\
                  EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY ;

 WaitHandles[0] = this->m_pPort->GetCloseHandle();
 WaitHandles[1] = this->m_ReadOverlapped.hEvent;
 WaitHandles[2] = this->m_BreakOverlapped.hEvent;

 this->m_pPort->GetSerialPort()->SetMask(dwStoredFlags);
 if(!SetBreakEvent(dwMask))
  goto EndThread;
 //设置读事件
 if(!SetReadEvent(this->m_ReadOverlapped))
  goto EndThread;

    //设置comEvent
 for(;;)
 {
    dwSignaledHandle=::WaitForMultipleObjects(3,WaitHandles,false,INFINITE);
       switch(dwSignaledHandle)
    {
       case WAIT_OBJECT_0:
              goto EndThread;
     break;

       case WAIT_OBJECT_0+1:
              if(!this->HandleReadEvent(this->m_ReadOverlapped))
       goto EndThread;
        if(!this->SetReadEvent(this->m_ReadOverlapped))
            goto EndThread;
     break;

       case WAIT_OBJECT_0+2:
              if(!this->HandleBreakEvent(dwMask))
        goto EndThread;
 
     if(!this->SetBreakEvent(dwMask))
             goto EndThread;
     break;

    default:
     //goto EndThread;
     break;
    }
   
 
 }

    EndThread:
    this->m_pPort->GetSerialPort()->Purge(PURGE_RXABORT | PURGE_RXCLEAR); 
     ::CloseHandle(this->m_ReadOverlapped.hEvent);
     ::CloseHandle(this->m_BreakOverlapped.hEvent); 
        return ;  

}

void CReadComThread::ExecuteByManualQueryRecvMode()
{
 DWORD dwMask=0;
 HANDLE WaitHandles[2]; //监听事件数组
 DWORD dwSignaledHandle;

 WaitHandles[0] = this->m_pPort->GetCloseHandle();

  /*this->m_pPort->GetSerialPort()->SetMask(dwStoredFlags);
    this->m_pPort->GetSerialPort()->SetBreak(); */
  for(;;)
 {
    dwSignaledHandle=::WaitForMultipleObjects(1,WaitHandles,false,INFINITE);
       switch(dwSignaledHandle)
    {
       case WAIT_OBJECT_0:
              goto EndThread;
     break;

    default:
     //goto EndThread;
     break;
    }
     this->m_pPort->GetSerialPort()->GetMask(dwMask);
    if(dwMask>0)
    {
       this->m_pPort->ComBreak(dwMask);      
    }
 }

    EndThread:
    this->m_pPort->GetSerialPort()->Purge(PURGE_RXABORT | PURGE_RXCLEAR); 
        return ;  

}

void CReadComThread::ExecuteByManualConstRecvMode()
{
 DWORD dwMask=0;
 HANDLE WaitHandles[2]; //监听事件数组
 DWORD dwSignaledHandle;
    DWORD dwStoredFlags = EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING |\
                  EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY ;

 WaitHandles[0] = this->m_pPort->GetCloseHandle();
 WaitHandles[1] = this->m_BreakOverlapped.hEvent;

 this->m_pPort->GetSerialPort()->SetMask(dwStoredFlags);

 if(!SetBreakEvent(dwMask))
  goto EndThread;
  
    //设置comEvent
 for(;;)
 {
    dwSignaledHandle=::WaitForMultipleObjects(2,WaitHandles,false,INFINITE);
       switch(dwSignaledHandle)
    {
       case WAIT_OBJECT_0:
              goto EndThread;
     break;

       case WAIT_OBJECT_0+1:
     if(!this->HandleBreakEvent(dwMask))
       goto EndThread;
        if(!this->SetBreakEvent(dwMask))
          goto EndThread;
     break;

    default:
     //goto EndThread;
     break;
    }
   
 
 }

    EndThread:
    this->m_pPort->GetSerialPort()->Purge(PURGE_RXABORT | PURGE_RXCLEAR); 
     ::CloseHandle(this->m_ReadOverlapped.hEvent);
     ::CloseHandle(this->m_BreakOverlapped.hEvent); 
        return ;  

}
void CReadComThread::ExecuteByAutoBreakRecvMode()
{
    DWORD dwMask=0;
 HANDLE WaitHandles[2]; //监听事件数组
 DWORD dwSignaledHandle;
    DWORD dwStoredFlags = EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING |\
                  EV_RLSD | EV_RXCHAR | EV_RXFLAG ;//??| EV_TXEMPTY 添加后在首次执行时总是接收不到全部数据

 WaitHandles[0] = this->m_pPort->GetCloseHandle();
 WaitHandles[1] = this->m_BreakOverlapped.hEvent;

 
 this->m_pPort->GetSerialPort()->SetMask(dwStoredFlags);

    //this->m_BreakOverlapped??两个事件同时给一个重叠结果的话??
 if(!SetBreakEvent(dwMask))
  goto EndThread;
 //设置读事件
 if(!SetReadEvent(this->m_BreakOverlapped))
  goto EndThread;

    //设置comEvent
 for(;;)
 {
    dwSignaledHandle=::WaitForMultipleObjects(2,WaitHandles,false,INFINITE);
       switch(dwSignaledHandle)
    {
       case WAIT_OBJECT_0:
              goto EndThread;
     break;

       case WAIT_OBJECT_0+1:
              if((dwMask&EV_RXCHAR)==EV_RXCHAR)
     {
                  if(!this->HandleReadEvent(this->m_BreakOverlapped))
      goto EndThread;
                  if(!SetReadEvent(this->m_BreakOverlapped))
               goto EndThread;
     }
     else
     {
         if(!this->HandleBreakEvent(dwMask))
            goto EndThread;
         if(!this->SetBreakEvent(dwMask))
               goto EndThread;
     }
     break;

    default:
     //goto EndThread;
     break;
    }
   
 
 }

    EndThread:
    this->m_pPort->GetSerialPort()->Purge(PURGE_RXABORT | PURGE_RXCLEAR); 
     ::CloseHandle(this->m_ReadOverlapped.hEvent);
     ::CloseHandle(this->m_BreakOverlapped.hEvent); 
        return ;  

}

DWORD WINAPI ThreadFunc(LPVOID  lpParam )
{
    CReadComThread* pThread =(CReadComThread*)lpParam;
 ASSERT(pThread);
 pThread->m_IsTerminated = false;
    pThread->Execute();
 pThread->m_IsTerminated = true;
 return 0;
}

void CReadComThread::Create()
{
    m_hThread = CreateThread(
        NULL,                        // no security attributes
        0,                           // use default stack size 
        ThreadFunc,                  // thread function
        this,                // argument to thread function
        CREATE_SUSPENDED,           // use default creation flags
        &dwThreadId);                // returns the thread identifier
 ::SetThreadPriority(m_hThread,THREAD_PRIORITY_HIGHEST);
   
}

void CReadComThread::Terminate()
{
   char szMsg[80];
   if (m_hThread == NULL)
   {
      wsprintf( szMsg, "CreateThread failed." );
   ::MessageBox(NULL,szMsg,"ok",0);
   }
   else
   {
      if(!this->IsTerminated())
   {
      Sleep(1000);
   }
   if(!this->IsTerminated())
   {
         Sleep(1000);
         //::TerminateThread(m_hThread,0);
   }
      CloseHandle( m_hThread );
   }
}

void CReadComThread::Resume()
{
   ResumeThread(this->m_hThread);
}

void CReadComThread::BandSerialPort(CComPort* pPort)
{
 ASSERT(pPort);
 this->m_pPort = pPort;
 //创建异步读取事件
    
 if(this->m_pPort->IsOverlapped())
 {
    this->m_ReadOverlapped.hEvent =::CreateEvent(NULL,true,false,NULL); 
    ASSERT(this->m_ReadOverlapped.hEvent); 
       this->m_BreakOverlapped.hEvent = ::CreateEvent(NULL,true,false,NULL);
    ASSERT(this->m_BreakOverlapped.hEvent);
 }
 
}

DWORD CReadComThread::ReadInput(void* pBuf,DWORD Count,DWORD dwMilliseconds)
{
 DWORD dwRead=0;
 if(!this->m_pPort->GetSerialPort()->Read(pBuf,Count,this->m_ReadOverlapped,&dwRead))
 {
  if(WaitForSingleObject(this->m_ReadOverlapped.hEvent,dwMilliseconds)==WAIT_OBJECT_0)
  {
      this->m_pPort->GetSerialPort()->GetOverlappedResult(this->m_ReadOverlapped,dwRead,false);
  }
 }

 return dwRead;  
  
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值