SerialPort类

来源:互联网 发布:天龙八部有挂机软件 编辑:程序博客网 时间:2024/06/06 15:41

做个记录自己看。

串口:USB-232(最好使用最新版的驱动)

SerialPort.h

#ifndef __SERIALPORT_H__  #define __SERIALPORT_H__    #define WM_COMM_BREAK_DETECTED      WM_USER+1     #define WM_COMM_CTS_DETECTED            WM_USER+2     #define WM_COMM_DSR_DETECTED            WM_USER+3  #define WM_COMM_ERR_DETECTED            WM_USER+4     #define WM_COMM_RING_DETECTED           WM_USER+5     #define WM_COMM_RLSD_DETECTED           WM_USER+6     #define WM_COMM_RXCHAR                      WM_USER+7     #define WM_COMM_RXFLAG_DETECTED     WM_USER+8     #define WM_COMM_TXEMPTY_DETECTED    WM_USER+9       class CSerialPort  {  public:      void CloseComm();//2      //      CSerialPort();      virtual     ~CSerialPort();        //                                            BOOL        InitPort(CWnd* pPortOwner, UINT portnr, UINT baud,          char parity, UINT databits, UINT stopsbits,          DWORD dwCommEvents, UINT nBufferSize);        //      BOOL        StartMonitoring();      BOOL        RestartMonitoring();      BOOL        StopMonitoring();        DWORD       GetWriteBufferSize();      DWORD       GetCommEvents();      DCB         GetDCB();        void        WriteToPort(char* string);  protected:        //       void        ProcessErrorMessage(char* ErrorText);      static UINT CommThread(LPVOID pParam);      static void ReceiveChar(CSerialPort* port, COMSTAT comstat);      static void WriteChar(CSerialPort* port);        //       CWinThread*         m_Thread;        //       CRITICAL_SECTION    m_csCommunicationSync;      BOOL                m_bThreadAlive;        //       HANDLE              m_hShutdownEvent;      HANDLE              m_hComm;      HANDLE              m_hWriteEvent;        //       HANDLE              m_hEventArray[3];        //       OVERLAPPED          m_ov;      COMMTIMEOUTS        m_CommTimeouts;      DCB                 m_dcb;        //      CWnd*               m_pOwner;        //       UINT                m_nPortNr;      char*               m_szWriteBuffer;      DWORD               m_dwCommEvents;      DWORD               m_nWriteBufferSize;  };    #endif __SERIALPORT_H__  

SerialPort.cpp

#include "stdafx.h"  #include "SerialPort.h"    #include <assert.h>      CSerialPort::CSerialPort()  {      m_hComm = NULL;          m_ov.Offset = 0;      m_ov.OffsetHigh = 0;          m_ov.hEvent = NULL;      m_hWriteEvent = NULL;      m_hShutdownEvent = NULL;        m_szWriteBuffer = NULL;        m_bThreadAlive = FALSE;  }    //  //  //  CSerialPort::~CSerialPort()  {      do      {          SetEvent(m_hShutdownEvent);      } while (m_bThreadAlive);        TRACE("Thread ended\n");        delete[] m_szWriteBuffer;    }    //  //   //  BOOL CSerialPort::InitPort(CWnd* pPortOwner,    //       UINT  portnr,       //       UINT  baud,         //       char  parity,       //       UINT  databits,     //       UINT  stopbits,     //       DWORD dwCommEvents, //       UINT  writebuffersize)  //   {      assert(portnr > 0 && portnr <= 256);      assert(pPortOwner != NULL);      unsigned int t = 0;      //       if (m_bThreadAlive)      {          MSG message;          while (m_bThreadAlive)          {              if (::PeekMessage(&message, m_pOwner->m_hWnd, 0, 0, PM_REMOVE))              {                  ::TranslateMessage(&message);                  ::DispatchMessage(&message);              }              SetEvent(m_hShutdownEvent);          }            TRACE("Thread ended\n");      }        //       if (m_ov.hEvent != NULL)          ResetEvent(m_ov.hEvent);      m_ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);        if (m_hWriteEvent != NULL)          ResetEvent(m_hWriteEvent);      m_hWriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);        if (m_hShutdownEvent != NULL)          ResetEvent(m_hShutdownEvent);      m_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);        //       m_hEventArray[0] = m_hShutdownEvent;    //       m_hEventArray[1] = m_ov.hEvent;      m_hEventArray[2] = m_hWriteEvent;        //       InitializeCriticalSection(&m_csCommunicationSync);        //       m_pOwner = pPortOwner;        if (m_szWriteBuffer != NULL)          delete[] m_szWriteBuffer;      m_szWriteBuffer = new char[writebuffersize];        m_nPortNr = portnr;        m_nWriteBufferSize = writebuffersize;      m_dwCommEvents = dwCommEvents;        BOOL bResult = FALSE;      char *szPort = new char[50];      char *szBaud = new char[50];        //       EnterCriticalSection(&m_csCommunicationSync);        //       if (m_hComm != NULL)      {          CloseHandle(m_hComm);          m_hComm = NULL;      }        //       //      if (portnr<10)      {          sprintf(szPort, "COM%d", portnr);      }      else      {          sprintf(szPort, "\\\\.\\COM%d", portnr);      }      sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, stopbits);        //      m_hComm = CreateFile(szPort,                        //           GENERIC_READ | GENERIC_WRITE,   //           0,                              //           NULL,                           //          OPEN_EXISTING,                  //           FILE_FLAG_OVERLAPPED,           //          0);                         //         if (m_hComm == INVALID_HANDLE_VALUE)      {          //           delete[] szPort;          delete[] szBaud;            return FALSE;      }        //       m_CommTimeouts.ReadIntervalTimeout = 1000;      m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000;      m_CommTimeouts.ReadTotalTimeoutConstant = 1000;      m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000;      m_CommTimeouts.WriteTotalTimeoutConstant = 1000;        //      if (SetCommTimeouts(m_hComm, &m_CommTimeouts))      {          if (SetCommMask(m_hComm, dwCommEvents))          {              if (GetCommState(m_hComm, &m_dcb))              {                  m_dcb.fRtsControl = RTS_CONTROL_ENABLE;     //                  if (BuildCommDCB(szBaud, &m_dcb))                  {                        m_dcb.XonLim = 2048;                      m_dcb.XoffLim = 2048;                      if (SetCommState(m_hComm, &m_dcb))                          ; //                       else                          ProcessErrorMessage("SetCommState()");                  }                  else                      ProcessErrorMessage("BuildCommDCB()");              }              else                  ProcessErrorMessage("GetCommState()");          }          else              ProcessErrorMessage("SetCommMask()");      }      else          ProcessErrorMessage("SetCommTimeouts()");        delete[] szPort;      delete[] szBaud;        //       PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);        //       LeaveCriticalSection(&m_csCommunicationSync);        TRACE("Initialisation for communicationport %d completed.\nUse Startmonitor to communicate.\n", portnr);        return TRUE;  }    //  //    //  UINT CSerialPort::CommThread(LPVOID pParam)  {      //       //       CSerialPort *port = (CSerialPort*)pParam;        //       //       port->m_bThreadAlive = TRUE;        //       DWORD BytesTransfered = 0;      DWORD Event = 0;      DWORD CommEvent = 0;      DWORD dwError = 0;      static COMSTAT comstat;      BOOL  bResult = TRUE;        //       if (port->m_hComm)       //           PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);        //       for (;;)      {                bResult = WaitCommEvent(port->m_hComm, &Event, &port->m_ov);            if (!bResult)          {              //               //               switch (dwError = GetLastError())              {              case ERROR_IO_PENDING:              {                                       //                                        //                                        //                                        break;              }              case 87:              {                         //                          //                          //                          break;              }              default:              {                         //                          //                          port->ProcessErrorMessage("WaitCommEvent()");                         break;              }              }          }          else          {                  bResult = ClearCommError(port->m_hComm, &dwError, &comstat);                if (comstat.cbInQue == 0)                  continue;          }   //             //           //           Event = WaitForMultipleObjects(3, port->m_hEventArray, FALSE, INFINITE);            switch (Event)          {          case 0:          {                    //                     //                       port->m_bThreadAlive = FALSE;                      //                     AfxEndThread(100);                    break;          }          case 1: //           {                      GetCommMask(port->m_hComm, &CommEvent);                      if (CommEvent & EV_CTS)                          ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_CTS_DETECTED, (WPARAM)0, (LPARAM)port->m_nPortNr);                      if (CommEvent & EV_RXFLAG)                          ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_RXFLAG_DETECTED, (WPARAM)0, (LPARAM)port->m_nPortNr);                      if (CommEvent & EV_BREAK)                          ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_BREAK_DETECTED, (WPARAM)0, (LPARAM)port->m_nPortNr);                      if (CommEvent & EV_ERR)                          ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_ERR_DETECTED, (WPARAM)0, (LPARAM)port->m_nPortNr);                      if (CommEvent & EV_RING)                          ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_RING_DETECTED, (WPARAM)0, (LPARAM)port->m_nPortNr);                        if (CommEvent & EV_RXCHAR)                          //                           ReceiveChar(port, comstat);                        break;          }          case 2: //           {                      //                      WriteChar(port);                      break;          }            } //         } //        return 0;  }    //  //   //  BOOL CSerialPort::StartMonitoring()  {      if (!(m_Thread = AfxBeginThread(CommThread, this)))          return FALSE;      TRACE("Thread started\n");      return TRUE;  }    //  //   //  BOOL CSerialPort::RestartMonitoring()  {      TRACE("Thread resumed\n");      m_Thread->ResumeThread();      return TRUE;  }      //  //  //  BOOL CSerialPort::StopMonitoring()  {      TRACE("Thread suspended\n");      m_Thread->SuspendThread();      return TRUE;  }      //  //   //  void CSerialPort::ProcessErrorMessage(char* ErrorText)  {      char *Temp = new char[200];        LPVOID lpMsgBuf;        FormatMessage(          FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,          NULL,          GetLastError(),          MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //           (LPTSTR)&lpMsgBuf,          0,          NULL          );        sprintf(Temp, "WARNING:  %s Failed with the following error: \n%s\nPort: %d\n", (char*)ErrorText, lpMsgBuf, m_nPortNr);      MessageBox(NULL, Temp, "Application Error", MB_ICONSTOP);        LocalFree(lpMsgBuf);      delete[] Temp;  }    //  //   //  void CSerialPort::WriteChar(CSerialPort* port)  {      BOOL bWrite = TRUE;      BOOL bResult = TRUE;        DWORD BytesSent = 0;        ResetEvent(port->m_hWriteEvent);        //       EnterCriticalSection(&port->m_csCommunicationSync);        if (bWrite)      {          //           port->m_ov.Offset = 0;          port->m_ov.OffsetHigh = 0;            //           PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);            bResult = WriteFile(port->m_hComm,                           //               port->m_szWriteBuffer,                   //               strlen((char*)port->m_szWriteBuffer),    //               &BytesSent,                             //               &port->m_ov);                            //             //           if (!bResult)          {              DWORD dwError = GetLastError();              switch (dwError)              {              case ERROR_IO_PENDING:              {                                       //                                        BytesSent = 0;                                       bWrite = FALSE;                                       break;              }              default:              {                         //                          port->ProcessErrorMessage("WriteFile()");              }              }          }          else          {              LeaveCriticalSection(&port->m_csCommunicationSync);          }      } //         if (!bWrite)      {          bWrite = TRUE;            bResult = GetOverlappedResult(port->m_hComm, //               &port->m_ov,     //              &BytesSent,     //               TRUE);          //            LeaveCriticalSection(&port->m_csCommunicationSync);            //          if (!bResult)          {              port->ProcessErrorMessage("GetOverlappedResults() in WriteFile()");          }      } //         //      if (BytesSent != strlen((char*)port->m_szWriteBuffer))      {          TRACE("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)port->m_szWriteBuffer));      }  }    //  //   //  void CSerialPort::ReceiveChar(CSerialPort* port, COMSTAT comstat)  {      BOOL  bRead = TRUE;      BOOL  bResult = TRUE;      DWORD dwError = 0;      DWORD BytesRead = 0;      unsigned char RXBuff;        for (;;)      {          //           //          //             EnterCriticalSection(&port->m_csCommunicationSync);            //           //             bResult = ClearCommError(port->m_hComm, &dwError, &comstat);            LeaveCriticalSection(&port->m_csCommunicationSync);                if (comstat.cbInQue == 0)          {              //               break;          }            EnterCriticalSection(&port->m_csCommunicationSync);            if (bRead)          {              bResult = ReadFile(port->m_hComm,        //                   &RXBuff,                //                  1,                  //                   &BytesRead,         //                  &port->m_ov);        //              //              if (!bResult)              {                  switch (dwError = GetLastError())                  {                  case ERROR_IO_PENDING:                  {                                           //                                            //                                            bRead = FALSE;                                           break;                  }                  default:                  {                             //                              port->ProcessErrorMessage("ReadFile()");                             break;                  }                  }              }              else              {                  //                   bRead = TRUE;              }          }  //             if (!bRead)          {              bRead = TRUE;              bResult = GetOverlappedResult(port->m_hComm, //                   &port->m_ov,     //                   &BytesRead,     //                  TRUE);          //                //              if (!bResult)              {                  port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");              }          }  //            LeaveCriticalSection(&port->m_csCommunicationSync);            //          ::SendMessage((port->m_pOwner)->m_hWnd, WM_COMM_RXCHAR, (WPARAM)RXBuff, (LPARAM)port->m_nPortNr);      } //    }    //  //   //  void CSerialPort::WriteToPort(char* string)  {      assert(m_hComm != 0);      memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));      strcpy(m_szWriteBuffer, string);          //       SetEvent(m_hWriteEvent);  }    //  //   //  DCB CSerialPort::GetDCB()  {      return m_dcb;  }    //  //   //  DWORD CSerialPort::GetCommEvents()  {      return m_dwCommEvents;  }    //  //   //  DWORD CSerialPort::GetWriteBufferSize()  {      return m_nWriteBufferSize;  }      void CSerialPort::CloseComm()  {      CloseHandle(m_hComm);  }  





0 0