Explorar o código

完成dll封装。

scbc.sat2 %!s(int64=5) %!d(string=hai) anos
pai
achega
92eaee2aa4

+ 992 - 0
TestWizard/TestWizard/SerialPort.cpp

@@ -0,0 +1,992 @@
+///////////////////////////////// Includes ////////////////////////////////////
+#include "stdafx.h"
+#include "serialport.h"
+#ifndef _WINERROR
+#pragma message("To avoid this message, please put WinError.h in your pre compiled header")
+#include <WinError.h>
+#endif
+
+///////////////////////////////// Defines /////////////////////////////////////
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+//////////////////////////////// Implementation ///////////////////////////////
+CSerialException::CSerialException(DWORD dwError) : m_dwError(dwError)
+{
+}
+
+BOOL CSerialException::GetErrorMessage(LPTSTR lpszError, UINT nMaxError, PUINT pnHelpContext /* = 0 */)
+{
+	// Validate our parameters
+	ASSERT(lpszError != NULL && AfxIsValidString(lpszError, nMaxError));
+	
+	if(pnHelpContext != NULL)
+		*pnHelpContext = 0;
+
+	// What will be the return value from this function(assume the worst)
+	BOOL bSuccess = FALSE;
+	
+	LPTSTR lpBuffer;
+	DWORD dwReturn = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+									NULL, 
+									m_dwError, 
+									MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
+									reinterpret_cast<LPTSTR>(&lpBuffer), 
+									0, 
+									NULL
+									);
+	if(dwReturn == 0)
+	{
+		*lpszError = _T('\0');
+	}
+	else
+	{
+		bSuccess = TRUE;
+		Checked::tcsncpy_s(lpszError, nMaxError, lpBuffer, _TRUNCATE);
+		LocalFree(lpBuffer);
+	}
+	
+	return bSuccess;
+}
+
+CString CSerialException::GetErrorMessage()
+{
+	CString strVal;
+	LPTSTR pstrError = strVal.GetBuffer(ERR_BUFFER);
+
+	GetErrorMessage(pstrError, ERR_BUFFER, NULL);
+	strVal.ReleaseBuffer();
+
+	return strVal;
+}
+
+IMPLEMENT_DYNAMIC(CSerialException, CException)
+
+#ifdef _DEBUG
+void CSerialException::Dump(CDumpContext &dc) const
+{
+	CObject::Dump(dc);
+	dc << _T("m_dwError = ") << m_dwError << _T("\n");
+}
+#endif
+
+CSerialPort::CSerialPort() : m_hComm(INVALID_HANDLE_VALUE), m_hEvent(NULL)
+{
+	m_hKernel32 = GetModuleHandle(_T("KERNEL32.DLL"));
+	if(m_hKernel32)
+		m_lpfnCancelIO = reinterpret_cast<LPCANCELIO>(GetProcAddress(m_hKernel32, "CancelIo"));
+	else
+		m_lpfnCancelIO = NULL;
+}
+
+CSerialPort::~CSerialPort()
+{
+	Close();
+}
+
+void CSerialPort::ThrowSerialException(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);
+}
+
+#ifdef _DEBUG
+void CSerialPort::Dump(CDumpContext &dc) const
+{
+	dc << _T("m_hComm = ") << m_hComm << _T("\n");
+}
+#endif
+
+void CSerialPort::Open(LPCTSTR pszPort,					/* COM1   */
+					   DWORD dwBaud						/* = 9600 */, 
+					   Parity parity		/* = NoParity */, 
+					   BYTE dataBits					/* = 8 */, 
+					   StopBits stopBits	/* = OneStopBit */, 
+					   FlowControl flowCtl	/* = NoFlowControl */, 
+					   BOOL bOverlapped					/* = 0 */)
+{
+	Close();	// In case we are already open
+	// Call CreateFile to open the comms port
+	TCHAR szPort[16] = {0};
+	_stprintf_s(szPort, _T("\\\\.\\%s"), pszPort);
+	m_hComm = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, bOverlapped ? FILE_FLAG_OVERLAPPED : 0, NULL);
+	if(m_hComm == INVALID_HANDLE_VALUE)
+	{
+		DWORD dwLastError = GetLastError();
+		//LOG4C((LOG_WARN,"%s打开失败,GetLastError=%ld", szPort, dwLastError));
+		//Global::WriteReportLog(1, "Serial port error", "Open Serial Port Fail, GetLastError=%ld !", dwLastError);
+		return;
+	}
+
+	// Create the event we need for later synchronisation use
+	m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+	if(m_hEvent == NULL)
+	{
+		DWORD dwLastError = GetLastError();		
+		//LOG4C((LOG_WARN,"CreateEvent失败,GetLastError=%ld", szPort, dwLastError));
+		//Global::WriteReportLog(1, "Serial port error", "CreateEvent Fail, GetLastError=%ld !", dwLastError);
+		Close();
+		return;
+	}
+
+	if ( !SetupComm(m_hComm,10240,2048) )
+	{
+		DWORD dwLastError = GetLastError();
+		CloseHandle(m_hComm);
+		CloseHandle(m_hEvent);
+//		Global::WriteReportLog(1, "Serial port error", "SetupComm Fail, GetLastError=%ld !", dwLastError);
+		Close();
+		return ;
+	}
+	// Get the current state prior to changing it
+	DCB dcb;
+	dcb.DCBlength = sizeof(DCB);
+	GetState(dcb);
+
+	// Setup the baud rate
+	dcb.BaudRate = dwBaud;
+
+	// Setup the Parity
+	switch(parity)
+	{
+	case NoParity:
+		dcb.Parity = NOPARITY;
+		break;
+	case OddParity:
+		dcb.Parity = ODDPARITY;
+		break;
+	case EvenParity:
+		dcb.Parity = EVENPARITY;
+		break;
+	case MarkParity:
+		dcb.Parity = MARKPARITY;
+		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(flowCtl)
+	{
+	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.fDtrControl = DTR_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);
+}
+
+void CSerialPort::Open(int nPort, 
+					   DWORD dwBaud						/* = 9600 */, 
+					   Parity parity		/* = NoParity */, 
+					   BYTE dataBits					/* = 8 */, 
+					   StopBits stopBits	/* = OneStopBit */, 
+					   FlowControl flowCtl	/* = NoFlowControl */, 
+					   BOOL bOverlapped					/* = 0 */)
+{
+	//Form the string version of the port number
+	CString strPort;
+	strPort.Format(_T("\\\\.\\COM%d"), nPort);
+
+	//Then delegate the work to the other version of Open
+	Open(strPort, dwBaud, parity, dataBits, stopBits, flowCtl, bOverlapped);
+}
+
+void CSerialPort::Close()
+{
+	if(IsOpen())
+	{
+		// Close down the comms port
+		BOOL bSuccess = CloseHandle(m_hComm);
+		m_hComm = INVALID_HANDLE_VALUE;
+		if(!bSuccess)
+			TRACE(_T("CSerialPort::Close, Failed to close up the comms port, Error:%d\n"), GetLastError());
+//			LOG4C((LOG_WARN,"关闭串口失败,GetLastError=%ld", GetLastError()));
+
+		// Free the event object we are using
+		if(m_hEvent)
+		{
+			CloseHandle(m_hEvent);
+			m_hEvent = NULL;
+		}
+	}
+}
+
+void CSerialPort::Attach(HANDLE hComm)
+{
+	Close();
+
+	//Validate our parameters, now that the port has been closed
+	ASSERT(m_hComm == INVALID_HANDLE_VALUE);
+	ASSERT(m_hEvent == NULL);
+
+	m_hComm = hComm;
+
+	//Create the event we need for later synchronisation use
+	m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+	if (m_hEvent == NULL)
+	{
+		DWORD dwLastError = GetLastError();
+		Close();
+		//TRACE(_T("CSerialPort::Attach, Failed in call to CreateEvent in Attach, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"CreateEvent失败,GetLastError=%ld", GetLastError()));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+HANDLE CSerialPort::Detach()
+{
+	// What will be the return value from this function
+	HANDLE hVal = m_hComm;
+
+	m_hComm = INVALID_HANDLE_VALUE;
+
+	if(m_hEvent)
+	{
+		CloseHandle(m_hEvent);
+		m_hEvent = NULL;
+	}
+	
+	return hVal;
+}
+
+DWORD CSerialPort::Read(void *lpBuf, DWORD dwCount)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	if (lpBuf == NULL || !::AfxIsValidAddress(lpBuf, dwCount, FALSE))
+	{
+//		LOG4C((LOG_WARN, "Read的缓存地址无效!"))
+		return 0;
+	}
+
+	DWORD dwErrorFlags = 0;
+	COMSTAT ComStat;
+	ClearCommError(m_hComm, &dwErrorFlags, &ComStat);
+
+#if 1
+	// 使用ClearCommError来读取缓存区接受到的字节时, 
+	// 可能受系统线程调试或硬件延时, cbInQue为空, 
+	// 这里要用while延时获取;
+	DWORD dwTick = GetTickCount();
+	DWORD dwLastLen = 0;
+	//while (ComStat.cbInQue == 0)
+	while(1)
+	{// cbInQue表示输入缓冲区的字节数; 
+		Sleep(150);
+		if (GetTickCount() - dwTick > 5000)
+			break;
+		ClearCommError(m_hComm, &dwErrorFlags, &ComStat);
+		if ( ComStat.cbInQue != 0 && dwLastLen == ComStat.cbInQue )
+			break;
+		dwLastLen = ComStat.cbInQue;
+	}
+
+	if (ComStat.cbInQue == 0)
+	{
+		// 串口无数据返回;
+//		LOG4C((LOG_ERROR, "1.5秒超时已过,读串口失败,缓存区无数据"));
+		return 0;
+	}
+#endif
+
+	DWORD dwBytesRead = 0;
+	if(!ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, NULL))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Read, Failed in call to ReadFile, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"ReadFile失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+
+	return dwBytesRead;
+}
+
+void CSerialPort::Read(void *lpBuf, DWORD dwCount, OVERLAPPED &overlapped, DWORD *pBytesRead /* = 0 */)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	DWORD dwBytesRead = 0;
+	BOOL bSuccess = ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, &overlapped);
+	if(!bSuccess)
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Read, Failed in call to ReadFile, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"ReadFile失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+	else
+	{
+		if(pBytesRead)
+			*pBytesRead = dwBytesRead;
+	}
+}
+
+DWORD CSerialPort::Write(const void *lpBuf, DWORD dwCount)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	DWORD dwBytesWritten = 0;
+	// 写前,清空缓存区;
+	PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
+	if(!WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, NULL))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Write, Failed in call to WriteFile, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"WriteFile失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+
+	return dwBytesWritten;
+}
+
+void CSerialPort::Write(const void *lpBuf, DWORD dwCount, OVERLAPPED &overlapped, DWORD *pBytesWritten /* = 0 */)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	DWORD dwBytesWritten = 0;
+	// 写前,清空缓存区;
+	PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
+	BOOL bSuccess = WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, &overlapped);
+	if(!bSuccess)
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Write, Failed in call to WriteFile, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"WriteFile失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+	else
+	{
+		if(pBytesWritten)
+			*pBytesWritten = dwBytesWritten;
+	}
+}
+
+void CSerialPort::GetOverlappedResult(OVERLAPPED &overlapped, DWORD &dwBytesTransferred, BOOL bWait)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	if(!::GetOverlappedResult(m_hComm, &overlapped, &dwBytesTransferred, bWait))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetOverlappedResult, Failed in call to GetOverlappedResult, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"GetOverlappedResult失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::_OnCompletion(DWORD dwErrorCode, DWORD dwCount, LPOVERLAPPED lpOverlapped)
+{
+	// Validate our parameters
+	AFXASSUME(lpOverlapped);
+
+	// Convert back to the C++ world
+	CSerialPort* pSerialPort = static_cast<CSerialPort*>(lpOverlapped->hEvent);
+	AFXASSUME(pSerialPort);
+
+	// Call the C++ function
+	pSerialPort->OnCompletion(dwErrorCode, dwCount, lpOverlapped);
+}
+
+void CSerialPort::OnCompletion(DWORD /* dwErrorCode */, DWORD /* dwCount */, LPOVERLAPPED lpOverlapped)
+{
+	// Just free 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
+}
+
+void CSerialPort::CancelIO()
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	if(m_lpfnCancelIO == NULL)
+	{
+		//TRACE(_T("CSerialPort::CancelIO, 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"));
+//		LOG4C((LOG_WARN,"CancelIO失败,m_lpfnCancelIO函数指针空"));
+		//ThrowSerialException(ERROR_CALL_NOT_IMPLEMENTED);
+	}
+
+	if(!m_lpfnCancelIO(m_hComm))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("Failed in call to CancelIO, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"CancelIO失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+DWORD CSerialPort::BytesWaiting()
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	// Check to see how many characters are unread
+	COMSTAT stat;
+	GetStatus(stat);
+	return stat.cbInQue;
+}
+
+BOOL CSerialPort::DataWaiting(DWORD dwTimeout)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	// Setup to wait fo incoming data
+	DWORD dwOldMask;
+	GetMask(dwOldMask);
+	SetMask(EV_RXCHAR);
+
+	// Setup the overlapped structure
+	OVERLAPPED overlapped;
+	overlapped.hEvent = m_hEvent;
+
+	// Assume the worst
+	BOOL bSuccess = FALSE;
+
+	DWORD dwEvent;
+	bSuccess = WaitEvent(dwEvent, overlapped);
+	if(!bSuccess)
+	{
+		if(WaitForSingleObject(overlapped.hEvent, dwTimeout) == WAIT_OBJECT_0)
+		{
+			DWORD dwBytesTransferred;
+			GetOverlappedResult(overlapped, dwBytesTransferred, FALSE);
+			bSuccess = TRUE;
+		}
+	}
+
+	// Reset the event mask
+	SetMask(dwOldMask);
+
+	return bSuccess;
+}
+
+void CSerialPort::WriteEx(const void *lpBuf, DWORD dwCount)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	OVERLAPPED* pOverlapped = new OVERLAPPED;
+	memset(pOverlapped, 0, sizeof(OVERLAPPED));
+	pOverlapped->hEvent = static_cast<HANDLE>(this);
+	if(!WriteFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
+	{
+		DWORD dwLastError = GetLastError();
+		delete pOverlapped;
+		//TRACE(_T("CSerialPort::WriteEx, Failed in call to WriteFileEx, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"WriteEx失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::ReadEx(void *lpBuf, DWORD dwCount)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	OVERLAPPED* pOverlapped = new OVERLAPPED;
+	memset(pOverlapped, 0, sizeof(OVERLAPPED));
+	pOverlapped->hEvent = static_cast<HANDLE>(this);
+	if(!ReadFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
+	{
+		DWORD dwLastError = GetLastError();
+		delete pOverlapped;
+		//TRACE(_T("CSerialPort::ReadEx, Failed in call to ReadFileEx, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"ReadEx失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::TransmitChar(char cChar)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	if(!TransmitCommChar(m_hComm, cChar))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::TransmitChar, Failed in call to TransmitCommChar, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"TransmitCommChar失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::GetConfig(COMMCONFIG &config)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	DWORD dwSize = sizeof(COMMCONFIG);
+	if(!GetCommConfig(m_hComm, &config, &dwSize))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetConfig, Failed in call to GetCommConfig, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"GetCommConfig失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::SetConfig(COMMCONFIG &config)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	DWORD dwSize = sizeof(COMMCONFIG);
+	if(!SetCommConfig(m_hComm, &config, dwSize))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::SetConfig, Failed in call to SetCommConfig, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"SetCommConfig失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::SetBreak()
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	if(!SetCommBreak(m_hComm))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::SetBreak, Failed in call to SetCommBreak, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"SetCommBreak失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::ClearBreak()
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	if(!ClearCommBreak(m_hComm))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::ClearBreak, Failed in call to ClearCommBreak, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"ClearCommBreak失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::ClearError(DWORD &dwErrors)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	if(!ClearCommError(m_hComm, &dwErrors, NULL))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::ClearError, Failed in call to ClearCommError, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"ClearCommError失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::GetDefaultConfig(int nPort, COMMCONFIG &config)
+{
+	// Create the device name as a string
+	CString strPort;
+	strPort.Format(_T("COM%d"), nPort);
+
+	DWORD dwSize = sizeof(COMMCONFIG);
+	if(!GetDefaultCommConfig(strPort, &config, &dwSize))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetDefaultConfig, Failed in call to GetDefaultCommConfig, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"GetDefaultCommConfig失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::SetDefaultConfig(int nPort, COMMCONFIG &config)
+{
+	// Create the device name as a string
+	CString strPort;
+	strPort.Format(_T("COM%d"), nPort);
+
+	DWORD dwSize = sizeof(COMMCONFIG);
+	if(!SetDefaultCommConfig(strPort, &config, dwSize))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::SetDefaultConfig, Failed in call to SetDefaultCommConfig, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"SetDefaultConfig失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::GetStatus(COMSTAT &stat)
+{
+	// Validate our parameters
+	ASSERT(IsOpen());
+
+	DWORD dwErrors;
+	if (!ClearCommError(m_hComm, &dwErrors, &stat))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetStatus, Failed in call to ClearCommError, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"ClearCommError失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::GetState(DCB &dcb)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!GetCommState(m_hComm, &dcb))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetState, Failed in call to GetCommState, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"GetCommState失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::SetState(DCB &dcb)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!SetCommState(m_hComm, &dcb))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::SetState, Failed in call to SetCommState, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"SetState失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::Escape(DWORD dwFunc)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!EscapeCommFunction(m_hComm, dwFunc))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Escape, Failed in call to EscapeCommFunction, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"Escape失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+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)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!GetCommProperties(m_hComm, &properties))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetProperties, Failed in call to GetCommProperties, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"GetProperties失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::GetModemStatus(DWORD& dwModemStatus)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!GetCommModemStatus(m_hComm, &dwModemStatus))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetModemStatus, Failed in call to GetCommModemStatus, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"GetModemStatus失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::SetMask(DWORD dwMask)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!SetCommMask(m_hComm, dwMask))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::SetMask, Failed in call to SetCommMask, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"SetMask失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::GetMask(DWORD& dwMask)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!GetCommMask(m_hComm, &dwMask))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetMask, Failed in call to GetCommMask, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"GetMask失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::Flush()
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!FlushFileBuffers(m_hComm))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Flush, Failed in call to FlushFileBuffers, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"Flush失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::Purge(DWORD dwFlags)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!PurgeComm(m_hComm, dwFlags))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Purge, Failed in call to PurgeComm, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"Purge失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+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)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!SetupComm(m_hComm, dwInQueue, dwOutQueue))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::Setup, Failed in call to SetupComm, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"Setup失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::SetTimeouts(COMMTIMEOUTS& timeouts)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!SetCommTimeouts(m_hComm, &timeouts))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::SetTimeouts, Failed in call to SetCommTimeouts, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"SetTimeouts失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::GetTimeouts(COMMTIMEOUTS& timeouts)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!GetCommTimeouts(m_hComm, &timeouts))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::GetTimeouts, Failed in call to GetCommTimeouts, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"GetTimeouts失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+void CSerialPort::Set0Timeout()
+{
+	COMMTIMEOUTS Timeouts;
+	memset(&Timeouts, 0, sizeof(Timeouts));
+	Timeouts.ReadIntervalTimeout = MAXDWORD;
+	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)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+
+	if (!WaitCommEvent(m_hComm, &dwMask, NULL))
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::WaitEvent, Failed in call to WaitCommEvent, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"WaitEvent失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+}
+
+BOOL CSerialPort::WaitEvent(DWORD& dwMask, OVERLAPPED& overlapped)
+{
+	//Validate our parameters
+	ASSERT(IsOpen());
+	ASSERT(overlapped.hEvent);
+
+	BOOL bSuccess = WaitCommEvent(m_hComm, &dwMask, &overlapped);
+	if (!bSuccess)
+	{
+		DWORD dwLastError = GetLastError();
+		//TRACE(_T("CSerialPort::WaitEvent, Failed in call to WaitCommEvent, Error:%d\n"), dwLastError);
+//		LOG4C((LOG_WARN,"WaitEvent失败,GetLastError=%ld", dwLastError));
+		//ThrowSerialException(dwLastError);
+	}
+
+	return bSuccess;
+}

+ 168 - 0
TestWizard/TestWizard/SerialPort.h

@@ -0,0 +1,168 @@
+#ifndef __SERIAL_PORT_H__
+#define __SERIAL_PORT_H__
+
+//#include "stdafx.h"
+
+#ifndef CSERIALPORT_EXT_CLASS
+#define CSERIALPORT_EXT_CLASS
+#endif
+
+#define ERR_BUFFER	4096
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+	/////////////////////////////////////////// Classes ///////////////////////////////////////////
+	class CSERIALPORT_EXT_CLASS CSerialException : public CException
+	{
+	public:
+		// Constructors / Destructors
+		CSerialException(DWORD dwError);
+
+		// Methods
+#ifdef _DEBUG
+		virtual void Dump(CDumpContext& dc) const;
+#endif
+		virtual BOOL GetErrorMessage(__out_ecount_z(nMaxError) LPTSTR lpszError, __in UINT nMaxError, __out_opt PUINT pnHelpContext = NULL);
+		CString GetErrorMessage();
+
+		// Data members
+		DWORD m_dwError;
+
+	protected:
+		DECLARE_DYNAMIC(CSerialException)
+	};
+
+	class CSerialPort
+	{
+	public:
+		//Enums
+		enum FlowControl
+		{
+			NoFlowControl,
+			CtsRtsFlowControl,
+			CtsDtrFlowControl,
+			DsrRtsFlowControl,
+			DsrDtrFlowControl,
+			XonXoffFlowControl
+		};
+
+		enum Parity
+		{
+			NoParity = 0,
+			OddParity = 1,
+			EvenParity = 2,
+			MarkParity = 3,
+			SpaceParity = 4
+		};
+
+		enum StopBits
+		{
+			OneStopBit,
+			OnePointFiveStopBits,
+			TwoStopBits
+		};
+
+		//Constructors / Destructors
+		CSerialPort();
+		virtual ~CSerialPort();
+
+		//General Methods
+		void	Open(int nPort, DWORD dwBaud = 9600, Parity parity = NoParity, BYTE dataBits = 8,
+			StopBits stopBits = OneStopBit, FlowControl flowCtl = NoFlowControl, BOOL bOverlapped = FALSE);
+		void	Open(LPCTSTR pszPort, DWORD dwBaud = 9600, Parity parity = NoParity, BYTE dataBits = 8,
+			StopBits stopBits = OneStopBit, FlowControl flowCtl = 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 Dump(CDumpContext& dc) const;
+#endif
+
+		// Reading / Writting Methods
+		DWORD Read(void* lpBuf, DWORD dwCount);
+		void Read(void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped, DWORD* pBytesRead = NULL);
+		void ReadEx(void* lpBuf, DWORD dwCount);
+		DWORD Write(const void* lpBuf, DWORD dwCount);
+		void Write(const void* lpBuf, DWORD dwCount, OVERLAPPED& overlapped, DWORD* pBytesWritten = NULL);
+		void WriteEx(const void* lpBuf, DWORD dwCount);
+		void TransmitChar(char cChar);
+		void GetOverlappedResult(OVERLAPPED& overlapped, DWORD& dwBytesTransferred, BOOL bWait);
+		void CancelIO();
+		DWORD BytesWaiting();
+		BOOL DataWaiting(DWORD dwTimeout);
+
+		// 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);
+		void Escape(DWORD dwFunc);
+		void ClearDTR();
+		void ClearRTS();
+		void SetDTR();
+		void SetRTS();
+		void SetXOFF();
+		void SetXON();
+		void GetProperties(COMMPROP& porperties);
+		void GetModemStatus(DWORD& dwModemStatus);
+
+		// Timeouts
+		void SetTimeouts(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);
+		BOOL 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);
+
+		// Static methods
+		static void ThrowSerialException(DWORD dwError = 0);
+
+	protected:
+		// Typedefs
+		typedef BOOL(WINAPI CANCELIO)(HANDLE);
+		typedef CANCELIO* LPCANCELIO;
+
+		// Static methods
+		static void WINAPI _OnCompletion(DWORD dwErrorCode, DWORD dwCount, LPOVERLAPPED lpOverlapped);
+
+		// Member variables
+		HANDLE		m_hComm;		// Handle to the comms port
+		HANDLE		m_hEvent;		// A event handle we need for internal synchronisation
+		HINSTANCE	m_hKernel32;	// Kernel32 handle
+		LPCANCELIO	m_lpfnCancelIO;	// CancelIO function pointer
+	};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	// __SERIAL_PORT_H__

+ 83 - 2
TestWizard/TestWizard/TestWizard.cpp

@@ -4,6 +4,7 @@
 #include "stdafx.h"
 #include "TestWizard.h"
 #include "SynSerial.h"
+#include "SerialPort.h"
 #ifdef __MAKE_PYD__
 #include "Python.h"
 #endif
@@ -18,6 +19,7 @@ bool g_bEnableLoad = false;
 std::string g_strXMLPath;
 std::vector<KeyItem> g_vtKeyItem;
 CSynSerial g_synSerial;
+CSerialPort g_serialPort;
 
 // 唯一的应用程序对象
 #ifdef __CONSOLE__ 
@@ -42,9 +44,10 @@ int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 		// TODO: 在此处为应用程序的行为编写代码。
 		if ( OpenDevice(7, 115200, 8, 0, 0) )
 		{
-			while ( ReadKey() )
+			while ( 1 ){
+				ReadKey();
 				Sleep(100);
-			Sleep(10000000);
+			}
 
 			OpenXML("E:\\bin\\TestWizard\\data.xml");
 			
@@ -348,6 +351,7 @@ TESTWIZARD_API int Save2XML(LPCTSTR lpXMLPath)
 // 打开串口;
 TESTWIZARD_API BOOL OpenDevice(int nPort, DWORD dwBaudrate, BYTE ByteSize, BYTE Parity, BYTE StopBits)
 {
+#if 0
 	// 关闭打开的;
 	if ( g_synSerial.IsOpen() )
 		g_synSerial.CloseSerialPort();
@@ -355,17 +359,31 @@ TESTWIZARD_API BOOL OpenDevice(int nPort, DWORD dwBaudrate, BYTE ByteSize, BYTE
 	g_synSerial.OpenSerialPort(nPort, dwBaudrate, ByteSize, Parity, StopBits, 0, 1000);
 
 	return g_synSerial.IsOpen();
+#else
+	if ( g_serialPort.IsOpen())
+		g_serialPort.Close();
+
+	g_serialPort.Open(nPort, dwBaudrate, static_cast<CSerialPort::Parity>(Parity), ByteSize, static_cast<CSerialPort::StopBits>(StopBits));
+
+	return g_serialPort.IsOpen();
+#endif
 }
 
 // 关闭串口;
 TESTWIZARD_API void CloseDevice()
 {
+#if 0
 	if ( g_synSerial.IsOpen() )
 		g_synSerial.CloseSerialPort();
+#else
+	if ( g_serialPort.IsOpen() )
+		g_serialPort.Close();
+#endif
 }
 
 TESTWIZARD_API bool SendKey(LPCTSTR lpKeyName)
 {
+#if 0
 	if ( !g_synSerial.IsOpen() )
 		return false;
 
@@ -383,10 +401,33 @@ TESTWIZARD_API bool SendKey(LPCTSTR lpKeyName)
 
 	DWORD dwNumberOfBytesRead = g_synSerial.ReadComm(szSendData, MAX_PATH);
 	return dwNumberOfBytesRead ? true : false;
+#else
+	if ( !g_serialPort.IsOpen() )
+		return false;
+
+	KeyItem *pkeyItem = FindItem(lpKeyName);
+	if ( pkeyItem == NULL )
+		return false;
+
+	// 封装发送包;
+	byte szSendData[MAX_PATH] = {0};
+	_stprintf_s((TCHAR*)szSendData, MAX_PATH, _T("*INPUT %s %s\r"), pkeyItem->keyType.c_str(), pkeyItem->keyCode.c_str());
+
+	DWORD dwNumberOfBytesWritten = g_serialPort.Write(szSendData, _tcslen((TCHAR*)szSendData));
+	if ( dwNumberOfBytesWritten != _tcslen((TCHAR*)szSendData) )
+		return false;
+
+	DWORD dwNumberOfBytesRead = g_serialPort.Read(szSendData, MAX_PATH);
+	return dwNumberOfBytesRead ? true : false;
+#endif
 }
 
 TESTWIZARD_API bool ReadKey()
 {
+#if 1
+	if ( !g_synSerial.IsOpen() )
+		return false;
+
 	byte szKeyData[MAX_PATH] = {0};
 	DWORD dwNumberOfBytesRead = g_synSerial.ReadComm(szKeyData, MAX_PATH, 300);
 	if ( dwNumberOfBytesRead <= 0 )
@@ -418,6 +459,46 @@ TESTWIZARD_API bool ReadKey()
 	keyItem.keyCode.append((char*)(&szKeyData[pos+1]), dwNumberOfBytesRead-pos-4);
 
 	return true;
+#else
+	if ( !g_serialPort.IsOpen() )
+		return false;
+
+	byte szKeyData[MAX_PATH] = {0};
+	COMMTIMEOUTS Timeouts;
+	Timeouts.WriteTotalTimeoutMultiplier = 100;
+	Timeouts.WriteTotalTimeoutConstant = 15000;
+	g_serialPort.SetTimeouts(Timeouts);
+	DWORD dwNumberOfBytesRead = g_serialPort.Read(szKeyData, MAX_PATH);
+	if ( dwNumberOfBytesRead <= 0 )
+		return false;
+
+	// 如果是C++11,使用std正则;[码类型]<码内容>0D 0A;
+	// 不是 "[" 开头;
+	if ( szKeyData[0] != 0x5B )
+		return false;
+
+	// 查找 "]" 的位置;
+	int pos = 0;
+	byte *p = szKeyData;
+	while ( p++, pos++ )
+		if (*p == 0x5D)
+			break;
+
+	// 不在有效范围内;
+	if ( pos >= dwNumberOfBytesRead - 2 )
+		return false;
+
+
+	// 不是0d 0a结束;
+	if ( szKeyData[dwNumberOfBytesRead-2] != 0x0D &&  szKeyData[dwNumberOfBytesRead-1] != 0x0A)
+		return false;
+
+	KeyItem keyItem;
+	keyItem.keyType.append((char*)(&szKeyData[1]), pos-2);
+	keyItem.keyCode.append((char*)(&szKeyData[pos+1]), dwNumberOfBytesRead-pos-4);
+
+	return true;
+#endif
 }
 
 #endif

+ 11 - 11
TestWizard/TestWizard/TestWizard.h

@@ -18,19 +18,19 @@ public:
 };
 
 #ifndef __MAKE_PYD__
-TESTWIZARD_API int OpenXML(LPCTSTR lpXMLPath);
-TESTWIZARD_API int LoadXML(LPCTSTR lpXMLPath);
-TESTWIZARD_API void AddItem(LPCTSTR lpKeyName, LPCTSTR lpKeyDesc, LPCTSTR lpKeyType, LPCTSTR lpKeyCode);
-TESTWIZARD_API void DelItem(LPCTSTR lpKeyName);
-TESTWIZARD_API void RemoveAllItem(void);
-TESTWIZARD_API KeyItem* FindItem(LPCTSTR lpKeyName);
-TESTWIZARD_API int Save2XML(LPCTSTR lpXMLPath);
+extern "C" TESTWIZARD_API int OpenXML(LPCTSTR lpXMLPath);
+extern "C" TESTWIZARD_API int LoadXML(LPCTSTR lpXMLPath);
+extern "C" TESTWIZARD_API void AddItem(LPCTSTR lpKeyName, LPCTSTR lpKeyDesc, LPCTSTR lpKeyType, LPCTSTR lpKeyCode);
+extern "C" TESTWIZARD_API void DelItem(LPCTSTR lpKeyName);
+extern "C" TESTWIZARD_API void RemoveAllItem(void);
+extern "C" TESTWIZARD_API KeyItem* FindItem(LPCTSTR lpKeyName);
+extern "C" TESTWIZARD_API int Save2XML(LPCTSTR lpXMLPath);
 // 打开串口;
-TESTWIZARD_API BOOL OpenDevice(int nPort, DWORD dwBaudrate, BYTE ByteSize, BYTE Parity, BYTE StopBits);
+extern "C" TESTWIZARD_API BOOL OpenDevice(int nPort, DWORD dwBaudrate, BYTE ByteSize, BYTE Parity, BYTE StopBits);
 // 关闭串口;
-TESTWIZARD_API void CloseDevice();
+extern "C" TESTWIZARD_API void CloseDevice();
 // 发送按键;
-TESTWIZARD_API bool SendKey(LPCTSTR lpKeyName);
+extern "C" TESTWIZARD_API bool SendKey(LPCTSTR lpKeyName);
 // 读取学习按键;
-TESTWIZARD_API bool ReadKey();
+extern "C" TESTWIZARD_API bool ReadKey();
 #endif

+ 8 - 0
TestWizard/TestWizard/TestWizard.vcproj

@@ -327,6 +327,10 @@
 				RelativePath=".\Global.cpp"
 				>
 			</File>
+			<File
+				RelativePath=".\SerialPort.cpp"
+				>
+			</File>
 			<File
 				RelativePath=".\stdafx.cpp"
 				>
@@ -389,6 +393,10 @@
 				RelativePath=".\Resource.h"
 				>
 			</File>
+			<File
+				RelativePath=".\SerialPort.h"
+				>
+			</File>
 			<File
 				RelativePath=".\stdafx.h"
 				>