一个串口组件类
网上这方面三方类多如牛毛,真不知道用哪个好,不过不管用哪个,一定要在严格检查完善后再使用,不然给以后通信埋下隐患,只会让以后的调试会更痛苦!
ComAccess.h
////////////////////////////////////////////////////////////////////// // // ComAccess.h: interface for the CComAccess class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_COMACCESS_H__F15FFC6E_D059_4E57_97CD_A672C05FF9B7__INCLUDED_) #define AFX_COMACCESS_H__F15FFC6E_D059_4E57_97CD_A672C05FF9B7__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CComAccess { private: HANDLE m_hCom; // Device handle OVERLAPPED m_ov; // A structure that contains informations which are // used for asynchronous input and output operations TCHAR m_lpszErrorMessage[256]; public: CComAccess(); CComAccess(LPCSTR lpszPortNum); ~CComAccess(); // For more definitions see <winbase.h> BOOL Open(LPCSTR lpszPortNum = "com1", DWORD dwBaudRate = CBR_9600, BYTE byParity = NOPARITY, BYTE byStopBits = ONESTOPBIT, BYTE byByteSize = 8); VOID Close(); DWORD WriteData(LPCVOID pdata, DWORD len); DWORD ReadData(LPVOID pdest, DWORD len, DWORD dwMaxWait = 500); LPSTR GetErrorMessage(VOID) { return m_lpszErrorMessage; } private: VOID ErrorToString(LPCSTR lpszMessage); BOOL IsNT(VOID); }; #endif // !defined(AFX_COMACCESS_H__F15FFC6E_D059_4E57_97CD_A672C05FF9B7__INCLUDED_)
ComAccess.cpp
////////////////////////////////////////////////////////////////////// // // ComAccess.cpp: implementation of the CComAccess class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ComAccess.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CComAccess::CComAccess(VOID) { m_hCom = 0; m_lpszErrorMessage[0] = '/0'; ZeroMemory(&m_ov, sizeof(m_ov)); } CComAccess::CComAccess(LPCSTR lpszPortNum) { CComAccess::CComAccess(); CComAccess::Open(lpszPortNum); } CComAccess::~CComAccess() { Close(); } //////////////////////////////////////////////////////////////////////////////////////// // // Function: Open(LPCSTR lpszPortNum, // DWORD dwBaudRate, // BYTE byParity, // BYTE byStopBits, // BYTE byByteSize) // // Return value: BOOL TRUE or FALSE // BOOL CComAccess::Open(LPCSTR lpszPortNum, DWORD dwBaudRate, BYTE byParity, BYTE byStopBits, BYTE byByteSize) { DCB dcb; // structure that defines the control setting for a serial communications device BOOL bSuccess; m_hCom = CreateFile(lpszPortNum, // pointer to name of the file GENERIC_READ|GENERIC_WRITE, // access mode 0, // comm devices must be opened w/exclusive-access NULL, // no security attributs OPEN_EXISTING, // comm devices must use OPEN_EXISTING FILE_FLAG_OVERLAPPED, // overlapped I/O NULL); // hTemplate must be NULL for comm devices if ( m_hCom == INVALID_HANDLE_VALUE ) { // handle the error CComAccess::ErrorToString("Open(): CreateFile() failed, invalid handle value"); return FALSE; } // // Omit the call to SetupComm to use the default queue sizes. // Get the current configuration. // bSuccess = GetCommState(m_hCom, &dcb); if ( ! bSuccess ) { // Handle the error. CComAccess::ErrorToString("Open(): GetCommState() failed"); CComAccess::Close(); return FALSE; } // // Fill in the DCB: baud=9600, 8 data bits, no parity, 1 stop bit are default parameters // dcb.BaudRate = dwBaudRate; dcb.ByteSize = byByteSize; dcb.Parity = byParity; dcb.StopBits = byStopBits; bSuccess = SetCommState(m_hCom, &dcb); if ( ! bSuccess ) { // Handle the error. CComAccess::ErrorToString("Open(): SetCommState() failed"); CComAccess::Close(); return FALSE; } return TRUE; } //////////////////////////////////////////////////////////////////////////////////////// // // Function: Close(VOID) // // Return value: VOID // VOID CComAccess::Close() { if ( m_hCom > 0 ) { CloseHandle(m_hCom); } m_hCom = 0; } //////////////////////////////////////////////////////////////////////////////////////// // // Function: WriteData(LPCVOID pdata, // DWORD len) // // Return value: DWORD -1 failed, above, num written bytes // DWORD CComAccess::WriteData(LPCVOID pdata, DWORD len) { BOOL bSuccess; DWORD written = 0; if ( len < 1 ) return(0); // create event for overlapped I/O m_ov.hEvent = CreateEvent(NULL, // pointer to security attributes FALSE, // flag for manual-reset event FALSE, // flag for initial state ""); // pointer to event-object name if ( m_ov.hEvent == INVALID_HANDLE_VALUE ) { // Handle the error. CComAccess::ErrorToString("WriteData(): CreateEvent() failed"); return(-1); } bSuccess = WriteFile(m_hCom, // handle to file to write to pdata, // pointer to data to write to file len, // number of bytes to write &written, // pointer to number of bytes written &m_ov); // pointer to structure needed for overlapped I/O if ( CComAccess::IsNT() ) { bSuccess = GetOverlappedResult(m_hCom, &m_ov, &written, TRUE); if ( ! bSuccess ) { // Handle the error. CloseHandle(m_ov.hEvent); CComAccess::ErrorToString("WriteData(): GetOverlappedResult() failed"); return(-1); } } else if ( len != written ) { // Handle the error. CloseHandle(m_ov.hEvent); CComAccess::ErrorToString("WriteData(): WriteFile() failed"); return(-1); } CloseHandle(m_ov.hEvent); return written; } //////////////////////////////////////////////////////////////////////////////////////// // // Function: ReadData(LPVOID pdest, // DWORD len, // DWORD dwMaxWait) // // Return value: DWORD -1 failed, above, num read bytes // DWORD CComAccess::ReadData(LPVOID pdest, DWORD len, DWORD dwMaxWait) { BOOL bSuccess; DWORD result = 0, read = 0, // num read bytes mask = 0; // a 32-bit variable that receives a mask // indicating the type of event that occurred if ( len < 1 ) return(0); // create event for overlapped I/O m_ov.hEvent = CreateEvent(NULL, // pointer to security attributes FALSE, // flag for manual-reset event FALSE, // flag for initial state ""); // pointer to event-object name if ( m_ov.hEvent == INVALID_HANDLE_VALUE ) { // Handle the error. CComAccess::ErrorToString("ReadData(): CreateEvent() failed"); return(-1); } // Specify here the event to be enabled bSuccess = SetCommMask(m_hCom, EV_RXCHAR); if ( ! bSuccess ) { // Handle the error. CloseHandle(m_ov.hEvent); CComAccess::ErrorToString("ReadData(): SetCommMask() failed"); return(-1); } // WaitForSingleObject bSuccess = WaitCommEvent(m_hCom, &mask, &m_ov); if ( ! bSuccess ) { int err = GetLastError(); if ( err == ERROR_IO_PENDING) { result = WaitForSingleObject(m_ov.hEvent, dwMaxWait); //wait dwMaxWait // milli seconds before returning if ( result == WAIT_FAILED ) { // Handle the error. CloseHandle(m_ov.hEvent); CComAccess::ErrorToString("ReadData(): WaitForSingleObject() failed"); return(-1); } } } // The specified event occured? if ( mask & EV_RXCHAR) { bSuccess = ReadFile(m_hCom, // handle of file to read pdest, // address of buffer that receives data len, // number of bytes to read &read, // address of number of bytes read &m_ov); // address of structure for data if ( CComAccess::IsNT() ) { bSuccess = GetOverlappedResult(m_hCom, &m_ov, &read, TRUE); if ( ! bSuccess ) { // Handle the error. CloseHandle(m_ov.hEvent); CComAccess::ErrorToString("WriteData(): GetOverlappedResult() failed"); return(-1); } } else if ( ! bSuccess ) { // Handle the error. CloseHandle(m_ov.hEvent); CComAccess::ErrorToString("ReadData(): ReadFile() failed"); return(-1); } } else { // Handle the error. CloseHandle(m_ov.hEvent); wsprintf(m_lpszErrorMessage, "Error ReadData(): No EV_RXCHAR occured/n"); return(-1); } CloseHandle(m_ov.hEvent); return read; } //////////////////////////////////////////////////////////////////////////////////////// // // Function: ErrorToString(LPCSTR lpszMessage) // // Return value: VOID // VOID CComAccess::ErrorToString(LPCSTR lpszMessage) { LPVOID lpMessageBuffer; DWORD error = GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, // source and processing options NULL, // pointer to message source error, // requested message identifie MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // the user default language. (LPTSTR) &lpMessageBuffer, // pointer to message buffer 0, // maximum size of message buffer NULL); // address of array of message inserts // and copy it in our error string wsprintf(m_lpszErrorMessage,"%s: (%d) %s/n", lpszMessage, error, lpMessageBuffer); LocalFree(lpMessageBuffer); } //////////////////////////////////////////////////////////////////////////////////////// // // Function: IsNT(VOID) // // Return value: BOOL True or False // BOOL CComAccess::IsNT(VOID) { OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) { return TRUE; } else { return FALSE; } }