LabWindowsCVI 程序 回调函数设计.docx
- 文档编号:3545147
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:12
- 大小:22.07KB
LabWindowsCVI 程序 回调函数设计.docx
《LabWindowsCVI 程序 回调函数设计.docx》由会员分享,可在线阅读,更多相关《LabWindowsCVI 程序 回调函数设计.docx(12页珍藏版)》请在冰豆网上搜索。
LabWindowsCVI程序回调函数设计
LabWindows/CVI程序回调函数设计
1.1回调函数1.1.1回调函数设计方法
在LabWindows/CVI程序设计系统中,一个程序可分为若干个程序模块,每个模块用来实现一个特定的功能,这些模块可以是子程序也可以是回调函数。
一个LabWindows/CVI应用程序由一个主函数和若干个其他函数构成,由主函数调用其他函数,其他函数之间也可互相调用,并且可以将一些常用的功能编写成函数形式,供其他模块调用,以提高代码利用率,减少程序编写的工作量。
实际上,主程序为用户功能逻辑的入口点,任何一个C语言程序都需要通过主函数进入该程序的消息循环。
回调函数是系统框架设计中非常重要的一种手段,所谓回调函数(callback)是指一个通过函数指针调用的函数。
回调函数可由用户设计并被系统所调用,主要用于截获消息、获取系统信息或处理异常事件。
回调函数必须遵守事先规定好的参数格式和传递方式,否则会引起程序或系统的崩溃。
在使用LabWindows/CVI进行程序设计时,用框架确定主要的处理流程,而将某些具体的实现交给用户来做。
使用回调函数实际上就是在调用某个函数时,将一个函数(这个函数为回调函数)的地址作为参数传递给另一个函数。
而另一个函数在需要时,利用传递的地址调用回调函数来处理消息或完成一定的操作。
如C函数库中的qsort函数,它可以接收一个函数指针做参数来确定排序的策略,用到的就是回调函数的方法。
又如,当用Windows进行系统消息处理时,如果用户注册了回调函数,系统中该消息触发时会调用这个回调函数,使用户逻辑得以执行。
在LabWindows/CVI中,采用回调函数形式响应系统消息循环。
回调函数能响应产生于用户界面库(UserInterfaceLibrary)的所有事件,其回调函数原型定义存储于userint.h头文件中。
面板、菜单、控件等都可安装回调函数,对于特定的接口对象,LabWindows/CVI会分配适合的回调函数以使程序正常运行。
包括系统空闲(Idle)事件和任务结束(end-task)事件都可以通过主回调函数得到响应与执行。
在LabWindows/CVI系统中,一些事件通过GUI界面产生并传递给回调函数。
如回调函数接收到用户界面的鼠标点击(EVENT_LEFT_CLICK)事件,连同一些相关信息可被记录下来,包括回调函数中鼠标的X轴(eventData2)、Y轴(eventData1)坐标,面板(panel)、控件(control)信息,并可以通过回调数据(callbackdata)传递用户自定义数据。
LabWindows/CVI中的回调函数宏定义为CVICALLBACK存储于cvidefs.h头文件中,其定义为:
#defineCVICDECL__cdecl
#defineCVICALLBACKCVICDECL
CVICALLBACK常被用来定义函数指针,
如:
typedefvoid(CVICALLBACK*MenuDimmerCallbackPtr)(intmenuBar,intpanel);
值得注意的是,CVICALLBACK宏定义在进行编译时优先于函数,以保证任何用户界面库函
数以cdecl方式被编译,即使stdcall调用约定下也是如此。
在LabWindows/CVI中,由五类对象可通过事件触发回调函数,即控件触发、面板触发、菜单触发、定时器触发和主回调函数触发,回调函数触发优先级定义如下。
控件触发优先级:
●控件回调函数
●面板回调函数(键盘和鼠标事件)
●主回调函数
面板触发优先级:
●面板回调函数
●主回调函数
菜单触发优先级:
●菜单项回调函数
●主回调函数
定时器触发优先级:
●控件回调函数
主回调函数触发优先级:
●主回调函数
值得注意的是,EVENT_COMMIT事件是存放在用户事件队列中的,通过GetUserEvent函数
传递给所有回调函数。
1.1.2回调函数程序设计
(1)面板设计
编写一个伪随机信号发生器程序,并将产生的数据在Graph控件中显示出来,将生成程序的文件名在String控件中显示。
为了使整个面板居中显示,双击面板调出EditPanel对话框,选择Auto-CenterVerTIcally(whenloaded)和Auto-Centerhorizontally(whenloaded),并点击OtherAttributes按钮,选择Movable、CanMinimize、TItleBarVisible、UseWindowsVisualStylesforControls项。
面板设计如图1-1所示,面板中主要控件属性设置如表1-1所示。
图1-1回调函数面板
表1-1控件属性设置表
(2)程序源代码
//头文件声明,系统自动添加
#include《ansi_c.h》
#include《cvirte.h》
#include《userint.h》
#include回调函数.h
//全局静态变量
staTIcintpanelHandle;
//主函数
intmain(intargc,char*argv[])
{
//初始化LabWindows/CVI运行时库引擎
if(InitCVIRTE(0,argv,0)==0)
//如果返回值为0,则初始化失败,返回1
return1;
//装载面板,返回面板句柄
if((panelHandle=LoadPanel(0,回调函数.uir,PANEL))《0)
//如果装载面板失败,则返回1
return1;
//获得*argv[]中的字符串,即为文件名
SetCtrlVal(panelHandle,PANEL_STRING,argv[0]);
//显示面板
DisplayPanel(panelHandle);
//运行用户界面
RunUserInterface();
//删除面板句柄
DiscardPanel(panelHandle);
//主函数执行成功,返回0
return0;
}
//面板回调函数
intCVICALLBACKPanelCB(intpanel,intevent,void*callbackData,
inteventData1,inteventData2)
{
switch(event)
{
//面板响应事件
caseEVENT_CLOSE:
//调用退出按钮的EVENT_COMMIT事件
QuitCallback(panelHandle,PANEL_QUITBUTTON,EVENT_COMMIT,0,0,0);
break;
}
//函数返回值,0表示成功
return0;
}
//退出按钮
intCVICALLBACKQuitCallback(intpanel,intcontrol,intevent,
void*callbackData,inteventData1,inteventData2)
{
if(event==EVENT_COMMIT)
{
//退出用户界面
QuitUserInterface(0);
}
return0;
}
//显示按钮
intCVICALLBACKOkCallback(intpanel,intcontrol,intevent,
void*callbackData,inteventData1,inteventData2)
{
//定义局部变量
inti;
doubledatapoints[100];
switch(event)
{
caseEVENT_COMMIT:
//产生100个随机数,放入数组datapoints中
for(i=0;i《100;i++)
{
datapoints[i]=rand()/32767.0*100.0;
}
//清除以前Graph中绘制的波形
DeleteGraphPlot(panelHandle,PANEL_GRAPH,-1,VAL_IMMEDIATE_DRAW);
//在Graph中绘制波形
PlotY(panelHandle,PANEL_GRAPH,datapoints,100,VAL_DOUBLE,VAL_THIN_LINE,
VAL_EMPTY_SQUARE,VAL_SOLID,1,VAL_RED);
break;
}
return0;
}
3:
程序注释
①main函数
每一个C程序都必须从一个main函数开始,在调用其他函数流程后再次回到main函数,并且在main函数中结束整个程序的运行。
实际上,main函数可以放在程序的任何地方:
有些程序员喜欢把它放在最前面,而另一些程序员把它放在最后面,无论放在哪个地方,以下几点说明都是适合的。
在C语言中,main函数可以有三个参数,即:
argc,argv和env。
argc:
整数类型,表示传给main函数的命令行参数个数,一般为1。
*argv[]:
二维字符串数组。
在LabWindows/CVI中,argv[0]为程序运行时的文件名,与编译设置有关,在菜单BuildConfiguraTIon下有两个选项,即:
Release和Debug。
当选择Release时,argv[0]为当前工程名加上.exe;当选择Debug时,argv[0]为当前工程名加上_dbg.exe。
argv[argc]为NULL。
*env:
二维字符串数组,为环境变量。
在LabWindows/CVI中,env[]一般为空字符串且省略不写。
LabWindows/CVI启动时总是把这三个参数传递给main函数,参数的传递顺序为:
argc、argv、env,可以在用户程序中加以说明也可以不说明,如果说明了部分或全部参数,它们就成为main主函数的局部变量。
main主函数的声明方式主要有以下几种:
main(void)
main(intargc,char*argv[])
main(intargc,char*argv[],char*env[])
②InitCVIRTE函数
初始化LabWindows/CVI运行时(库)引擎。
在使用外部编译器VisualC++、BorlandC++Builder时调用,如果不使用外部编译器,不会影响程序正常运行。
函数原型为:
intInitCVIRTE(void*HInstance,char*Argv[],void*Reserved);
*HInstance:
对于main函数应为0;对于WinMain函数应为hInstance;对于DllMain应为
hInstDLL。
*Argv[]:
对应于main函数的*argv[]参数。
*Reserved:
保留参数,设置为0。
一般在使用main函数、WinMain函数、DllMain函数时,InitCVIRTE函数的参数设置稍有不
同,其具体调用方式如下所示:
main函数
intmain(intargc,char*argv[])
{
if(InitCVIRTE(0,argv,0)==0)
return1;/*outofmemory*///用户程序
return0;
}WinMain函数
int__stdcallWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpszCmdLine,int
nCmdShow)
{
if(InitCVIRTE(hInstance,0,0)==0)
return1;/*outofmemory*///用户程序
return0;
}DllMain函数
int__stdcallDllMain(void*hinstDLL,intfdwReason,void*lpvReserved)
{
if(fdwReason==DLL_PROCESS_ATTACH)
{
if(InitCVIRTE(hinstDLL,0,0)==0)
return0;
//用户ATTACH程序
}
elseif(fdwReason==DLL_PROCESS_DETACH)
{
//用户DETACH程序
CloseCVIRTE();
}
return1;
}
LabWindows/CVI运行时库引擎主要用在程序发布,并安装在其他计算机上独立运行时。
运行时库包括:
UserInterfaceLibrary、AdvancedAnalysisLibrary、FormattingandI/OLibrary、UtilityLibrary、ANSICLibrary、RS-232Library、TCPSupportLibrary、InternetLibrary、NetworkVariableLibrary、DDESupportLibrary、ActiveXLibrary、DIAdemConnectivityLibrary、TDMStreamingLibrary、.NETLibrary等。
③LoadPanel函数装载用户界面文件(*.uir)或文本用户界面(*.tui)到内存中。
装载后,面板不可见,需要调用DisplayPanel函数来显示面板。
函数原型为:
intLoadPanel(intParent_Panel_Handle,charFilename[],intPanel_Resource_ID);Parent_Panel_Handle:
父面板句柄。
如果为0,则表示所装载的面板为顶层窗口;如果为面板句柄,则表示所装载的面板为该面板的子面板。
Filename[]:
用户界面文件(*.uir)或文本用户界面(*.tui)的文件名。
可以包含全部的路径名或只包含一个简单的文件名,如果为简单的文件名,则必须与工程文件在同一目录下。
Panel_Resource_ID:
面板常量名。
返回值:
面板句柄。
④DisplayPanel函数将内存中装载的面板显示出来。
函数原型为:
intDisplayPanel(intPanel_Handle);
Panel_Handle:
面板句柄。
⑤RunUserInterface函数
运行用户界面并响应回调函数事件。
RunUserInterface在程序开始后始终运行,直到调用
QuitUserInterface函数时才返回。
函数原型为:
intRunUserInterface(void);
返回值:
返回由用户在QuitUserInterface函数的参数中设置的值。
⑥QuitUserInterface函数
QuitUserInterface函数并不直接终止程序的运行,而是使RunUserInterface函数返回一个特定值,并进入终止程序运行处理过程。
staticintpanelHandle;
intmain(intargc,char*argv[])
{
intstatus;
if(InitCVIRTE(0,argv,0)==0)
return1;
if((panelHandle=LoadPanel(0,sample.uir,PANEL))《0)
return1;
DisplayPanel(panelHandle);
//返回值status为10,即:
QuitUserInterface函数的参数设置值
status=RunUserInterface();
DiscardPanel(panelHandle);
return0;
}
//退出按钮
intCVICALLBACKQuitCallback(intpanel,intcontrol,intevent,void*callbackData,inteventData1,int
eventData2)
{
switch(event)
{
caseEVENT_COMMIT:
//QuitUserInterface的参数值为10,即RunUserInterface的返回值
QuitUserInterface(10);
break;
}
return0;
}
⑦DiscardPanel函数释放面板资源,包含父面板下的子面板。
函数原型为:
intDiscardPanel(intPanel_Handle);
Panel_Handle:
面板句柄。
⑧SetCtrlVal函数设置控件值。
函数原型为:
intSetCtrlVal(intPanel_Handle,intControl_ID,);
Panel_Handle:
面板句柄。
Control_ID:
控件常量,通常在头文件中声明。
:
设置值。
⑨rand函数产生0~32767之间的伪随机数。
函数原型为:
intrand(void);
返回值:
伪随机数。
⑩DeleteGraphPlot函数删除控件所绘制的图形。
函数原型为:
intDeleteGraphPlot(intPanel_Handle,intControl_ID,intPlot_Handle,intRefresh);Panel_Handle:
面板句柄。
Control_ID:
控件常量。
Plot_Handle:
绘图句柄,表示所要删除的图形,如果为1,则删除所有图形。
Refresh:
刷新方式。
主要有三种刷新方式,包括:
VAL_DELAYED_DRAW、VAL_IMMEDIATE_DRAW、VAL_NO_DRAW。
⑪PlotY函数沿X轴方向绘制图形,其中Y轴为数据点。
函数原型为:
intPlotY(intPanel_Handle,intControl_ID,void*Y_Array,intNumber_of_Points,floatY_Data_Type[],intPlot_Style,intPoint_Style,intLine_Style,intPoint_Frequency,intColor);
Panel_Handle:
面板句柄,指控件所在的面板。
Control_ID:
控件常量。
*Y_Array:
绘制图形的数据点数组,其数据类型为Y_Data_Type[]所指定的类型。
Number_of_Points:
绘制图形的数据点数,*Y_Array中所包含的数据点数应不小于
Number_of_Points所指定的数据点数。
Y_Data_Type[]:
数据类型,其数据类型如表1-2所示。
表1-2Y_Data_Type数据类型表
表1-3Plot_Style曲线类型表
Point_Style:
数据点类型。
数据点的类型决定VAL_CONNECTED_POINTS或VAL_SCATTER
标记的类型,默认值为VAL_EMPTY_SQUARE。
其主要类型如表1-4所示。
表1-4Point_Style数据点类型表
注:
LabWindows/CVI8.0以上版本中,VAL_EMPTY_SQUARE_WITH_CROSS不能自动切换,需要手动输入此值。
Line_Style:
线型。
其主要类型如表1-5所示。
表1-5Line_Style线型表
Point_Frequency:
当曲线类型为VAL_CONNECTED_POINTS或VAL_SCATTER时,绘制数据点的频率。
默认值为1。
Color:
颜色值。
为4个字节整型RGB值,用十六进制表示为0x00RRGGBB,可以使用MakeColor函数自定义颜色。
返回值:
绘制图形的句柄。
正值表示绘制曲线成功,负值表示产生错误。
若将Graph的ATTR_DATA_MODE属性设置为VAL_DISCARD,则返回值为0。
⑫函数的调用对于控件而言,其回调函数原型为:
intCVICALLBACKControlCallback(intpanel,intcontrol,intevent,void*callbackData,inteventData1,inteventData2);
panel:
控件所在面板句柄。
control:
控件常量。
event:
控件所响应的事件。
*callbackData:
回调数据。
eventData1:
对应于具体控件响应事件的设置值。
eventData2:
对应于具体控件响应事件的设置值。
本程序在面板的EVENT_CLOSE事件中,调用了QuitCallback函数,调用格式为:
QuitCallback(panelHandle,PANEL_QUITBUTTON,EVENT_COMMIT,0,0,0);
即调用在panelHandle这个句柄所在面板的PANEL_QUITBUTTON常量(退出按钮)的EVENT_COMMIT事件(左击事件)。
⑬回调函数中参数的传递对于退出按钮,其回调函数为:
intCVICALLBACKQuitCallback(intpanel,intcontrol,intevent,
void*callbackData,inteventData1,inteventData2)
if(event==EVENT_COMMIT)
QuitUserInterface(0);}return0;
}
当有左击事件发生时,会将一个常量值传递给event参数,如果值为EVENT_COMMIT时,则执行该函数。
其函数也可以写成标准的LabWindows/CVI形式,两者功能完全相同,只是形式表现不同。
intCVICALLBACKQuitCallback(intpanel,intcontrol,intevent,void*callbackData,inteventData1,inteventData2)
{switch(event){caseEVENT_COMMIT:
QuitUserInterface(0);break;}return0;
}
⑭面板中的热键设置
面板中的显示与退出按钮的表现形式为显示(S)、退出(Q),设计时以显示(__S)、退出(__Q)来表示,说明可以通过键盘或鼠标来进行程序的控制。
如要显示图形,则可以按下Alt+S的组合键,如果要退出程序,可以按下Alt+Q键,一般将采用Alt键与字母键组合的形式称为热键(HotKey),与快捷键(ShortcutKey)采用的Ctrl键与字母组合的形式稍有不同,例如在Word中进行的剪切操作,如果用快捷键来完成,直接按
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- LabWindowsCVI 程序 回调函数设计 调函 设计
![提示](https://static.bdocx.com/images/bang_tan.gif)