我的程序使用定时器Timer控件作为事件驱动,做法是这样的:
1.form load的时候,打开串口,并定义好timer控件。
2.timer控件触发事件的时候(100ms一次),WriteFile到串口,sleep 50 等待50ms,然后ReadFile,如下:fReadStat = ReadFile(m_Handle, bytBuffer(0), lngSize, lngBytesRead, m_OverlappedRead)然后处理数据。我在VB中按F5运行,通讯器发送,接收灯都会闪动,表示发出收回都有数据,而且每次都可以读取出来数据,而且处理也很正常。但是我把这个工程生成EXE文件后,运行这个EXE文件,那么通讯器发送,接收灯也都会闪动,表示发出收回都有数据,但是奇怪的是ReadFile就读不到数据了,而通讯器显示有数据返回,我把Sleep等待时间延长到100ms,定时器触发发送接收时间延长到1000ms,效果还是一样。貌似使用了定时器进行读写操作就读不到数据了,而我用按钮点击发送,点击接收,却能很好的读取数据(不管是否生产EXE)。为什么在VB中按F5可以,生成EXE之后就不可以了呢?求解释……想不通啊

解决方案 »

  1.   

    不要用 Sleep 这样的延时,用 WaitCommEvent API 来挂起等待接收事件,然后 ReadFile 读取缓存。
      

  2.   

    也是建议不要使用Sleep,因为它会阻塞程序。可以把ReadFile放置到Timer的下一个循环中。
    或者一个TimerWriteFile一个TimerReadFile也不错。
      

  3.   

    sleep 会挂起当前线程。
    作为一般 exe,只有一个线程,挂起后就不能响应硬件通讯了。
    而在 IDE 中调试运行,sleep 只挂起了调试线程(程序),IDE 本身还是有响应的。既然用到了定时器,可以这样做:
    1)先用 ReadFile 读取上个定时的回复;
    2)再用 WriteFile 发送本次的数据。
    根本不需要 sleep。
      

  4.   

    哥们,还是不行,使用Tiger_Zhao的方法,之后,去掉sleep延时,同样的,程序下F5运行没问题,但是生成EXE之后就又读不到数据了。of123,请你告诉我怎么用WaitCommEvent API 处理这种情况,我试着把读取指令中的各行加入运行参数在界面上显示,程序段如题,这个类是我在网上挡下来来,是叶帆写的,基本上都没怎么改。其中读是这一段:
    fReadStat = ReadFile(m_Handle, bytBuffer(0), lngSize, lngBytesRead, m_OverlappedRead)
        
        
        '-------------
        
        If fReadStat = 0 Then
            If GetLastError() = ERROR_IO_PENDING Then                           '重叠 I/O 操作在进行中
                dwRes = WaitForSingleObject(m_OverlappedRead.hEvent, Overtime)  '等待,直到超时
                Select Case dwRes
                Case WAIT_OBJECT_0:   '读完成                frmMain.Label4.Caption = m_Handle
                    If GetOverlappedResult(m_Handle, m_OverlappedRead, lngBytesRead, 0) = 0 Then
                        '错误
                        fReadData = -2
                        Exit Function
                    End If
                Case WAIT_TIMEOUT:    '超时                fReadData = -1
                    Exit Function
                Case Else:                  'WaitForSingleObject 错误            End Select
            End If    End If    fReadData = lngBytesRead
    程序F5运行情况下,可以运行到Case WAIT_OBJECT_0,执行读完成。但是生成EXE之后,执行到
    If GetLastError() = ERROR_IO_PENDING Then就跳出if,表示if之后的判断为否。我想知道这是为什么呢?我现在是搞不清楚这个readfile的执行机制,数据是有返回的,这个我用F5运行是有收到数据,而且通讯器的REC灯是在闪动的。
      

  5.   

    在工程中试试全编译执行看效果跟exe的一样么?(Ctrl+F5)
      

  6.   

    话说,当数据写入串口寄存器之后,实际发送由硬件接管,和VB的线程是没有关系滴。sleep是没有问题的,我的通信都是这样处理。
      

  7.   

    不用去只用api读写串口啦,使用mscomm控件帮组你处理很多的内部细节,何乐不为?
      

  8.   


    Option Explicit
    Dim bolRead As Boolean
    Private Sub Form_Load()
        Timer1.Interval = 1000
    End SubPrivate Sub Timer1_Timer()
        If Not bolRead Then
            '写
            WriteFile
        Else
            '读
            ReadFile
        End If
        bolRead = Not bolRead
    End Sub
    用类似于这样的形式,一发一收,有什么不对吗?
      

  9.   


    mscomm不合适我的工程,不解释
      

  10.   


    不是说不行,我用F5运行是可以啊,没问题的,但是生成EXE就不行了,读不到数据,我是想弄明白这个ReadFile的运行机制是怎样的,我的问题到底出在哪里。不然这个问题一直都解决不了。
      

  11.   

    你适当的把Timer.Interval放大点点。比如2秒
      

  12.   

    我的timer是50ms,我改过100ms,1000ms,甚至5000ms都有试过。效果都一样的,readfile的重置IO没有发生,也就是说读未成功,我是循环发送的,那么即便是我这次没有读成功,那么我的缓冲区还是有数据的,所以,我说应该是readfile这个地方可能有什么问题吧。
      

  13.   

    这是我的ReadFile
    ReadFile lngPortHandle, BytesBuffer(0), UBound(BytesBuffer) + 1, dwBytesRead, 0
    这是你的ReadFile
    ReadFile m_Handle, bytBuffer(0), lngSize, lngBytesRead, m_OverlappedRead问题是不是出在最后一个参数上?个人认为有可能
      

  14.   

    exe 执行后凭什么判断是 If GetLastError() = ERROR_IO_PENDING Then 为假而不是 If fReadStat = 0 Then 为假?
    多写点日志,仔细对比两种运行状态的差别,先将出问题的地方找出来,而不是让大家猜!
      

  15.   

    我在界面上添加了Label,在ReadFile的各语句之后加入了labelX.caption=** 各语句特性的标识。还有一个问题,我是在类里面声明的TimerPrivate WithEvents pteTmrCOMM   As Timer
    然后再给予实例化和设置
    Public Property Let setTimerOCX(ByRef LcTimer As Timer)              '实例化Timer控件
        Set pteTmrCOMM = LcTimer
        pteTmrCOMM.Enabled = FalseEnd Property
    然后再开始通讯的时候进行初始化Public Sub sOpenThePort(ByVal LcComPort As Long, ByVal LcComSetting As String)
        
        
        fOpenPort LcComPort, LcComSetting‘打开串口
        fClearInBuf’清除
        fClearOutBuf‘清除
        
        '-------给Timer控件进行定义
        pteTmrCOMM.Interval = 100   '100ms通讯一次
        pteTmrCOMM.Enabled = True
        
        
    End Sub是不是这个类里面的Timer控件造成了这种情况的发生呢?
      

  16.   

    我刚才新建了一个工程,只有一个Form1,代码全写在Form里面,在form1的timer1控件中进行错时读写操作,生成EXE之后,是成功的。难道是类模块里面用timer事件就不行?
      

  17.   

    14楼的意见我试过了,我看问题貌似是出在我的类模块里面的Timer 事件,但是为什么会这样我也不清楚,把类里面的代码全部写到Form里面,然后用Form上的实体Timer进行错时读写,数据都是正常,生成EXE之后也是正常,放到类里,用Form的Timer控件实例化给类里面的WithEvent的Timer,F5正常,生成EXE就读不到数据了。
      

  18.   

    正在测试原因,如果不能实例化类,全部代码写在Form里面,这样应该不是很好的解决方案
      

  19.   


    你能不能把你的这个类贴出来我看看,这句ReadFile的最后一个参数不能为0吧,是指定的一个自定义类型。
      

  20.   


    Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As OVERLAPPED) As Long这个ReadFile,其中nNumberOfBytesToRead是指定要读多少byte的数据出来,但是如果我指定多了,即便是多了一个Byte,生成的EXE也会报错,如果指定少了,那么顶多是没读完,下次接着读上次剩下的。但是由于现场通讯有时候有干扰,返回的包可能会多,在正常情况下我能确定是15个byte,但是有时候干扰会多包、少包。我能否消除这个错误,或者这样讲,不管缓冲区有多少数据,我都读50个byte,如果没有这么多数据,那么后面的补零就是了,不要报错,我测试过,即便是有干扰,返回都不会大于50个byte。
      

  21.   

    下载这个,进去查询ReadFile上面说最后一个参数是Byval xxx as long的话,要传送0
      

  22.   

    Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As OVERLAPPED) As Long这是ReadFileDeclare Function ReadFileEx Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpOverlapped As OVERLAPPED, ByVal lpCompletionRoutine As Long) As Long这是ReadFileX
      

  23.   

    我的实现代码中是:
    Public Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, _
                                                     lpBuffer As Any, _
                                                     ByVal nNumberOfBytesToRead As Long, _
                                                     lpNumberOfBytesRead As Long, _
                                                     ByVal lpOverlapped As Long) As Long
      

  24.   

    我现在大概是找到出错的地方了,如果我指定ReadFile的nNumberOfBytesToRead参数是正确的,而且缓冲区里面刚好有这么多byte的数据,那么,我读就会成功,我是指生成EXE的情况下,我指定错误的nNumberOfBytesToRead参数,在VB下F5也能成功,但是EXE就不能成功,我想知道这个如何解决。
      

  25.   

    下载了,我用了你的那个ReadFile定义,但是读取不成功,我想要你整个实现读写的类,我不知道你跟我的到底还有那些不同,我贴我的出来,成功读写了的,只是在指定错误的nNumberOfBytesToRead时生成EXE不能成功。
    '*************************************************************************
    '**模 块 名:SerialPort
    '**说    明:YFsoft 版权所有2006 - 2007(C)
    '**创 建 人:叶帆
    '**日    期:2006-08-17 14:32:29
    '**修 改 人:
    '**日    期:
    '**描    述:串口异步读写(API)
    '**版    本:V1.0.0
    '*************************************************************************Private Type COMSTAT
        fCtsHold As Long
        fDsrHold As Long
        fRlsdHold As Long
        fXoffHold As Long
        fXoffSent As Long
        fEof As Long
        fTxim As Long
        fReserved As Long
        cbInQue As Long
        cbOutQue As Long
    End Type
     
    Private Type COMMTIMEOUTS
        ReadIntervalTimeout As Long
        ReadTotalTimeoutMultiplier As Long
        ReadTotalTimeoutConstant As Long
        WriteTotalTimeoutMultiplier As Long
        WriteTotalTimeoutConstant As Long
    End Type
     
    Private Type DCB
        DCBlength As Long
        BaudRate As Long
        'DWORD DCBlength;      /* sizeof(DCB)                     */
        'DWORD BaudRate;       /* Baudrate at which running       */
    '        /* Binary Mode (skip EOF check)    */
    '        /* Enable parity checking          */
    '    /* CTS handshaking on output       */
    '    /* DSR handshaking on output       */
    '     /* DTR Flow control                */
    '    /* DSR Sensitivity              */
    '    /* Continue TX when Xoff sent */
    '          /* Enable output X-ON/X-OFF        */
    '           /* Enable input X-ON/X-OFF         */
    '     /* Enable Err Replacement          */
    '          /* Enable Null stripping           */
    '     /* Rts Flow control                */
    '    /* Abort all reads and writes on Error */
    '         /* Reserved                        */
        fBitFields As Long 'See Comments in Win32API.Txt
        wReserved As Integer
        XonLim As Integer
        XoffLim As Integer
        ByteSize As Byte
        Parity As Byte
        StopBits As Byte
        XonChar As Byte
        XoffChar As Byte
        ErrorChar As Byte
        EofChar As Byte
        EvtChar As Byte
        wReserved1 As Integer 'Reserved; Do Not Use
    End Type
     
    Private Type OVERLAPPED
        Internal As Long
        InternalHigh As Long
        offset As Long
        OffsetHigh As Long
        hEvent As Long
    End Type
     
    Private Type SECURITY_ATTRIBUTES
        nLength As Long
        lpSecurityDescriptor As Long
        bInheritHandle As Long
    End Type'Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long
     
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Private Declare Function GetLastError Lib "kernel32" () As Long
    Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As OVERLAPPED) As Long
    Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As OVERLAPPED) As Long 'OVERLAPPED
    Private Declare Function SetCommTimeouts Lib "kernel32" (ByVal hFile As Long, lpCommTimeouts As COMMTIMEOUTS) As Long
    Private Declare Function GetCommTimeouts Lib "kernel32" (ByVal hFile As Long, lpCommTimeouts As COMMTIMEOUTS) As Long
    Private Declare Function BuildCommDCB Lib "kernel32" Alias "BuildCommDCBA" (ByVal lpDef As String, lpDCB As DCB) As Long
    Private Declare Function SetCommState Lib "kernel32" (ByVal hCommDev As Long, lpDCB As DCB) As Long
    Private Declare Function GetCommState Lib "kernel32" (ByVal nCid As Long, lpDCB As DCB) As Long
    Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
    Private Declare Function FlushFileBuffers Lib "kernel32" (ByVal hFile As Long) As Long
    Private Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA" (lpEventAttributes As SECURITY_ATTRIBUTES, ByVal bManualReset As Long, ByVal bInitialState As Long, ByVal lpName As String) As Long
    Private Declare Function SetCommMask Lib "kernel32" (ByVal hFile As Long, ByVal dwEvtMask As Long) As Long
    Private Declare Function SetEvent Lib "kernel32" (ByVal hEvent As Long) As Long
    Private Declare Function PurgeComm Lib "kernel32" (ByVal hFile As Long, ByVal dwFlags As Long) As Long
    Private Declare Function ClearCommError Lib "kernel32" (ByVal hFile As Long, lpErrors As Long, lpStat As COMSTAT) As Long
    Private Declare Function GetOverlappedResult Lib "kernel32" (ByVal hFile As Long, lpOverlapped As OVERLAPPED, lpNumberOfBytesTransferred As Long, ByVal bWait As Long) As Long
    Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
    Private Declare Function SetupComm Lib "kernel32" (ByVal hFile As Long, ByVal dwInQueue As Long, ByVal dwOutQueue As Long) As Long
     
    Private Const GENERIC_WRITE = &H40000000
    Private Const GENERIC_READ = &H80000000
    Private Const OPEN_EXISTING = 3
    Private Const FILE_ATTRIBUTE_NORMAL = &H80
    Private Const FILE_FLAG_OVERLAPPED = &H40000000
    Private Const DTR_CONTROL_DISABLE = &H0
    Private Const RTS_CONTROL_ENABLE = &H1
    Private Const PURGE_RXABORT = &H2
    Private Const PURGE_RXCLEAR = &H8
    Private Const PURGE_TXABORT = &H1
    Private Const PURGE_TXCLEAR = &H4
    Private Const ERROR_IO_PENDING = 997
    Private Const STATUS_WAIT_0 = &H0
    Private Const WAIT_OBJECT_0 = (STATUS_WAIT_0 + 0)
    Private Const WAIT_TIMEOUT = 258&
     
    Private m_Handle As Long
    Private m_OverlappedRead As OVERLAPPED
    Private m_OverlappedWrite As OVERLAPPED
     
    '*************************************************************************
    '**函 数 名:OpenPort
    '**输    入:ComNumber(Long)     - 串口号
    '**        :Comsettings(String) - 配置信息
    '**输    出:(Long) - 0 成功 非 0 失败
    '**功能描述:打开串口
    '**全局变量:
    '**调用模块:
    '**作    者:叶帆
    '**日    期:2006-08-17 14:40:14
    '**修 改 人:
    '**日    期:
    '**版    本:V1.0.0
    '*************************************************************************
    Public Function OpenPort(ComNumber As Long, Comsettings As String, Optional lngInSize As Long = 1024, Optional lngOutSize As Long = 512) As Long
        On Error GoTo handelinitcom
        Dim RetVal As Long
        Dim CtimeOut As COMMTIMEOUTS, dcbs As DCB
        Dim strCOM As String, strConfig As String
     
        strCOM = IIf(ComNumber > 9, "\\.\COM", "COM") & Format(ComNumber, "0")
    '    strCOM = "COM" & Format(ComNumber, "0")
        m_Handle = CreateFile(strCOM, GENERIC_READ Or GENERIC_WRITE, 0, 0&, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL Or FILE_FLAG_OVERLAPPED, 0)
        If m_Handle = -1 Then
            OpenPort = -1
            Exit Function
        End If
     
        '设置dcb块
        dcbs.DCBlength = Len(dcbs)                           '长度
        Call GetCommState(m_Handle, dcbs)
     
        '波特率,奇偶校验,数据位,停止位  如:9600,n,8,1
        strConfig = "COM" & Format(ComNumber, "0") & ":" & Comsettings
        Call BuildCommDCB(strConfig, dcbs)
     
        '------------------------------
        '    dcbs.fBinary = 1                          '二进制方式
        '    dcbs.fOutxCtsFlow = 0                     '不用CTS检测发送流控制
        '    dcbs.fOutxDsrFlow = 0                     '不用DSR检测发送流控制
        '    dcbs.fDtrControl = DTR_CONTROL_DISABLE    '禁止DTR流量控制
        '    dcbs.fDsrSensitivity = 0                  '对DTR信号线不敏感
        '    dcbs.fTXContinueOnXoff = 1                '检测接收缓冲区
        '    dcbs.fOutX = 0                            '不做发送字符控制
        '    dcbs.fInX = 0                             '不做接收控制
        '    dcbs.fErrorChar = 0                       '是否用指定字符替换校验错的字符
        '    dcbs.fNull = 0                            '保留NULL字符
        '    dcbs.fRtsControl = RTS_CONTROL_ENABLE     '允许RTS流量控制
        '    dcbs.fAbortOnError = 0                    '发送错误后,继续进行下面的读写操作
        '    dcbs.fDummy2 = 0                          '保留
        dcbs.fBitFields = 1 * 2 ^ 0 Or DTR_CONTROL_DISABLE * 2 ^ 4 Or 1 * 2 ^ 7 Or RTS_CONTROL_ENABLE * 2 ^ 12
     
        dcbs.wReserved = 0                        '没有使用,必须为0
        dcbs.XonLim = 0                           '指定在XOFF字符发送之前接收到缓冲区中可允许的最小字节数
        dcbs.XoffLim = 0                          '指定在XOFF字符发送之前缓冲区中可允许的最小可用字节数
        dcbs.XonChar = 0                          '发送和接收的XON字符
        dcbs.XoffChar = 0                         '发送和接收的XOFF字符
        dcbs.ErrorChar = 0                        '代替接收到奇偶校验错误的字符
        dcbs.EofChar = 0                          '用来表示数据的结束
        dcbs.EvtChar = 0                          '事件字符,接收到此字符时,会产生一个事件
        'dcbs.wReserved1 = 0                      '没有使用
        'dcbs.BaudRate =9600                      '波特率
        'dcbs.Parity=0                            '奇偶校验
        'dcbs.ByteSize=8                          '数据位
        'dcbs.StopBits=0                          '停止位
        '------------------------------
     
        If dcbs.Parity = 0 Then                   ' 0-4=None,Odd,Even,Mark,Space
            dcbs.fBitFields = dcbs.fBitFields And &HFFFD     'dcbs.fParity = 0                      '奇偶校验无效
        Else
            dcbs.fBitFields = dcbs.fBitFields Or &H2         'dcbs.fParity = 1                      '奇偶校验有效
        End If
     
        '超时设置
        CtimeOut.ReadIntervalTimeout = 20                  '0
        CtimeOut.ReadTotalTimeoutConstant = 1              '2500
        CtimeOut.ReadTotalTimeoutMultiplier = 1            '0
        CtimeOut.WriteTotalTimeoutConstant = 10            '2500
        CtimeOut.WriteTotalTimeoutMultiplier = 1           '0
       
        RetVal = SetCommTimeouts(m_Handle, CtimeOut)
     
        If RetVal = -1 Then
            RetVal = GetLastError()
            OpenPort = RetVal
            RetVal = CloseHandle(m_Handle)
            Exit Function
        End If
     
      

  26.   

    接上面    '获取信号句柄
        Dim lpEventAttributes1 As SECURITY_ATTRIBUTES
        Dim lpEventAttributes2 As SECURITY_ATTRIBUTES
     
        m_OverlappedRead.hEvent = CreateEvent(lpEventAttributes1, 1, 0, 0)
        m_OverlappedWrite.hEvent = CreateEvent(lpEventAttributes2, 1, 0, 0)
     
        '判断设置参数是否成功   设置输入和输出缓冲区是否成功
        If SetCommState(m_Handle, dcbs) = -1 Or SetupComm(m_Handle, lngInSize, lngOutSize) = -1 Or m_OverlappedRead.hEvent = 0 Or m_OverlappedWrite.hEvent = 0 Then
            RetVal = GetLastError()
            OpenPort = RetVal
            If (m_OverlappedRead.hEvent <> 0) Then CloseHandle (m_OverlappedRead.hEvent)
            If (m_OverlappedWrite.hEvent <> 0) Then CloseHandle (m_OverlappedWrite.hEvent)
            Call CloseHandle(m_Handle)
            m_Handle = 0
            Exit Function
        End If
     
        OpenPort = 0
        Exit Function
    handelinitcom:
        Call CloseHandle(m_Handle)
        m_Handle = 0
        OpenPort = -2
        Exit Function
    End Function
     
    '*************************************************************************
    '**函 数 名:ClosePort
    '**输    入:无
    '**输    出:(Long) - 0 成功 -1 失败
    '**功能描述:关闭串口
    '**全局变量:
    '**调用模块:
    '**作    者:叶帆
    '**日    期:2006-08-17 14:56:13
    '**修 改 人:
    '**日    期:
    '**版    本:V1.0.0
    '*************************************************************************
    Public Function ClosePort() As Long
        If (m_Handle = 0) Then
            ClosePort = 1
            Exit Function
        End If
     
        Call SetCommMask(m_Handle, 0)
        Call SetEvent(m_OverlappedRead.hEvent)
        Call SetEvent(m_OverlappedWrite.hEvent)
     
        If (m_OverlappedRead.hEvent <> 0) Then CloseHandle (m_OverlappedRead.hEvent)
        If (m_OverlappedWrite.hEvent <> 0) Then CloseHandle (m_OverlappedWrite.hEvent)
     
        If CloseHandle(m_Handle) <> 0 Then
            ClosePort = 0
        Else
            ClosePort = -1
        End If
     
        m_Handle = 0
    End Function
     
    '*************************************************************************
    '**函 数 名:ClearInBuf
    '**输    入:无
    '**输    出:无
    '**功能描述:清空输入缓冲区
    '**全局变量:
    '**调用模块:
    '**作    者:叶帆
    '**日    期:2006-08-17 14:57:26
    '**修 改 人:
    '**日    期:
    '**版    本:V1.0.0
    '*************************************************************************
    Public Function ClearInBuf() As Long
        If (m_Handle = 0) Then
            ClearInBuf = 1
            Exit Function
        End If
        Call PurgeComm(m_Handle, PURGE_RXABORT Or PURGE_RXCLEAR)
        ClearInBuf = 0
    End Function
     
    '*************************************************************************
    '**函 数 名:ClearOutBuf
    '**输    入:无
    '**输    出:(Long) -
    '**功能描述:清空输出缓冲区
    '**全局变量:
    '**调用模块:
    '**作    者:叶帆
    '**日    期:2006-08-17 15:40:38
    '**修 改 人:
    '**日    期:
    '**版    本:V1.0.0
    '*************************************************************************
    Public Function ClearOutBuf() As Long
        If (m_Handle = 0) Then
            ClearOutBuf = 1
            Exit Function
        End If
        Call PurgeComm(m_Handle, PURGE_TXABORT Or PURGE_TXCLEAR)
        ClearOutBuf = 0
    End Function
     
    '*************************************************************************
    '**函 数 名:SendData
    '**输    入:bytBuffer()(Byte) - 数据
    '**        :lngSize(Long)     - 数据长度
    '**输    出:(Long) -
    '**功能描述:发送数据
    '**全局变量:
    '**调用模块:
    '**作    者:叶帆
    '**日    期:2006-08-17 15:43:42
    '**修 改 人:
    '**日    期:
    '**版    本:V1.0.0
    '*************************************************************************
    Public Function SendData(bytBuffer() As Byte, lngSize As Long) As Long
        On Error GoTo ToExit '打开错误陷阱
        '------------------------------------------------
        If (m_Handle = 0) Then
    '        SendData = 1
            SendData = -2
            Exit Function
        End If
     
        Dim dwBytesWritten As Long
        Dim bWriteStat As Long
        Dim ComStats As COMSTAT
        Dim dwErrorFlags As Long
     
        dwBytesWritten = lngSize
     
        Call ClearCommError(m_Handle, dwErrorFlags, ComStats)
        bWriteStat = WriteFile(m_Handle, bytBuffer(0), lngSize, dwBytesWritten, m_OverlappedWrite)
     
        If bWriteStat = 0 Then
            If GetLastError() = ERROR_IO_PENDING Then
                Call GetOverlappedResult(m_Handle, m_OverlappedWrite, dwBytesWritten, 1)                  '等待直到发送完毕
            End If
        Else
            dwBytesWritten = 0
        End If
     
        SendData = dwBytesWritten
        '------------------------------------------------
        Exit Function
        '----------------
    ToExit:
        SendData = -1
    End FunctionPublic Function ReadCOMMStatus() As Boolean
        
        Dim tpErrFlag As Long, tpComStats As COMSTAT
        
        
        Call ClearCommError(m_Handle, tpErrFlag, tpComStats)
        
        If tpComStats.cbInQue = 0 Then
            ReadCOMMStatus = False
        Else
            ReadCOMMStatus = True
        End If
        
    End Function
     
    '*************************************************************************
    '**函 数 名:ReadData
    '**输    入:bytBuffer()(Byte) - 数据
    '**        :lngSize(Long)     - 数据长度
    '**输    出:(Long) -
    '**功能描述:读取数据
    '**全局变量:
    '**调用模块:
    '**作    者:叶帆
    '**日    期:2006-08-17 16:04:38
    '**修 改 人:
    '**日    期:
    '**版    本:V1.0.0
    '*************************************************************************
    Public Function ReadData(bytBuffer() As Byte, lngSize As Long, Optional Overtime As Long = 3000) As Long
        On Error GoTo ToExit '打开错误陷阱
        '------------------------------------------------
        If (m_Handle = 0) Then
    '        ReadData = 1
            ReadData = -3
            Exit Function
        End If
     
        Dim lngBytesRead As Long
        Dim fReadStat As Long
        Dim dwRes  As Long
     
        lngBytesRead = lngSize
        
        '读数据
        
        
        fReadStat = ReadFile(m_Handle, bytBuffer(0), lngSize, lngBytesRead, m_OverlappedRead)
        If fReadStat = 0 Then
            If GetLastError() = ERROR_IO_PENDING Then                           '重叠 I/O 操作在进行中
                dwRes = WaitForSingleObject(m_OverlappedRead.hEvent, Overtime)  '等待,直到超时
                Select Case dwRes
                Case WAIT_OBJECT_0:   '读完成
                    If GetOverlappedResult(m_Handle, m_OverlappedRead, lngBytesRead, 0) = 0 Then
                        '错误
                        ReadData = -2
                        Exit Function
                    End If
                Case WAIT_TIMEOUT:    '超时
                    ReadData = -1
                    Exit Function
                Case Else:                  'WaitForSingleObject 错误
                End Select
            End If
        End If
        ReadData = lngBytesRead
        '------------------------------------------------
        Exit Function
        '----------------
    ToExit:
        ReadData = -1
    End Function
     
    '*************************************************************************
    '**函 数 名:Class_Terminate
    '**输    入:无
    '**输    出:无
    '**功能描述:
    '**全局变量:
    '**调用模块:
    '**作    者:叶帆
    '**日    期:2006-08-17 16:36:21
    '**修 改 人:
    '**日    期:
    '**版    本:V1.0.0
    '*************************************************************************
    Private Sub Class_Terminate()
        Call ClosePort
    End Sub
      

  27.   

    一个一个的读取?知道ReadFile返回False