📄 serialport.cpp
字号:
return bSuccess;
#endif
}
//---------------------------------------------------------------------------------------
// io 完成端口操作
//---------------------------------------------------------------------------------------
void CSerialPort::_OnCompletion(DWORD dwErrorCode, DWORD dwCount, LPOVERLAPPED lpOverlapped)
{
// Validate our parameters
ASSERT(lpOverlapped);
// Convert back to the C++ world
CSerialPort* pSerialPort = (CSerialPort*) lpOverlapped->hEvent;
ASSERT(pSerialPort);
ASSERT(pSerialPort->IsKindOf(RUNTIME_CLASS(CSerialPort)));
// Call the C++ function
pSerialPort->OnCompletion(dwErrorCode, dwCount, lpOverlapped);
}
/*virtual*/
void CSerialPort::OnCompletion(DWORD /*dwErrorCode*/, DWORD /*dwCount*/, LPOVERLAPPED lpOverlapped)
{
// Just free up 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 up
}
void CSerialPort::CancelIo()
{
ASSERT(IsOpen());
if( _SerialPortData.m_lpfnCancelIo == NULL )
{
TRACE(_T("CancelIo function is not supported on this OS.\nYou need to be running at least NT 4 or Win 98 to use this function\n"));
AfxThrowSerialException(ERROR_CALL_NOT_IMPLEMENTED);
return;
}
if( !::_SerialPortData.m_lpfnCancelIo(m_hComm) )
{
TRACE(_T("Failed in call to \"CancelIO()\"\n"));
AfxThrowSerialException();
}
}
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());
ASSERT(m_hEvent);
// 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)
{
#ifdef UNDER_CE
TRACE(_T("Call unsupported function \"WriteFileEx()\"!\n"));
AfxThrowSerialException(ERROR_CALL_NOT_IMPLEMENTED);
#else
ASSERT(IsOpen());
ASSERT(m_bOverlapped);
OVERLAPPED* pOverlapped = new OVERLAPPED;
ZeroMemory(pOverlapped, sizeof(OVERLAPPED));
pOverlapped->hEvent = (HANDLE) this;
// pOverlapped 和 dwCount 传入 _OnCompletion
if (!WriteFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
{
delete pOverlapped;
TRACE(_T("Failed in call to WriteFileEx\n"));
AfxThrowSerialException();
}
delete pOverlapped;
#endif
}
void CSerialPort::ReadEx(void* lpBuf, DWORD dwCount)
{
#ifdef UNDER_CE
TRACE(_T("Call unsupported function \"ReadFileEx()\"!\n"));
AfxThrowSerialException(ERROR_CALL_NOT_IMPLEMENTED);
#else
ASSERT(IsOpen());
ASSERT(m_bOverlapped);
OVERLAPPED* pOverlapped = new OVERLAPPED;
ZeroMemory(pOverlapped, sizeof(OVERLAPPED));
pOverlapped->hEvent = (HANDLE) this;
// pOverlapped 和 dwCount 传入 _OnCompletion
if (!ReadFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
{
delete pOverlapped;
TRACE(_T("Failed in call to ReadFileEx\n"));
AfxThrowSerialException();
}
delete pOverlapped;
#endif
}
void CSerialPort::TransmitChar(char cChar)
{
ASSERT(IsOpen());
if (!TransmitCommChar(m_hComm, cChar))
{
TRACE(_T("Failed in call to TransmitCommChar\n"));
AfxThrowSerialException();
}
}
//---------------------------------------------------------------------------------------
// 串口属性
//---------------------------------------------------------------------------------------
void CSerialPort::GetConfig(COMMCONFIG& config)
{
#ifdef UNDER_CE
TRACE(_T("Call unsupported function \"GetCommConfig()\"!\n"));
AfxThrowSerialException(ERROR_CALL_NOT_IMPLEMENTED);
#else
ASSERT(IsOpen());
DWORD dwSize = sizeof(COMMCONFIG);
if (!GetCommConfig(m_hComm, &config, &dwSize))
{
TRACE(_T("Failed in call to GetCommConfig\n"));
AfxThrowSerialException();
}
#endif
}
void CSerialPort::SetConfig(COMMCONFIG& config)
{
#ifdef UNDER_CE
TRACE(_T("Call unsupported function \"SetCommConfig()\"!\n"));
AfxThrowSerialException(ERROR_CALL_NOT_IMPLEMENTED);
#else
ASSERT(IsOpen());
DWORD dwSize = sizeof(COMMCONFIG);
if (!SetCommConfig(m_hComm, &config, dwSize))
{
TRACE(_T("Failed in call to SetCommConfig\n"));
AfxThrowSerialException();
}
#endif
}
void CSerialPort::SetBreak()
{
ASSERT(IsOpen());
if (!SetCommBreak(m_hComm))
{
TRACE(_T("Failed in call to SetCommBreak\n"));
AfxThrowSerialException();
}
}
void CSerialPort::ClearBreak()
{
ASSERT(IsOpen());
if (!ClearCommBreak(m_hComm))
{
TRACE(_T("Failed in call to SetCommBreak\n"));
AfxThrowSerialException();
}
}
void CSerialPort::ClearError(DWORD& dwErrors)
{
ASSERT(IsOpen());
if (!ClearCommError(m_hComm, &dwErrors, NULL))
{
TRACE(_T("Failed in call to ClearCommError\n"));
AfxThrowSerialException();
}
}
void CSerialPort::GetDefaultConfig(int nPort, COMMCONFIG& config)
{
#ifdef UNDER_CE
TRACE(_T("Call unsupported function \"GetDefaultCommConfig()\"!\n"));
AfxThrowSerialException(ERROR_CALL_NOT_IMPLEMENTED);
#else
// Validate our parameters
ASSERT(nPort>0 && nPort<=255);
// Create the device name as a string
CString strPort;
#ifdef UNDER_CE
strPort.Format(_T("COM%d:"), nPort);
#else
strPort.Format(_T("COM%d"), nPort);
#endif
DWORD dwSize = sizeof(COMMCONFIG);
if (!GetDefaultCommConfig(strPort, &config, &dwSize))
{
TRACE(_T("Failed in call to GetDefaultCommConfig\n"));
AfxThrowSerialException();
}
#endif
}
void CSerialPort::SetDefaultConfig(int nPort, COMMCONFIG& config)
{
#ifdef UNDER_CE
TRACE(_T("Call unsupported function \"SetDefaultConfig()\"!\n"));
AfxThrowSerialException(ERROR_CALL_NOT_IMPLEMENTED);
#else
// Validate our parameters
ASSERT(nPort>0 && nPort<=255);
// Create the device name as a string
CString strPort;
#ifdef UNDER_CE
strPort.Format(_T("COM%d:"), nPort);
#else
strPort.Format(_T("COM%d"), nPort);
#endif
DWORD dwSize = sizeof(COMMCONFIG);
if (!SetDefaultCommConfig(strPort, &config, dwSize))
{
TRACE(_T("Failed in call to SetDefaultCommConfig\n"));
AfxThrowSerialException();
}
#endif
}
//---------------------------------------------------------------------------------------
// 当前串口属性
//---------------------------------------------------------------------------------------
void CSerialPort::GetStatus(COMSTAT& stat)
{
ASSERT(IsOpen());
DWORD dwErrors;
if (!ClearCommError(m_hComm, &dwErrors, &stat))
{
TRACE(_T("Failed in call to ClearCommError\n"));
AfxThrowSerialException();
}
}
void CSerialPort::GetState(DCB& dcb)
{
ASSERT(IsOpen());
if (!GetCommState(m_hComm, &dcb))
{
TRACE(_T("Failed in call to GetCommState\n"));
AfxThrowSerialException();
}
}
void CSerialPort::SetState(DCB& dcb)
{
ASSERT(IsOpen());
if (!SetCommState(m_hComm, &dcb))
{
TRACE(_T("Failed in call to SetCommState\n"));
AfxThrowSerialException();
}
}
void CSerialPort::Escape(DWORD dwFunc)
{
ASSERT(IsOpen());
if (!EscapeCommFunction(m_hComm, dwFunc))
{
TRACE(_T("Failed in call to EscapeCommFunction\n"));
AfxThrowSerialException();
}
}
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("Failed in call to GetCommProperties\n"));
AfxThrowSerialException();
}
}
void CSerialPort::GetModemStatus(DWORD& dwModemStatus)
{
ASSERT(IsOpen());
if (!GetCommModemStatus(m_hComm, &dwModemStatus))
{
TRACE(_T("Failed in call to GetCommModemStatus\n"));
AfxThrowSerialException();
}
}
void CSerialPort::SetMask(DWORD dwMask)
{
ASSERT(IsOpen());
if (!SetCommMask(m_hComm, dwMask))
{
TRACE(_T("Failed in call to SetCommMask\n"));
AfxThrowSerialException();
}
}
void CSerialPort::GetMask(DWORD& dwMask)
{
ASSERT(IsOpen());
if (!GetCommMask(m_hComm, &dwMask))
{
TRACE(_T("Failed in call to GetCommMask\n"));
AfxThrowSerialException();
}
}
void CSerialPort::Flush()
{
ASSERT(IsOpen());
if (!FlushFileBuffers(m_hComm))
{
TRACE(_T("Failed in call to FlushFileBuffers\n"));
AfxThrowSerialException();
}
}
void CSerialPort::Purge(DWORD dwFlags)
{
ASSERT(IsOpen());
if (!PurgeComm(m_hComm, dwFlags))
{
TRACE(_T("Failed in call to PurgeComm\n"));
AfxThrowSerialException();
}
}
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("Failed in call to SetupComm\n"));
AfxThrowSerialException();
}
}
void CSerialPort::SetTimeouts(COMMTIMEOUTS& timeouts)
{
ASSERT(IsOpen());
if (!SetCommTimeouts(m_hComm, &timeouts))
{
TRACE(_T("Failed in call to SetCommTimeouts\n"));
AfxThrowSerialException();
}
}
void CSerialPort::GetTimeouts(COMMTIMEOUTS& timeouts)
{
ASSERT(IsOpen());
if (!GetCommTimeouts(m_hComm, &timeouts))
{
TRACE(_T("Failed in call to GetCommTimeouts\n"));
AfxThrowSerialException();
}
}
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()
{
// 仅适用于 PC 系列
COMMTIMEOUTS Timeouts;
GetTimeouts(Timeouts);
Timeouts.ReadIntervalTimeout = MAXDWORD;
Timeouts.ReadTotalTimeoutMultiplier = 0;
Timeouts.ReadTotalTimeoutConstant = 0;
SetTimeouts(Timeouts);
}
BOOL CSerialPort::WaitEvent(DWORD& dwMask)
{
ASSERT(IsOpen());
ASSERT(!m_bOverlapped);
if (!WaitCommEvent(m_hComm, &dwMask, NULL))
{
TRACE(_T("Failed in call to \"WaitCommEvent()\"!\n"));
// AfxThrowSerialException();
return FALSE;
}
else
return TRUE;
}
BOOL CSerialPort::WaitEvent(DWORD& dwMask, OVERLAPPED& overlapped)
{
ASSERT(IsOpen());
ASSERT(m_bOverlapped);
ASSERT(overlapped.hEvent);
BOOL bSuccess = WaitCommEvent(m_hComm, &dwMask, &overlapped);
if (!bSuccess)
{
if (GetLastError() != ERROR_IO_PENDING)
{
TRACE(_T("Failed in call to \"WaitCommEvent()\"\n"));
// AfxThrowSerialException();
}
}
return bSuccess;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -