- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试编写一个基于 MFC 对话框的应用程序,它从您的 PC 的串行 COMM 端口读取信息,然后将一些信息写回到串行 COMM 端口。关于我从哪里开始的任何想法?
提前致谢。
最佳答案
这有帮助吗? :-)
SerialPort.h
/* /////////////////// Macros / Structs etc ////////////////////////// */
#ifndef __SERIALPORT_H__
#define __SERIALPORT_H__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <vector>
/* ///////////////////////// Classes /////////////////////////////////////////// */
/* //// Serial port exception class //////////////////////////////////////////// */
void AfxThrowSerialException(DWORD dwError = 0);
class CSerialException : public CException
{
public:
/* Constructors / Destructors */
CSerialException (DWORD dwError);
~CSerialException ();
/* Methods */
#ifdef _DEBUG
virtual void Dump(CDumpContext & dc) const;
#endif
virtual BOOL GetErrorMessage(LPTSTR lpstrError, UINT nMaxError, PUINT pnHelpContext = NULL);
CString GetErrorMessage();
/* Data members */
DWORD m_dwError;
protected:
DECLARE_DYNAMIC(CSerialException)
};
/* // The actual serial port class ///////////////////////////////////////////// */
class CSerialPort : public CObject
{
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 ();
~CSerialPort ();
/* General Methods */
static std::vector<CString> EnumSerialPorts( void );
void Open(int nPort, DWORD dwBaud = 9600, Parity parity = NoParity, BYTE dataBits = 8,
StopBits stopBits = OneStopBit, FlowControl fc = NoFlowControl, BOOL bOverlapped = FALSE);
void Open(LPCTSTR szPort, 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 CSerialPort::Dump(CDumpContext & dc) const;
#endif
/* Reading / Writing Methods */
DWORD Read(void *lpBuf, DWORD dwCount);
BOOL Read(void *lpBuf, DWORD dwCount, OVERLAPPED &overlapped);
void ReadEx(void *lpBuf, DWORD dwCount);
DWORD Write(const void *lpBuf, DWORD dwCount);
BOOL Write(const void *lpBuf, DWORD dwCount, OVERLAPPED &overlapped);
void WriteEx(const void *lpBuf, DWORD dwCount);
void TransmitChar(char cChar);
void GetOverlappedResult(OVERLAPPED & overlapped,
DWORD & dwBytesTransferred,
BOOL bWait);
void CancelIo();
/* 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, BOOL bClosePortOnErr = FALSE);
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(const 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);
void 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);
protected:
HANDLE m_hComm; /* Handle to the comms port */
BOOL m_bOverlapped; /* Is the port open in overlapped IO */
static void WINAPI _OnCompletion(DWORD dwErrorCode, DWORD dwCount, LPOVERLAPPED lpOverlapped);
DECLARE_DYNAMIC(CSerialPort)
private:
void OpenComm(LPCTSTR szPort, DWORD dwBaud = 9600, Parity parity = NoParity, BYTE dataBits = 8,
StopBits stopBits = OneStopBit, FlowControl fc = NoFlowControl, BOOL bOverlapped = FALSE);
};
#endif /* __SERIALPORT_H__ */
SerialPort.cpp
/* /////////////////////////////// Includes ////////////////////////////////// */
#include "stdafx.h"
#include <winspool.h>
#include "serialport.h"
#include "winerror.h"
/* /////////////////////////////// defines ///////////////////////////////////// */
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/* ////////////////////////////// Implementation /////////////////////////////// */
/* Class which handles CancelIo function which must be constructed at run time
* since it is not imeplemented on NT 3.51 or Windows 95. To avoid the loader
* bringing up a message such as "Failed to load due to missing export...", the
* function is constructed using GetProcAddress. The CSerialPort::CancelIo
* function then checks to see if the function pointer is NULL and if it is it
* throws an exception using the error code ERROR_CALL_NOT_IMPLEMENTED which
* is what 95 would have done if it had implemented a stub for it in the first
* place !!
*/
class _SERIAL_PORT_DATA
{
public:
/* Constructors /Destructors */
_SERIAL_PORT_DATA ();
~_SERIAL_PORT_DATA ();
HINSTANCE m_hKernel32;
typedef BOOL ( CANCELIO )( HANDLE );
typedef CANCELIO *LPCANCELIO;
LPCANCELIO m_lpfnCancelIo;
};
_SERIAL_PORT_DATA::_SERIAL_PORT_DATA ()
{
m_hKernel32 = LoadLibrary( _T("KERNEL32.DLL") );
VERIFY(m_hKernel32 != NULL);
m_lpfnCancelIo = (LPCANCELIO)GetProcAddress(m_hKernel32, "CancelIo");
}
_SERIAL_PORT_DATA::~_SERIAL_PORT_DATA ()
{
FreeLibrary(m_hKernel32);
m_hKernel32 = NULL;
}
/* The local variable which handle the function pointers */
_SERIAL_PORT_DATA _SerialPortData;
/* //////// Exception handling code */
void AfxThrowSerialException(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 );
}
BOOL CSerialException::GetErrorMessage(LPTSTR pstrError, UINT nMaxError, PUINT pnHelpContext)
{
ASSERT( pstrError != NULL && AfxIsValidString(pstrError, nMaxError) );
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),
(LPTSTR)&lpBuffer, 0, NULL);
if(bRet == FALSE) {
*pstrError = '\0';
} else {
lstrcpyn(pstrError, lpBuffer, nMaxError);
bRet = TRUE;
LocalFree(lpBuffer);
}
return bRet;
} /* GetErrorMessage */
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;
}
CSerialException::~CSerialException ()
{}
IMPLEMENT_DYNAMIC(CSerialException, CException)
#ifdef _DEBUG
void CSerialException::Dump(CDumpContext & dc) const
{
CObject::Dump(dc);
dc << "m_dwError = " << m_dwError;
}
#endif
/* //////// The actual serial port code */
CSerialPort::CSerialPort ()
{
m_hComm = INVALID_HANDLE_VALUE;
m_bOverlapped = FALSE;
}
CSerialPort::~CSerialPort ()
{
Close();
}
IMPLEMENT_DYNAMIC(CSerialPort, CObject)
#ifdef _DEBUG
void CSerialPort::Dump(CDumpContext & dc) const
{
CObject::Dump(dc);
dc << _T("m_hComm = ") << m_hComm << _T("\n");
dc << _T("m_bOverlapped = ") << m_bOverlapped;
}
#endif
std::vector<CString> CSerialPort::EnumSerialPorts(void)
{
/* Clear existing list of COMM ports */
std::vector<CString> commPortList;
/* COM ports can be numbered from 1 to 255, loop through all possibilities and add the ones we
* find.
*/
for( UINT i = 1; i < 256; i++ ) {
//Form the Raw device name
CString sPort;
sPort.Format( _T("COM%d"), i );
COMMCONFIG cc;
DWORD dwSize = sizeof(cc);
if( GetDefaultCommConfig(sPort, &cc, &dwSize) != 0 ) {
commPortList.push_back( (LPCTSTR)sPort );
}
}
return commPortList;
}
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);
/* Call CreateFile to open up the comms port */
CString sPort;
sPort.Format(_T("\\\\.\\COM%d"), nPort);
OpenComm(sPort, dwBaud, parity, dataBits, stopBits, fc, bOverlapped);
}
void CSerialPort::Open(LPCTSTR szPort, DWORD dwBaud, Parity parity, BYTE dataBits, StopBits stopBits,
FlowControl fc, BOOL bOverlapped)
{
OpenComm(szPort, dwBaud, parity, dataBits, stopBits, fc, bOverlapped);
}
void CSerialPort::OpenComm(LPCTSTR szPort, DWORD dwBaud, Parity parity, BYTE dataBits, StopBits stopbits,
FlowControl fc, BOOL bOverlapped)
{
m_hComm = CreateFile(szPort, (GENERIC_READ | GENERIC_WRITE), 0, NULL, OPEN_EXISTING,
bOverlapped ? FILE_FLAG_OVERLAPPED : 0, NULL);
if(m_hComm == INVALID_HANDLE_VALUE) {
TRACE( _T("Failed to open up the comms port\n") );
AfxThrowSerialException();
}
m_bOverlapped = bOverlapped;
/* Get the current state prior to changing it */
DCB 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);
} /* Open */
void CSerialPort::Close()
{
if( IsOpen() ) {
BOOL bSuccess = CloseHandle(m_hComm);
m_hComm = INVALID_HANDLE_VALUE;
if(!bSuccess) {
TRACE( _T("Failed to close up the comms port, GetLastError:%d\n"), GetLastError() );
}
m_bOverlapped = FALSE;
}
}
void CSerialPort::Attach(HANDLE hComm)
{
Close();
m_hComm = hComm;
}
HANDLE CSerialPort::Detach()
{
HANDLE hrVal = m_hComm;
m_hComm = INVALID_HANDLE_VALUE;
return hrVal;
}
DWORD CSerialPort::Read(void *lpBuf, DWORD dwCount)
{
ASSERT( IsOpen() );
ASSERT(!m_bOverlapped);
DWORD dwBytesRead = 0;
if( !ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, NULL) ) {
TRACE( _T("Failed in call to ReadFile\n") );
AfxThrowSerialException();
}
return dwBytesRead;
}
BOOL CSerialPort::Read(void *lpBuf, DWORD dwCount, OVERLAPPED & overlapped)
{
ASSERT( IsOpen() );
ASSERT(m_bOverlapped);
ASSERT(overlapped.hEvent);
DWORD dwBytesRead = 0;
BOOL bSuccess = ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, &overlapped);
if(!bSuccess) {
if(GetLastError() != ERROR_IO_PENDING) {
TRACE( _T("Failed in call to ReadFile\n") );
AfxThrowSerialException();
}
}
return bSuccess;
}
DWORD CSerialPort::Write(const void *lpBuf, DWORD dwCount)
{
ASSERT( IsOpen() );
ASSERT(!m_bOverlapped);
DWORD dwBytesWritten = 0;
if( !WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, NULL) ) {
TRACE( _T("Failed in call to WriteFile\n") );
AfxThrowSerialException();
}
return dwBytesWritten;
}
BOOL CSerialPort::Write(const void *lpBuf, DWORD dwCount, OVERLAPPED & overlapped)
{
ASSERT( IsOpen() );
ASSERT(m_bOverlapped);
ASSERT(overlapped.hEvent);
DWORD dwBytesWritten = 0;
BOOL bSuccess = WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, &overlapped);
if(!bSuccess) {
if(GetLastError() != ERROR_IO_PENDING) {
TRACE( _T("Failed in call to WriteFile\n") );
AfxThrowSerialException();
}
}
return bSuccess;
}
void CSerialPort::GetOverlappedResult(OVERLAPPED & overlapped,
DWORD & dwBytesTransferred,
BOOL bWait)
{
ASSERT( IsOpen() );
ASSERT(m_bOverlapped);
ASSERT(overlapped.hEvent);
//DWORD dwBytesWritten = 0;
if( !::GetOverlappedResult(m_hComm, &overlapped, &dwBytesTransferred, bWait) ) {
if(GetLastError() != ERROR_IO_PENDING) {
TRACE( _T("Failed in call to GetOverlappedResult\n") );
AfxThrowSerialException();
}
}
}
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->IsKindOf( RUNTIME_CLASS(CSerialPort) ) );
/* Call the C++ function */
pSerialPort->OnCompletion(dwErrorCode, dwCount, lpOverlapped);
}
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. You need to be running at least NT 4 or Win 98 to use this function\n") );
AfxThrowSerialException(ERROR_CALL_NOT_IMPLEMENTED);
}
if( !::_SerialPortData.m_lpfnCancelIo(m_hComm) ) {
TRACE( _T("Failed in call to CancelIO\n") );
AfxThrowSerialException();
}
}
void CSerialPort::WriteEx(const void *lpBuf, DWORD dwCount)
{
ASSERT( IsOpen() );
OVERLAPPED *pOverlapped = new OVERLAPPED;
ZeroMemory( pOverlapped, sizeof(OVERLAPPED) );
pOverlapped->hEvent = (HANDLE) this;
if( !WriteFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion) ) {
delete pOverlapped;
TRACE( _T("Failed in call to WriteFileEx\n") );
AfxThrowSerialException();
}
}
void CSerialPort::ReadEx(void *lpBuf, DWORD dwCount)
{
ASSERT( IsOpen() );
OVERLAPPED *pOverlapped = new OVERLAPPED;
ZeroMemory( pOverlapped, sizeof(OVERLAPPED) );
pOverlapped->hEvent = (HANDLE) this;
if( !ReadFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion) ) {
delete pOverlapped;
TRACE( _T("Failed in call to ReadFileEx\n") );
AfxThrowSerialException();
}
}
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)
{
ASSERT( IsOpen() );
DWORD dwSize = sizeof(COMMCONFIG);
if( !GetCommConfig(m_hComm, &config, &dwSize) ) {
TRACE( _T("Failed in call to GetCommConfig\n") );
AfxThrowSerialException();
}
}
void CSerialPort::SetConfig(COMMCONFIG & config)
{
ASSERT( IsOpen() );
DWORD dwSize = sizeof(COMMCONFIG);
if( !SetCommConfig(m_hComm, &config, dwSize) ) {
TRACE( _T("Failed in call to SetCommConfig\n") );
AfxThrowSerialException();
}
}
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)
{
/* 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("Failed in call to GetDefaultCommConfig\n") );
AfxThrowSerialException();
}
}
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("Failed in call to GetDefaultCommConfig\n") );
AfxThrowSerialException();
}
}
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, BOOL bClosePortOnErr)
{
ASSERT( IsOpen() );
if( !SetCommState(m_hComm, &dcb) ) {
if( bClosePortOnErr == TRUE ) {
Close();
}
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(const COMMTIMEOUTS& timeouts)
{
ASSERT( IsOpen() );
if( !SetCommTimeouts(m_hComm, (LPCOMMTIMEOUTS)&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;
Timeouts.ReadTotalTimeoutMultiplier = 0;
Timeouts.ReadTotalTimeoutConstant = 0;
Timeouts.WriteTotalTimeoutMultiplier = 0;
Timeouts.WriteTotalTimeoutConstant = 0;
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() );
ASSERT(!m_bOverlapped);
if( !WaitCommEvent(m_hComm, &dwMask, NULL) ) {
TRACE( _T("Failed in call to WaitCommEvent\n") );
AfxThrowSerialException();
}
}
void CSerialPort::WaitEvent(DWORD & dwMask, OVERLAPPED & overlapped)
{
ASSERT( IsOpen() );
ASSERT(m_bOverlapped);
ASSERT(overlapped.hEvent);
if( !WaitCommEvent(m_hComm, &dwMask, &overlapped) ) {
if(GetLastError() != ERROR_IO_PENDING) {
TRACE( _T("Failed in call to WaitCommEvent\n") );
AfxThrowSerialException();
}
}
}
关于c++ - 从串口mfc读取信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7095569/
我有一个 MFC 项目,它链接到第三方 dll。在程序退出时,IDE 会报告“检测到内存泄漏!”并倾倒泄漏物。 这些泄漏来自第三方 dll。我很确定这些是错误的报道。 (Google 的快速检查表明
首先我想要的是:能够显示具有多列的网格,每个单元格都有一个自定义渲染回调。因此,您可以使用这样的控件在游戏中显示您的库存,或者类似于 Google Chrome 中的行为,它会显示您访问的热门页面的网
在新的 MFC 功能(功能包)中,菜单出现在三个地方: 在菜单栏中 (CMFCMenuBar) 在弹出菜单中 (CMFCPopupMenu) 在 CMFCButton 的“下拉菜单”版本中 我想在所有
在我的 MFC 项目中,我想动态生成标签。例如:我必须为它们生成 4 个编辑控件和相应的标签——比如“Label1”“Label2”...... CStatic *label[MAX_THREAD];
我有第一个对话框,上面有一个简单的按钮,单击该按钮时,使用 CDialog::Create(IDD,this) 创建了第二个对话框。我希望在销毁第二个对话框但不向第二个对话框添加任何代码时通知父级,即
我们的代码库中的添加到剪贴板代码非常低级 - 分配全局内存等等。对于简单的情况,我只想将一些纯文本放在剪贴板上,是否有任何例程可以包装所有这些内容? 一个例子是 CRichEditCtrl 具有 Co
我对 mfc 中事件和消息之间的区别有点困惑。 他们是一样的吗? 最佳答案 由于您专门询问 MFC,我假设您指的是可以在 MFC 类的属性窗口中定义的事件处理程序和消息处理程序。 在“事件”下,您可以
如何以编程方式检测我的 MFC 应用程序当前是否正在显示模式对话框或属性表?目前我正在使用以下内容,但我觉得该代码也会触发无模式对话框。 bool HasModalDialog(const CWnd*
我有两个按钮: 单选按钮:“十六进制” 按钮:“A” 我想在用户选中“十六进制”按钮时启用“A”(“A”在创建时的状态为“禁用”),我该怎么做?谢谢大家。 最佳答案 您需要使用 CButton 's
通常情况下,窗口的厚度为 4 个像素,可以通过 GetSystemMetrics 方法获取。我可以更改它的值,例如 2 个像素吗? 非常感谢! 最佳答案 简单的回答:不。不适用于特定窗口。 复杂的答案
我需要打开一个从同一个类实例化的对话框两次。当我尝试这个时 CdelmeDlg dlg; dlg.DoModal(); dlg.DoModal(); 第二个调用只打开对话框一瞬间,然后关闭。我敢打赌消
如何通过代码在 mfc 中减少标题栏的窗口? 最佳答案 用: ModifyStyle (WS_CAPTION, 0); // to hide ModifyStyle (0, WS_CAPTION);
我使用 AfxMessageBox 关键字显示消息框。基本的东西。 但是,由于路径的长度,它显示如下: 有什么方法可以阻止它以这种方式自动换行吗? 抱歉,如果这是一个愚蠢的问题。但如果我只有一个句子,
所以,我有一个 MFC 程序的插件。我正在使用鼠标事件 Hook (来自 SetWindowsHookEx)来捕获点击。主机应用程序可以打开任意数量的(可能重叠的)子窗口,但我只想拦截特定子窗口中的点
我正在尝试将图像添加到现有按钮..我在一定程度上做到了这一点,问题是我可以添加一个所有者绘制的图像,但无法添加我想要的确切图像..示例见下文代码 CButton* pBtn= (CButton*)Ge
我想在对话框的标题栏上放置一些控件。一种可能的解决方案是,我只是从对话框中删除标题栏并绘制自己的标题栏。 但是如果我自己画标题栏,标题栏的外观不会根据窗口的主题而改变。而且我也不得不忍受接近、最小化和
我已经使用 MinGW 开发了 WinAPI 应用程序,没有问题。现在,我可以用 MFC 做同样的事情吗? 最佳答案 你不能。 MFC 代表 Microsoft Foundation Classes,
(我正在使用VS ++ 2005) 我在对话框上放置了编辑框控件(ID为ID_edit_box),并为其关联了两个变量(使用处理程序向导):控件(c_editbox)和值(v_editbox)变量。我
我有一个自定义 MFC 对话框 CMyDialog,使用资源编辑器添加了一个类型为 CMyControl 的自定义控件 - 该对话框有一个控件的成员变量并且有 DDX设置。 该控件正在接收绘制消息,并
直到现在,我从未真正需要我正在开发的大型 MFC(如果重要,则为单文档界面)应用程序的 Winapp ExitInstance()。但现在我这样做了,主要是为了清理内存分配、卸载一些 DLL 等。好吧
我是一名优秀的程序员,十分优秀!