
3.1 MSComm控件简介
MSComm是Microsoft公司出品的一种ActiveX控件,该控件可以为Windows应用程序提供串口通信功能。本节将详细介绍MSComm控件的属性和事件。
3.1.1 MSComm控件描述
一个MSComm控件对应一个串行端口。应用程序访问了多少个串行端口就必须使用多少个MSComm控件。MSComm控件实现串口通信时,实际上调用了API函数,但是程序员不必知道MSComm控件调用API函数的具体细节,对他们而言,只需要了解MSComm控件具有哪些属性和如何添加事件处理代码就能实现串口操作。
3.1.2 MSComm控件常用属性
MSComm控件具有很多属性,先来看其中最重要的5个属性:CommPort属性、Setting属性、PortOpen属性、Input属性和Output属性。
1. CommPort属性
程序员可以通过CommPort属性,设置或者获取当前使用的串行端口编号。注意,必须在打开串行端口之前,完成串行端口编号设置。
设置串行端口编号的函数是:
void SetCommPort (short nNewValue);
这里,nNewValue的取值范围是1~16(默认值为1),对应的串行端口编号为COM1~COM16。当程序员试图用SetCommPort函数打开一个并不存在的串行端口时,MSComm控件将返回错误代码68,表示指定设备无效。
获取串行端口编号的函数是:
short GetCommPort ();
2. Settings属性
程序员可以通过Settings属性,设置或者获取当前串行端口的通信参数,主要包括数据传输速率(波特率)、奇偶校验类型、数据位数和停止位数等4个参数。
设置当前串行端口通信参数的函数是:
Void SetSettings(LPCTSTR lpszNewValue);
这里,LPCTSTR类型表示指向固定地址,可根据一些宏定义改变语义的一个字符串,这就意味着串行端口通信参数是用特殊组成格式的字符串表示的。这种特殊组成格式为“BBBB,P,D,S”,其中“BBBB”表示波特率,“P”表示奇偶校验类型,“D”表示数据位数,“S”表示停止位数。lpszNewValue的默认值是“9600,N,8,1”,即当前串行端口的波特率为9600 bit/s,无奇偶校验,数据位数为8位,停止位数为1位。
■ 波特率的合法取值可以是110、300、600、1200、2400、4800、9600、14400、19200、28800、38400、56000、12800、25600。
■ 奇偶校验类型的合法取值可以是E(偶校验)、M(标记校验)、N(无校验)、O(奇校验)、S(空格校验)。
■ 数据位数的合法取值可以是4、5、6、7、8。
■ 停止位数的合法取值可以是1、1.5、2。
获取当前串行端口通信参数的函数是:
CString GetSettings();
串口通信双方的串行端口通信参数设置必须完全相同,并且串行端口硬件特性支持Settings属性设置值,双方才能进行正确通信。
3. PortOpen属性
程序员可以通过PortOpen属性,打开或者关闭指定串行端口,或者获取指定串行端口的状态。
打开指定串行端口的函数是:
void SetPortOpen(BOOL bNewValue);
这里,bNewValue为True,则打开指定串行端口;相反,bNewValue为False,则关闭指定串行端口。通常情况下,在确定CommPort属性设置正确后,程序才使用SetPortOpen()函数打开串行端口。
获取指定串行端口状态的函数是:
BOOL GetPortOpen();
4. Input属性
程序员可以通过Input属性,将接收缓冲区中字符串读入指定变量。当串行端口没有打开时,该属性不可用。程序运行时,该属性是只读的。
使用Input属性的函数是:
VARIANT GetInput();
GetInput()函数将读取接收缓冲区中全部字符。如果MSComm控件的InputLen属性值大于1,那么读取字符数由InputLen属性值决定。需要注意的是,GetInput()返回值类型为VARIANT,当MSComm控件的InputMode属性为0时,返回值类型转换为String字符串类型,当InputMode属性为1时,返回值类型转换为Byte数组类型。
5. Output属性
程序员可以通过Output属性,将数据流写入发送缓冲区中。当串行端口没有打开时,该属性不可用。程序运行时,该属性是只读的。
使用Output属性的函数是:
void SetOutput(const VARIANT& nNewValue);
Output属性可以发送文本数据或者二进制数据。当传输文本数据时,应先将字符型数据放入VARIANT类型变量中。当传输二进制数据时,应先将二进制数据放入VARIANT类型变量中。一般情况下,ANSI字符串以文本方式发送,包含有内嵌控制符或者Null字符的数据必须以二进制方式发送。
3.1.3 MSComm控件其他属性
除了5个常用属性外,MSComm控件还具有和输入操作、输出操作、传输过程控制相关的其他属性。
1. 与输入操作相关的属性
和输入操作相关的属性包括InputLen属性、InputMode属性、InBufferSize属性、InBufferCount属性、RThreshold属性、CommEvent属性和EOFEnable属性。
(1)InputLen属性
程序员可以通过InputLen属性,设置或者获取GetInput()函数每次从接收缓冲区读取数据的字节数。
设置每次从接收缓冲区读取数据字节数的函数是:
void SetInputLen(short nNewValue);
获取每次从接收缓冲区读取数据字节数的函数是:
short GetInputLen();
该属性默认值为0,表示每次读取接收缓冲区中全部数据。
(2)InputMode属性
程序员可以通过InputMode属性,设置或者获取GetInput()函数从接收缓冲区读取数据的方式。
设置读取数据方式的函数是:
void SetInputMode(long nNewValue);
获取读取数据方式的函数是:
long GetInputMode();
该属性默认值为0,表示以文本形式读取数据;当属性值为1时,表示以二进制形式读取数据。
(3)InBufferSize属性
程序员可以通过InBufferSize属性,设置或者获取接收缓冲区的容量,以字节为单位。
设置接收缓冲区容量的函数是:
void SetInBufferSize(short nNewValue);
获取接收缓冲区容量的函数是:
short GetInBufferSize();
该属性默认值为1024,表示接收缓冲区容量是1024字节。
(4)InBufferCount属性
程序员可以通过InBufferCount属性,设置或者获取接收缓冲区中待读取的有效数据字节数。
设置接收缓冲区中待读取有效数据字节数的函数是:
void SetInBufferCount(short nNewValue);
这里,nNewValue参数只能为0,表示该函数将清空接收缓冲区。其他nNewValue值将导致该函数出错。
获取接收缓冲区中待读取有效数据字节数的函数是:
short GetInBufferCount();
(5)RThreshold属性
程序员可以通过RThreshold属性,设置或者获取接收缓冲区触发OnComm事件的阈值。当接收缓冲区字节数达到该阈值时,MSComm控件会触发一次OnComm事件,同时将CommEvent属性值设置为ComEvReceive,表示此次OnComm事件是接收事件。
设置接收缓冲区触发OnComm事件阈值的函数是:
void SetRThreshold(short nNewValue);
获取接收缓冲区触发OnComm事件阈值的函数是:
short GetRThreshold();
(6)CommEvent属性
程序员可以通过CommEvent属性,获取MSComm控件运行时触发事件或者发生错误的类型。根据CommEvent属性值,程序员可编写相应处理代码。
获取函数是:
short GetCommEvent();
(7)EOFEnable属性
程序员可以通过EOFEnable属性,设置或者查询接收过程中是否允许MSComm控件查找文件结束符EOF。
设置函数是:
void SetEOFEnable(BOOL bNewValue);
查询函数是:
BOOL GetEOFEnable();
当EOFEnable属性为True,则MSComm控件查找文件结束符EOF,当找到EOF时,将停止接收,触发一次OnComm事件,将CommEvent属性值设置为comEvEOF。当EOFEnable属性为False,则MSComm控件不查找文件结束符EOF。
2. 与输出操作相关的属性
和输出操作相关的属性包括OutBufferSize属性、OutBufferCount属性和SThreshold属性。
(1)OutBufferSize属性
程序员可以通过OutBufferSize属性,设置或者获取发送缓冲区的容量,以字节为单位。
设置发送缓冲区容量的函数是:
void SetOutBufferSize(short nNewValue);
获取发送缓冲区容量的函数是:
short GetOutBufferSize();
(2)OutBufferCount属性
程序员可以通过OutBufferCount属性,设置或者获取发送缓冲区中待发送的有效数据字节数。
设置发送缓冲区中待发送有效数据字节数的函数是:
void SetOutBufferCount(short nNewValue);
这里,nNewValue只能为0,表示该函数将清空发送缓冲区。当nNewValue不为0时,该函数运行出错。
获取发送缓冲区中待发送有效数据字节数的函数是:
short GetOutBufferCount();
(3)SThreshold属性
程序员可以通过SThreshold属性,设置或者获取发送缓冲区触发OnComm事件的阈值。当发送缓冲区字节数达到该阈值时,MSComm控件会触发一次OnComm事件,同时将CommEvent属性值设置为ComEvSend,表示此次OnComm事件是发送事件。
设置发送缓冲区触发OnComm事件阈值的函数是:
void SetSThreshold(short nNewValue);
获取发送缓冲区触发OnComm事件阈值的函数是:
short GetSThreshold();
SThreshold属性的默认值为0,表示发送缓冲区内容变化不会触发发送事件。
3. 与传输过程控制相关的属性
和传输过程控制相关的属性包括Handshaking属性、DTREnable属性、RTSEnable属性、DSRHolding属性、CTSHolding属性和CDHolding属性。
(1)Handshaking属性
程序员可以通过Handshaking属性,设置或者获取硬件握手协议,即串口通信双方为控制串口通信而设定的内部协议。表3-1给出了Handshaking属性的合法取值。
表3-1 硬件握手协议合法取值

设置硬件握手协议的函数是:
void SetHandshaking(long nNewValue);
获取硬件握手协议的函数是:
long GetHandshaking();
(2)DTREnable属性
程序员可以通过DTREnable属性,设置或者查询数据终端就绪(Data Terminal Ready,DTR)信号线的状态。DTR信号是计算机发送到其他串行设备的信号,表示计算机是否准备好接收数据。
设置DTR信号状态的函数是:
void SetDTREnable(BOOL bNewValue);
当该属性值为True时,表示计算机准备好接收数据。当该属性值为False时,表示计算机尚未就绪。
查询DTR信号状态的函数是:
BOOL GetDTREnable();
(3)RTSEnable属性
程序员可以通过RTSEnable属性,设置或者查询请求发送(Request To Send,RTS)信号线的状态。RTS信号是计算机发送到其他串行设备的信号,表示计算机是否准备好发送数据。
设置RTS信号状态的函数是:
void SetRTSEnable(BOOL bNewValue);
当该属性值为True时,表示计算机请求发送数据。当该属性值为False时,表示计算机尚未请求发送数据。
查询RTS信号状态的函数是:
BOOL GetRTSEnable();
(4)DSRHolding属性
程序员可以通过DSRHolding属性,查询数据设备就绪(Data Set Ready,DSR)信号线的状态。DSR信号是其他串行设备发送到计算机的信号,表示串行设备是否准备好数据发送。
查询DSR信号状态的函数是:
BOOL GetDSRHolding();
当该属性值为True时,表示串行设备准备好数据发送。当该属性值为False时,表示串行设备尚未就绪。
(5)CTSHolding属性
程序员可以通过CTSHolding属性,查询清除发送(Clear To Send,CTS)信号线的状态。CTS信号是其他串行设备发送到计算机的信号,表示串行设备是否准备好接收数据。
查询CTS信号状态的函数是:
BOOL GetCTSHolding();
当该属性值为True时,表示串行设备准备好接收数据。当该属性值为False时,表示串行设备尚未就绪。
(6)CDHolding属性
程序员可以通过CDHolding属性,查询清除发送(Carrier Detect,CD)信号线的状态。CD信号是其他串行设备发送到计算机的信号,表示当前串行设备和计算机之间是否有传输。
查询CD信号状态的函数是:
BOOL GetCDHolding();
当该属性值为True时,表示当前串行设备和计算机之间无传输。当该属性值为False时,表示当前串行设备和计算机之间有传输。
3.1.4 MSComm控件的事件
MSComm控件只有一个事件,即OnComm事件。MSComm控件运行触发事件或者发生错误时,都会触发OnComm事件,同时改变CommEvent属性值。根据CommEvent属性值,程序员可以判断MSComm控件当前触发事件或发生错误的具体类型,在OnComm事件响应代码段中,编写对应各种CommEvent属性值的处理代码。