Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
CSerialPort
===========
Windows串口通讯封装类,支持ANSI和Unicode编码

First Version by Remon Spekreijse on 2000-02-08
http://www.codeguru.com/cpp/i-n/network/serialcommunications/article.php/c2483/A-communication-class-for-serial-port.htm
Expand Down Expand Up @@ -39,4 +40,7 @@ http://blog.csdn.net/itas109/article/details/18358297


by liquanhai on 2014-12-18
* 增加一些处理措施,主要是对减少CPU占用率
* 增加一些处理措施,主要是对减少CPU占用率

by lvlinkeji on 2016-7-23
* 修正了部分BUG,支持ANSI和Unicode编码,使用了一些安全的函数,支持VS2015正常编译。
161 changes: 85 additions & 76 deletions SerialPort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ CSerialPort::~CSerialPort()
BOOL CSerialPort::InitPort(HWND pPortOwner, // the owner (CWnd) of the port (receives message)
UINT portnr, // portnumber (1..MaxSerialPortNum)
UINT baud, // baudrate
char parity, // parity
TCHAR parity, // parity
UINT databits, // databits
UINT stopbits, // stopbits
DWORD dwCommEvents, // EV_RXCHAR, EV_CTS etc
Expand Down Expand Up @@ -152,16 +152,16 @@ BOOL CSerialPort::InitPort(HWND pPortOwner, // the owner (CWnd) of the port (rec

if (m_szWriteBuffer != NULL)
delete [] m_szWriteBuffer;
m_szWriteBuffer = new char[writebuffersize];
m_szWriteBuffer = new BYTE[writebuffersize];

m_nPortNr = portnr;

m_nWriteBufferSize = writebuffersize;
m_dwCommEvents = dwCommEvents;

BOOL bResult = FALSE;
char *szPort = new char[50];
char *szBaud = new char[50];
TCHAR *szPort = new TCHAR[MAX_PATH];
TCHAR *szBaud = new TCHAR[MAX_PATH];


/*
Expand All @@ -182,7 +182,8 @@ BOOL CSerialPort::InitPort(HWND pPortOwner, // the owner (CWnd) of the port (rec
}

// prepare port strings
sprintf(szPort, "\\\\.\\COM%d", portnr);///������ʾCOM10���϶˿�//add by itas109 2014-01-09
//sprintf(szPort, "\\\\.\\COM%d", portnr);///������ʾCOM10���϶˿�//add by itas109 2014-01-09
_stprintf_s(szPort, MAX_PATH, _T("\\\\.\\COM%d"), portnr);

// stop is index 0 = 1 1=1.5 2=2
int mystop;
Expand All @@ -200,27 +201,27 @@ BOOL CSerialPort::InitPort(HWND pPortOwner, // the owner (CWnd) of the port (rec
break;
}
myparity = 0;
parity = toupper(parity);
//parity = _totupper(parity);
switch(parity)
{
case 'N':
case _T('N'):
myparity = 0;
break;
case 'O':
case _T('O'):
myparity = 1;
break;
case 'E':
case _T('E'):
myparity = 2;
break;
case 'M':
case _T('M'):
myparity = 3;
break;
case 'S':
case _T('S'):
myparity = 4;
break;
}
sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, mystop);

//sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, mystop);
_stprintf_s(szBaud, MAX_PATH,_T("baud=%d parity=%c data=%d stop=%d"), baud, parity, databits, mystop);
// get a handle to the port
/*
ͨ�ų�����CreateFile��ָ�������豸����صIJ������ԣ��ٷ���һ�������
Expand Down Expand Up @@ -281,29 +282,29 @@ BOOL CSerialPort::InitPort(HWND pPortOwner, // the owner (CWnd) of the port (rec
{
m_dcb.EvtChar = 'q';
m_dcb.fRtsControl = RTS_CONTROL_ENABLE; // set RTS bit high!
m_dcb.BaudRate = baud; // add by mrlong
m_dcb.Parity = myparity;
m_dcb.ByteSize = databits;
m_dcb.StopBits = mystop;
//m_dcb.BaudRate = baud; // add by mrlong
//m_dcb.Parity = myparity;
//m_dcb.ByteSize = databits;
//m_dcb.StopBits = mystop;

//if (BuildCommDCB(szBaud, &m_dcb))///��дDCB�ṹ
//{
if (BuildCommDCB(szBaud, &m_dcb))///��дDCB�ṹ
{
if (SetCommState(m_hComm, &m_dcb))///����DCB
; // normal operation... continue
else
ProcessErrorMessage("SetCommState()");
//}
//else
// ProcessErrorMessage("BuildCommDCB()");
ProcessErrorMessage(_T("SetCommState()"));
}
else
ProcessErrorMessage(_T("BuildCommDCB()"));
}
else
ProcessErrorMessage("GetCommState()");
ProcessErrorMessage(_T("GetCommState()"));
}
else
ProcessErrorMessage("SetCommMask()");
ProcessErrorMessage(_T("SetCommMask()"));
}
else
ProcessErrorMessage("SetCommTimeouts()");
ProcessErrorMessage(_T("SetCommTimeouts()"));

delete [] szPort;
delete [] szBaud;
Expand Down Expand Up @@ -402,7 +403,7 @@ DWORD WINAPI CSerialPort::CommThread(LPVOID pParam)
{
// All other error codes indicate a serious error has
// occured. Process this error.
port->ProcessErrorMessage("WaitCommEvent()");
port->ProcessErrorMessage(_T("WaitCommEvent()"));
break;
}
}
Expand Down Expand Up @@ -498,7 +499,7 @@ DWORD WINAPI CSerialPort::CommThread(LPVOID pParam)
}
default:
{
AfxMessageBox("����������!");
AfxMessageBox(_T("����������!"));
break;
}

Expand Down Expand Up @@ -552,9 +553,9 @@ BOOL CSerialPort::StopMonitoring()
// If there is a error, give the right message
///����д��󣬸�����ʾ
//
void CSerialPort::ProcessErrorMessage(char* ErrorText)
void CSerialPort::ProcessErrorMessage(TCHAR* ErrorText)
{
char *Temp = new char[200];
TCHAR Temp[200] = { 0 };

LPVOID lpMsgBuf;

Expand All @@ -568,11 +569,12 @@ void CSerialPort::ProcessErrorMessage(char* ErrorText)
NULL
);

sprintf(Temp, "WARNING: %s Failed with the following error: \n%s\nPort: %d\n", (char*)ErrorText, lpMsgBuf, m_nPortNr);
MessageBox(NULL, Temp, "Application Error", MB_ICONSTOP);
//sprintf(Temp, "WARNING: %s Failed with the following error: \n%s\nPort: %d\n", ErrorText, lpMsgBuf, m_nPortNr);
_stprintf_s(Temp, sizeof(Temp), _T("WARNING: %s Failed with the following error: \n%s\nPort: %d\n"), ErrorText,(TCHAR*) lpMsgBuf, m_nPortNr);
MessageBox(NULL, Temp, _T("Application Error"), MB_ICONSTOP);

LocalFree(lpMsgBuf);
delete[] Temp;
//delete[] Temp;
}

//
Expand All @@ -584,7 +586,11 @@ void CSerialPort::WriteChar(CSerialPort* port)
BOOL bResult = TRUE;

DWORD BytesSent = 0;
#pragma warning(push)
#pragma warning(disable:4267)
DWORD SendLen = port->m_nWriteSize;
#pragma warning(pop)

ResetEvent(port->m_hWriteEvent);


Expand Down Expand Up @@ -623,7 +629,7 @@ void CSerialPort::WriteChar(CSerialPort* port)
default:
{
// all other error codes
port->ProcessErrorMessage("WriteFile()");
port->ProcessErrorMessage(_T("WriteFile()"));
}
}
}
Expand All @@ -647,7 +653,7 @@ void CSerialPort::WriteChar(CSerialPort* port)
// deal with the error code
if (!bResult)
{
port->ProcessErrorMessage("GetOverlappedResults() in WriteFile()");
port->ProcessErrorMessage(_T("GetOverlappedResults() in WriteFile()"));
}
} // end if (!bWrite)

Expand Down Expand Up @@ -734,7 +740,7 @@ void CSerialPort::ReceiveChar(CSerialPort* port)
default:
{
// Another error has occured. Process this error.
port->ProcessErrorMessage("ReadFile()");
port->ProcessErrorMessage(_T("ReadFile()"));
break;
//return;///��ֹ��д����ʱ�����ڷ������Ͽ�������ѭ��һֱִ�С�add by itas109 2014-01-09 ������liquanhai���ӷ������Ĵ�����
}
Expand All @@ -759,7 +765,7 @@ void CSerialPort::ReceiveChar(CSerialPort* port)
// deal with the error code
if (!bResult)
{
port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
port->ProcessErrorMessage(_T("GetOverlappedResults() in ReadFile()"));
}
} // close if (!bRead)

Expand All @@ -774,16 +780,16 @@ void CSerialPort::ReceiveChar(CSerialPort* port)
//
// Write a string to the port
//
void CSerialPort::WriteToPort(char* string)
{
assert(m_hComm != 0);

memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
strcpy(m_szWriteBuffer, string);
m_nWriteSize=strlen(string); // add by mrlong
// set event for write
SetEvent(m_hWriteEvent);
}
//void CSerialPort::WriteToPort(char* string)
//{
// assert(m_hComm != 0);
//
// memset(m_szWriteBuffer, 0, m_nWriteBufferSize);
// strcpy_s((char*)m_szWriteBuffer, m_nWriteBufferSize,string);
// m_nWriteSize=strlen(string); // add by mrlong
// // set event for write
// SetEvent(m_hWriteEvent);
//}

//
// Return the device control block
Expand Down Expand Up @@ -852,54 +858,60 @@ void CSerialPort::ClosePort()

}

void CSerialPort::WriteToPort(char* string,int n)
void CSerialPort::WriteToPort(char* string,size_t nBytesOfTheBuffer)
{
assert(m_hComm != 0);
memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
memcpy(m_szWriteBuffer, string, n);
m_nWriteSize = n;
memset(m_szWriteBuffer, 0, m_nWriteBufferSize);
//memcpy(m_szWriteBuffer, string, n);
StringCbCopyA((char*)m_szWriteBuffer, m_nWriteBufferSize, string);

// set event for write
SetEvent(m_hWriteEvent);
}
m_nWriteSize = nBytesOfTheBuffer;

void CSerialPort::WriteToPort(LPCTSTR string)
{
assert(m_hComm != 0);
memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
strcpy(m_szWriteBuffer, string);
m_nWriteSize=strlen(string);
// set event for write
SetEvent(m_hWriteEvent);
}

void CSerialPort::WriteToPort(BYTE* Buffer, int n)
//void CSerialPort::WriteToPort(char* string)
//{
// assert(m_hComm != 0);
// memset(m_szWriteBuffer, 0, m_nWriteBufferSize);
// strcpy_s((char*)m_szWriteBuffer, m_nWriteBufferSize, string);
// m_nWriteSize=strlen(string);
// // set event for write
// SetEvent(m_hWriteEvent);
//}

void CSerialPort::WriteToPort(PBYTE Buffer, size_t n)
{
assert(m_hComm != 0);
memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
int i;
for(i=0; i<n; i++)
{
m_szWriteBuffer[i] = Buffer[i];
}
memset(m_szWriteBuffer, 0, m_nWriteBufferSize);
memcpy(m_szWriteBuffer, Buffer, n);

//int i;
//for(i=0; i<n; i++)
//{
// m_szWriteBuffer[i] = Buffer[i];
//}
m_nWriteSize=n;

// set event for write
SetEvent(m_hWriteEvent);
}


void CSerialPort::SendData(LPCTSTR lpszData, const int nLength)
void CSerialPort::SendData(const PBYTE lpszData, DWORD nLength)
{
assert(m_hComm != 0);
memset(m_szWriteBuffer, 0, nLength);
strcpy(m_szWriteBuffer, lpszData);
memset(m_szWriteBuffer, 0, m_nWriteBufferSize);
//strcpy_s((char*)m_szWriteBuffer, m_nWriteBufferSize,lpszData);
memcpy(m_szWriteBuffer, lpszData, nLength);

m_nWriteSize=nLength;
// set event for write
SetEvent(m_hWriteEvent);
}

BOOL CSerialPort::RecvData(LPTSTR lpszData, const int nSize)
BOOL CSerialPort::RecvData(PBYTE lpszData, DWORD nSize)
{
//
//��������
Expand All @@ -912,10 +924,7 @@ BOOL CSerialPort::RecvData(LPTSTR lpszData, const int nSize)
if(!ReadFile(m_hComm,lpszData,nSize,&mylen2,NULL))
return FALSE;
mylen += mylen2;


}

return TRUE;
}
//
Expand Down Expand Up @@ -967,7 +976,7 @@ void CSerialPort::QueryKey(HKEY hKey)
// Enumerate the key values.
if (cValues > 0) {
for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++) {
cchValue = MAX_VALUE_NAME; achValue[0] = '\0';
cchValue = MAX_VALUE_NAME; achValue[0] = _T('\0');
if (ERROR_SUCCESS == RegEnumValue(hKey, i, achValue, &cchValue, NULL, NULL, NULL, NULL)) {
CString szName(achValue);
if (-1 != szName.Find(_T("Serial")) || -1 != szName.Find(_T("VCom")) ){
Expand All @@ -977,7 +986,7 @@ void CSerialPort::QueryKey(HKEY hKey)
int nIndex = -1;
while(++nIndex < MaxSerialPortNum){
if (-1 == m_nComArray[nIndex]) {
m_nComArray[nIndex] = atoi((char*)(strDSName + 3));
m_nComArray[nIndex] = _wtoi((wchar_t*)(strDSName + 3));//������������⣬��ô��Ϊm_nComArray[nIndex] = _wtoi((wchar_t*)(strDSName + 3*sizeof(TCHAR)));
break;
}
}
Expand Down
Loading