13.9 主窗体菜单及工具栏模块的功能实现
主窗体的菜单栏及工具栏主要用于串口的属性、通信及界面的显示控制。根据功能将其分成两类:串口控制及操作控制。串口控制主要实现串口开关、参数的设置。操作控制主要实现发送接收的数据格式控制、数据自动发送控制、数据保存控制、通信计数清零控制及退出程序的功能。其中数据接收的数据格式控制、自动发送控制将在后面两节中进行介绍。本节将分成几节讲解其他功能控制的实现。
13.9.1 串口开关控制功能的实现
串口菜单及工具栏菜单中都有串口的开关控制,且菜单的串口开关菜单选项与工具栏的串口开关控制按钮的ID相同。因此这两个控制部分有共同的一个处理函数OnComOpen()。在这个函数中判断当前的串口开关状态,如果当前串口已经打开则关闭串口,否则打开串口。实现如下:
- 01 void CComElvesDlg::OnComOpen()
- 02 {
- 03 if(!m_bOpened)
- 04 {
- 05 OpenPort(); //打开串口函数
- 06 }
- 07 else
- 08 {
- 09 m_Port.ClosePort(); //关闭串口
- 10 m_bOpened = false; //串口开关标识
- 11 m_bAuto = false; //自动发送标识
- 12 GetDlgItem(IDC_SEND)->SetWindowText("发送");
- 13 KillTimer(1);
- 14 UpdateData(false);
- 15 SetOpenButton(); //设置工具栏串口开关控制按钮
- 16 }
- 17 }
【代码解析】
第3行判断当前串口的开关状态。如果当前串口为关闭状态,则在第5行调用自定义函数OpenPort()打开串口,否则在第9~15行关闭串口,并进行一些关闭后的处理。如将开关标识置为false,将自动发送标识置为false,将发送按钮的标题恢复(在自动发送的时候会修改这个按钮的标题,在后面将进行介绍),关闭定时器,最后将工具栏的开关按钮设置为关闭状态。
在这里OpenPort()函数用于打开串口,并进行打开串口后的一系列处理。实现如下:
- 01 void CComElvesDlg::OpenPort()
- 02 {
- 03 //打开串口
- 04 bool result = m_Port.OpenSerialPort(this, m_nCom, m_nBaud,m_cParity,
- 05 m_nDatabits,m_nStopbits,m_dwCommEvents,512)
- 06 if (result )
- 07 { //打开串口成功
- 08 m_Port.StartMonitoring(); //开始串口监控线程
- 09 m_bOpened = true; //将串口开关标识置为true
- 10 }
- 11 else
- 12 { //打开串口失败
- 13 m_bOpened = false; //将串口开关标识置为false
- 14 AfxMessageBox("没有发现此串口");
- 15 }
- 16 SetOpenButton(); //设置串口开关按钮状态
- 17 }
【代码解析】
第4、5行调用串口类的OpenSerialPort()函数打开串口。第6行判断串口是否打开成功,如是,则在第8行启动串口的监控子线程,并将串口开关标识置为true。如果串口打开失败,则在第13行将串口开关标识置为false,并在第14行提示串口打开失败信息。最后在第16行设置菜单栏串口开关工具按钮的状态。
在以上这两个函数中都调用了SetOpenButton()函数,该函数实现了根据当前串口开关状态,设置工具栏串口开关按钮状态的功能。此外还根据当前串口的开关状态及串口参数更新了状态栏中串口属性信息,实现如下:
- 01 void CComElvesDlg::SetOpenButton()
- 02 {
- 03 CImageList imageList;
- 04 CBitmap bitmap;
- 05 if(!m_bOpened)
- 06 {
- 07 //设置串口状态栏中信息为关闭状态
- 08 m_Status.Format("STATUS:COM%d CLOSED,%d,%c,%d,%d",
- 09 m_nCom, m_nBaud,m_cParity,
- 10 m_nDatabits,m_nStopbits);
- 11 //为菜单栏添加开关按钮为青色的位图资源
- 12 bitmap.LoadBitmap(IDB_TOOL_CLOSE);
- 13 imageList.Create(32, 32, ILC_COLORDDB|ILC_MASK, 13, 1);
- 14 imageList.Add(&bitmap, RGB(192,192,192));//这是Windows 98的按钮颜色
- 15 //向工具栏发送消息
- 16 m_ToolBar.SendMessage(TB_SETIMAGELIST, 0,
- 17 (LPARAM)imageList.m_hImageList);
- 18 }
- 19 else
- 20 {
- 21 //设置串口状态栏中信息为打开状态
- 22 m_Status.Format("STATUS:COM%d OPENED,%d,%c,%d,%d",m_nCom,
- 23 m_nBaud,m_cParity,m_nDatabits,m_nStopbits);
- 24 //为菜单栏添加开关按钮为红色的位图资源
- 25 bitmap.LoadBitmap(IDB_TOOL_OPEN);
- 26 imageList.Create(32, 32, ILC_COLORDDB|ILC_MASK, 13, 1);
- 27 imageList.Add(&bitmap, RGB(192,192,192));
- //这是Windows98的按钮颜色
- 28 //向工具栏发送消息
- 29 m_ToolBar.SendMessage(TB_SETIMAGELIST, 0,
- 30 (LPARAM)imageList.m_hImageList);
- 31 }
- 32 imageList.Detach(); //释放图像列表
- 33 bitmap.Detach(); //释放位图资源
- 34 m_ToolBar.Invalidate(); //刷新工具栏
- 35 UpdateData(false); //更新状态栏
- 36 }
【代码解析】
在第5行根据串口开关标识判断当前串口的开关状态。如果串口处于关闭状态,则在第8行将串口的关闭状态更新到状态栏的串口属性信息中。在第12行为工具栏载入开关按钮为青色的位图资源,在第13行利用这个位图资源创建一个位图列表,在第14行将这个图像列表添加到工具栏上。第15~17行向工具栏发送消息、更新工具栏的位图列表资源。当串口处于打开状态时的处理与此几乎类似。首先在第22、23行将状态栏中串口属性信息更改为打开状态。第25行为载入开关按钮是红色的位图资源,第26行利用这个位图资源初始化一个位图列表,并在第27行将这个图像列表绑定到工具栏上。第28~30行向工具栏发送消息,更新工具栏的位图列表资源。最后在第32、33行释放位图资源及图像列表资源,在第34、35行刷新工具栏并更新调试器的状态栏信息。