The article was published in the July 1997 issue of The C/C++ User's Journal. It is not explicitly stated in the article, but permission is hereby given to use any and all source code from the article in your own projects as long as my copyright notice remains in the source files.
A problem common to anyone porting 16-bit serial communication code to 32-bit Windows NT or Windows 95 is that the familiar methods of performing that task are at the very least different and at the worst, no longer present. The article presented a class that encapsulates the Win32 API functions used for serial communication and simplifies their use. The class also contains some member functions that make it simple to start and stop a separate thread for sending and receiving data. Some sample programs were included to demonstrate how the class can be used.
The DumbTerminal() function in both files needs to be corrected to set the stop bits option correctly.
DumbTerminal()
if(pszOptions[2] == '2') nStopBits = TWOSTOPBITS; // <----- nStopBits instead of nDataBits
CGUITermDoc::OnFileConnect() needs to set the selected baud rate. Here's the affected section of code:
CGUITermDoc::OnFileConnect()
if(m_csFlowControl == "Software") nFlow = PCF_XONXOFF; else if(m_csFlowControl == "None") nFlow = PCF_NOFLOWCTL; COMPort->SetBaudRate(nBaud); // <--- ADD THIS LINE COMPort->SetParityDataStop(nParity, nData, nStop); COMPort->SetFlowControl(nFlow);
CSerialPort::EscapeCommFunction() was incorrectly using the xxxDTR and xxxRTS values. Replace it with this code:
CSerialPort::EscapeCommFunction()
BOOL CSerialPort::EscapeCommFunction(DWORD dwFunc) { DCB dcb; BOOL bRetVal; dwLastError = ERROR_SUCCESS; dwLastError = ERROR_SUCCESS; dcb.DCBlength = sizeof(DCB); ::GetCommState(hPortId, &dcb); // The EscapeComm() function should not be used to adjust line // settings if dcb.fDtrControl is set to DTR_CONTROL_HANDSHAKE // or dcb.fRtsControl is set to RTS_CONTROL_HANDSHAKE or // RTS_CONTROL_TOGGLE (that's what is says in the online help // for the DCB structure). if((dcb.fDtrControl & DTR_CONTROL_HANDSHAKE) && (dwFunc == CLRDTR || dwFunc == SETDTR)) return FALSE; if((dcb.fRtsControl & (RTS_CONTROL_HANDSHAKE | RTS_CONTROL_TOGGLE)) && (dwFunc == CLRRTS || dwFunc == SETRTS)) return FALSE; bRetVal = ::EscapeCommFunction(hPortId, dwFunc); if(!bRetVal) dwLastError = ::GetLastError(); return bRetVal; }
If you see the above error message while trying to compile the code, you need to turn off the precompiled header option for the SerialPort.cpp source file as it is not using them. To do this you need to do the following:
Now when you rebuild, precompiled headers won't be used for that source file and it will compile without any errors.