📄 chap12_3.htm
字号:
<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 + -