⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chap12_3.htm

📁 vc教程,真正的程序员用Visual C++。如果你想当程序员
💻 HTM
📖 第 1 页 / 共 2 页
字号:
            <p align="JUSTIFY">LPDWORD lpNumberOfBytesRead, // 实际读入的字节数</p>
            <p align="JUSTIFY">LPOVERLAPPED lpOverlapped // 指向一个OVERLAPPED结构</p>
            <p align="JUSTIFY">); //若返回TRUE则表明操作成功</p>
          </blockquote>
          <p> </p>
          <p align="JUSTIFY">  需要注意的是如果该函数因为超时而返回,那么返回值是TRUE。参数lpOverlapped在重叠操作时应该指向一个OVERLAPPED结构,如果该参数为NULL,那么函数将进行同步操作,而不管句柄是否是由FILE_FLAG_OVERLAPPED标志建立的。</p>
          <p align="JUSTIFY">  当ReadFile和WriteFile返回FALSE时,不一定就是操作失败,线程应该调用GetLastError函数分析返回的结果。例如,在重叠操作时如果操作还未完成函数就返回,那么函数就返回FALSE,而且GetLastError函数返回ERROR_IO_PENDING。</p>
          <p align="JUSTIFY">  在使用重叠I/O时,线程需要创建OVERLAPPED结构以供读写函数使用。OVERLAPPED结构最重要的成员是hEvent,hEvent是一个事件对象句柄,线程应该用CreateEvent函数为hEvent成员创建一个手工重置事件,hEvent成员将作为线程的同步对象使用。如果读写函数未完成操作就返回,就那么把hEvent成员设置成无信号的。操作完成后(包括超时),hEvent会变成有信号的。</p>
          <p align="JUSTIFY">  如果GetLastError函数返回ERROR_IO_PENDING,则说明重叠操作还为完成,线程可以等待操作完成。有两种等待办法:一种办法是用象WaitForSingleObject这样的等待函数来等待OVERLAPPED结构的hEvent成员,可以规定等待的时间,在等待函数返回后,调用GetOverlappedResult。另一种办法是调用GetOverlappedResult函数等待,如果指定该函数的bWait参数为TRUE,那么该函数将等待OVERLAPPED结构的hEvent 
            事件。GetOverlappedResult可以返回一个OVERLAPPED结构来报告包括实际传输字节在内的重叠操作结果。</p>
          <p align="JUSTIFY">  如果规定了读/写操作的超时,那么当超过规定时间后,hEvent成员会变成有信号的。因此,在超时发生后,WaitForSingleObject和GetOverlappedResult都会结束等待。WaitForSingleObject的dwMilliseconds参数会规定一个等待超时,该函数实际等待的时间是两个超时的最小值。注意GetOverlappedResult不能设置等待的时限,因此如果hEvent成员无信号,则该函数将一直等待下去。</p>
          <p align="JUSTIFY">  在调用ReadFile和WriteFile之前,线程应该调用ClearCommError函数清除错误标志。该函数负责报告指定的错误和设备的当前状态。</p>
          <p align="JUSTIFY">  调用PurgeComm函数可以终止正在进行的读写操作,该函数还会清除输入或输出缓冲区中的内容。</p>
          <p><b> </b></p>
          <p align="JUSTIFY"> <b></b><font color="#3973DE" face="Times New Roman">12.3.4 
            </font><font color="#3973DE">通信事件</font></p>
          <p align="JUSTIFY">  在Windows 95/NT中,WM_COMMNOTIFY消息已经取消,在串行口产生一个通信事件时,程序并不会收到通知消息。线程需要调用WaitCommEvent函数来监视发生在串行口中的各种事件,该函数的第二个参数返回一个事件屏蔽变量,用来指示事件的类型。线程可以用SetCommMask建立事件屏蔽以指定要监视的事件,表12.4列出了可以监视的事件。调用GetCommMask可以查询串行口当前的事件屏蔽。</p>
          <p align="JUSTIFY"><b> </b></p>
          <b> 
          <p align="CENTER">表12.4 通信事件</p>
          </b> 
          <table border="1" cellspacing="1" cellpadding="1" width="579">
            <tr> 
              <td width="35%"><b>
                <p align="JUSTIFY">事件屏蔽
                </b></td>
              <td width="65%"><b>
                <p align="JUSTIFY">含义
                </b></td>
            </tr>
            <tr> 
              <td width="35%">
                <p align="JUSTIFY">EV_BREAK
              </td>
              <td width="65%">
                <p align="JUSTIFY">检测到一个输入中断
              </td>
            </tr>
            <tr> 
              <td width="35%">
                <p align="JUSTIFY">EV_CTS
              </td>
              <td width="65%">
                <p align="JUSTIFY">CTS信号发生变化
              </td>
            </tr>
            <tr> 
              <td width="35%">
                <p align="JUSTIFY">EV_DSR
              </td>
              <td width="65%">
                <p align="JUSTIFY">DSR信号发生变化
              </td>
            </tr>
            <tr> 
              <td width="35%">
                <p align="JUSTIFY">EV_ERR
              </td>
              <td width="65%">
                <p align="JUSTIFY">发生行状态错误
              </td>
            </tr>
            <tr> 
              <td width="35%">
                <p align="JUSTIFY">EV_RING
              </td>
              <td width="65%">
                <p align="JUSTIFY">检测到振铃信号
              </td>
            </tr>
            <tr> 
              <td width="35%">
                <p align="JUSTIFY">EV_RLSD
              </td>
              <td width="65%">
                <p align="JUSTIFY">RLSD(CD)信号发生变化
              </td>
            </tr>
            <tr> 
              <td width="35%">
                <p align="JUSTIFY">EV_RXCHAR
              </td>
              <td width="65%">
                <p align="JUSTIFY">输入缓冲区接收到新字符
              </td>
            </tr>
            <tr> 
              <td width="35%">
                <p align="JUSTIFY">EV_RXFLAG
              </td>
              <td width="65%">
                <p align="JUSTIFY">输入缓冲区收到事件字符
              </td>
            </tr>
            <tr> 
              <td width="35%">
                <p align="JUSTIFY">EV_TXEMPTY
              </td>
              <td width="65%">
                <p align="JUSTIFY">发送缓冲区为空
              </td>
            </tr>
          </table>
          <p align="JUSTIFY">  WaitCommEvent即可以同步使用,也可以重叠使用。如果串口是用FILE_FLAG_OVERLAPPED标志打开的,那么WaitCommEvent就进行重叠操作,此时该函数需要一个OVERLAPPED结构。线程可以调用等待函数或GetOverlappedResult函数来等待重叠操作的完成。</p>
          <p align="JUSTIFY">  当指定范围内的某一事件发生后,线程就结束等待并把该事件的屏蔽码设置到事件屏蔽变量中。需要注意的是,WaitCommEvent只检测调用该函数后发生的事件。例如,如果在调用WaitCommEvent前在输入缓冲区中就有字符,则不会因为这些字符而产生EV_RXCHAR事件。</p>
          <p align="JUSTIFY">  如果检测到输入的硬件信号(如CTS、RTS和CD信号等)发生了变化,线程可以调用GetCommMaskStatus函数来查询它们的状态。而用EscapeCommFunction函数可以控制输出的硬件信号(如DTR和RTS信号)。</p>
          <div align="center">
            <center>
              <table border="0" cellpadding="0" cellspacing="0" width="615">
                <tr> 
                  <td><a href="chap12_2.htm">上一页</a></td>
                  <td>
                    <p align="right"><a href="chap12_4.htm">下一页</a>
                  </td>
                </tr>
              </table>
              <p><a href="http://www.cpcw.com">电脑报首页</a> <a href="../../index.htm">网络学院首页</a></p>
            </center>
          </div>
          <font size="5">
          <hr noshade color="#3973DE" size="1">
          </font>
          <p align="center"><font size="5"></font><font size="2" color="#000000">本教程由<a href="http://vcdynasty.yeah.net">Visual 
            C++王朝(Where programmers come together)</a>协助制作<br>
            未经许可,请勿以任何形式复制</font>
        </td>
      </tr>
    </table>
    </center>
</div>

</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -