zoukankan      html  css  js  c++  java
  • 一个完整的COM通信类


                                      郑重声明:本文摘自www.codeworks.it 版权归作者所有,如有违权请告之,本人将在一周内清除.若转载本站文章请标明出处




    /Files/msnadair/rs232.rar
    (解压密码:msnadair)

    Imports System.Runtime.InteropServices
    Imports System.Text
    Imports System.Threading
    Imports System.ComponentModel
    Imports System.IO

    #Region "RS232"
    Public Class Rs232 : Implements IDisposable
       '===================================================
       '
       ' Module    : Rs232
       ' Description  : Class for handling RS232 comunication with VB.Net
       ' Created    : 10/08/2001 - 8:45:25
       ' Author    : Corrado Cavalli 
       '   '    '=================================================== 
       '// Class Members  
     Private mhRS As IntPtr = New IntPtr(0)   '// Handle to Com Port         
       Private miPort As Integer = 1   '//  Default is COM1 
       Private miTimeout As Int32 = 70   '// Timeout in ms
       Private miBaudRate As Int32 = 9600
       Private meParity As DataParity = 0
       Private meStopBit As DataStopBit = 0
       Private miDataBit As Int32 = 8
       Private miBufferSize As Int32 = 512   '// Buffers size default to 512 bytes
       Private mabtRxBuf As Byte()   '//  Receive buffer 
        Private meMode As Mode  '//  Class working mode 

     Private moThreadTx As Thread
     Private moThreadRx As Thread
        Private moEvents As Thread

       Private miTmpBytes2Read As Int32
       Private meMask As EventMasks
       Private mbDisposed As Boolean
     Private mbUseXonXoff As Boolean
     Private mbEnableEvents As Boolean
     Private miBufThreshold As Int32 = 1
     Private muOvlE As OVERLAPPED
     Private muOvlW As OVERLAPPED
     Private muOvlR As OVERLAPPED
     Private mHE As GCHandle
     Private mHR As GCHandle
     Private mHW As GCHandle
     '----------------------------------------------------------------------------------------

    #Region "Enums"
     '// Parity Data
     Public Enum DataParity
      Parity_None = 0
            Parity_Odd
      Parity_Even
      Parity_Mark
     End Enum
     '// StopBit Data
     Public Enum DataStopBit
      StopBit_1 = 1
      StopBit_2
     End Enum
     <Flags()> Public Enum PurgeBuffers
      RXAbort = &H2
      RXClear = &H8
      TxAbort = &H1
      TxClear = &H4
     End Enum
     Private Enum Lines
      SetRts = 3
      ClearRts = 4
      SetDtr = 5
      ClearDtr = 6
      ResetDev = 7   ' // Reset device if possible
      SetBreak = 8   ' // Set the device break line.
      ClearBreak = 9   ' // Clear the device break line.
     End Enum
     '// Modem Status
     <Flags()> Public Enum ModemStatusBits
      ClearToSendOn = &H10
      DataSetReadyOn = &H20
      RingIndicatorOn = &H40
      CarrierDetect = &H80
     End Enum
     '// Working mode
     Public Enum Mode
      NonOverlapped
      Overlapped
     End Enum
     '// Comm Masks
     <Flags()> Public Enum EventMasks
      RxChar = &H1
      RXFlag = &H2
      TxBufferEmpty = &H4
      ClearToSend = &H8
      DataSetReady = &H10
      CarrierDetect = &H20
      Break = &H40
      StatusError = &H80
      Ring = &H100
     End Enum

    #End Region
    #Region "Structures"
     <StructLayout(LayoutKind.Sequential, Pack:=1)> Private Structure DCB
      Public DCBlength As Int32
      Public BaudRate As Int32
      Public Bits1 As Int32
      Public wReserved As Int16
      Public XonLim As Int16
      Public XoffLim As Int16
      Public ByteSize As Byte
      Public Parity As Byte
      Public StopBits As Byte
      Public XonChar As Char
      Public XoffChar As Char
      Public ErrorChar As Char
      Public EofChar As Char
      Public EvtChar As Char
      Public wReserved2 As Int16
     End Structure
     <StructLayout(LayoutKind.Sequential, Pack:=1)> Private Structure COMMTIMEOUTS
      Public ReadIntervalTimeout As Int32
      Public ReadTotalTimeoutMultiplier As Int32
      Public ReadTotalTimeoutConstant As Int32
      Public WriteTotalTimeoutMultiplier As Int32
      Public WriteTotalTimeoutConstant As Int32
     End Structure
        <StructLayout(LayoutKind.Sequential, Pack:=8)> Private Structure COMMCONFIG
            Public dwSize As Int32
            Public wVersion As Int16
            Public wReserved As Int16
            Public dcbx As DCB
            Public dwProviderSubType As Int32
            Public dwProviderOffset As Int32
            Public dwProviderSize As Int32
            Public wcProviderData As Int16
        End Structure
        <StructLayout(LayoutKind.Sequential, Pack:=1)> Public Structure OVERLAPPED
            Public Internal As Int32
            Public InternalHigh As Int32
            Public Offset As Int32
            Public OffsetHigh As Int32
            Public hEvent As IntPtr
        End Structure
        <StructLayout(LayoutKind.Sequential, Pack:=1)> Private Structure COMSTAT
            Dim fBitFields As Int32
            Dim cbInQue As Int32
            Dim cbOutQue As Int32
        End Structure

    #End Region
    #Region "Constants"
     Private Const PURGE_RXABORT As Integer = &H2
     Private Const PURGE_RXCLEAR As Integer = &H8
     Private Const PURGE_TXABORT As Integer = &H1
     Private Const PURGE_TXCLEAR As Integer = &H4
     Private Const GENERIC_READ As Integer = &H80000000
     Private Const GENERIC_WRITE As Integer = &H40000000
     Private Const OPEN_EXISTING As Integer = 3
     Private Const INVALID_HANDLE_VALUE As Integer = -1
     Private Const IO_BUFFER_SIZE As Integer = 1024
     Private Const FILE_FLAG_OVERLAPPED As Int32 = &H40000000
     Private Const ERROR_IO_PENDING As Int32 = 997
     Private Const WAIT_OBJECT_0 As Int32 = 0
     Private Const ERROR_IO_INCOMPLETE As Int32 = 996
     Private Const WAIT_TIMEOUT As Int32 = &H102&
     Private Const INFINITE As Int32 = &HFFFFFFFF


    #End Region
    #Region "Win32API"
     '// Win32 API
       <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function SetCommState(ByVal hCommDev As IntPtr, ByRef lpDCB As DCB) As Int32
       End Function
       <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function GetCommState(ByVal hCommDev As IntPtr, ByRef lpDCB As DCB) As Int32
       End Function
       <DllImport("kernel32.dll", SetlastError:=True, CharSet:=CharSet.Auto)> Private Shared Function BuildCommDCB(ByVal lpDef As String, ByRef lpDCB As DCB) As Int32
       End Function
       <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function SetupComm(ByVal hFile As IntPtr, ByVal dwInQueue As Int32, ByVal dwOutQueue As Int32) As Int32
       End Function
       <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function SetCommTimeouts(ByVal hFile As IntPtr, ByRef lpCommTimeouts As COMMTIMEOUTS) As Int32
       End Function
       <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function GetCommTimeouts(ByVal hFile As IntPtr, ByRef lpCommTimeouts As COMMTIMEOUTS) As Int32
       End Function
       <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function ClearCommError(ByVal hFile As IntPtr, ByRef lpErrors As Int32, ByRef lpComStat As COMSTAT) As Int32
       End Function
       <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function PurgeComm(ByVal hFile As IntPtr, ByVal dwFlags As Int32) As Int32
       End Function
        <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function EscapeCommFunction(ByVal hFile As IntPtr, ByVal ifunc As Int32) As Boolean
        End Function
        <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function WaitCommEvent(ByVal hFile As IntPtr, ByRef Mask As EventMasks, ByRef lpOverlap As OVERLAPPED) As Int32
        End Function
        <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function WriteFile(ByVal hFile As IntPtr, ByVal Buffer As Byte(), ByVal nNumberOfBytesToWrite As Integer, ByRef lpNumberOfBytesWritten As Integer, ByRef lpOverlapped As OVERLAPPED) As Integer
        End Function
        <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function ReadFile(ByVal hFile As IntPtr, <Out()> ByVal Buffer As Byte(), ByVal nNumberOfBytesToRead As Integer, ByRef lpNumberOfBytesRead As Integer, ByRef lpOverlapped As OVERLAPPED) As Integer
        End Function
        <DllImport("kernel32.dll", SetlastError:=True, CharSet:=CharSet.Auto)> Private Shared Function CreateFile(ByVal lpFileName As String, ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer, ByVal lpSecurityAttributes As Integer, ByVal dwCreationDisposition As Integer, ByVal dwFlagsAndAttributes As Integer, ByVal hTemplateFile As Integer) As IntPtr
        End Function
        <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function CloseHandle(ByVal hObject As IntPtr) As Boolean
        End Function
        <DllImport("kernel32.dll", SetlastError:=True)> Public Shared Function GetCommModemStatus(ByVal hFile As IntPtr, ByRef lpModemStatus As Int32) As Boolean
        End Function
        <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function SetEvent(ByVal hEvent As IntPtr) As Boolean
        End Function
        <DllImport("kernel32.dll", SetlastError:=True, CharSet:=CharSet.Auto)> Private Shared Function CreateEvent(ByVal lpEventAttributes As IntPtr, ByVal bManualReset As Int32, ByVal bInitialState As Int32, ByVal lpName As String) As IntPtr
        End Function
        <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function WaitForSingleObject(ByVal hHandle As IntPtr, ByVal dwMilliseconds As Int32) As Int32
        End Function
        <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function GetOverlappedResult(ByVal hFile As IntPtr, ByRef lpOverlapped As OVERLAPPED, ByRef lpNumberOfBytesTransferred As Int32, ByVal bWait As Int32) As Int32
        End Function
        <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function SetCommMask(ByVal hFile As IntPtr, ByVal lpEvtMask As Int32) As Int32
        End Function
        <DllImport("kernel32.dll", SetlastError:=True, CharSet:=CharSet.Auto)> Private Shared Function GetDefaultCommConfig(ByVal lpszName As String, ByRef lpCC As COMMCONFIG, ByRef lpdwSize As Integer) As Boolean
        End Function
        <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function SetCommBreak(ByVal hFile As IntPtr) As Boolean
        End Function
        <DllImport("kernel32.dll", SetlastError:=True)> Private Shared Function ClearCommBreak(ByVal hFile As IntPtr) As Boolean
        End Function


    #End Region
    #Region "Events"
     Public Event CommEvent As CommEventHandler
    #End Region
    #Region "Delegates"
     Public Delegate Sub CommEventHandler(ByVal source As Rs232, ByVal Mask As EventMasks)
    #End Region

     Public Property Port() As Integer
      '===================================================
      '
      '  Description :  Comunication Port
      '  Created   :  21/09/2001 - 11:25:49
      '
      '            *Parameters Info*
      '
      '  Notes    :
      '===================================================
      Get
       Return miPort
      End Get
      Set(ByVal Value As Integer)
       miPort = Value
      End Set
     End Property
     Public Sub PurgeBuffer(ByVal Mode As PurgeBuffers)
      '===================================================
      '            ?003 ALSTOM FIR S.p.A All rights reserved
      '
      ' Description : Purge Communication Buffer
      ' Created   : 01/09/03 - 10:37:39
      ' Author   : Corrado Cavalli
      '
      '      *Parameters Info*
      '
      ' Notes    : This method will clear any character into buffer, use TxAbort/RxAbort
      '        to terminate any pending overlapped Tx/Rx operation.
      '===================================================
      If (mhRS.ToInt32 > 0) Then PurgeComm(mhRS, Mode)
     End Sub
     Public Overridable Property Timeout() As Integer
      '===================================================
      '
      '  Description:  Comunication timeout in seconds
      '  Created   :  21/09/2001 - 11:26:50
      '
      '            *Parameters Info*
      '
      '  Notes    :
      '===================================================
      Get
       Return miTimeout
      End Get
      Set(ByVal Value As Integer)
       miTimeout = CInt(IIf(Value = 0, 500, Value))
       '// If Port is open updates it on the fly
       pSetTimeout()
      End Set
     End Property
     Public Property Parity() As DataParity
      '===================================================
      '
      '  Description :  Comunication parity
      '  Created   :  21/09/2001 - 11:27:15
      '
      '            *Parameters Info*
      '
      '  Notes    :
      '===================================================
      Get
       Return meParity
      End Get
      Set(ByVal Value As DataParity)
       meParity = Value
      End Set
     End Property
     Public Property StopBit() As DataStopBit
      '===================================================
      '
      '  Description:  Comunication StopBit
      '  Created   :  21/09/2001 - 11:27:37
      '
      '            *Parameters Info*
      '
      '  Notes    :
      '===================================================
      Get
       Return meStopBit
      End Get
      Set(ByVal Value As DataStopBit)
       meStopBit = Value
      End Set
     End Property
     Public Property BaudRate() As Integer
      '===================================================
      '
      '  Description:  Comunication BaudRate
      '  Created   :  21/09/2001 - 11:28:00
      '
      '            *Parameters Info*
      '
      '  Notes    :
      '===================================================
      Get
       Return miBaudRate
      End Get
      Set(ByVal Value As Integer)
       miBaudRate = Value
      End Set
     End Property
     Public Property DataBit() As Integer
      '===================================================
      '
      '  Description :  Comunication DataBit
      '  Created   :  21/09/2001 - 11:28:20
      '
      '            *Parameters Info*
      '
      '  Notes    :
      '===================================================
      Get
       Return miDataBit
      End Get
      Set(ByVal Value As Integer)
       miDataBit = Value
      End Set
     End Property
     Public Property BufferSize() As Integer
      '===================================================
      '
      '  Description :  Receive Buffer size  
      '  Created   :  21/09/2001 - 11:33:05
      '
      '            *Parameters Info*
      '
      '  Notes    :
      '===================================================
      Get
       Return miBufferSize
      End Get
      Set(ByVal Value As Integer)
       miBufferSize = Value
      End Set
     End Property
     Public Overloads Sub Open()
      '===================================================
      '
      '  Description :  Initializes and Opens comunication port
      '  Created   :  21/09/2001 - 11:33:40
      '
      '            *Parameters Info*
      '
      '  Notes    :
      '===================================================
      '// Get Dcb block,Update with current data
      Dim uDcb As DCB, iRc As Int32
      '// Set working mode
      meMode = Mode.Overlapped
      Dim iMode As Int32 = Convert.ToInt32(IIf(meMode = Mode.Overlapped, FILE_FLAG_OVERLAPPED, 0))
      '// Initializes Com Port
      If miPort > 0 Then
       Try
        '// Creates a COM Port stream handle
        mhRS = CreateFile("\\.\COM" & miPort.ToString, GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, iMode, 0)
        If (mhRS.ToInt32 > 0) Then
         '// Clear all comunication errors
         Dim lpErrCode As Int32
         iRc = ClearCommError(mhRS, lpErrCode, New COMSTAT)
         '// Clears I/O buffers
         iRc = PurgeComm(mhRS, PurgeBuffers.RXClear Or PurgeBuffers.TxClear)
         '// Gets COM Settings
         iRc = GetCommState(mhRS, uDcb)
         '// Updates COM Settings
         Dim sParity As String = "NOEM"
         sParity = sParity.Substring(meParity, 1)
         '// Set DCB State
         Dim sDCBState As String = String.Format("baud={0} parity={1} data={2} stop={3}", miBaudRate, sParity, miDataBit, CInt(meStopBit))
         iRc = BuildCommDCB(sDCBState, uDcb)
         uDcb.Parity = CByte(meParity)
         '// Set Xon/Xoff State
         If mbUseXonXoff Then
          uDcb.Bits1 = 768
         Else
          uDcb.Bits1 = 0
         End If
         iRc = SetCommState(mhRS, uDcb)
         If iRc = 0 Then
          Dim sErrTxt As String = New Win32Exception().Message
          Throw New CIOChannelException("Unable to set COM state " & sErrTxt)
         End If
         '// Setup Buffers (Rx,Tx)
         iRc = SetupComm(mhRS, miBufferSize, miBufferSize)
         '// Set Timeouts
         pSetTimeout()
         '//Enables events if required
         If mbEnableEvents Then Me.EnableEvents()
        Else
         '// Raise Initialization problems
         Dim sErrTxt As String = New Win32Exception().Message
         Throw New CIOChannelException("Unable to open COM" + miPort.ToString + ControlChars.CrLf + sErrTxt)
        End If
       Catch Ex As Exception
        '// Generica error
        Throw New CIOChannelException(Ex.Message, Ex)
       End Try
      Else
       '// Port not defined, cannot open
       Throw New ApplicationException("COM Port not defined,use Port property to set it before invoking InitPort")
      End If
     End Sub
     Public Overloads Sub Open(ByVal Port As Integer, ByVal BaudRate As Integer, ByVal DataBit As Integer, ByVal Parity As DataParity, ByVal StopBit As DataStopBit, ByVal BufferSize As Integer)
      '===================================================
      '
      '  Description:  Opens comunication port (Overloaded method)
      '  Created  :  21/09/2001 - 11:33:40
      '
      '            *Parameters Info*
      '
      '  Notes   :
      '===================================================
      Me.Port = Port
      Me.BaudRate = BaudRate
      Me.DataBit = DataBit
      Me.Parity = Parity
      Me.StopBit = StopBit
      Me.BufferSize = BufferSize
      Open()
     End Sub
     Public Sub Close()
      '===================================================
      '
      '  Description:  Close comunication channel
      '  Created   :  21/09/2001 - 11:38:00
      '
      '            *Parameters Info*
      '
      '  Notes    :
      '===================================================
      If mhRS.ToInt32 > 0 Then
       If mbEnableEvents = True Then
        Me.DisableEvents()
       End If
       Dim ret As Boolean = CloseHandle(mhRS)
       If Not ret Then Throw New Win32Exception
       mhRS = New IntPtr(0)
      End If
     End Sub
     ReadOnly Property IsOpen() As Boolean
      '===================================================
      '
      '  Description:  Returns Port Status  
      '  Created   :  21/09/2001 - 11:38:51
      '
      '            *Parameters Info*
      '
      '  Notes    :
      '===================================================
      Get
       Return CBool(mhRS.ToInt32 > 0)
      End Get
     End Property
     Public Overloads Sub Write(ByVal Buffer As Byte())
      '===================================================
      '
      '  Description:  Transmit a stream
      '  Created   :  21/09/2001 - 11:39:51
      '
      '            *Parameters Info*
      '  Buffer    :   Array of Byte() to write
      '  Notes    :
      '===================================================
      Dim iRc, iBytesWritten As Integer, hOvl As GCHandle
      '-----------------------------------------------------------------
      muOvlW = New Overlapped
      If mhRS.ToInt32 <= 0 Then
       Throw New ApplicationException("Please initialize and open port before using this method")
      Else
       '// Creates Event
       Try
                    hOvl = GCHandle.Alloc(muOvlW, GCHandleType.Pinned)
        muOvlW.hEvent = CreateEvent(Nothing, 1, 0, Nothing)
        If muOvlW.hEvent.ToInt32 = 0 Then Throw New ApplicationException("Error creating event for overlapped writing")
        '// Clears IO buffers and sends data
        iRc = WriteFile(mhRS, Buffer, Buffer.Length, 0, muOvlW)
        If iRc = 0 Then
         If Marshal.GetLastWin32Error <> ERROR_IO_PENDING Then
          Throw New ApplicationException("Write command error")
         Else
          '// Check Tx results
          If GetOverlappedResult(mhRS, muOvlW, iBytesWritten, 1) = 0 Then
           Throw New ApplicationException("Write pending error")
          Else
           '// All bytes sent?
           If iBytesWritten <> Buffer.Length Then Throw New ApplicationException("Write Error - Bytes Written " & iBytesWritten.ToString & " of " & Buffer.Length.ToString)
          End If
         End If
        End If
       Finally
        '//Closes handle
        CloseHandle(muOvlW.hEvent)
                    If (hOvl.IsAllocated = True) Then hOvl.Free()
       End Try
      End If
     End Sub
     Public Overloads Sub Write(ByVal Buffer As String)
      '===================================================
      '
      ' Description : Writes a string to RS232
      ' Created   : 04/02/2002 - 8:46:42
      '
      '      *Parameters Info*
      '
      ' Notes    :  24/05/2002 Fixed problem with ASCII Encoding
      '===================================================
      Dim oEncoder As New System.Text.ASCIIEncoding
      Dim oEnc As Encoding = oEncoder.GetEncoding(1252)
      '-------------------------------------------------------------
      Dim aByte() As Byte = oEnc.GetBytes(Buffer)
      Me.Write(aByte)
     End Sub
     Public Function Read(ByVal Bytes2Read As Integer) As Integer
      '===================================================
      '
      '  Description:  Read Bytes from Port
      '  Created   :  21/09/2001 - 11:41:17
      '
      '            *Parameters Info*
      '  Bytes2Read  :  Bytes to read from port
      '  Returns     :  Number of readed chars
      '
      '  Notes    :
      '===================================================
      Dim iReadChars, iRc As Integer, bReading As Boolean, hOvl As GCHandle
      '--------------------------------------------------------------
      '// If Bytes2Read not specified uses Buffersize
      If Bytes2Read = 0 Then Bytes2Read = miBufferSize
      muOvlR = New Overlapped
      If mhRS.ToInt32 <= 0 Then
       Throw New ApplicationException("Please initialize and open port before using this method")
      Else
       '// Get bytes from port
       Try
                    hOvl = GCHandle.Alloc(muOvlR, GCHandleType.Pinned)
        muOvlR.hEvent = CreateEvent(Nothing, 1, 0, Nothing)
        If muOvlR.hEvent.ToInt32 = 0 Then Throw New ApplicationException("Error creating event for overlapped reading")
        '// Clears IO buffers and reads data
        ReDim mabtRxBuf(Bytes2Read - 1)
        iRc = ReadFile(mhRS, mabtRxBuf, Bytes2Read, iReadChars, muOvlR)
        If iRc = 0 Then
         If Marshal.GetLastWin32Error() <> ERROR_IO_PENDING Then
          Throw New ApplicationException("Read pending error")
         Else
          '// Wait for characters
          iRc = WaitForSingleObject(muOvlR.hEvent, miTimeout)
          Select Case iRc
           Case WAIT_OBJECT_0
            '// Some data received...
            If GetOverlappedResult(mhRS, muOvlR, iReadChars, 0) = 0 Then
             Throw New ApplicationException("Read pending error.")
            Else
             Return iReadChars
            End If
           Case WAIT_TIMEOUT
            Throw New IOTimeoutException("Read Timeout.")
           Case Else
            Throw New ApplicationException("General read error.")
          End Select
         End If
        Else
         Return (iReadChars)
        End If
       Finally
        '//Closes handle
        CloseHandle(muOvlR.hEvent)
        If (hOvl.IsAllocated) Then hOvl.Free()
       End Try
      End If
     End Function
     Overridable ReadOnly Property InputStream() As Byte()
      '===================================================
      '
      '  Description:  Returns received data as Byte() 
      '  Created   :  21/09/2001 - 11:45:06
      '
      '            *Parameters Info*
      '  
      '  Notes    :
      '===================================================
          Get
             Return mabtRxBuf
          End Get
       End Property
     Overridable ReadOnly Property InputStreamString() As String
      '===================================================
      '
      ' Description : Return a string containing received data
      ' Created   : 04/02/2002 - 8:49:55
      '
      '      *Parameters Info*
      '
      ' Notes    :
      '===================================================
      Get
             Dim oEncoder As New System.Text.ASCIIEncoding
             Dim oEnc As Encoding = oEncoder.GetEncoding(1252)
       '-------------------------------------------------------------
       If Not Me.InputStream Is Nothing Then Return oEnc.GetString(Me.InputStream)
      End Get
     End Property
     Public Sub ClearInputBuffer()
      '===================================================
      '
      '  Description:  Clears Input buffer
      '  Created   :  21/09/2001 - 11:45:34
      '
      '            *Parameters Info*
      '
      '  Notes    :  Gets all character until end of buffer
      '===================================================
      If mhRS.ToInt32 > 0 Then
       PurgeComm(mhRS, PURGE_RXCLEAR)
      End If
     End Sub
     Public WriteOnly Property Rts() As Boolean
      '===================================================
      '
      '  Description:  Set/Resets RTS Line  
      '  Created   :  21/09/2001 - 11:45:34
      '
      '            *Parameters Info*
      '
      '  Notes    :
      '===================================================
      Set(ByVal Value As Boolean)
       If mhRS.ToInt32 > 0 Then
        If Value Then
         EscapeCommFunction(mhRS, Lines.SetRts)
        Else
         EscapeCommFunction(mhRS, Lines.ClearRts)
        End If
       End If
      End Set
     End Property
     Public WriteOnly Property Dtr() As Boolean
      '===================================================
      '
      '  Description:  Set/Resets DTR Line  
      '  Created   :  21/09/2001 - 11:45:34
      '
      '            *Parameters Info*
      '
      '  Notes    :
      '===================================================
      Set(ByVal Value As Boolean)
       If mhRS.ToInt32 > 0 Then
        If Value Then
         EscapeCommFunction(mhRS, Lines.SetDtr)
        Else
         EscapeCommFunction(mhRS, Lines.ClearDtr)
        End If
       End If
      End Set
     End Property
     Public ReadOnly Property ModemStatus() As ModemStatusBits
      '===================================================
      '
      ' Description : Gets Modem status
      ' Created   : 28/02/2002 - 8:58:04
      '
      '      *Parameters Info*
      '
      ' Notes    :
      '===================================================
      Get
       If mhRS.ToInt32 <= 0 Then
        Throw New ApplicationException("Please initialize and open port before using this method")
       Else
        '// Retrieve modem status
        Dim lpModemStatus As Int32
        If Not GetCommModemStatus(mhRS, lpModemStatus) Then
         Throw New ApplicationException("Unable to get modem status")
        Else
         Return CType(lpModemStatus, ModemStatusBits)
        End If
       End If
      End Get
     End Property
     Public Function CheckLineStatus(ByVal Line As ModemStatusBits) As Boolean
      '===================================================
      '
      ' Description : Check status of a Modem Line
      ' Created   : 28/02/2002 - 10:25:17
      '
      '      *Parameters Info*
      '
      ' Notes    :
      '===================================================
      Return Convert.ToBoolean(ModemStatus And Line)
     End Function
     Public Property UseXonXoff() As Boolean
      '===================================================
      '
      ' Description : Set XON/XOFF mode
      ' Created   : 26/05/2003 - 21:16:18
      '
      '      *Parameters Info*
      '
      ' Notes    :
      '===================================================
      Get
       Return mbUseXonXoff
      End Get
      Set(ByVal Value As Boolean)
       mbUseXonXoff = Value
      End Set
     End Property
     Public Sub EnableEvents()
      '===================================================
      '
      ' Description : Enables monitoring of incoming events
      ' Created   : 15/07/2003 - 12:00:56
      '
      '      *Parameters Info*
      '
      ' Notes    :
      '===================================================
      If mhRS.ToInt32 <= 0 Then
       Throw New ApplicationException("Please initialize and open port before using this method")
      Else
       If moEvents Is Nothing Then
        mbEnableEvents = True
        moEvents = New Thread(AddressOf pEventsWatcher)
        moEvents.IsBackground = True
        moEvents.Start()
       End If
      End If
     End Sub
     Public Sub DisableEvents()
      '===================================================
      '
      ' Description : Disables monitoring of incoming events
      ' Created   : 15/07/2003 - 12:00:56
      '
      '      *Parameters Info*
      '
      ' Notes    :
      '===================================================
      If mbEnableEvents = True Then
       SyncLock Me
        mbEnableEvents = False     '// This should kill the thread
       End SyncLock
       '// Let WaitCommEvent exit...
       If muOvlE.hEvent.ToInt32 <> 0 Then SetEvent(muOvlE.hEvent)
       moEvents = Nothing
      End If
     End Sub
     Public Property RxBufferThreshold() As Int32
      '===================================================
      '        '
      ' Description : Numer of characters into input buffer
      ' Created   : 16/07/03 - 9:00:57
      ' Author   : Corrado Cavalli
      '
      '      *Parameters Info*
      '
      ' Notes    :
      '===================================================
      Get
       Return miBufThreshold
      End Get
      Set(ByVal Value As Int32)
       miBufThreshold = Value
      End Set
     End Property
        Public Shared Function IsPortAvailable(ByVal portNumber As Int32) As Boolean
            '===================================================
            '                '
            ' Description : Returns true if a specific port number is supported by the system
            ' Created   : 14/09/03 - 17:00:57
            ' Author   : Corrado Cavalli
            '
            '      *Parameters Info*
            ' portNumber : port number to check
            '
            ' Notes    :
            '===================================================
            If portNumber <= 0 Then
                Return False
            Else
                Dim cfg As COMMCONFIG
                Dim cfgsize As Int32 = Marshal.SizeOf(cfg)
                cfg.dwSize = cfgsize
                Dim ret As Boolean = GetDefaultCommConfig("COM" + portNumber.ToString, cfg, cfgsize)
                Return ret
            End If
        End Function
        Public Sub SetBreak()
            '===================================================
            '                '
            ' Description : Set COM in break modem
            ' Created   : 12/10/03 - 10:00:57
            ' Author   : Corrado Cavalli
            '
            '      *Parameters Info*
            ' 
            '
            ' Notes    :
            '===================================================
            If mhRS.ToInt32 > 0 Then
                If SetCommBreak(mhRS) = False Then Throw New Win32Exception
            End If
        End Sub
        Public Sub ClearBreak()
            '===================================================
            '              '
            ' Description : Clear COM break mode
            ' Created   : 12/10/03 - 10:02:57
            ' Author   : Corrado Cavalli
            '
            '      *Parameters Info*
            ' 
            '
            ' Notes    :
            '===================================================
            If mhRS.ToInt32 > 0 Then
                If ClearCommBreak(mhRS) = False Then Throw New Win32Exception
            End If

        End Sub
        Public ReadOnly Property InBufferCount() As Int32
            '===================================================
            '               '
            ' Description : Returns the number of bytes inside Rx buffer
            ' Created   : 20/04/05 - 10:02:57
            ' Author   : Corrado Cavalli/Jean-Pierre ZANIER
            '
            '
            '===================================================
            Get
                Dim comStat As COMSTAT
                Dim lpErrCode As Int32
                Dim iRc As Int32
                comStat.cbInQue = 0
                If mhRS.ToInt32 > 0 Then
                    iRc = ClearCommError(mhRS, lpErrCode, comStat)
                    Return comStat.cbInQue
                End If
                Return 0
            End Get
        End Property


    #Region "Finalize"
        Protected Overrides Sub Finalize()
            '===================================================
            '
            ' Description : Closes COM port if object is garbage collected and still owns
            '                       COM port reosurces
            '
            ' Created   : 27/05/2002 - 19:05:56
            '
            '      *Parameters Info*
            '
            ' Notes    :
            '===================================================
            Try
                If Not mbDisposed Then
                    If mbEnableEvents Then Me.DisableEvents()
                    Close()
                End If
            Finally
                MyBase.Finalize()
            End Try
        End Sub
    #End Region

    #Region "Private Routines"
        Private Sub pSetTimeout()
            '===================================================
            '
            '  Description:  Set comunication timeouts
            '  Created   :  21/09/2001 - 11:46:40
            '
            '            *Parameters Info*
            '
            '  Notes    :
            '===================================================
            Dim uCtm As COMMTIMEOUTS
            '// Set ComTimeout
            If mhRS.ToInt32 <= 0 Then
                Exit Sub
            Else
                '// Changes setup on the fly
                With uCtm
                    .ReadIntervalTimeout = 0
                    .ReadTotalTimeoutMultiplier = 0
                    .ReadTotalTimeoutConstant = miTimeout
                    .WriteTotalTimeoutMultiplier = 10
                    .WriteTotalTimeoutConstant = 100
                End With
                SetCommTimeouts(mhRS, uCtm)
            End If
        End Sub
        Private Sub pDispose() Implements IDisposable.Dispose
            '===================================================
            '
            ' Description : Handles correct class disposing Write
            ' Created   : 27/05/2002 - 19:03:06
            '
            '      *Parameters Info*
            '
            ' Notes    :
            '===================================================
            If (Not mbDisposed AndAlso (mhRS.ToInt32 > 0)) Then
                '// Closes Com Port releasing resources
                Try
                    Me.Close()
                Finally
                    mbDisposed = True
                    '// Suppress unnecessary Finalize overhead
                    GC.SuppressFinalize(Me)
                End Try
            End If


        End Sub
        Private Sub pEventsWatcher()
            '===================================================
            '               '
            ' Description : Watches for all events raising events when they arrive to the port
            ' Created   : 15/07/03 - 11:45:13
            ' Author   : Corrado Cavalli
            '
            '      *Parameters Info*
            '
            ' Notes    :
            '===================================================
            '// Events to watch
            Dim lMask As EventMasks = EventMasks.Break Or EventMasks.CarrierDetect Or EventMasks.ClearToSend Or _
            EventMasks.DataSetReady Or EventMasks.Ring Or EventMasks.RxChar Or EventMasks.RXFlag Or _
            EventMasks.StatusError
            Dim lRetMask As EventMasks, iBytesRead, iTotBytes, iErrMask As Int32, iRc As Int32, aBuf As New ArrayList
            Dim uComStat As COMSTAT
            '-----------------------------------
            '// Creates Event
            muOvlE = New Overlapped
            Dim hOvlE As GCHandle = GCHandle.Alloc(muOvlE, GCHandleType.Pinned)
            muOvlE.hEvent = CreateEvent(Nothing, 1, 0, Nothing)
            If muOvlE.hEvent.ToInt32 = 0 Then Throw New ApplicationException("Error creating event for overlapped reading")
            '// Set mask
            SetCommMask(mhRS, lMask)
            '// Looks for RxChar
            While mbEnableEvents = True
                WaitCommEvent(mhRS, lMask, muOvlE)
                Select Case WaitForSingleObject(muOvlE.hEvent, INFINITE)
                    Case WAIT_OBJECT_0
                        '// Event (or abort) detected
                        If mbEnableEvents = False Then Exit While
                        If (lMask And EventMasks.RxChar) > 0 Then
                            '// Read incoming data
                            ClearCommError(mhRS, iErrMask, uComStat)
                            If iErrMask = 0 Then
                                Dim ovl As New Overlapped
                                Dim hOvl As GCHandle = GCHandle.Alloc(ovl, GCHandleType.Pinned)
                                ReDim mabtRxBuf(uComStat.cbInQue - 1)
                                If ReadFile(mhRS, mabtRxBuf, uComStat.cbInQue, iBytesRead, ovl) > 0 Then
                                    If iBytesRead > 0 Then
                                        '// Some bytes read, fills temporary buffer
                                        If iTotBytes < miBufThreshold Then
                                            aBuf.AddRange(mabtRxBuf)
                                            iTotBytes += iBytesRead
                                        End If
                                        '// Threshold reached?, raises event
                                        If iTotBytes >= miBufThreshold Then
                                            '//Copies temp buffer into Rx buffer
                                            ReDim mabtRxBuf(iTotBytes - 1)
                                            aBuf.CopyTo(mabtRxBuf)
                                            '// Raises event
                                            Try
                                                Me.OnCommEventReceived(Me, lMask)
                                            Finally
                                                iTotBytes = 0
                                                aBuf.Clear()
                                            End Try
                                        End If
                                    End If
                                End If
                                If (hOvl.IsAllocated) Then hOvl.Free()
                            End If
                        Else
                            '// Simply raises OnCommEventHandler event
                            Me.OnCommEventReceived(Me, lMask)
                        End If
                    Case Else
                        Dim sErr As String = New Win32Exception().Message
                        Throw New ApplicationException(sErr)
                End Select
            End While
            '// Release Event Handle
            CloseHandle(muOvlE.hEvent)
            muOvlE.hEvent = IntPtr.Zero
            If (hOvlE.IsAllocated) Then hOvlE.Free()
            muOvlE = Nothing
        End Sub

    #End Region

    #Region "Protected Routines"
        Protected Sub OnCommEventReceived(ByVal source As Rs232, ByVal mask As EventMasks)
            '===================================================
            '             '
            ' Description : Raises CommEvent
            ' Created   : 15/07/03 - 15:09:50
            ' Author   : Corrado Cavalli
            '
            '      *Parameters Info*
            '
            ' Notes    :
            '===================================================
            Dim del As CommEventHandler = Me.CommEventEvent
            If (Not del Is Nothing) Then
                Dim SafeInvoker As ISynchronizeInvoke
                Try
                    SafeInvoker = DirectCast(del.Target, ISynchronizeInvoke)
                Catch
                End Try
                If (Not SafeInvoker Is Nothing) Then
                    SafeInvoker.Invoke(del, New Object() {source, mask})
                Else
                    del.Invoke(source, mask)
                End If
            End If
        End Sub
    #End Region

    End Class
    #End Region

    #Region "Exceptions"
    Public Class CIOChannelException : Inherits ApplicationException
     '===================================================
     '
     '  Module   :  CChannellException
     '  Description:  Customized Channell Exception
     '  Created   :  17/10/2001 - 10:32:37
     '
     '  Notes    :  This exception is raised when NACK error found
     '===================================================
     Sub New(ByVal Message As String)
      MyBase.New(Message)
     End Sub
     Sub New(ByVal Message As String, ByVal InnerException As Exception)
      MyBase.New(Message, InnerException)
     End Sub
    End Class
    Public Class IOTimeoutException : Inherits CIOChannelException
     '===================================================
     '
     ' Description : Timeout customized exception
     ' Created   : 28/02/2002 - 10:43:43
     '
     '      *Parameters Info*
     '
     ' Notes    :
     '===================================================
     Sub New(ByVal Message As String)
      MyBase.New(Message)
     End Sub
     Sub New(ByVal Message As String, ByVal InnerException As Exception)
      MyBase.New(Message, InnerException)
     End Sub
    End Class

    #End Region

  • 相关阅读:
    系统安装之:虚拟机VMware V12.0.1 专业版 + 永久密钥
    PHP之:析构函数
    HTML之:让网页中的<a>标签属性统一设置-如‘新窗口打开’
    HTML之:fieldset——一个不常用的HTML标签
    系统配置 之:远程桌面连接(win7系统)
    Code笔记 之:注册页面验证码
    PHP之:PHP框架
    Code笔记 之:防盗链(图片)
    Ehcache(2.9.x)
    Ehcache(2.9.x)
  • 原文地址:https://www.cnblogs.com/msnadair/p/745993.html
Copyright © 2011-2022 走看看