-
vb教程之Windows环境下的串行数据通信程序设计
夏云
摘 要 该文详细讨论了MSCOMM.VBX通信控件在Windows平台下的通信软件设计方法,借
助于Visual Basic所附的通信控件能非常方便地开发出高级和专业性通信软件来满足不同
业务的需要。
关键词 Windows Visual Basic 通信控件 通信软件
在Windows操作系统平台上开发通信软件时,虽然Windows 3.1 SDK提供了完备的API应
用程序接口函数和以中断方式驱动的通信设备驱动程序COMM.DRV,从而可以用C或C++来完成
这类应用程序的设计,但其复杂化和专业化程度仍然很高。所以,目前许多软件开发人员都
在使用Microsoft Visual Basic来开发Windows应用程序。本文将详细叙述VB环境的通信软
件开发方法,通过对通信控件MSCOMM.VBX的分析,我们可以看到利用VB来开发Windows平台下
的通信软件非常简单。最后结合我们工作中的一个实例来完整地描述该类软件的设计方法
。
一、MSCOMM.VBX的描述
VB中的串行通信控件已全面提供了使用RS-232来进行数据通信软件开发设计的所有细
则,Microsoft Visual Basic 3.0中的MSCOMM.VBX(需要安装在indowsystem\目录下)是199
2年Crescent software Inc. 公司专为Microsoft的VB平台设计的,它使用以下两种不同的
方式来处理和解决各类通信软件的开发和设计问题。
(1) 事件驱动,它和我们用C/C++写Windows软件时的窗口回调函数类似,是一种功能强
大的处理问题的方法。在实际工作中,往往要求我们处理许多通信中的相关事件。例如:当
线路数据到达本端或CD(Carrier Detect)和RTS(Request To Send)信号线状态发生变化时
,这就要求我们使用相应的事件来跟踪和处理。在该控件中,是使用OnComm来实现的,它也包
括检测和处理通信错误等方面的问题。以下是MSCOMM详细的错误和事件列表(读者可参阅S
KD或MSC/C++ 7.0等中的Windows.h有关的通信部分常数和函数原型):
MSCOMM_ER_BREAKA收到一个Break signal.
MSCOMM_ER_CDTOCD信号超时
MSCOMM_ER_CTSTOCTS信号超时
MSCOMM_ER_DSRTODSR信号超时
MSCOMM_ER_FRAME帧错误发生
MSCOMM_ER_OVERRUN接收数据丢失
MSCOMM_ER_RXOVER接收缓冲器溢出
MSCOMM_ER_RXPARITY纠验错
MSCOMM_ER_TXFULL发送缓冲器满
MSCOMM_EV_CDCD信号改变
MSCOMM_EV_CTSCTS信号改变
MSCOMM_EV_DSRDSR信号改变
MSCOMM_EV_EOF收到一个文本文件结束字符(26)
MSCOMM_EV_RING检测到一个振铃信号
MSCOMM_EV_RECEIVE接收到设定的字符数时产生该事件
MSCOMM_EV_SEND发生缓冲器中的字符数低于设定的数值时产生该事件
以上常数定义在CONSTANT.TXT文件中。
(2) 查询方式,由程序设计者来负责读取CommEvent的值并处理所发生的错误或事件。
通常简单的应用程序设计可采用这种方法。
使用通信控件开发通信软件时,能非常简单地设计出同时访问多个通信口的程序,这就
是Windows的好处。例如使用Commi.OnComm,其中1≤i≤n(n:当前可用的通信口),就可以设
计多个通信串口处理程序。例如,一个基于电话网用来检索信息资料的小型服务器的后台软
件的设计应用就是一个很好的例子。MSCOMM.VBX中提供了27个关于通信控件方面的属性,以
下列出最重要的几个:
CommPort设置和返回通信口的数目
Settings设置和返回以字符串形式给出的数据通信格式:波特率,校验,数据位和停止
位
PortOpen设置和返回通信口的状态(包括打开和关闭一个通信口)
Input读串行数据接收缓冲器
Output发送一个串
在MSCOMM.VBX中,有两个与Input和Output性质相等同的函数;
(1) 输入函数,从串行通信接收缓冲器中读取字符串,句型如下:
Comlnput(By Val hWnd As Integer, lpData As Any,By Val cbData As Integer) A
s Integer
@@T8S14200.GIF;图1@@
返回值:本次读操作实际读取的字符数
(2) 输出函数,向通信口发送一个字符串,句型如下:ComOutput(By Val hWnd As Inte
ger, lpData As Any,By Val cbData As Integer) As integer
@@T8S14201.GIF;图2@@
返回值:本次写操作实际发送的字符数
二、事件驱动和查询方式下的两种通信软件开发模板
这两种方式分别对应我们通常使用汇编或C/C++来写通信程序中的中断和查询方法。
(1) 事件驱动
下例是一个使用事件驱动方式设计通信程序的模板,我们只需根据自己的实际情况来选
择在下列的Case语句中插入相应的代码即可。
Sub Comm_OnComm()
Select Case Commi.CommEvent'i=1,2...
' 错误部分
Case MSCOMM-ER_BREAK'插入处理BREAK代码
Case MSCOMM-ER_CDTO'插入处理CD(RLSD)超时代码
Case MSCOMM-ER_CTSTO'插入处理CTS超时代码
Case MSCOMM-ER_DSRTO'插入处理DSR超时代码
Case MSCOMM-ER_FRAME'插入处理帧错误代码
Case MSCOMM-ER_OVERRUN'插入处理数据丢失代码
Case MSCOMM-ER_RXOVER'插入处理接收缓冲器溢出代码
Case MSCOMM-ER_RXPARITY'插入处理校验错误代码
Case MSCOMM-ER_TXFULL'插入处理发送缓冲器满代码
'事件部分
Case MSCOMM-EV_CD'插入处理CD信号改变代码
Case MSCOMM-EV_CTS'插入处理CTS信号改变代码
Case MSCOMM-EV_DSR'插入处理DST信号改变代码
Case MSCOMM-EV_EOF'插入处理收到一个文本文件结束字(26)代码
Case MSCOMM-EV_RING'插入处理检测到一个振铃信号代码
Case MSCOMM-EV_RECEIVE'插入接收到设定的字符数时产生该事件代码
Case MSCOMM-EV_SEND'插入处理发生缓冲器中的字符数低于设定的数值时产生该
事件的代码
End Select
End Sub
(2) 查询方式
查询方式,就是每个命令(含数据块)都要查询等待对它的回答。详细使用方法请见下文
的实例叙述。
三、一个完整例子
该程序的设计背景是全军医药信息网上电话拨号用户前台软件中的自动拨号部分,为节
省篇幅和说明问题,这里进行了重新编辑,但其本身是完整的。该程序帮助主人进行电话拨
号以呼通被叫。
调试环境:LEO 486/50,HiTec MODEM,院内电话脉冲拨号,使用串行口1,PWIN 3.1
程序Form由下列部分组成:List1电话号码显示列表;Label1拨号状态显示;Dial,Canc
el,
Quit三个按钮;MSCOMM.VBX通信控件。
' ------------
' Visual Basic 3.0 MSCOMM.VBX程序设计:使用MODEM拨号,人工通话
' 程序名:MDIALER.TXT
' 军事医学科学院计算中心 夏云,1995.2.12
' 运行:使用VB FILE中的Load Text项装入,按F5或生成.EXE文件运行
' ------------
Option Explicit
Dim PhoneNumbers$()'电话号码存储变量
Dim CancelFlag'Cancel按钮状态标志
Sub Dial(Number$)'拨号例程
Dim DialString$,FromModem$,dummy
'根据脉冲/双音多频拨号方式来选择DT/DP;
'所拨号码存放在变量PhoneNumbers$(Index)中;
'命令中的分号表示MODEM在拨号后重新回到命令状态;
'每个命令由回车符Chr$(13)结束;
DialString$="ATDT"+Number$+";"+Chr$(13)
Commi.Settings="2400,N,8,1"'设置帧格式
On Error Resume Next'错误恢复
Commi.PortOpen=True'启动该口工作
If Err Then'如果该口不可启动,则显示信息
MsgBox"当前串行通信端口不能工作,请选择使用另外端口。”
Exit Sub
End if
Commi.InBufferCount=0'清除接收缓冲器
Commi.Output=DialString$'开始拨号
Do'等待MODEM返回“OK”回答
dummy=DoEvents()'进入等待方式,将资源提交系统管理
If Commi.InBufferCount Then'若接收缓冲器中有数据存在,则读
FromModem$=FromModem$+Commi.Input
If InStr(FromModem$,"OK")Then '是否接收到“OK”
Beep'已经接收到“OK”,发蜂呜声
MsgBox"对方电话已经拨通,请摘话机并按回车或OK钮”
Exit Do
End If
End If
If CancelFlag Then'若Cancel钮按下则处理
CancelFlag=False
Exit Do
End If
Loop
Commi.Output="ATH"+Chr$(13)'挂断命令
Commi.PortOpen=False'关闭该口
End Sub
Sub DialButton_Click()'Dial按钮处理程序
Dim Number$,Temp$
DialButton.Enabled=False'Dial,Quit二个按钮同时无效
QuitButton.Enabled=False
CancelButton.Enabled=True'开放Cancel按钮
Number$=PhoneNumbers$(List1.ListIndex))'获得一个电话号码
Temp$=Status'保存状态
Status$=“正在拨号码:”+Number$
Dial Number$'拨号例程执行
DialButton.Enabled=True'拨号结束开放Dail,Quit按钮
DialButton.Enabled=True
CancelButton.Enabled=False'禁止Cancel按钮
Status=Temp$'恢复状态
End Sub
Sub Form_Load()
Commi.InputLen=0'设置0值:读全部接收缓冲器内容
MDialer.Show'显示窗口
List1.AddItem“四环医学研究院计算中心”
List1.AddItem“军事医学科学院情报所张华研究员”
ReDim PhoneNumbers$(0 To List1.ListCount-1)
PhoneNumbers$(0)="1-8233296"
PhoneNumber$(1)="1-8232255"
List1.ListIndex=0'默认第一个号码
End Sub
Sub List1-DblClick()'列表框选择号码启动拨号
DialButton-Click
End Sub
Sub CancelButton-Click()'Cancel按钮处理程序
CancelFlag=True'标识Cancel钮已按下
CancelButton.Enabled=False'取消该钮继续活动
End Sub
Sub QuitButton-Click()'Quit按钮
End'结束
End Sub
MSCOMM.VBX对开发Windows平台下的通信软件的确方便容易,使用事件驱动能设计良好
的后台通信程序、开发终端仿真软件和解决更复杂的实际问题。该通信控件不但包括了全
部Windows API中关于串行通信的16个函数所完成的功能,而且开拓了更多的使用户设计方
便的对象属性来满足不同用户不同业务的需求。因此我们可以应用上文讨论的内容和方法
,利用Windows环境,使用VB工具来开发设计所有串行通信的软件。另外,MSCOMM为了能在下
一个高速调制解调设备标准中直接使用,它提供了14.4Kbps一档的速率接口。
(作者地址:北京太平路27号计算中心,100039;收稿日期:1995年3月)
摘 要 该文详细讨论了MSCOMM.VBX通信控件在Windows平台下的通信软件设计方法,借
助于Visual Basic所附的通信控件能非常方便地开发出高级和专业性通信软件来满足不同
业务的需要。
关键词 Windows Visual Basic 通信控件 通信软件
在Windows操作系统平台上开发通信软件时,虽然Windows 3.1 SDK提供了完备的API应
用程序接口函数和以中断方式驱动的通信设备驱动程序COMM.DRV,从而可以用C或C++来完成
这类应用程序的设计,但其复杂化和专业化程度仍然很高。所以,目前许多软件开发人员都
在使用Microsoft Visual Basic来开发Windows应用程序。本文将详细叙述VB环境的通信软
件开发方法,通过对通信控件MSCOMM.VBX的分析,我们可以看到利用VB来开发Windows平台下
的通信软件非常简单。最后结合我们工作中的一个实例来完整地描述该类软件的设计方法
。
一、MSCOMM.VBX的描述
VB中的串行通信控件已全面提供了使用RS-232来进行数据通信软件开发设计的所有细
则,Microsoft Visual Basic 3.0中的MSCOMM.VBX(需要安装在indowsystem\目录下)是199
2年Crescent software Inc. 公司专为Microsoft的VB平台设计的,它使用以下两种不同的
方式来处理和解决各类通信软件的开发和设计问题。
(1) 事件驱动,它和我们用C/C++写Windows软件时的窗口回调函数类似,是一种功能强
大的处理问题的方法。在实际工作中,往往要求我们处理许多通信中的相关事件。例如:当
线路数据到达本端或CD(Carrier Detect)和RTS(Request To Send)信号线状态发生变化时
,这就要求我们使用相应的事件来跟踪和处理。在该控件中,是使用OnComm来实现的,它也包
括检测和处理通信错误等方面的问题。以下是MSCOMM详细的错误和事件列表(读者可参阅S
KD或MSC/C++ 7.0等中的Windows.h有关的通信部分常数和函数原型):
MSCOMM_ER_BREAKA收到一个Break signal.
MSCOMM_ER_CDTOCD信号超时
MSCOMM_ER_CTSTOCTS信号超时
MSCOMM_ER_DSRTODSR信号超时
MSCOMM_ER_FRAME帧错误发生
MSCOMM_ER_OVERRUN接收数据丢失
MSCOMM_ER_RXOVER接收缓冲器溢出
MSCOMM_ER_RXPARITY纠验错
MSCOMM_ER_TXFULL发送缓冲器满
MSCOMM_EV_CDCD信号改变
MSCOMM_EV_CTSCTS信号改变
MSCOMM_EV_DSRDSR信号改变
MSCOMM_EV_EOF收到一个文本文件结束字符(26)
MSCOMM_EV_RING检测到一个振铃信号
MSCOMM_EV_RECEIVE接收到设定的字符数时产生该事件
MSCOMM_EV_SEND发生缓冲器中的字符数低于设定的数值时产生该事件
以上常数定义在CONSTANT.TXT文件中。
(2) 查询方式,由程序设计者来负责读取CommEvent的值并处理所发生的错误或事件。
通常简单的应用程序设计可采用这种方法。
使用通信控件开发通信软件时,能非常简单地设计出同时访问多个通信口的程序,这就
是Windows的好处。例如使用Commi.OnComm,其中1≤i≤n(n:当前可用的通信口),就可以设
计多个通信串口处理程序。例如,一个基于电话网用来检索信息资料的小型服务器的后台软
件的设计应用就是一个很好的例子。MSCOMM.VBX中提供了27个关于通信控件方面的属性,以
下列出最重要的几个:
CommPort设置和返回通信口的数目
Settings设置和返回以字符串形式给出的数据通信格式:波特率,校验,数据位和停止
位
PortOpen设置和返回通信口的状态(包括打开和关闭一个通信口)
Input读串行数据接收缓冲器
Output发送一个串
在MSCOMM.VBX中,有两个与Input和Output性质相等同的函数;
(1) 输入函数,从串行通信接收缓冲器中读取字符串,句型如下:
Comlnput(By Val hWnd As Integer, lpData As Any,By Val cbData As Integer) A
s Integer
@@T8S14200.GIF;图1@@
返回值:本次读操作实际读取的字符数
(2) 输出函数,向通信口发送一个字符串,句型如下:ComOutput(By Val hWnd As Inte
ger, lpData As Any,By Val cbData As Integer) As integer
@@T8S14201.GIF;图2@@
返回值:本次写操作实际发送的字符数
二、事件驱动和查询方式下的两种通信软件开发模板
这两种方式分别对应我们通常使用汇编或C/C++来写通信程序中的中断和查询方法。
(1) 事件驱动
下例是一个使用事件驱动方式设计通信程序的模板,我们只需根据自己的实际情况来选
择在下列的Case语句中插入相应的代码即可。
Sub Comm_OnComm()
Select Case Commi.CommEvent'i=1,2...
' 错误部分
Case MSCOMM-ER_BREAK'插入处理BREAK代码
Case MSCOMM-ER_CDTO'插入处理CD(RLSD)超时代码
Case MSCOMM-ER_CTSTO'插入处理CTS超时代码
Case MSCOMM-ER_DSRTO'插入处理DSR超时代码
Case MSCOMM-ER_FRAME'插入处理帧错误代码
Case MSCOMM-ER_OVERRUN'插入处理数据丢失代码
Case MSCOMM-ER_RXOVER'插入处理接收缓冲器溢出代码
Case MSCOMM-ER_RXPARITY'插入处理校验错误代码
Case MSCOMM-ER_TXFULL'插入处理发送缓冲器满代码
'事件部分
Case MSCOMM-EV_CD'插入处理CD信号改变代码
Case MSCOMM-EV_CTS'插入处理CTS信号改变代码
Case MSCOMM-EV_DSR'插入处理DST信号改变代码
Case MSCOMM-EV_EOF'插入处理收到一个文本文件结束字(26)代码
Case MSCOMM-EV_RING'插入处理检测到一个振铃信号代码
Case MSCOMM-EV_RECEIVE'插入接收到设定的字符数时产生该事件代码
Case MSCOMM-EV_SEND'插入处理发生缓冲器中的字符数低于设定的数值时产生该
事件的代码
End Select
End Sub
(2) 查询方式
查询方式,就是每个命令(含数据块)都要查询等待对它的回答。详细使用方法请见下文
的实例叙述。
三、一个完整例子
该程序的设计背景是全军医药信息网上电话拨号用户前台软件中的自动拨号部分,为节
省篇幅和说明问题,这里进行了重新编辑,但其本身是完整的。该程序帮助主人进行电话拨
号以呼通被叫。
调试环境:LEO 486/50,HiTec MODEM,院内电话脉冲拨号,使用串行口1,PWIN 3.1
程序Form由下列部分组成:List1电话号码显示列表;Label1拨号状态显示;Dial,Canc
el,
Quit三个按钮;MSCOMM.VBX通信控件。
' ------------
' Visual Basic 3.0 MSCOMM.VBX程序设计:使用MODEM拨号,人工通话
' 程序名:MDIALER.TXT
' 军事医学科学院计算中心 夏云,1995.2.12
' 运行:使用VB FILE中的Load Text项装入,按F5或生成.EXE文件运行
' ------------
Option Explicit
Dim PhoneNumbers$()'电话号码存储变量
Dim CancelFlag'Cancel按钮状态标志
Sub Dial(Number$)'拨号例程
Dim DialString$,FromModem$,dummy
'根据脉冲/双音多频拨号方式来选择DT/DP;
'所拨号码存放在变量PhoneNumbers$(Index)中;
'命令中的分号表示MODEM在拨号后重新回到命令状态;
'每个命令由回车符Chr$(13)结束;
DialString$="ATDT"+Number$+";"+Chr$(13)
Commi.Settings="2400,N,8,1"'设置帧格式
On Error Resume Next'错误恢复
Commi.PortOpen=True'启动该口工作
If Err Then'如果该口不可启动,则显示信息
MsgBox"当前串行通信端口不能工作,请选择使用另外端口。”
Exit Sub
End if
Commi.InBufferCount=0'清除接收缓冲器
Commi.Output=DialString$'开始拨号
Do'等待MODEM返回“OK”回答
dummy=DoEvents()'进入等待方式,将资源提交系统管理
If Commi.InBufferCount Then'若接收缓冲器中有数据存在,则读
FromModem$=FromModem$+Commi.Input
If InStr(FromModem$,"OK")Then '是否接收到“OK”
Beep'已经接收到“OK”,发蜂呜声
MsgBox"对方电话已经拨通,请摘话机并按回车或OK钮”
Exit Do
End If
End If
If CancelFlag Then'若Cancel钮按下则处理
CancelFlag=False
Exit Do
End If
Loop
Commi.Output="ATH"+Chr$(13)'挂断命令
Commi.PortOpen=False'关闭该口
End Sub
Sub DialButton_Click()'Dial按钮处理程序
Dim Number$,Temp$
DialButton.Enabled=False'Dial,Quit二个按钮同时无效
QuitButton.Enabled=False
CancelButton.Enabled=True'开放Cancel按钮
Number$=PhoneNumbers$(List1.ListIndex))'获得一个电话号码
Temp$=Status'保存状态
Status$=“正在拨号码:”+Number$
Dial Number$'拨号例程执行
DialButton.Enabled=True'拨号结束开放Dail,Quit按钮
DialButton.Enabled=True
CancelButton.Enabled=False'禁止Cancel按钮
Status=Temp$'恢复状态
End Sub
Sub Form_Load()
Commi.InputLen=0'设置0值:读全部接收缓冲器内容
MDialer.Show'显示窗口
List1.AddItem“四环医学研究院计算中心”
List1.AddItem“军事医学科学院情报所张华研究员”
ReDim PhoneNumbers$(0 To List1.ListCount-1)
PhoneNumbers$(0)="1-8233296"
PhoneNumber$(1)="1-8232255"
List1.ListIndex=0'默认第一个号码
End Sub
Sub List1-DblClick()'列表框选择号码启动拨号
DialButton-Click
End Sub
Sub CancelButton-Click()'Cancel按钮处理程序
CancelFlag=True'标识Cancel钮已按下
CancelButton.Enabled=False'取消该钮继续活动
End Sub
Sub QuitButton-Click()'Quit按钮
End'结束
End Sub
MSCOMM.VBX对开发Windows平台下的通信软件的确方便容易,使用事件驱动能设计良好
的后台通信程序、开发终端仿真软件和解决更复杂的实际问题。该通信控件不但包括了全
部Windows API中关于串行通信的16个函数所完成的功能,而且开拓了更多的使用户设计方
便的对象属性来满足不同用户不同业务的需求。因此我们可以应用上文讨论的内容和方法
,利用Windows环境,使用VB工具来开发设计所有串行通信的软件。另外,MSCOMM为了能在下
一个高速调制解调设备标准中直接使用,它提供了14.4Kbps一档的速率接口。
(作者地址:北京太平路27号计算中心,100039;收稿日期:1995年3月)
最新更新
python爬虫及其可视化
使用python爬取豆瓣电影短评评论内容
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
uniapp/H5 获取手机桌面壁纸 (静态壁纸)
[前端] DNS解析与优化
为什么在js中需要添加addEventListener()?
JS模块化系统
js通过Object.defineProperty() 定义和控制对象
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比