📄 7.图形化编程软件平台.txt
字号:
图7.4 核心模块结构框图
其中,编辑模块负责在编辑窗口中放置元件,选择元件,删除元件,改变元件的位
置和大小,编辑元件的属性,管理元件的数据端口和顺序端口,在元件之间连线,
删除连线;还负责选择需要的元件往运行面板上增加、删除与修改,并可编辑运行
面板中元件的位置和大小。编辑模块还应具备图形化平台源文件(*.VPP文件)的
打开模块ReadVPP和保存模块SaveVPP。ReadVPP根据 *.VPP文件内容,恢复生成编
辑窗口中的所有元件和连线,建立VIList和EdgeList列表。SaveVPP的操作则正好
相反。下面分项进行介绍:
l 放置元件:由图形化元件基类VIBASE派生,动态生成相应的元件,其中的一些属
性和方法根据不同元件的性能要求添加或修改。
l 选择元件:所有图形化元件都能响应鼠标左键的单击选择操作。
l 删除元件:将选择的元件从当前编辑窗口中删除,同时删除连接在该元件上的所
有连线,并对VIList和EdgeList列表作相应的改变。
l 改变元件的位置和大小:由编辑模块调用元件的HANDLE方法来完成。HANDLE方法
在VIBASE基类中已完成,每个元件只要继承即可。HANDLE方法修改元件的位置和大
小属性,并在保存文件时将这些属性也同时记录在文件中。
l 编辑元件的属性:每个元件都应提供编辑各自有关属性的方法。要编辑的属性主
要包括字体、前背景颜色、是否显示数据出入端口等。除了这些共同的属性需要设
置外,每个元件还具有各自需要编辑的属性。
l 管理元件的数据端口:部分元件的数据输入端口和数据输出端口要求能手动增减
,但具体每个元件可增减的数据端口的数目与含义则不一样,所以在由VIBASE基类
派生出各种元件类型时,应该具有描述该元件可增减数据端口情况的属性。如果已
有连线的数据端口被删除,那么相应的连线也要删除,并且相应改变EdgeList列表
。
l 元件之间连线:每个元件的所有数据输入端口、数据输出端口、顺序输入端口和
顺序输出端口都能响应鼠标操作,以纵横线构成的折线在元件之间连上连线。同时
相应改变EdgeList列表,保存文件时将元件引脚连接情况以及该连线经过的几个折
点位置信息都保存在*.VPP文件中,以保证重新打开源程序文件时看到的编程状况
与保存时一致。该折线的具体形状和折点位置由编辑模块根据已有元件和连线的位
置自动判断决定(折线算法详见耿晨歌博士论文)。
l 删除连线:编辑模块可进入删除连线状态,可一次删除一条连线,也可连续执行
删除连线操作。
l 往运行面板中添加元件:由VIBASE基类派生,在运行面板上同时动态生成相应的
元件。但与编辑窗口中相应的元件相比,运行面板中的元件不具有编辑元件属性、
响应连线操作、增减数据输入/输出端口等功能。
l 改变元件在运行面板中的位置和大小:同样由元件的HANDLE方法完成,与编辑窗
口中改变元件的位置和大小方法一样。
以上叙述的各项功能大多由各元件的函数来完成,这些函数由编辑模块调用获得控
制权。编辑元件的属性、增减元件的数据端口和顺序端口、往运行面板中添加元件
等操作,都是由鼠标右键单击产生弹出式菜单,然后选择相应子菜单项来调用相应
元件操作函数。
运行模块负责将已编制的图形化源程序在图形化软件环境中运行。运行时根据运行
面板的内容生成外观一致的运行窗口,运行结束后则关闭运行窗口。运行模块可以
通过运行操作从编辑模块获得控制权,也可以打开*.VPP源文件直接运行。
在运行模块中,关键是通过扫描建立的VIList列表,决定当前运行元件,判断该元
件是否被激活。如果不是激活元件则跳过,判断下一元件;如果是激活元件,则调
用元件的执行(EXECUTE)函数,进行元件所要求完成的数据处理、数据赋值和显
示更新工作。当前元件执行完毕后再判断和执行下一个元件,这整个过程循环执行
,直到用户结束程序。运行模块对元件的扫描过程如图7.5所示。
图7.5 运行模块扫描过程框图
在本图形化平台中,元件激活条件是各数据输入端口的数据有效,各数据输入端口
不允许没有连线;如果顺序输入端口有连线,则顺序输入端口也要有效触发。以上
两个条件均满足时,认为该元件已可激活。激活条件的判断是由VERIFY函数执行的
,VERIFY函数和EXECUTE函数都是元件的方法。在编写元件的VERIFY函数时,具体
的激活条件可有所变通,原因是有些元件(如循环、延时等需要反复激活的控件)
的激活条件可能不同。
运行模块对各元件的执行是通过扫描依次进行的,所以整个扫描周期的长短直接影
响到软件运行的性能,特别是响应速度。对扫描程序而言,其时间主要花费在元件
EXECUTE函数的调用执行上,因此所编写的EXECUTE函数要求精练高效,执行时间越
短越好。不允许在EXECUTE函数中有循环等待和延时之类的代码。对于循环和延时
元件,可利用定时器反复激活取得控制权,如果判断延时时间未到,则必须马上将
控制权交回扫描程序。当一个元件的EXECUTE函数执行结束,扫描程序重新获得控
制权后,就需要完成数据传递(即赋值)工作。查询EdgeList列表,了解刚执行过
的元件的输出引脚与哪些元件的输入引脚连接,然后将输出引脚处的出口数据赋与
相连接的元件的数据入口。要说明的是,元件的出口数据是由各自的EXECUTE函数
根据计算结果赋予的。用户在使用VPP编程时,会出现一些非法的连接,使得程序
无法运行。所以在运行模块开始执行时,首先应检查程序的合法性,然后将非法的
出错信息以对话框形式显示。
调试模块可以帮助编程人员了解图形化软件的执行过程,了解运行过程中各变量的
内容变化,以便找出软件的缺陷,从而改进完善。从调试模块的功能上看,有类似
运行模块的地方,但具有很多扩展的内容。如图7.6所示,调试模块除了与运行模
块类似的元件扫描程序以外,还包括断点设置、单步运行、变量观察等程序调试必
不可少的功能。
图7.6 调试模块扫描过程框图
二、 仪器接口模块:
在整个图形化平台中,仪器接口模块的设计目的是研究如何在图形化平台和各种虚
拟仪器之间提供一个图形化的接口,即向整个平台提供一个所有符合VPP规范的虚
拟仪器统一接口。基本设计方法是通过在图形化编程平台中提供一个仪器接口控件
,这个仪器接口控件代表和统一了所有VPP仪器驱动程序,这个控件在平台中就如
同其它的控件(如文本显示框等)一样,根据用户需要动态生成,可以由用户改变
属性参数,并在运行状态时被激活,完成对相应仪器驱动程序的调用。在第四章中
介绍虚拟仪器功能面板文件的应用时,我们已经了解到本图形化编程软件平台的仪
器接口模块的开发,采用了通过解析虚拟仪器驱动程序功能面板文件与动态链接库
文件相结合的方法。功能面板文件是一个结构化定义的文件,包括了仪器、函数类
、函数、函数中的参数的所有描述信息,不仅有类型说明,还有详细的各级帮助文
本。整个功能面板文件结构有详细定义规范,因此,接口模块的任务即是如何分析
这个功能面板文件结构,将其中信息以可视化的形式表示出来,并组合相应的驱动
程序动态链接库文件,进行相应的函数调用。这种方法的提出,兼顾了效率与扩展
性,为接口模块的设计提供了理论基础。
仪器接口模块的总设计思路分两个步骤:
l 用VC编写的DLL完成装入仪器驱动程序DLL,且完成对虚拟仪器功能面板文件的解
析,实现虚拟仪器驱动程序相应函数的正确调用。
l 用DELPHI编写图形化的部分,完成仪器函数图形化的元件显示及帮助文本的显示
。
在实际开发过程中,我们将仪器接口模块的开发步骤分成两大部分:第一部分在
VC++环境下开发,完成与仪器驱动程序交互的所有工作,包括一个虚拟仪器集树视
图的创建与维护、虚拟仪器的添加、虚拟仪器的删除、仪器函数的选择与调用、仪
器函数的存盘与恢复(这与图形化平台中控件操作相关联),并以动态链接库的形
式进行引出。在VC++环境下开发,主要考虑到仪器驱动程序的源代码一般是用C语
言,利用C环境进行分析与定位,不仅编程简单,而且效率高。第二部分是在
Delphi环境下开发,实质是创建一个函数控件,以这个函数控件形式代理所有的仪
器函数,对于这个函数控件的所有操作,是通过对于动态链接库的调用来完成的。
Delphi环境下的主要开发任务是完成这个函数控件在平台中如何与其它控件一起工
作,并提供调试与运行机制。
在VC环境下的设计步骤如下所示:
1、 在VC环境下用MFC DLL模式创建一个新工程(vidll.dll),选择MFC静态库链
接方式,这样使生成的动态链接库DLL可以应用于不包括MFC环境的计算机系统中。
2、 在资源视图中添加虚拟仪器管理器对话框,对话框中包括的项有树视图、帮助
文本编辑器与功能按钮,功能按钮有四个,分别为加入仪器、删除仪器、选中仪器
与取消操作。
3、 利用View/Class Wizard创建相应的类,为虚拟仪器管理器创建CDViMan,而缺
省工程类为CVidllApp。为类创建相应的成员变量与成员函数。CVidllApp类没有成
员变量,只有一个成员函数为InitInstance()完成缺省的虚拟仪器功能面板文件的
装载。这个装载过程主要完成对于内存空间的申请与功能面板文件列结构的登记,
关键的自定义类是OpenedFp。CDViMan类的成员变量为m_help(帮助文本编辑器)
、m_functree(树视图),成员函数为OnInitDialog,主要建立树视图,将功能面
板文件的树视图转化到对话框的树视图中;OnAdd,主要是加入新仪器,并为新打开
的功能面板文件创建一个OpenedFp数据结构;OnDel,主要是删除仪器,并释放分
配的内存空间;OnSel,主要是选中函数,首先确认所选中的函数结点是否是函数
结点,将进行函数登记,在图形化平台中,一旦选中了函数,将创建函数控件;
OnCancel,主要是取消操作;OnDblclkTree,主要是双击树视图,这个效果其实是
与选中函数的过程是一样的;OnSelChangeTree,主要是改变树结点的位置,由于
每个树结点均可以包含相应的帮助信息,故改变树结点位置的结果实质上是显示不
同的帮助信息。
4、 类OpenedFp定义一个打开的功能面板文件结构,它是以类的数据结构重定义了
实际的功能面板文件结构。在定义类OpenedFp的同时,还定义了其它一些重要的类
(所有类定义在classes.h和classes.cpp文件中),其中包括:struct _Ctrls(
面板函数控件结构);struct PanelNode(函数结点结构)、struct
FuncTreeNode(功能面板树结点结构)、struct DataType(定义数据类型结构)
、struct UserDataType(定义用户数据类型类)、struct ParaStruct(函数参数
结构)、struct CallFuncStruct(运行函数结构)、 struct RegistedFunction
(定义登记函数结构)、struct Terminal(端点结构)、strunct ToDelphi(传
送到Delphi信息结构)。同时,为了分析FP文件结构,还必须给出VPP规范下的功
能面板文件结构定义,这些定义均以结构形式给出,分别在Fp.h和Fp.cpp文件中。
5、 在工程类文件中引出五个引出函数,作为生成的动态链接库文件与外部程序的
接口:
l int _stdcall AddFunction(ToDelphi **, int):添加仪器控件;
l int _stdcall DelFunction(ToDelphi *):删除仪器控件;
l int _stdcall CallFunction(ToDelphi *):调用仪器控件;
l int _stdcall SaveInf(ToDelphi *):保存仪器控件;
l int _stdcall RestoreInf(ToDelphi **):恢复仪器控件。
这五个函数,实质定义了图形化平台软件与仪器控件的几种交互方式,因此,在
Delphi程序中作为外部函数被调用。
6. 编译该工程,生成vidll.dll文件,这个动态链接库文件将在Delphi环境下被调
用。
Delphi环境下的设计步骤:
在Delphi环境下,设计的主要目的是一个函数控件,所需创建的文件包括
ViInstrument.pas,ViInstrument.dcu,InsAttribute.pas,InsAttribute.dcu,
InsAtrribute.dfm,datatype.pas等,并要修改平台相应文件vppmain.pas与
vidialg.pas。其中datatype.pas文件主要定义了其中所涉及的全局变量类型,
ViInstrument.pas定义了函数控件,VIINSTRUMENT从VIBASE继承而来,它的端点编
辑功能不是调用继承来的可变端点,考虑这种控件的特殊性,用户对于端点的编辑
函数是重载的,在InsAttribute.pas中定义,端点的编辑界面主要由一个页控制器
完成的,包括端点的一般特性、输入端点特性、输出端点特性。尤其当输出端点为
指针类型时,需要用户为它选择指针类型并分配相应的内存(由内存管理页面完成
)。
在图形化平台仪器接口控件的设计中,Delphi部分与VC部分程序是相互关联的,数
据通信过程如下:
图7.7 图形化平台虚拟仪器管理器
1、 用户在平台中选择了生成一个虚拟仪器控件;
2、 Delphi部分调用vidll.dll的AddFunction函数加入函数控件,生成了虚拟仪器
管理器界面,并在树视图上列出了在缺省目录下所找到的功能面板文件对应的仪器
名,如图7.7所示。
3、 用户选择结点,一旦选中函数结点,则由VC部分分析函数信息,得到仪器索引
值与函数索引值,以唯一确定所选中的函数,正确选中之后,关闭对话框,并生成
图形化平台上的控件。
4、 在控件生成时,一旦输出参数中包括指针类型,则会弹出一个端点属性对话框
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -