第4章 ASK数字通信系统的软件实现
4.1 使用MFC进行可视化编程
4.1.1 使用MFC进行窗口界面的设计
用MFC的AppWizard生成一个名为ASK_Pro应用程序的项目文件。编写应用程序,其主窗口如图4-1所示,标题为ASK_Pro。在这个窗口中,包含有四个标题为基本输入、滤波器特性、发射机和接收机的组合框,两个名字为噪声和信道命令按钮和两个名字分别为时域波形和频域波形的静态文本框及五个图像控件。在基本输入组合框中含有两个名字分别为学号和噪声强度的编辑框;在滤波器特性组合框中含有两个名字分别为低通滤波器和带通滤波器的命令按钮;在发射机组合框中含有三个名字分别为基带信号、过低通和调制的命令按钮;在接收机组合框中含有四个名字分别为过带通、解调、过低通和恢复判决的命令按钮。
图4-1 应用程序主窗口界面
该应用程序还含有一个名为窗函数选择的次窗口。该对话框的创建过程为:在Visual C++的主菜单栏中选择插入菜单中的窗体选项,出现一个新建窗体对话框,在名称中选择输入CChuangHanShu,单击右边的确定按钮,则出现一个对话框窗口。单击鼠标右键选择属性项,出现属性对话框,选择常规选项卡,在ID中设置其ID为ID_CHUANGHANSHU_DIALOG,在标题中输入对话框的名字“窗函数选择”,即完成对其名字的修改。对对话框进行编辑,如图4-2所示,这个窗口中含有三个名字分别为汉宁窗、哈名窗和布莱克曼窗的单选按钮。
图4-2 窗函数选择窗口界面
该应用程序窗口中各控件的功能如下:
(1)基本输入组合框中的控件 学号编辑框:学号编辑框用来接收用户输入的四位数字学号信息,如果用户没有输入,则显示对话框初始化时给它传入的数据。噪声强度编辑框:噪声强度编辑框用来接收用户输入的噪声强度信息,如果用户没有输入,则显示对话框初始化时给它传入的数据。
(2)滤波器特性组合框中的控件 低通滤波器按钮:单击此按钮,则弹出窗函数选择对话框,在窗函数组合框中有汉宁窗、哈名窗、布莱克曼窗三个单选按钮,单击其中的任何一项进行窗函数的选择。选完窗函数后关闭窗函数选择对话框,则在右边的时域波形和频域波形静态文本框中分别显示低通滤波器的时域波形和频域波形。带通滤波器按钮:单击此按钮,则在右边的时域波形和频域波形静态文本框中分别显示带通滤波器的时域波形和频域波形。
(3)发射机组合框中的控件 基带信号按钮:单击此按钮,则在右边的时域波形和频域波形静态文本框中分别显示编码采样后的数字基带信号的时域波形和频域波形。过低通按钮:单击此按钮,则在右边的时域波形和频域波形静态文本框中分别显示通过低通滤波器后的信号的时域波形和频域波形。调制按钮:单击调制按钮,则在右边的时域波形和频域波形静态文本框中分别显示调制后的信号的时域波形和频域波形。
(4)噪声按钮 单击此按钮,则右边的时域波形和频域波形静态文本框中分别显示高斯白噪声的时域波形和频域波形。
表4-1 对话框中个对象的属性
对象 基本输入组合框 “学号”编辑框 “噪声强度”编辑框 滤波器特性组合框 低通滤波器命令安扭 带通滤波器命令按钮 ID IDC_STATIC IDC_ID IDC_ Intensity IDC_STATIC IDC_Lpf IDC_Bpf Caption 基本输入 无 无 滤波器特性 低通滤波器 带通滤波器 发射机组合框 对象 基带信号命令按钮 过低通命令按钮 调制命令按钮 对象 噪声命令按钮 信道命令按钮 接收机组合框 过带通命令按钮 解调命令按钮 过低通命令按钮 判决恢复命令按钮 “时域波形”编辑框 “频域波形”编辑框 窗函数组合框 汉宁窗单选按钮 哈名窗单选按钮 布莱克曼窗单选按钮 IDC_STATIC ID IDC_BaseSignal IDC_PassLpf1 IDC_Modulate ID IDC_ Noise IDC_Channel IDC_STATIC IDC_PassBpf IDC_DeModulate IDC_PassLpf2 IDC_Adjust IDC_T IDC_F IDC_STATIC IDC_HanNing IDC_HaMing IDC_BuLaiKeMan 发射机 Caption 基带信号 过低通 调制 Caption 噪声 信道 接收机 过带通 解调 过低通 判决恢复 无 无 窗函数 汉宁窗 哈明窗 布莱克曼窗 (5)信道按钮 单击此按钮,则在右边的时域波形和频域波形静态文本框中分别显示过信道后的信号的时域波形和频域波形。
(6)接收机组合框 带通滤波器按钮:单击此按钮,在右边的时域波 形和频域波形静态文本框中分别显示过带通后的信号的时域波形和频域波形。解调按钮:单击此按钮,在右边的时域波形和频域波形静态文本框中分别显示解调后的信号的时域波形和频域波形。过低通按钮:单击此按钮,则在右边的时域波形和频域波形静态文本框中分别显示过低通滤波器后的信号的时域波形和频域波形。恢复判决按钮:单击此按钮,则在右边的时域波形和频域波形静态文本框中分别显示抽样判决后的信号的时域波形和频域波形。
(7)时域波形静态文本框 该静态文本框用来显示信号的时域波形。 (8)频域波形静态文本框 该静态文本框用来显示信号的频域波形。
表4-1是对话框中各个控件的显示内容和对应的ID号。
4.1.2 控件变量的设置
控件变量是MFC中一个很重要的机制。
第一,关于DDX(动态数据交换)的基础知识。
MFC提供了一套被称为“数据映射”的机制来完成对话框里控件的数据交换。同消息映射一样,数据映射将对话框里的控件同对话框里的成员变量连接起
来,使得这些成员变量的值能够自动反映相应控件的内容或状态。在这种机制的实现过程中,MFC还提供了类CDataExchang来实现对话框类与控件的数据交换(DDX),该类还提供了数据有效验证机制(DDV)。DDX(动态数据交换)看起来好象是在对话框中某控件和某成员变量之间建立连接,自动实现控件和变量之间的数据转移。但这只是一个幻觉,它的实际工作方式是这样的:当你用ClassWizard把某变量和控件连接起来时(通过Member Variables选项卡),它在数据映射中创建一个入口。实际上也就是在对话框的DoDataExchange函数中添加一个入口函数(DoDataExchange函数是Class Wizard产生和维护的函数) 。数据交换的工作由函数CDialog:: DoDataExchang完成。当程序需要交换数据时,不要直接调用DoDataExchang函数,而应该调用CWnd::UpdateData。UpdateData函数内部只有一个布尔型参数,它决定了数据传送的方向。当你调用UpdateData(FALSE)时,MFC调用DoDataExchange函数,Class Wizard放于DoDataExchange中的实现代码将把来自控件变量的数据拷贝到对应的控件上。相应的如果调用UpdateData(TRUE),MFC反过来把控件上的数据拷贝回其对应的变量(并且可能同时进行数据验证)。在对话框初始化函数CDialog::OnInitDialog中调用UpdateData(FALSE),这样在对话框创建时,数据成员的初值就会反映到相应的控件上。若用户是按了“OK”按钮退出对话框,则对话框认为输入有效,就会调用UpdateData(TRUE)将控件中的数据传输给对话框数据成员。
第二,ASK数字通信系统中控件变量的设置。
该系统中需要用户设定将要传输的学号信息和信道中的噪声强度,我们设定对话框中的“学号”和“噪声强度”编辑框用来接收用户输入的信息。为了将编辑框中的信息传入到通信系统中,需要分别给它们设置控件变量。设置方法已在第三章中讲述,原则是根据DDX工作机制来实现的,具体如表4-2所示:
控件名称 学号 噪声强度 表4-2 对话框的控件变量 对应的控件变量 控件ID 控件变量类型 IDC_ID IDC_Intensity nMyID nIntensity int int 当设置好控件变量以后,可以在初始化函数中给它们赋初值并调用UpdateData(FALSE)将初值传给编辑框控件,即显示在编辑框中。如果学号和噪声强度这两个编辑框里的值发生改变,就可以直接调用函数UpdateData(TRUE)来完成控件变量的即时更新。
4.1.3 关于ASK通信系统中对话框控件的消息响应
消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉。一个消息,是系统定义的一个32位的值,它唯一的定义了一个事件,向Windows发出一个通知,告诉应用程序某个事情发生了。例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。在本次系统的设计中应用最多的是响应按扭单击的消息和编辑框值改变的消息。
Windows中的消息虽然很多,但是种类并不繁杂,大体上有3种:窗口消息、命令消息和控件通知消息。
窗口消息大概是系统中最为常见的消息,它是指由操作系统和控制其它窗口的窗口所使用的消息。例如CreateWindow、DestroyWindow和MoveWindow等都会激发窗口消息,还有我们在上面谈到的单击鼠标所产生的消息也是一种窗口消息。
命令消息,这是一种特殊的窗口消息,它用来处理从一个窗口发送到另一个窗口的用户请求,例如按下一个按钮,它就会向主窗口发送一个命令消息。 控件通知消息,是指这样一种消息,一个窗口内的子控件发生了一些事情,需要通知父窗口。通知消息只适用于标准的窗口控件如按钮、列表框、组合框、编辑框,以及Windows公共控件如树状视图、列表视图等。例如,单击或双击一个控件、在控件中选择部分文本、操作控件的滚动条都会产生通知消息。 它类似于命令消息,当用户与控件窗口交互时,那么控件通知消息就会从控件窗口发送到它的主窗口。但是这种消息的存在并不是为了处理用户命令,而是为了让主窗口能够改变控件,例如加载、显示数据。例如按下一个按钮,它向父窗口发送的消息也可以看作是一个控件通知消息;单击鼠标所产生的消息可以由主窗口直接处理,然后交给控件窗口处理。
其中窗口消息及控件通知消息主要由窗口类即直接或间接由CWND类派生类处理。相对窗口消息及控件通知消息而言,命令消息的处理对象范围就广得多,它不仅可以由窗口类处理,还可以由文档类,文档模板类及应用类所处理。 由于控件通知消息很重要的,人们用的也比较多,下面列出开发系统时使用的常见控件的通知消息的具体含义的: 按扭控件
BN_CLICKED 用户单击了按钮 BN_DISABLE 按钮被禁止
BN_DOUBLECLICKED 用户双击了按钮 BN_HILITE 用户加亮了按钮 BN_PAINT 按钮应当重画
BN_UNHILITE 编辑框控件加亮应当去掉
EN_CHANGE 编辑框中的文本己更新 EN_ERRSPACE 编辑框内存不足
EN_HSCROLL 用户点击了水平滚动条 EN_KILLFOCUS 编辑框正在失去输入焦点 EN_MAXTEXT 插入的内容被截断 EN_SETFOCUS 编辑框获得输入焦点
EN_UPDATE 编辑框中的文本将要更新
EN_VSCROLL 用户点击了垂直滚动条消息含义