/*-----------------------Developed by Nefarian Zhu Version 1.00 for Alpha LTDAll rights reserved .QQ 909990295 ------------------------*/#ifndef H_H_CSERIALPORT#define H_H_CSERIALPORT#include <iostream>#include <windows.h>#include <process.h>//Define function pointertypedef void(*pFunction)(void); class CSerialPort{ private: HANDLE m_hCom, m_hEvent; DCB m_dcb; COMMTIMEOUTS m_to; COMSTAT m_comStat; DWORD m_dwRead, m_dwWrite; DWORD m_inBufSize, m_outBufSize; pFunction m_pDelegateFunc; BOOL m_bCloseCom; BOOL m_bThreadRunning; private: template <class ToType, class FromType> void GetMemberFuncAddr_VC6(ToType& addr,FromType f); void static ThreadProc(void *pThis); public: CSerialPort(); ~CSerialPort(); BOOL ScanComs(char *pPortsName); BOOL Open(LPCTSTR lpCom = "COM1"); BOOL Setting(LPCTSTR lpConfig = "9600,n,8,1"); BOOL SetBufferSize(DWORD cbInQue = 512, DWORD cbOutQue = 512); BOOL SetCommTimeouts(DWORD dwReadTimeOut = 100, DWORD dwWriteTimeOut = 100); BOOL Read(LPVOID lpBuffer); BOOL Write(LPVOID lpBuffer,DWORD nNumberOfBytesToWrite); BOOL Close(); template <class FromType> void BindDelegateFunc(FromType f); }; CSerialPort::CSerialPort() { m_hCom = NULL; m_hEvent = CreateEvent(NULL, true, false, NULL); memset(&m_dcb, 0, sizeof(DCB)); memset(&m_to, 0, sizeof(COMMTIMEOUTS)); memset(&m_comStat, 0, sizeof(COMSTAT)); m_dwRead = 0; m_dwWrite = 0; m_inBufSize = 512; m_outBufSize = 512; m_pDelegateFunc = NULL; m_bCloseCom = FALSE; m_bThreadRunning = FALSE;}CSerialPort::~CSerialPort() { if (m_hCom != NULL) Close(); }//Function to get address of member function in classtemplate <class ToType, class FromType>void CSerialPort::GetMemberFuncAddr_VC6(ToType& addr,FromType f){ union { FromType _f; ToType _t; }ut; ut._f = f; addr = ut._t; } //Get all local host coms from RegeditBOOL CSerialPort::ScanComs(char *pPortsName){ HKEY hkey = 0; RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_READ, &hkey); DWORD dIndex = 0; DWORD dwNameRead = 128; DWORD dwValuRead = 128; char szName[128] = ""; char szValue[128] = ""; short sIndex = 0; while (RegEnumValue(hkey, dIndex++, szName, &dwNameRead, NULL, NULL, (LPBYTE)szValue, &dwValuRead) == ERROR_SUCCESS) { strcat(pPortsName, szValue); strcat(pPortsName, "\n"); memset(szValue, 0, sizeof(szValue)); dwValuRead = 128; }} //Open specified comBOOL CSerialPort::Open(LPCTSTR lpCom){ m_hCom = CreateFile(lpCom, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if (m_hCom == INVALID_HANDLE_VALUE) { return FALSE; } else { return TRUE; }}//Set com (baudrate,parity,stopbits)BOOL CSerialPort::Setting(LPCTSTR lpConfig){ BuildCommDCB(lpConfig, &m_dcb); SetCommState(m_hCom,&m_dcb); }//Set com IO buff sizeBOOL CSerialPort::SetBufferSize(DWORD cbInQue, DWORD cbOutQue){ m_inBufSize = cbInQue; m_outBufSize = cbOutQue; SetupComm(m_hCom, m_inBufSize, m_outBufSize);}//Set com IO time for timeoutBOOL CSerialPort::SetCommTimeouts(DWORD dwReadTimeOut, DWORD dwWriteTimeOut){ m_to.ReadTotalTimeoutConstant = dwReadTimeOut; m_to.WriteTotalTimeoutConstant = dwWriteTimeOut; ::SetCommTimeouts(m_hCom, &m_to); }//Read com from output buffBOOL CSerialPort::Read(LPVOID lpBuffer){ DWORD dwError = 0; ClearCommError(m_hCom, &dwError, &m_comStat); if ( (m_comStat.cbInQue == 0) || (dwError != 0) ) { return FALSE; } ReadFile(m_hCom, lpBuffer, m_comStat.cbInQue, &m_dwRead, NULL); }//Write data to input buffBOOL CSerialPort::Write(LPVOID lpBuffer,DWORD nNumberOfBytesToWrite){ WriteFile(m_hCom, lpBuffer, nNumberOfBytesToWrite, &m_dwWrite, NULL);}//Close comBOOL CSerialPort::Close(){ if (m_bThreadRunning == TRUE) { m_bCloseCom = TRUE; WaitForSingleObject(m_hEvent, 2000); } CloseHandle(m_hCom);}//Bind fuction to deal with RX_CHAR eventtemplate <class FromType>void CSerialPort::BindDelegateFunc(FromType f){ DWORD dwAddr = 0; GetMemberFuncAddr_VC6(dwAddr, f); assert(dwAddr != 0); m_pDelegateFunc = (pFunction)dwAddr; _beginthread(ThreadProc,0,this); } //Thread proc for RX_CHARvoid CSerialPort::ThreadProc(void *pThis){ CSerialPort *pCSerialPort = (CSerialPort*)pThis; pCSerialPort->m_bThreadRunning = TRUE; while (TRUE) { if (pCSerialPort->m_bCloseCom == TRUE) { SetEvent(pCSerialPort->m_hEvent); pCSerialPort->m_bThreadRunning = FALSE; return; } DWORD dwError = 0; ClearCommError(pCSerialPort->m_hCom, &dwError, &pCSerialPort->m_comStat); if ( (pCSerialPort->m_comStat.cbInQue == 0) || (dwError != 0) ) { Sleep(10); continue; } else { pCSerialPort->m_pDelegateFunc(); } } } #endif /*-----H_H_CSERIALPORT-----*/