📄 comport.cpp
字号:
_RPTF0(_CRT_WARN,"CComPort::SetupReadTimeouts - Unable to set timeout information\n");
return m_lLastError;
}
// Return successful
return m_lLastError;
}
CComPort::EBaudrate CComPort::GetBaudrate (void)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CComPort::GetBaudrate - Device is not opened\n");
return EBaudUnknown;
}
// Obtain the DCB structure for the device
CDCB dcb;
if (!::GetCommState(m_hFile,&dcb))
{
// Obtain the error code
m_lLastError = ::GetLastError();
// Display a warning
_RPTF0(_CRT_WARN,"CComPort::GetBaudrate - Unable to obtain DCB information\n");
return EBaudUnknown;
}
// Return the appropriate baudrate
return EBaudrate(dcb.BaudRate);
}
CComPort::EDataBits CComPort::GetDataBits (void)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CComPort::GetDataBits - Device is not opened\n");
return EDataUnknown;
}
// Obtain the DCB structure for the device
CDCB dcb;
if (!::GetCommState(m_hFile,&dcb))
{
// Obtain the error code
m_lLastError = ::GetLastError();
// Display a warning
_RPTF0(_CRT_WARN,"CComPort::GetDataBits - Unable to obtain DCB information\n");
return EDataUnknown;
}
// Return the appropriate bytesize
return EDataBits(dcb.ByteSize);
}
CComPort::EParity CComPort::GetParity (void)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CComPort::GetParity - Device is not opened\n");
return EParUnknown;
}
// Obtain the DCB structure for the device
CDCB dcb;
if (!::GetCommState(m_hFile,&dcb))
{
// Obtain the error code
m_lLastError = ::GetLastError();
// Display a warning
_RPTF0(_CRT_WARN,"CComPort::GetParity - Unable to obtain DCB information\n");
return EParUnknown;
}
// Check if parity is used
if (!dcb.fParity)
{
// No parity
return EParNone;
}
// Return the appropriate parity setting
return EParity(dcb.Parity);
}
CComPort::EStopBits CComPort::GetStopBits (void)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CComPort::GetStopBits - Device is not opened\n");
return EStopUnknown;
}
// Obtain the DCB structure for the device
CDCB dcb;
if (!::GetCommState(m_hFile,&dcb))
{
// Obtain the error code
m_lLastError = ::GetLastError();
// Display a warning
_RPTF0(_CRT_WARN,"CComPort::GetStopBits - Unable to obtain DCB information\n");
return EStopUnknown;
}
// Return the appropriate stopbits
return EStopBits(dcb.StopBits);
}
DWORD CComPort::GetEventMask (void)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CComPort::GetEventMask - Device is not opened\n");
return 0;
}
// Obtain the COM mask
DWORD dwMask = 0;
if (!::GetCommMask(m_hFile, &dwMask))
{
// Set the internal error code
m_lLastError = ::GetLastError();
// Issue an error and quit
_RPTF0(_CRT_WARN,"CComPort::GetEventMask - Unable to get the event mask\n");
return 0;
}
// Return the event mask
return dwMask;
}
BYTE CComPort::GetEventChar (void)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CComPort::GetEventChar - Device is not opened\n");
return 0;
}
// Obtain the DCB structure for the device
CDCB dcb;
if (!::GetCommState(m_hFile,&dcb))
{
// Obtain the error code
m_lLastError = ::GetLastError();
// Display a warning
_RPTF0(_CRT_WARN,"CComPort::GetEventChar - Unable to obtain DCB information\n");
return 0;
}
// Set the new event character
return BYTE(dcb.EvtChar);
}
CComPort::EHandshake CComPort::GetHandshaking (void)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CComPort::GetHandshaking - Device is not opened\n");
return EHandshakeUnknown;
}
// Obtain the DCB structure for the device
CDCB dcb;
if (!::GetCommState(m_hFile,&dcb))
{
// Obtain the error code
m_lLastError = ::GetLastError();
// Display a warning
_RPTF0(_CRT_WARN,"CComPort::GetHandshaking - Unable to obtain DCB information\n");
return EHandshakeUnknown;
}
// Check if hardware handshaking is being used
if ((dcb.fDtrControl == DTR_CONTROL_HANDSHAKE) && (dcb.fRtsControl == RTS_CONTROL_HANDSHAKE))
return EHandshakeHardware;
// Check if software handshaking is being used
if (dcb.fOutX && dcb.fInX)
return EHandshakeSoftware;
// No handshaking is being used
return EHandshakeOff;
}
LONG CComPort::Write (const void* pData, size_t iLen, DWORD* pdwWritten, LPOVERLAPPED lpOverlapped, DWORD dwTimeout)
{
// Overlapped operation should specify the pdwWritten variable
_ASSERTE(!lpOverlapped || pdwWritten);
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Use our own variable for read count
DWORD dwWritten;
if (pdwWritten == 0)
{
pdwWritten = &dwWritten;
}
// Reset the number of bytes written
*pdwWritten = 0;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CComPort::Write - Device is not opened\n");
return m_lLastError;
}
// Wait for the event to happen
OVERLAPPED ovInternal;
if (lpOverlapped == 0)
{
// Setup our own overlapped structure
memset(&ovInternal,0,sizeof(ovInternal));
ovInternal.hEvent = m_hevtOverlapped;
// Use our internal overlapped structure
lpOverlapped = &ovInternal;
}
// Make sure the overlapped structure isn't busy
_ASSERTE(HasOverlappedIoCompleted(lpOverlapped));
// Write the data
if (!::WriteFile(m_hFile,pData,iLen,pdwWritten,lpOverlapped))
{
// Set the internal error code
long lLastError = ::GetLastError();
// Overlapped operation in progress is not an actual error
if (lLastError != ERROR_IO_PENDING)
{
// Save the error
m_lLastError = lLastError;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CComPort::Write - Unable to write the data\n");
return m_lLastError;
}
// We need to block if the client didn't specify an overlapped structure
if (lpOverlapped == &ovInternal)
{
// Wait for the overlapped operation to complete
switch (::WaitForSingleObject(lpOverlapped->hEvent,dwTimeout))
{
case WAIT_OBJECT_0:
// The overlapped operation has completed
if (!::GetOverlappedResult(m_hFile,lpOverlapped,pdwWritten,FALSE))
{
// Set the internal error code
m_lLastError = ::GetLastError();
_RPTF0(_CRT_WARN,"CComPort::Write - Overlapped completed without result\n");
return m_lLastError;
}
break;
case WAIT_TIMEOUT:
// Cancel the I/O operation
::CancelIo(m_hFile);
// The operation timed out. Set the internal error code and quit
m_lLastError = ERROR_TIMEOUT;
return m_lLastError;
default:
// Set the internal error code
m_lLastError = ::GetLastError();
// Issue an error and quit
_RPTF0(_CRT_WARN,"CComPort::Write - Unable to wait until data has been sent\n");
return m_lLastError;
}
}
}
else
{
// The operation completed immediatly. Just to be sure
// we'll set the overlapped structure's event handle.
::SetEvent(lpOverlapped->hEvent);
}
// Return successfully
return m_lLastError;
}
LONG CComPort::Write (LPCSTR pString, DWORD* pdwWritten, LPOVERLAPPED lpOverlapped, DWORD dwTimeout)
{
// Determine the length of the string
return Write(pString,strlen(pString),pdwWritten,lpOverlapped,dwTimeout);
}
LONG CComPort::Read (void* pData, size_t iLen, DWORD* pdwRead, LPOVERLAPPED lpOverlapped, DWORD dwTimeout)
{
// Overlapped operation should specify the pdwRead variable
_ASSERTE(!lpOverlapped || pdwRead);
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Use our own variable for read count
DWORD dwRead;
if (pdwRead == 0)
{
pdwRead = &dwRead;
}
// Reset the number of bytes read
*pdwRead = 0;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CComPort::Read - Device is not opened\n");
return m_lLastError;
}
// Wait for the event to happen
OVERLAPPED ovInternal;
if (lpOverlapped == 0)
{
// Setup our own overlapped structure
memset(&ovInternal,0,sizeof(ovInternal));
ovInternal.hEvent = m_hevtOverlapped;
// Use our internal overlapped structure
lpOverlapped = &ovInternal;
}
// Make sure the overlapped structure isn't busy
_ASSERTE(HasOverlappedIoCompleted(lpOverlapped));
#ifdef _DEBUG
// The debug version fills the entire data structure with
// 0xDC bytes, to catch buffer errors as soon as possible.
memset(pData,0xDC,iLen);
#endif
// Read the data
if (!::ReadFile(m_hFile,pData,iLen,pdwRead,lpOverlapped))
{
// Set the internal error code
long lLastError = ::GetLastError();
// Overlapped operation in progress is not an actual error
if (lLastError != ERROR_IO_PENDING)
{
// Save the error
m_lLastError = lLastError;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CComPort::Read - Unable to read the data\n");
return m_lLastError;
}
// We need to block if the client didn't specify an overlapped structure
if (lpOverlapped == &ovInternal)
{
// Wait for the overlapped operation to complete
switch (::WaitForSingleObject(lpOverlapped->hEvent,dwTimeout))
{
case WAIT_OBJECT_0:
// The overlapped operation has completed
if (!::GetOverlappedResult(m_hFile,lpOverlapped,pdwRead,FALSE))
{
// Set the internal error code
m_lLastError = ::GetLastError();
_RPTF0(_CRT_WARN,"CComPort::Read - Overlapped completed without result\n");
return m_lLastError;
}
break;
case WAIT_TIMEOUT:
// Cancel the I/O operation
::CancelIo(m_hFile);
// The operation timed out. Set the internal error code and quit
m_lLastError = ERROR_TIMEOUT;
return m_lLastError;
default:
// Set the internal error code
m_lLastError = ::GetLastError();
// Issue an error and quit
_RPTF0(_CRT_WARN,"CComPort::Read - Unable to wait until data has been read\n");
return m_lLastError;
}
}
}
else
{
// The operation completed immediatly. Just to be sure
// we'll set the overlapped structure's event handle.
::SetEvent(lpOverlapped->hEvent);
}
// Return successfully
return m_lLastError;
}
LONG CComPort::Flush()
{
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CComPort::Read - Device is not opened\n");
return m_lLastError;
}
if (!::PurgeComm(m_hFile, PURGE_TXCLEAR | PURGE_RXCLEAR))
{
// Set the internal error code
m_lLastError = ::GetLastError();
_RPTF0(_CRT_WARN,"CComPort::Read - Overlapped completed without result\n");
}
// Return successfully
return m_lLastError;
}
CComPort::EEvent CComPort::GetEventType (void)
{
// Obtain the event
EEvent eEvent = m_eEvent;
// Reset internal event type
m_eEvent = EEventNone;
// Return the current cause
return eEvent;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -