DIY编程器网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 3417|回复: 0
打印 上一主题 下一主题

[待整理] LabWindows/CVI虚拟仪器设计技术基本控件使用之: Tab 控件

[复制链接]
跳转到指定楼层
楼主
发表于 2014-10-12 07:21:51 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
1.4 Tab 控件
                        1.4.1 Tab 控件设计方法
                        Tab 控件类似分隔标签或一组文件夹上的标签,使用Tab 控件可以在应用程序窗口或对话框中的同一区域定义多个页面。该控件包含了一个或多个panel 面板集合。在设计时和运行时,可以设置其属性来控制Tab 控件的外观,如可设置标签以多行形式显示,将标签放在Tab 控件的上下左右各种位置,并可在标签上显示图标。
                         
                        LabWindows/CVI 中的Tab 控件最初是由Panel 面板转换而来,控件中的每个页面都有自己的句柄(类似于面板句柄),可以认为Tab 控件是一个容器,里面包含了面板的集合,因此,Tab 控件内也可重复内嵌Tab 控件。正是由于Tab 控件具有这些特点与属性,在使用某些函数时,如SetCtrlVal 、GetCtrlVal 等时,参数中的面板句柄设置应区分是一般面板句柄还是Tab 页面句柄。
                         
                        在LabWindows/CVI 中,Tab 控件是最为特殊的一个控件,这主要是因为引入了容器中的容器概念(笔者定义)。与其他语言最大的区别是,在LabWindows/CVI 中,一个面板即为一个容器,所有的控件必须放置在这个容器内,不允许在这个面板上存在其他的容器,如果换个角度,把容器看作句柄,也就是说,一个面板只有一个句柄,控件没有句柄,只有ID(ActiveX 控件除外),即使是Radio Group 这类控件,严格上来说也是由Tree 控件衍生而来,不具有控件句柄。这样设计的好处是,LabWindows/CVI 的消息传递是扁平化的,只在一个容器中进行消息循环,事件响应及时;缺点也显而易见,不能设计出像Visual Basic 或Delphi 中非常完美的控件组或页框(如Frame),但这也是LabWindows/CVI 设计的一大优点,简化设计思路,使程序设计者更加专注于逻辑系统设计而非语言本身。举例说明,如果在Visual Basic 或Delphi 中建有一个工程,Form (窗体)里面有一个Tab 控件,Tab 控件内嵌套一个Numeric 控件,可以对其进行属性操作,即获得或设置属性值;同理,在LabWindows/CVI 集成开发环境中也建有一个工程,Panel(面板)里面有一个Tab 控件,控件内嵌套一个Numeric 控件,则引用方法如下:
                         
                        (1)Visual Basic 语句      
                        赋值  
                        Form.Tab.Numeric.value = 1      
                        取值  
                        x = Form.Tab.Numeric.value      
                        (2)Delphi 语句  
                        赋值  
                        Form.Tab.Numeric.value := 1     
                        取值  
                        x := Form.Tab.Numeric.value     
                        (3)LabWindows/CVI 函数   
                        赋值(函数语句取自本例程)
                        panelHandle = LoadPanel (0, "Tab 控件.uir", PANEL); GetPanelHandleFromTabPage (panelHandle, PANEL_TAB, 0, &TabPanelHandle); SetCtrlVal (TabPanelHandle, TABPANEL_NUMERICTHERM, temp); 取值(函数语句取自本例程)
                        panelHandle = LoadPanel (0, "Tab 控件.uir", PANEL); GetPanelHandleFromTabPage (panelHandle, PANEL_TAB, 0, &TabPanelHandle); GetCtrlVal (TabPanelHandle, TABPANEL_NUMERICKNOB, &temp);   
                         
                        有意思的是,Visual Basic 和Delphi 对控件属性的引用中用了3 个“.”,这3 个“.”对应于LabWindows/CVI 的3 个函数语句,三种语言之间,属性获得或设置都是从容器到实例的逐次递进引用,逻辑上是相同的,只是表现方式不同,其逻辑关系如图1-9 所示。
       
               

       
                (a) Visual Basic 或Delphi (b)LabWindows/CVI

       
                图1-9 属性获得或设置逻辑关系

                 
                        与Visual Basic 和Delphi 的差别也可以很清晰地发现,LabWindows/CVI 的编码量巨大,函数量众多,而且大量的编码是用在属性设置上的,为了克服编码量大、函数多程序员不容易记,书写容易出现错误的缺点,LabWindows/CVI 引入函数面板(Function Panel),即我们常用的.fp 文件,使得对于属性的编程只需要用函数面板输入几个参数就可以实现大部分功能,简单、易操作。
                         
                        在编辑状态,双击面板中的Tab 控件,弹出Edit Tab 对话框,如图1-10 所示。在Control Apperarance 框中,Tabs Fit Mode 用来设置单行、多行显示等,默认为单行显示,Tab Location 用来设置Tab 标签的位置,默认放置在控件的左上角。在Tab 框中,可以设置每一个页面的标签、常量名等,可以进行添加、剪切、复制、粘贴,页面的前后移动,对页面标签添加图标以及设置每个页面控件的焦点转移次序Tab Order 等操作。
       
               

       
                图1-10 Edit Tab 对话框

                         
                        1.4.2 Tab 控件程序设计
                        (1)面板设计
                        编写一个Tab 控件属性设置程序,能够响应页面(标签页)内的事件、设置标签、计算Tab 页面数目,改变标签的显示风格,并且在标签上可以设置显示图标。在页面中,有两个Command Button 控件,拥有相同的常量值和回调函数名,在调用时,需要通过标题字符来区分所要响应的事件。面板设计如图1-11 所示,面板中主要控件属性设置如表1-11 所示。
       
               

       
                图1-11  Tab 控件面板

                         
                        表1-11 控件属性设置表
                         
       
                                       
                                                常量名

                               
                                       
                                                控件类型

                               
                                       
                                                控件的主要属性

                               
                                       
                                                PANEL

                               
                                       
                                                Panel

                               
                                       
                                                标题:Tab 控件

                                       
                                                回调函数:PanelCB

                               
                                       
                                                 

                               
                                       
                                                 

                               
                                       
                                                标题:事件响应(__T)

                               
                                       
                                                 

                               
                                       
                                                 

                               
                                       
                                                常量名:TABPANEL

                               
                                       
                                                TAB

                               
                                       
                                                Tab

                               
                                       
                                                标题:标签设置(__S) 常量名:TABPANEL_2

                               
                                       
                                                标题:Tab 数目(__N) 常量名:TABPANEL_3

                               
                                       
                                                 

                               
                                       
                                                 

                               
                                       
                                                标题:显示风格(__K)

                               
                                       
                                                 

                               
                                       
                                                 

                               
                                       
                                                常量名:TABPANEL_4

                               
                                       
                                                NUMERICKNOB

                               
                                       
                                                Numeric Knob

                               
                                       
                                                标题:数值设置

                               
                                       
                                                NUMERICTHERM

                               
                                       
                                                Numeric Thermometer

                               
                                       
                                                标题:数值显示

                               
                                       
                                                STRING

                               
                                       
                                                String

                               
                                       
                                                标题:标签设置默认值:默认值(__D)

                               
                                       
                                                NUMERIC

                               
                                       
                                                Numeric

                               
                                       
                                                标题:Tab 数目

                               
                                       
                                                RING

                               
                                       
                                                Ring

                               
                                       
                                                标题:显示风格回调函数:style

                               
                                       
                                                 

                               
                                       
                                                 

                               
                                       
                                                标题:设置

                               
                                       
                                                 

                               
                                       
                                                 

                               
                                       
                                                回调函数:OkCallback

                               
                                       
                                                OKBUTTON

                               
                                       
                                                Command Button

                               
                                       
                                                 

                               
                                       
                                                 

                               
                                       
                                                 

                               
                                       
                                                 

                               
                                       
                                                标题:获取

                               
                                       
                                                 

                               
                                       
                                                 

                               
                                       
                                                回调函数:OkCallback

                               
                         
                 
                        (2)程序源代码
                         
                        //头文件声明  
                        #include <formatio.h>  
                        #include <cvirte.h>     
                        #include <userint.h>   
                        #include "Tab 控件.h"  
                        //Tab 页面句柄声明
                        static int TabPanelHandle;      
                        //Tab 页面索引声明
                        static int index = 0;  
                        static int panelHandle; //主函数  
                        int main (int argc, char *argv[])  
                        {  
                        if (InitCVIRTE (0, argv, 0) == 0)  
                        return &ndash;1; /* out of memory */ if ((panelHandle = LoadPanel (0, "Tab 控件.uir", PANEL)) < 0)  
                        return &ndash;1;   
                        DisplayPanel (panelHandle);     
                        RunUserInterface ();   
                        DiscardPanel (panelHandle);     
                        return 0;  
                        } //面板回调函数  
                        int CVICALLBACK PanelCB (int panel, int event, void *callbackData,      
                        int eventData1, int eventData2)     
                        {  
                        switch (event)      
                        {  
                        case EVENT_CLOSE:  
                        QuitUserInterface (0);      
                        break;
                        }  
                        return 0;  
                        }  
                        //事件响应页面
                        int CVICALLBACK valset (int panel, int control, int event,      
                        void *callbackData, int eventData1, int eventData2)     
                        {  
                        int temp;
                        switch (event)      
                        {  
                        case EVENT_COMMIT:
                        // 获得Tab 页面句柄   
                        GetPanelHandleFromTabPage (panelHandle, PANEL_TAB, 0, &TabPanelHandle);     
                        // 获得Tab 页面中控件值   
                        GetCtrlVal (TabPanelHandle, TABPANEL_NUMERICKNOB, &temp);
                        // 设置Tab 页面中控件值   
                        SetCtrlVal (TabPanelHandle, TABPANEL_NUMERICTHERM, temp);
                        break;
                        }  
                        return 0;  
                        }  
                        //页面中的Command Button 按钮
                        int CVICALLBACK OkCallback (int panel, int control, int event,      
                        void *callbackData, int eventData1, int eventData2)     
                        {  
                        int area;  
                        char s[20];   
                        char label[20];   
                        int count;      
                        switch (event)      
                        {  
                        case EVENT_COMMIT:
                        // 获得控件属性   
                        GetCtrlAttribute (panel, control, ATTR_LABEL_TEXT, label);      
                        // 获得当前激活页面索引   
                        GetActiveTabPage (panelHandle, PANEL_TAB, &index);
                        // 通过索引获得当前页面句柄   
                        GetPanelHandleFromTabPage (panelHandle, PANEL_TAB, index, &TabPanelHandle);   
                               // 如果当前页面中的按钮为“设置”时,执行以下操作  
                               if (CompareStrings (label, 0, " 设置", 0, 1) == 0)
                               {  
                               // 获得页面中指定值
                               GetCtrlVal (TabPanelHandle, TABPANEL_2_STRING, s);
                               // 设置当前页面中标签为指定值  
                               SetTabPageAttribute (panelHandle, PANEL_TAB, index, ATTR_LABEL_TEXT, s);   
                               }  
                               // 如果当前页面中的按钮为“获取”时,执行以下操作  
                               if (CompareStrings (label, 0, " 获取", 0, 1) == 0)
                               {  
                               // 获得Tab 控件中页面数目  
                               GetNumTabPages (panelHandle, PANEL_TAB, &count);   
                               // 显示页面数目
                               SetCtrlVal (TabPanelHandle, TABPANEL_3_NUMERIC, count);      
                               }  
                               break;
                           }        
                           return 0;        
                        }           
                        //显示风格回调函数        
                        int CVICALLBACK style (int panel, int control, int event,           
                        void *callbackData, int eventData1, int eventData2)            
                        {           
                        int kind;           
                        switch (event)              
                        {           
                        case EVENT_COMMIT:        
                        // 获得控件值         
                        GetCtrlVal (panel, control, &kind);           
                        // 设置Tabp 控件风格         
                        SetCtrlAttribute (panelHandle, PANEL_TAB, ATTR_TABS_LOCATION, kind);         
                        break;        
                        }           
                        return 0;           
        }                                   
                         
                 
                        3:程序注释
                        ① GetPanelHandleFromTabPage 函数获得Tab 页面句柄。函数原型为:
                        int GetPanelHandleFromTabPage (int Panel_Handle, int Control_ID, int Index, int
                        *Tab_Panel_Handle);
                        Panel_Handle:Tab 控件所在面板句柄。
                        Control_ID:Tab 控件ID。
                        Index:Tab 页面(标签页)索引,第一个页面为0,依次递增。注意,此值需要用户设定而非系统返回值。
                        *Tab_Panel_Handle :返回Tab 页面索引指定的页面句柄。
                         
                         
                        ② GetActiveTabPage 函数获得当前激活的Tab 页面索引。函数原型为:int GetActiveTabPage (int Panel_Handle, int Control_ID, int *Active_Index);
                        *Active_Index :当前激活页面索引值,从0 开始计,&ndash;1 表示没有活动页面。
                         
                        ③ CompareStrings 函数
                        字符串比较函数。将字符串1 中从某一位置开始所组成的子串与字符串2 中从某一位置开始所组成的子串进行比较。函数原型为:
                        int CompareStrings (char String_1[], int String_1_Index, char String_2[], int String_2_Index, int
                Case_Sensitive);
                String_1[] :字符串1。
                String_1_Index :子串1 起始位置。
                String_2[] :字符串2。
                String_2_Index :子串2 起始位置。
                Case_Sensitive:是否区分大小写。
                返回值:0 表示两子串相等,&ndash;1 表示子串1 小于子串2,1 表示子串1 大于子串2。
                         
                         
                        ④ valset 回调函数
                        在valset 回调函数中编写了GetCtrlVal (TabPanelHandle, TABPANEL_NUMERICKNOB, &temp) 语句,值得注意的是,GetCtrlVal 函数Panel Handle 参数并非在程序前面声明的panelHandle, 而是采用了GetPanelHandleFromTabPage 函数的返回Tab 页面句柄TabPanelHandle,也可以利用控件回调函数传回的函数句柄panel 。Control ID 参数可以写成TABPANEL_NUMERICKNOB ,也可以利用控件回调函数传回的控件常量control 参数。此外,为了使数值设置与数值显示看起来同步,可以将event 事件中的EVENT_COMMIT 改写为EVENT_VAL_CHANGED ,修改后的回调函数如下:
                        int CVICALLBACK valset (int panel, int control, int event,
                void *callbackData, int eventData1, int eventData2)
                {
                int temp;
                switch (event)
                {
                case EVENT_VAL_CHANGED:
                // 获得Tab 页面句柄
                GetPanelHandleFromTabPage (panelHandle, PANEL_TAB, 0, &TabPanelHandle);
                // 获得Tab 页面中控件值
                GetCtrlVal (panel, control, &temp);
                // 设置Tab 页面中控件值
                SetCtrlVal (panel, TABPANEL_NUMERICTHERM, temp);
                break;
                }
                return 0;
                }
                         
                         
                        ⑤ 具有相同常量名和回调函数的Command Button 按钮事件响应方式设计在面板设计中,Command Button 按钮在标签设置和Tab 数目页面出现了两次,分别为“设置”和“获取”按钮,其回调函数名称和常量名完全一致,只是标题不同,这是由于Tab 控件本身就是多面板的集合,类似于一个容器控件,Tab 页面以子面板的方式出现,造成了可以重命名不同控件的问题,虽然不利于控件事件的区分,但却能减少回调函数的数量,利于代码的优化。面板和控件在程序头文件中定义如下:
                        #define  PANEL  1
                #define  PANEL_TAB  2
                #define TABPANEL_NUMERICTHERM  2
                #define TABPANEL_NUMERICKNOB  3
                #define  TABPANEL_2_STRING  2
                #define  TABPANEL_2_OKBUTTON  3
                #define  TABPANEL_3_NUMERIC  2
                #define  TABPANEL_3_OKBUTTON  3
                #define  TABPANEL_4_RING  2
                         
                         
                        从以上代码可以看出,虽然两个控件在界面设计阶段具有相同的常量名,在由于所在的Tab 页面不同,系统生成的常量名并不相同,分别为TABPANEL_2_OKBUTTON 和TABPANEL_3_OKBUTTON ,但常量值是相同的且均为3,在相同回调函数下,只能通过控件的不同标题来区分所响应的事件。
                         
                        (4)运行效果图
                        点击工具栏中的Debug Project 按钮,程序开始运行,其效果如图1-12 所示。
       
               

       
                图1-12 运行效果图
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|文字版|手机版|DIY编程器网 ( 桂ICP备14005565号-1 )

GMT+8, 2025-6-23 04:04 , 耗时 0.104336 秒, 21 个查询请求 , Gzip 开启.

各位嘉宾言论仅代表个人观点,非属DIY编程器网立场。

桂公网安备 45031202000115号

DIY编程器群(超员):41210778 DIY编程器

DIY编程器群1(满员):3044634 DIY编程器1

diy编程器群2:551025008 diy编程器群2

QQ:28000622;Email:libyoufer@sina.com

本站由桂林市临桂区技兴电子商务经营部独家赞助。旨在技术交流,请自觉遵守国家法律法规,一旦发现将做封号删号处理。

快速回复 返回顶部 返回列表