1. 在当前Project中插入MSComm控件
打开 Project->Add to Project->Components and Controls->Registered ActiveX Controls->Components: Microsoft Communications Control, version 6.0 命令插入到当前的Project中,结果就添加了类CMSComm类。类CMSComm的相关文件mscomm.h和mscomm.cpp也一并添加到Project中。
如果Project中的视类是基于CFormView的,那么创建CMSComm类是相当简单的,只需在CFormView对应的对话框窗体中插入MSComm控件,再在视类的ClassWizard中喂该类声明一个变量即可,本文中设为m_Com。这样在程序运行中,该MSComm控件都将是有效的。在对话框创建MSComm控件的过程也是类似的。如果视类不是基于CFormView的,那么就需要建立一个MSComm控件。创建的方法与普通的ActiveX控件的创建相类似。下面是一个简单的例子:
在MainFrm.h中添加下面声明语句:
protected: CMSComm m_Com;
在MainFrm.cpp::OnCreate()函数中添加下列创建控件的语句:
DWORD style=WS_VISIBLE | WS_CHILD;
if(!m_Com.Create(NULL,style,CRect(0,0,0,0),this,ID_COMMCTRL))
{
TRACE0("Failed to create OLE Communications Control/n");
return -1; //fail to create
}
2. 初始化并打开串口
对串口进行初始化,一般来说要完成以下几个设置:
(1)设定通信端口号,即CommPort属性。
(2)设定通信协议,即HandShaking属性。
(3)设定传输速率等参数,即Settings属性。
(4)设定其它参数,有必要时再加上其它属性设定。
(5)打开通信端口,即将PortOpen属性设为TRUE。
下面通过一段简单的源代码对上述步骤进行说明(这里假定m_Com是有效的CMSComm对象,这个假定对于下文同样有效):
m_Com.SetCommPort(1); // 选择COM1
m_Com.SetInBufferSize(1024); // 设置输入缓冲区的大小,Bytes
m_Com.SetOutBufferSize(512); // 设置输出缓冲区的大小,Bytes
if(!m_Com.GetPortOpen()) m_Com.SetPortOpen(TRUE); // 打开串口
m_Com.SetInputModel(1); // 设置输入方式喂二进制方式
m_Com.SetSettings("9600,n,8,1"); // 设置数据传输速率等参数
m_Com.SetRTbreshold(1); // 为1表示有一个字符引发一个事件
m_Com.SetInputLen(0);
3. 捕捉串口事项
MSComm控件可以采用查询或事件驱动的方法从端口获取数据。这里介绍使用事件驱动方法:有事件(如接收到数据)发生时通知程序,并在程序中需要捕获并处理这些通信事件。
下面的例子简单地实现了对串口事项的捕捉。
在MainFrm.h中添加
protected:
afx_msg void OnCommMscomm();
DECLARE_EVENTSINK_MAP()
在MainFrm.cpp中添加事件的映射:
BEGIN_EVENTSINK_MAP(CMainFrame,CFrameWnd)
ON_EVENT(CMainFrame,ID_COMMCTRL,1,OnCommMscomm,VTS_NONE) // 映射ActiveX控件事件
END_EVENTSINK_MAP()
4. 串口读写
VARIANT GetInput()和void SetOutput(const VARIANT& newValue)可完成读写。无论是在PC机读取上传数据时还是在PC机发送下行命令时,习惯于使用字符串形式(也可以说是数组形式)。查阅VARIANT文档可知,可以用BSTR表示字符串,但遗憾的是所有的BSTR都包含宽字符,即使我们没有定义_UNICODE_UNICODE也是这样。Windows NT支持宽字符,而Windows 95并不支持。为解决上述问题,可以使用CbyteArray,给出相应部分程序如下:
void CMainFrame::OnCommMscomm()
{
VARIANT vResponse;
int k;
if(m_Com.GetCommEvent()==2)
{
k=m_Com.GetInBufferCount(); // 接收到的字符数目
if(k>0)
{
vResponse=m_Com.GetInput(); // read
// 对数据进行其它处理
}
}
// 处理其它MSComm控件
}
void CMainFrame::OnCommSend()
{
// 准备需要发送的命令,放在TxData[]中
CByteArray array;
array.RemoveAll();
array.SetSize(Count);
for(i=0;i<Count;i++) array.SetAt(i,TxData[i]);
m_Com.SetOutput(COleVariant(array)); // 发送数据
}
5. 关闭串口
在使用完MSComm通信对象后,需要将通信端口关闭。当然如果窗体注销时,MSComm控件注销同样可以完成这一功能。可以下面语句实现此功能:
m_Com.SetPortOpen(FALSE);