In order to use the following SerialPort class in your own projects, simply copy and paste the two files and save as SerialPort.cpp and SerialPort.h, include both files in your project, and add a #include "SerialPort.h" line in your main.cpp program.

I apologize for the need to copy and paste this, but unfortunately GeoCities won't allow me to upload .cpp files. An alternative solution would have been to put this in a .zip file, however since this is such a short program segment, I thought that was overkill...

If you have any questions/comments, please send me an email at: wkrawec@hotmail.com

SerialPort.cpp:
#include "StdAfx.h"
#include "serialport.h"

// default constructer... not much to do right now but set our handle (hComm) to NULL
SerialPort::SerialPort()
{
	hComm = NULL;
}

// destructor which will automatically close the serial port incase the user forgot to do so manually...
SerialPort::~SerialPort(void)
{
	Close();
}

// will close the serial port if it is open
void SerialPort::Close()
{
	if(hComm)
	{
		CloseHandle(hComm);
		hComm = NULL;
	}
}

// The following will open the serial port using the settings specified within COMPort (see SerialPort.h for more info on this)
bool SerialPort::InitSerialPort(SetupPort COMPort)
{
	hComm = CreateFile(_T("COM1:"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
	if(hComm == INVALID_HANDLE_VALUE)
		return false;	// Something went wrong, so quit

	DCB options;
	if(GetCommState(hComm, &options) == 0)	// try to get the current settings for the COM port
	{
		MessageBox(NULL, _T("InitSerialPort Error 0x02"),_T("Error"),MB_OK);	// didn't work, so quit
		CloseHandle(hComm);
		hComm = NULL;
		return false;
	}

	// OK, so now change these settings to the ones specified by COMPort
	options.BaudRate = COMPort.BaudRate;
	options.ByteSize = COMPort.ByteSize;
	options.Parity = COMPort.Parity;
	options.StopBits = COMPort.StopBits;
	options.fBinary = TRUE;
	options.fDsrSensitivity = false;
	options.fParity = COMPort.fParity;
	options.fOutX = false;
	options.fInX = false;
	options.fNull = false;
	options.fAbortOnError = true;
	options.fOutxCtsFlow = TRUE;
	options.fOutxDsrFlow = false;
	options.fDtrControl=DTR_CONTROL_ENABLE;
	options.fDsrSensitivity=false;
	options.fRtsControl=RTS_CONTROL_HANDSHAKE;
	options.fOutxCtsFlow=false;

	// And set the settings:
	if(SetCommState(hComm, &options) == 0)
	{
		MessageBox(NULL, _T("InitSerialPort Error 0x03"),_T("Error"),MB_OK);
		CloseHandle(hComm);
		hComm = NULL;
		return false;
	}

	// setup the timeouts:
	COMMTIMEOUTS timeOuts;
	if((GetCommTimeouts (hComm, &timeOuts))==0)
		return false;
	timeOuts.ReadIntervalTimeout = 0;
	timeOuts.ReadTotalTimeoutConstant = 10;
	timeOuts.ReadTotalTimeoutMultiplier = 10;
	timeOuts.WriteTotalTimeoutConstant = 1000;
	timeOuts.WriteTotalTimeoutMultiplier= 10;
	if(SetCommTimeouts (hComm, &timeOuts) == 0)
	{
		MessageBox(NULL, _T("InitSerialPort Error 0x04"),_T("Error"),MB_OK);
		CloseHandle(hComm);
		hComm = NULL;
		return false;
	}
	return true;	// done and all went well!
}

// This will send a single byte of data over the serial port
bool SerialPort::SendByte(char data)
{
	if(!hComm)
		return false;	// COM port not open, so quit

	DWORD bytesWritten = 0;
	if(WriteFile(hComm, &data, 1, &bytesWritten, NULL) == 0)
		return false;

	return true;
}

// This will check to see if there is anything to read in from the COM port
// If there is data to read, that byte is stored in data, and this returns a TRUE
// Otherwise a FALSE is returned and data is unaffected
bool SerialPort::ReadByte(char *data)
{
	BYTE b;

	DWORD bytesTransferred=0;

	if(ReadFile(hComm, &b, 1, &bytesTransferred, 0))
	{
		if (bytesTransferred == 1)
		{
			*data=b;
			return true;
		}
	}
	return false;
}

SerialPort.h:
#pragma once

// SerialPort.h written by Walter O. Krawec
// with thanks to this article which provided a ton of info on this topic:
// http://www.codeguru.com/Cpp/I-N/network/serialcommunications/article.php/c5395/
//
// USAGE:
// SerialPort Name;
//
// -- In WinMain --
// Name.InitSerialPort(SetupPort());
//
// -- on closing --
// Name.Close();
//
// -- to send a byte --
// Name.SendByte(BYTE_TO_SEND);
//
// -- to recv a byte --
// char c=0;
// Name.RecvByte(&c);	// returns TRUE if a byte was received.

// SetupPort is a structure holding basic COM port settings including
// baud rate, parity, etc.
struct SetupPort
{
	BYTE PortNum;
	BYTE ByteSize;
	BYTE Parity;
	BYTE StopBits;
	DWORD BaudRate;
	DWORD fParity;

	SetupPort()	// Default constructer loads default settings of (9600, 8, N, 1)
	{
		PortNum = 1; ByteSize = 8; Parity = NOPARITY; StopBits = ONESTOPBIT;
		BaudRate = 9600; fParity = false;
	}
	SetupPort(DWORD baudRate, BYTE byteSize, BYTE parity, BYTE stopBits)	// Setup basic options manually
	{
		PortNum = 1; ByteSize = byteSize; Parity = parity; StopBits = stopBits;
		BaudRate = 9600; fParity = false;
	}
};

// SerialPort is the main class responsible for communicating via the serial port on a PPC or PC
class SerialPort
{
public:
	SerialPort(void);
	~SerialPort(void);

	void Close();
	bool InitSerialPort(SetupPort COMPort);
	bool SendByte(char data);		// sends one byte of data through the COM port (call InitSerialPort first)
	bool ReadByte(char *data);		// recvs one byte of data through the COM port (call InitSerialPort first)

private:
	HANDLE hComm;				// handle to the serial port
};