May 27, 2019, 01:15:15 am

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Serialport functions : Help ! Can you please converted it into Aurora and EBASIC

Started by Techno, September 03, 2007, 05:34:25 am

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Techno

Dear Sapero

Can you rewritten this classes for using in Aurora AND EBASIC and compiled an static library because I haven't Visual Studio

serialport.cpp
Code Select

/////////////////////////////////  Includes  //////////////////////////////////

#include "stdafx.h"
#include "SerialPort.h"
#ifndef _WINERROR_
#pragma message("To avoid this message, please put WinError.h in your PCH (normally stdafx.h)")
#include <WinError.h>
#endif


///////////////////////////////// Defines /////////////////////////////////////

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


//////////////////////////////// Implementation ///////////////////////////////

BOOL CSerialException::GetErrorMessage(LPTSTR lpszError, UINT nMaxError, PUINT pnHelpContext)
{
  //Validate our parameters
ASSERT(lpszError != NULL && AfxIsValidString(lpszError, nMaxError));
if (lpszError == NULL || nMaxError == 0)
return FALSE;
if (pnHelpContext != NULL)
*pnHelpContext = 0;

LPTSTR lpBuffer;
BOOL bRet = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                      NULL,  m_dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
                      reinterpret_cast<LPTSTR>(&lpBuffer), 0, NULL);

if (bRet == FALSE)
*lpszError = '\0';
else
{
#if (_MSC_VER >= 1400)
  _tcsncpy_s(lpszError, nMaxError, lpBuffer, _TRUNCATE);
  #else
  lstrcpyn(lpszError, lpBuffer, nMaxError-1);
  lpszError[nMaxError-1] = '\0';
  #endif
bRet = TRUE;

LocalFree(lpBuffer);
}

return bRet;
}

CString CSerialException::GetErrorMessage()
{
  CString rVal;
  LPTSTR pstrError = rVal.GetBuffer(4096);
  GetErrorMessage(pstrError, 4096, NULL);
  rVal.ReleaseBuffer();
  return rVal;
}

CSerialException::CSerialException(DWORD dwError)
{
m_dwError = dwError;
}

IMPLEMENT_DYNAMIC(CSerialException, CException)

#ifdef _DEBUG
void CSerialException::Dump(CDumpContext& dc) const
{
CObject::Dump(dc);

dc << "m_dwError = " << m_dwError;
}
#endif


CSerialPort::CSerialPort() : m_hComm(INVALID_HANDLE_VALUE),
                             m_hEvent(NULL)
{
  m_hKernel32 = GetModuleHandle(_T("KERNEL32.DLL"));
  VERIFY(m_hKernel32 != NULL);
  m_lpfnCancelIo = (LPCANCELIO) GetProcAddress(m_hKernel32, "CancelIo");
}

CSerialPort::~CSerialPort()
{
  Close();
}

void CSerialPort::ThrowSerialException(DWORD dwError /*= 0*/)
{
if (dwError == 0)
dwError = ::GetLastError();

CSerialException* pException = new CSerialException (dwError);

TRACE(_T("Warning: throwing CSerialException for error %d\n"), dwError);
THROW(pException);
}

#ifdef _DEBUG
void CSerialPort::Dump(CDumpContext& dc) const
{
dc << _T("m_hComm = ") << m_hComm << _T("\n");
}
#endif

void CSerialPort::Open(int nPort, DWORD dwBaud, Parity parity, BYTE DataBits, StopBits stopbits, FlowControl fc, BOOL bOverlapped)
{
  //Validate our parameters
  ASSERT(nPort>0 && nPort<=255);

  Close(); //In case we are already open

  //Call CreateFile to open the comms port
  CString sPort;
  sPort.Format(_T("\\\\.\\COM%d"), nPort);
  m_hComm = CreateFile(sPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, bOverlapped ? FILE_FLAG_OVERLAPPED : 0, NULL);
  if (m_hComm == INVALID_HANDLE_VALUE)
  {
    TRACE(_T("CSerialPort::Open, Failed to open the comms port\n"));
    ThrowSerialException();
  }

  //Create the event we need for later synchronisation use
  m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  if (m_hEvent == NULL)
  {
    Close();
    TRACE(_T("CSerialPort::Open, Failed in call to CreateEvent in Open\n"));
    ThrowSerialException();
  }
 
  //Get the current state prior to changing it
  DCB dcb;
  dcb.DCBlength = sizeof(DCB);
  GetState(dcb);

  //Setup the baud rate
  dcb.BaudRate = dwBaud;

  //Setup the Parity
  switch (parity)
  {
    case EvenParity:  dcb.Parity = EVENPARITY;  break;
    case MarkParity:  dcb.Parity = MARKPARITY;  break;
    case NoParity:    dcb.Parity = NOPARITY;    break;
    case OddParity:   dcb.Parity = ODDPARITY;   break;
    case SpaceParity: dcb.Parity = SPACEPARITY; break;
    default:          ASSERT(FALSE);            break;
  }

  //Setup the data bits
  dcb.ByteSize = DataBits;

  //Setup the stop bits
  switch (stopbits)
  {
    case OneStopBit:           dcb.StopBits = ONESTOPBIT;   break;
    case OnePointFiveStopBits: dcb.StopBits = ONE5STOPBITS; break;
    case TwoStopBits:          dcb.StopBits = TWOSTOPBITS;  break;
    default:                   ASSERT(FALSE);               break;
  }

  //Setup the flow control
  dcb.fDsrSensitivity = FALSE;
  switch (fc)
  {
    case NoFlowControl:
    {
      dcb.fOutxCtsFlow = FALSE;
      dcb.fOutxDsrFlow = FALSE;
      dcb.fOutX = FALSE;
      dcb.fInX = FALSE;
      break;
    }
    case CtsRtsFlowControl:
    {
      dcb.fOutxCtsFlow = TRUE;
      dcb.fOutxDsrFlow = FALSE;
      dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
      dcb.fOutX = FALSE;
      dcb.fInX = FALSE;
      break;
    }
    case CtsDtrFlowControl:
    {
      dcb.fOutxCtsFlow = TRUE;
      dcb.fOutxDsrFlow = FALSE;
      dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
      dcb.fOutX = FALSE;
      dcb.fInX = FALSE;
      break;
    }
    case DsrRtsFlowControl:
    {
      dcb.fOutxCtsFlow = FALSE;
      dcb.fOutxDsrFlow = TRUE;
      dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
      dcb.fOutX = FALSE;
      dcb.fInX = FALSE;
      break;
    }
    case DsrDtrFlowControl:
    {
      dcb.fOutxCtsFlow = FALSE;
      dcb.fOutxDsrFlow = TRUE;
      dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
      dcb.fOutX = FALSE;
      dcb.fInX = FALSE;
      break;
    }
    case XonXoffFlowControl:
    {
      dcb.fOutxCtsFlow = FALSE;
      dcb.fOutxDsrFlow = FALSE;
      dcb.fOutX = TRUE;
      dcb.fInX = TRUE;
      dcb.XonChar = 0x11;
      dcb.XoffChar = 0x13;
      dcb.XoffLim = 100;
      dcb.XonLim = 100;
      break;
    }
    default:
    {
      ASSERT(FALSE);
      break;
    }
  }
 
  //Now that we have all the settings in place, make the changes
  SetState(dcb);
}

void CSerialPort::Close()
{
  if (IsOpen())
  {
    //Close down the comms port
    BOOL bSuccess = CloseHandle(m_hComm);
    m_hComm = INVALID_HANDLE_VALUE;
    if (!bSuccess)
      TRACE(_T("CSerialPort::Close, Failed to close up the comms port, GetLastError:%d\n"), GetLastError());

    //Free the event object we are using
    if (m_hEvent)
    {
      CloseHandle(m_hEvent);
      m_hEvent = NULL;
    }
  }
}

void CSerialPort::Attach(HANDLE hComm)
{
  Close();

  //Validate our parameters, now that the port has been closed
  ASSERT(m_hComm == INVALID_HANDLE_VALUE);
  ASSERT(m_hEvent == NULL);

  m_hComm = hComm; 

  //Create the event we need for later synchronisation use
  m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  if (m_hEvent == NULL)
  {
    DWORD dwError = GetLastError();
    Close();
    TRACE(_T("CSerialPort::Attach, Failed in call to CreateEvent in Attach\n"));
    ThrowSerialException(dwError);
  }
}

HANDLE CSerialPort::Detach()
{
  //What will be the return value from this function
  HANDLE hrVal = m_hComm;

  m_hComm = INVALID_HANDLE_VALUE;

  if (m_hEvent)
  {
    CloseHandle(m_hEvent);
    m_hEvent = NULL;
  }

  return hrVal;
}

DWORD CSerialPort::Read(void* lpBuf, DWORD dwCount)
{
  ASSERT(IsOpen());

  DWORD dwBytesRead = 0;
  if (!ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, NULL))
  {
    TRACE(_T("CSerialPort::Read, Failed in call to ReadFile\n"));
    ThrowSerialException();
  }

  return dwBytesRead;
}

BOOL CSerialPort::Read(void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped, DWORD* pBytesRead)
{
  ASSERT(IsOpen());

  DWORD dwBytesRead = 0;
  BOOL bSuccess = ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, &overlapped);
  if (!bSuccess)
  {
    if (GetLastError() != ERROR_IO_PENDING)
    {
      TRACE(_T("CSerialPort::Read, Failed in call to ReadFile\n"));
      ThrowSerialException();
    }
  }
  else
  {
    if (pBytesRead)
      *pBytesRead = dwBytesRead;
  }
  return bSuccess;
}

DWORD CSerialPort::Write(const void* lpBuf, DWORD dwCount)
{
  ASSERT(IsOpen());

  DWORD dwBytesWritten = 0;
  if (!WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, NULL))
  {
    TRACE(_T("CSerialPort::Write, Failed in call to WriteFile\n"));
    ThrowSerialException();
  }

  return dwBytesWritten;
}

BOOL CSerialPort::Write(const void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped, DWORD* pBytesWritten)
{
  ASSERT(IsOpen());

  DWORD dwBytesWritten = 0;
  BOOL bSuccess = WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, &overlapped);
  if (!bSuccess)
  {
    if (GetLastError() != ERROR_IO_PENDING)
    {
      TRACE(_T("CSerialPort::Write, Failed in call to WriteFile\n"));
      ThrowSerialException();
    }
  }
  else
  {
    if (pBytesWritten)
      *pBytesWritten = dwBytesWritten;
  }

  return bSuccess;
}

void CSerialPort::GetOverlappedResult(OVERLAPPED& overlapped, DWORD& dwBytesTransferred, BOOL bWait)
{
  ASSERT(IsOpen());

  if (!::GetOverlappedResult(m_hComm, &overlapped, &dwBytesTransferred, bWait))
  {
    if (GetLastError() != ERROR_IO_INCOMPLETE)
    {
      TRACE(_T("CSerialPort::GetOverlappedResult, Failed in call to GetOverlappedResult\n"));
      ThrowSerialException();
    }
  }
}

void CSerialPort::_OnCompletion(DWORD dwErrorCode, DWORD dwCount, LPOVERLAPPED lpOverlapped)
{
  //Validate our parameters
  ASSERT(lpOverlapped);

  //Convert back to the C++ world
  CSerialPort* pSerialPort = static_cast<CSerialPort*>(lpOverlapped->hEvent);
  ASSERT(pSerialPort);

  //Call the C++ function
  pSerialPort->OnCompletion(dwErrorCode, dwCount, lpOverlapped);
}

void CSerialPort::OnCompletion(DWORD /*dwErrorCode*/, DWORD /*dwCount*/, LPOVERLAPPED lpOverlapped)
{
  //Just free the memory which was previously allocated for the OVERLAPPED structure
  delete lpOverlapped;

  //Your derived classes can do something useful in OnCompletion, but don't forget to
  //call CSerialPort::OnCompletion to ensure the memory is freed
}

void CSerialPort::CancelIo()
{
  ASSERT(IsOpen());

  if (m_lpfnCancelIo == NULL)
  {
    TRACE(_T("CSerialPort::CancelIo, CancelIo function is not supported on this OS. You need to be running at least NT 4 or Win 98 to use this function\n"));
    ThrowSerialException(ERROR_CALL_NOT_IMPLEMENTED); 
  }

  if (!m_lpfnCancelIo(m_hComm))
  {
    TRACE(_T("Failed in call to CancelIO\n"));
    ThrowSerialException();
  }
}

DWORD CSerialPort::BytesWaiting()
{
  ASSERT(IsOpen());

  //Check to see how many characters are unread
  COMSTAT stat;
  GetStatus(stat);
  return stat.cbInQue;
}

BOOL CSerialPort::DataWaiting(DWORD dwTimeout)
{
  ASSERT(IsOpen());

  //Setup to wait for incoming data
  DWORD dwOldMask;
  GetMask(dwOldMask);
  SetMask(EV_RXCHAR);

  //Setup the overlapped structure
  OVERLAPPED o;
  o.hEvent = m_hEvent;

  //Assume the worst;
  BOOL bSuccess = FALSE;

  DWORD dwEvent;
  bSuccess = WaitEvent(dwEvent, o);
  if (!bSuccess)
  {
    if (WaitForSingleObject(o.hEvent, dwTimeout) == WAIT_OBJECT_0)
    {
      DWORD dwBytesTransferred;
      GetOverlappedResult(o, dwBytesTransferred, FALSE);
      bSuccess = TRUE;
    }
  }

  //Reset the event mask
  SetMask(dwOldMask);

  return bSuccess;
}

void CSerialPort::WriteEx(const void* lpBuf, DWORD dwCount)
{
  ASSERT(IsOpen());

  OVERLAPPED* pOverlapped = new OVERLAPPED;
  ZeroMemory(pOverlapped, sizeof(OVERLAPPED));
  pOverlapped->hEvent = static_cast<HANDLE>(this);
  if (!WriteFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
  {
    delete pOverlapped;
    TRACE(_T("CSerialPort::WriteEx, Failed in call to WriteFileEx\n"));
    ThrowSerialException();
  }
}

void CSerialPort::ReadEx(void* lpBuf, DWORD dwCount)
{
  ASSERT(IsOpen());

  OVERLAPPED* pOverlapped = new OVERLAPPED;
  ZeroMemory(pOverlapped, sizeof(OVERLAPPED));
  pOverlapped->hEvent = static_cast<HANDLE>(this);
  if (!ReadFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
  {
    delete pOverlapped;
    TRACE(_T("CSerialPort::ReadEx, Failed in call to ReadFileEx\n"));
    ThrowSerialException();
  }
}

void CSerialPort::TransmitChar(char cChar)
{
  ASSERT(IsOpen());

  if (!TransmitCommChar(m_hComm, cChar))
  {
    TRACE(_T("CSerialPort::TransmitChar, Failed in call to TransmitCommChar\n"));
    ThrowSerialException();
  }
}

void CSerialPort::GetConfig(COMMCONFIG& config)
{
  ASSERT(IsOpen());

  DWORD dwSize = sizeof(COMMCONFIG);
  if (!GetCommConfig(m_hComm, &config, &dwSize))
  {
    TRACE(_T("CSerialPort::GetConfig, Failed in call to GetCommConfig\n"));
    ThrowSerialException();
  }
}

void CSerialPort::SetConfig(COMMCONFIG& config)
{
  ASSERT(IsOpen());

  DWORD dwSize = sizeof(COMMCONFIG);
  if (!SetCommConfig(m_hComm, &config, dwSize))
  {
    TRACE(_T("CSerialPort::SetConfig, Failed in call to SetCommConfig\n"));
    ThrowSerialException();
  }
}

void CSerialPort::SetBreak()
{
  ASSERT(IsOpen());

  if (!SetCommBreak(m_hComm))
  {
    TRACE(_T("CSerialPort::SetBreak, Failed in call to SetCommBreak\n"));
    ThrowSerialException();
  }
}

void CSerialPort::ClearBreak()
{
  ASSERT(IsOpen());

  if (!ClearCommBreak(m_hComm))
  {
    TRACE(_T("CSerialPort::ClearBreak, Failed in call to SetCommBreak\n"));
    ThrowSerialException();
  }
}

void CSerialPort::ClearError(DWORD& dwErrors)
{
  ASSERT(IsOpen());

  if (!ClearCommError(m_hComm, &dwErrors, NULL))
  {
    TRACE(_T("CSerialPort::ClearError, Failed in call to ClearCommError\n"));
    ThrowSerialException();
  }
}

void CSerialPort::GetDefaultConfig(int nPort, COMMCONFIG& config)
{
  //Validate our parameters
  ASSERT(nPort>0 && nPort<=255);

  //Create the device name as a string
  CString sPort;
  sPort.Format(_T("COM%d"), nPort);

  DWORD dwSize = sizeof(COMMCONFIG);
  if (!GetDefaultCommConfig(sPort, &config, &dwSize))
  {
    TRACE(_T("CSerialPort::GetDefaultConfig, Failed in call to GetDefaultCommConfig\n"));
    ThrowSerialException();
  }
}

void CSerialPort::SetDefaultConfig(int nPort, COMMCONFIG& config)
{
  //Validate our parameters
  ASSERT(nPort>0 && nPort<=255);

  //Create the device name as a string
  CString sPort;
  sPort.Format(_T("COM%d"), nPort);

  DWORD dwSize = sizeof(COMMCONFIG);
  if (!SetDefaultCommConfig(sPort, &config, dwSize))
  {
    TRACE(_T("CSerialPort::SetDefaultConfig, Failed in call to SetDefaultCommConfig\n"));
    ThrowSerialException();
  }
}

void CSerialPort::GetStatus(COMSTAT& stat)
{
  ASSERT(IsOpen());

  DWORD dwErrors;
  if (!ClearCommError(m_hComm, &dwErrors, &stat))
  {
    TRACE(_T("CSerialPort::GetStatus, Failed in call to ClearCommError\n"));
    ThrowSerialException();
  }
}

void CSerialPort::GetState(DCB& dcb)
{
  ASSERT(IsOpen());

  if (!GetCommState(m_hComm, &dcb))
  {
    TRACE(_T("CSerialPort::GetState, Failed in call to GetCommState\n"));
    ThrowSerialException();
  }
}

void CSerialPort::SetState(DCB& dcb)
{
  ASSERT(IsOpen());

  if (!SetCommState(m_hComm, &dcb))
  {
    TRACE(_T("CSerialPort::SetState, Failed in call to SetCommState\n"));
    ThrowSerialException();
  }
}

void CSerialPort::Escape(DWORD dwFunc)
{
  ASSERT(IsOpen());

  if (!EscapeCommFunction(m_hComm, dwFunc))
  {
    TRACE(_T("CSerialPort::Escape, Failed in call to EscapeCommFunction\n"));
    ThrowSerialException();
  }
}

void CSerialPort::ClearDTR()
{
  Escape(CLRDTR);
}

void CSerialPort::ClearRTS()
{
  Escape(CLRRTS);
}

void CSerialPort::SetDTR()
{
  Escape(SETDTR);
}

void CSerialPort::SetRTS()
{
  Escape(SETRTS);
}

void CSerialPort::SetXOFF()
{
  Escape(SETXOFF);
}

void CSerialPort::SetXON()
{
  Escape(SETXON);
}

void CSerialPort::GetProperties(COMMPROP& properties)
{
  ASSERT(IsOpen());

  if (!GetCommProperties(m_hComm, &properties))
  {
    TRACE(_T("CSerialPort::GetProperties, Failed in call to GetCommProperties\n"));
    ThrowSerialException();
  }
}

void CSerialPort::GetModemStatus(DWORD& dwModemStatus)
{
  ASSERT(IsOpen());

  if (!GetCommModemStatus(m_hComm, &dwModemStatus))
  {
    TRACE(_T("CSerialPort::GetModemStatus, Failed in call to GetCommModemStatus\n"));
    ThrowSerialException();
  }
}

void CSerialPort::SetMask(DWORD dwMask)
{
  ASSERT(IsOpen());

  if (!SetCommMask(m_hComm, dwMask))
  {
    TRACE(_T("CSerialPort::SetMask, Failed in call to SetCommMask\n"));
    ThrowSerialException();
  }
}

void CSerialPort::GetMask(DWORD& dwMask)
{
  ASSERT(IsOpen());

  if (!GetCommMask(m_hComm, &dwMask))
  {
    TRACE(_T("CSerialPort::GetMask, Failed in call to GetCommMask\n"));
    ThrowSerialException();
  }
}

void CSerialPort::Flush()
{
  ASSERT(IsOpen());

  if (!FlushFileBuffers(m_hComm))
  {
    TRACE(_T("CSerialPort::Flush, Failed in call to FlushFileBuffers\n"));
    ThrowSerialException();
  }
}

void CSerialPort::Purge(DWORD dwFlags)
{
  ASSERT(IsOpen());

  if (!PurgeComm(m_hComm, dwFlags))
  {
    TRACE(_T("CSerialPort::Purge, Failed in call to PurgeComm\n"));
    ThrowSerialException();
  }
}

void CSerialPort::TerminateOutstandingWrites()
{
  Purge(PURGE_TXABORT);
}

void CSerialPort::TerminateOutstandingReads()
{
  Purge(PURGE_RXABORT);
}

void CSerialPort::ClearWriteBuffer()
{
  Purge(PURGE_TXCLEAR);
}

void CSerialPort::ClearReadBuffer()
{
  Purge(PURGE_RXCLEAR);
}

void CSerialPort::Setup(DWORD dwInQueue, DWORD dwOutQueue)
{
  ASSERT(IsOpen());

  if (!SetupComm(m_hComm, dwInQueue, dwOutQueue))
  {
    TRACE(_T("CSerialPort::Setup, Failed in call to SetupComm\n"));
    ThrowSerialException();
  }
}

void CSerialPort::SetTimeouts(COMMTIMEOUTS& timeouts)
{
  ASSERT(IsOpen());

  if (!SetCommTimeouts(m_hComm, &timeouts))
  {
    TRACE(_T("CSerialPort::SetTimeouts, Failed in call to SetCommTimeouts\n"));
    ThrowSerialException();
  }
}

void CSerialPort::GetTimeouts(COMMTIMEOUTS& timeouts)
{
  ASSERT(IsOpen());

  if (!GetCommTimeouts(m_hComm, &timeouts))
  {
    TRACE(_T("CSerialPort::GetTimeouts, Failed in call to GetCommTimeouts\n"));
    ThrowSerialException();
  }
}

void CSerialPort::Set0Timeout()
{
  COMMTIMEOUTS Timeouts;
  ZeroMemory(&Timeouts, sizeof(COMMTIMEOUTS));
  Timeouts.ReadIntervalTimeout = MAXDWORD;
  SetTimeouts(Timeouts);
}

void CSerialPort::Set0WriteTimeout()
{
  COMMTIMEOUTS Timeouts;
  GetTimeouts(Timeouts);
  Timeouts.WriteTotalTimeoutMultiplier = 0;
  Timeouts.WriteTotalTimeoutConstant = 0;
  SetTimeouts(Timeouts);
}

void CSerialPort::Set0ReadTimeout()
{
  COMMTIMEOUTS Timeouts;
  GetTimeouts(Timeouts);
  Timeouts.ReadIntervalTimeout = MAXDWORD;
  Timeouts.ReadTotalTimeoutMultiplier = 0;
  Timeouts.ReadTotalTimeoutConstant = 0;
  SetTimeouts(Timeouts);
}

void CSerialPort::WaitEvent(DWORD& dwMask)
{
  ASSERT(IsOpen());

  if (!WaitCommEvent(m_hComm, &dwMask, NULL))
  {
    TRACE(_T("CSerialPort::WaitEvent, Failed in call to WaitCommEvent\n"));
    ThrowSerialException();
  }
}

BOOL CSerialPort::WaitEvent(DWORD& dwMask, OVERLAPPED& overlapped)
{
  ASSERT(IsOpen());
  ASSERT(overlapped.hEvent);

  BOOL bSuccess = WaitCommEvent(m_hComm, &dwMask, &overlapped);
  if (!bSuccess)
  {
    if (GetLastError() != ERROR_IO_PENDING)
    {
      TRACE(_T("CSerialPort::WaitEvent, Failed in call to WaitCommEvent\n"));
      ThrowSerialException();
    }
  }

  return bSuccess;
}




Code Select

/*
Module : SerialPort.H
Purpose: Interface for an MFC wrapper class for serial ports

Copyright (c) 1999 - 2007 by PJ Naughter. 

All rights reserved.

Copyright / Usage Details:

You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise)
when your product is released in binary form. You are allowed to modify the source code in any way you want
except you cannot modify the copyright details at the top of each module. If you want to distribute source
code with your application, then you are only allowed to distribute versions released by the author. This is
to maintain a single distribution point for the source code.

*/


///////////////////// Macros / Structs etc //////////////////////////

#ifndef __SERIALPORT_H__
#define __SERIALPORT_H__

#ifndef CSERIALPORT_EXT_CLASS
#define CSERIALPORT_EXT_CLASS
#endif

#ifndef CSERIALPORT_EXT_API
#define CSERIALPORT_EXT_API
#endif


/////////////////////////// Classes ///////////////////////////////////////////

///////////////// Serial port exception class /////////////////////////////////

class CSERIALPORT_EXT_CLASS CSerialException : public CException
{
public:
//Constructors / Destructors
CSerialException(DWORD dwError);

//Methods
#ifdef _DEBUG
virtual void Dump(CDumpContext& dc) const;
#endif
virtual BOOL GetErrorMessage(LPTSTR lpszError, UINT nMaxError, PUINT pnHelpContext = NULL);
CString GetErrorMessage();

//Data members
DWORD m_dwError;

protected:
DECLARE_DYNAMIC(CSerialException)
};


/////////////// The main serial port class ////////////////////////////////////

class CSERIALPORT_EXT_CLASS CSerialPort
{
public:
//Enums
  enum FlowControl
  {
    NoFlowControl,
    CtsRtsFlowControl,
    CtsDtrFlowControl,
    DsrRtsFlowControl,
    DsrDtrFlowControl,
    XonXoffFlowControl
  };

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

  enum StopBits
  {
    OneStopBit,
    OnePointFiveStopBits,
    TwoStopBits
  };

//Constructors / Destructors
  CSerialPort();
  virtual ~CSerialPort();

//General Methods
  void Open(int nPort, DWORD dwBaud = 9600, Parity parity = NoParity, BYTE DataBits = 8,
            StopBits stopbits = OneStopBit, FlowControl fc = NoFlowControl, BOOL bOverlapped = FALSE);
  void Close();
  void Attach(HANDLE hComm);
  HANDLE Detach();
  operator HANDLE() const { return m_hComm; };
  BOOL IsOpen() const { return m_hComm != INVALID_HANDLE_VALUE; };
#ifdef _DEBUG
  void Dump(CDumpContext& dc) const;
#endif

//Reading / Writing Methods
  DWORD Read(void* lpBuf, DWORD dwCount);
  BOOL  Read(void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped, DWORD* pBytesRead=NULL);
  void  ReadEx(void* lpBuf, DWORD dwCount);
  DWORD Write(const void* lpBuf, DWORD dwCount);
  BOOL  Write(const void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped, DWORD* pBytesWritten=NULL);
  void  WriteEx(const void* lpBuf, DWORD dwCount);
  void  TransmitChar(char cChar);
  void  GetOverlappedResult(OVERLAPPED& overlapped, DWORD& dwBytesTransferred, BOOL bWait);
  void  CancelIo();
  DWORD BytesWaiting();
  BOOL  DataWaiting(DWORD dwTimeout);

//Configuration Methods
  void GetConfig(COMMCONFIG& config);
  static void GetDefaultConfig(int nPort, COMMCONFIG& config);
  void SetConfig(COMMCONFIG& Config);
  static void SetDefaultConfig(int nPort, COMMCONFIG& config);

//Misc RS232 Methods
  void ClearBreak();
  void SetBreak();
  void ClearError(DWORD& dwErrors);
  void GetStatus(COMSTAT& stat);
  void GetState(DCB& dcb);
  void SetState(DCB& dcb);
  void Escape(DWORD dwFunc);
  void ClearDTR();
  void ClearRTS();
  void SetDTR();
  void SetRTS();
  void SetXOFF();
  void SetXON();
  void GetProperties(COMMPROP& properties);
  void GetModemStatus(DWORD& dwModemStatus);

//Timeouts
  void SetTimeouts(COMMTIMEOUTS& timeouts);
  void GetTimeouts(COMMTIMEOUTS& timeouts);
  void Set0Timeout();
  void Set0WriteTimeout();
  void Set0ReadTimeout();

//Event Methods
  void SetMask(DWORD dwMask);
  void GetMask(DWORD& dwMask);
  void WaitEvent(DWORD& dwMask);
  BOOL WaitEvent(DWORD& dwMask, OVERLAPPED& overlapped);
 
//Queue Methods
  void Flush();
  void Purge(DWORD dwFlags);
  void TerminateOutstandingWrites();
  void TerminateOutstandingReads();
  void ClearWriteBuffer();
  void ClearReadBuffer();
  void Setup(DWORD dwInQueue, DWORD dwOutQueue);

//Overridables
  virtual void OnCompletion(DWORD dwErrorCode, DWORD dwCount, LPOVERLAPPED lpOverlapped);

//Static methods
  static void ThrowSerialException(DWORD dwError = 0);

protected:
//Typedefs
  typedef BOOL (WINAPI CANCELIO)(HANDLE);
  typedef CANCELIO* LPCANCELIO;

//Static methods
  static void WINAPI _OnCompletion(DWORD dwErrorCode, DWORD dwCount, LPOVERLAPPED lpOverlapped);

//Member variables
  HANDLE     m_hComm;        //Handle to the comms port
  HANDLE     m_hEvent;       //A event handle we need for internal synchronisation
  HINSTANCE  m_hKernel32;    //Kernel32 handle
  LPCANCELIO m_lpfnCancelIo; //CancelIO function pointer
};

#endif //__SERIALPORT_H__



App.cpp

Code Select

/*
Module : APP.CPP
Purpose: Provides the WinMain function for testing the serial port class
Created: PJN / 23-05-1999
History: None

Copyright (c) 1999 by PJ Naughter. 
All rights reserved.

*/

/////////////////////////////////  Includes  //////////////////////////////////

#include "stdafx.h"
#include "SerialPort.h"



///////////////////////////////// Defines /////////////////////////////////////

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif



//////////////////////////////// Implementation ///////////////////////////////


class CSerialPortApp : public CWinApp
{
public:
  virtual BOOL InitInstance();
};

CSerialPortApp theApp;

BOOL CSerialPortApp::InitInstance()
{
  BYTE* pBuf = new BYTE[10000];

  try
  {
    COMMCONFIG config;
    CSerialPort::GetDefaultConfig(1, config);

    CSerialPort port;
    port.Open(1, 1200, CSerialPort::NoParity, 8, CSerialPort::OneStopBit, CSerialPort::XonXoffFlowControl);

    HANDLE hPort = port.Detach();
    port.Attach(hPort);

    DWORD dwModemStatus;
    port.GetModemStatus(dwModemStatus);

    DCB dcb;
    port.GetState(dcb);

    dcb.BaudRate = 9600;
    port.SetState(dcb);   

    DWORD dwErrors;                     
    port.ClearError(dwErrors);

    port.SetBreak();
    port.ClearBreak();

    COMSTAT stat;
    port.GetStatus(stat);

    DWORD dwBytesWaiting = port.BytesWaiting();
    dwBytesWaiting;

    COMMTIMEOUTS timeouts;
    port.GetTimeouts(timeouts);

    port.Setup(10000, 10000);

    port.GetConfig(config);

    config.dcb.BaudRate = 9600;
    port.SetConfig(config);

    port.Set0WriteTimeout();
    port.Set0ReadTimeout();

    char sBuf[] = "This should appear on the serial port";
    port.Write(sBuf, (DWORD) strlen(sBuf));

    DWORD dwMask;
    port.GetMask(dwMask);

    port.SetMask(EV_TXEMPTY);

    //port.WaitEvent(dwMask);

    port.TerminateOutstandingWrites();

    port.TransmitChar('p');

    port.Set0Timeout();

    char sRxBuf[10];
    DWORD dwRead = port.Read(sRxBuf, 10);
    dwRead; //To remove unreferrenced variable in VC 6.

    port.TerminateOutstandingReads();

    port.ClearDTR();

    port.ClearRTS();

    port.SetDTR();

    port.SetRTS();

    port.SetXOFF();

    port.SetXON();

    COMMPROP properties;
    port.GetProperties(properties);

    port.ClearWriteBuffer();

    port.ClearReadBuffer();

    port.Flush();

    port.Close();


    //Try out the overlapped functions
    CSerialPort port2;
    port2.Open(1, 9600, CSerialPort::NoParity, 8, CSerialPort::OneStopBit, CSerialPort::XonXoffFlowControl, TRUE);

    CEvent event(FALSE, TRUE);
    OVERLAPPED overlapped;
    ZeroMemory(&overlapped, sizeof(OVERLAPPED));
    overlapped.hEvent = event;
    if (!port2.Write(pBuf, 10000, overlapped))
    {
      DWORD dwBytesWritten;
      WaitForSingleObject(event, INFINITE);
      port2.GetOverlappedResult(overlapped, dwBytesWritten, TRUE);
    }
    if (!port2.Read(pBuf, 10, overlapped))
    {
      DWORD dwBytesRead;
      if (WaitForSingleObject(event, 1000) == WAIT_OBJECT_0)
      {
        TRACE(_T("Data was read from the serial port\n"));
        port2.GetOverlappedResult(overlapped, dwBytesRead, FALSE);
      }
      else
        TRACE(_T("No data was read from the serial port\n"));
    }

    port2.SetMask(EV_TXEMPTY);
    port2.WaitEvent(dwMask, overlapped);                 

    /* for testing on NT only
    port2.WriteEx(sBuf, strlen(sBuf));
    SleepEx(INFINITE, TRUE);
    port2.ReadEx(pBuf, 10);
    SleepEx(INFINITE, TRUE);
    */

  }
  catch (CSerialException* pEx)
  {
    TRACE(_T("Handle Exception, Message:%s\n"), pEx->GetErrorMessage());
    pEx->Delete();
  }

  delete [] pBuf;

  return FALSE;
}


Sapero you are the best in programming can you please help me for created an static library for EBASIC and Aurora?

With kind regards

Source:
=====

http://www.naughter.com/serialport.html