一个串口组件类

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

 

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;  

    }  

}  

 

 
posted @ 2015-01-23 10:41  廖先生  阅读(322)  评论(0编辑  收藏  举报