网上这方面三方类多如牛毛,真不知道用哪个好,不过不管用哪个,一定要在严格检查完善后再使用,不然给以后通信埋下隐患,只会让以后的调试会更痛苦!
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;
- }
- }