第6章应用程序发布6.1应用程序开发者和应用者(略)6.2利用项目管理器管理应用程序对象6.3发布应用程序(略)第7章程序设计进阶7.1程序结构的图示化表示(略)7.2交互式输入输出语句7.3嵌套分支(略)7.4子程序、自定义函数、过程文件、变量作用域6.2利用项目管理器管理应用程序对象6.2.1管理和调试应用程序对象6.2.2应用程序执行入口与事件处理循环在一个应用程序项目中往往包含很多程序、表单、菜单等可执行程序对象,这些程序对象相互之间一般存在调用关系,其中最先执行的程序对象就是整个应用程序的执行入口。1、主文件设置与事件处理循环在VisualFoxPro项目管理器中,把应用程序的入口文件称为主文件。主文件的选择与应用程序的初始操作界面有关,一般有两种初始界面设置方式:1)应用程序打开单独的表单,称为主表单,在主表单上打开一个操作菜单,称为主菜单,通过主菜单可以打开其他功能表单。当操作结束时,关闭主表单,这时程序结束运行;2)应用程序使用VisualFoxPro主窗口,只是用主菜单替换掉主窗口菜单,在程序结束时,恢复VisualFoxPro主窗口菜单。对于表单、菜单等对象而言,如果希望程序可以响应相应对象的操作事件,就必须让程序进入等待并响应对象事件的状态,我们把这种状态叫做事件处理循环,在启动事件处理循环之后,用户对对象的各种操作会自动触发相应对象的事件并执行对应的脚本。启动事件处理循环的语句是READEVENTS语句,执行该语句后,程序自动进入事件处理循环,直到在某一事件发生时执行了CLEAREVENTS语句之后才退出事件处理循环,由对应的READEVENTS启动的事件处理循环结束,这时程序会继续执行READEVENTS语句之后的语句序列。在事件处理循环期间,程序的执行点一直停留在READEVENTS语句上。2、主程序-主表单-主菜单结构的事件处理循环1)在主程序(.PRG)中打开主表单并启动事件处理循环:DOFORM表单文件名.SCXREADEVENTS2)在主表单打开时显示主菜单;3)在关闭主表单时,释放主菜单,同时结束事件处理循环,设计表单的Destroy或Unload事件脚本中释放菜单命令后增加CLEAREVENTS即可。3、主程序-主菜单结构的事件处理循环1)在主程序中打开主菜单(在VisualFoxPro主窗口显示):DO菜单程序文件名.mprREADEVENTSSETSYSMENUTODEFAULT2)菜单“退出”菜单命令为CLEAREVENTS4、主菜单结构的事件处理循环在直接从主菜单开始执行的应用程序结构中,需要在菜单中启动和结束事件处理循环。启动事件处理循环应该在菜单对象已经建立和显示之后,在菜单常规选项中添加如下“清理”代码即可:*设置运行环境READEVENTSSETSYSMENUTODEFAULT*恢复初始环境菜单“退出”菜单命令为CLEAREVENTS6.2.3连编应用程序可以选择是否在连编结果程序中包含数据库及表4、主菜单结构的事件处理循环在直接从主菜单开始执行的应用程序结构中,需要在菜单中启动和结束事件处理循环。启动事件处理循环应该在菜单对象已经建立和显示之后,在菜单常规选项中添加如下“清理”代码即可:*设置运行环境READEVENTSSETSYSMENUTODEFAULT*恢复初始环境菜单“退出”菜单命令为CLEAREVENTS6.2.3连编应用程序连编前可以选择是否在连编结果程序中包含数据库及表,选择为包含状态的数据库和表在程序运行时不能被修改,如果希望程序运行时能够修改表及其数据,就必须把相应的表排除。7.2交互式输入输出语句在可视化程序设计工具出现以前,程序的输入和输出都是通过语句实现的,用户根据屏幕操作提示输入数据,程序把处理结果在屏幕上输出出来,就象人和计算机相互对话一样。一般把这样的操作状态叫做交互状态。VisualFoxPro依然保留了许多面向交互式操作的输入、输出语句。7.2.1交互式输入语句1、ACCEPT语句ACCEPT语句用于输入一个字符串,其典型语法格式如下:ACCEPT[提示字符串]TO内存变量2、INPUT语句INPUT语句可以输入多种类型的数据,其典型语法格式如下:INPUT[提示字符串]TO内存变量用户可以输入数值、日期、逻辑值或字符串,输入时需要输入相应数据的定界符。3、WAIT语句WAIT语句可以输入一个控制字符,以决定程序的执行路线。WAIT语句的典型语法格式如下:WAIT[提示字符串][TO内存变量]WAIT语句执行时,首先显示提示信息(如果给出了提示字符串则提示该字符串,否则显示“按任意键继续……”)并等待用户输入一个字符,用户按下键盘的任一键后结束执行。[例7-2]随机生成一个1-6的整数,然后用户猜想这个数是几(输入一个1-6的数),无论猜的对错,都给出提示并让用户选择是否继续。CLEARDOWHILE.T.I=INT(6*RAND()+1)ACCEPT已经生成了一个数(1-6),猜一下是几:TONIFVAL(N)=I?恭喜,猜对了!!!ELSE?哈哈,猜错了!!!??刚才产生的数是:,IENDIFWAIT继续吗(Y/N)?TOCIFUPPER(C)YEXITENDIFENDDO?“游戏结束了!!!”7.4子程序、自定义函数、过程文件、变量作用域在设计程序代码时,可能需要经常进行相同的处理,这些处理的代码完全相同,不同的只是参数,这样的程序代码可以独立出来单独编写,一般把这样的代码叫做程序模块,其他程序在需要时执行(调用)已经编写好的程序模块即可。子程序、自定义函数就是这样的程序模块。子程序、函数都是供其他程序调用的,一般把调用子程序或函数的程序称为调用程序(调用模块)或主程序(主模块)。当一个模块调用另一个模块时,往往把前者叫做上级模块,后者叫做下级模块。可以把不同的子程序或函数保存到一个程序文件中,这个程序文件就是过程文件,其中的程序模块就叫做过程(Procedure)。7.4.1子程序可以被其他程序调用执行,执行完成后返回到调用程序处继续执行的程序段叫做子程序。子程序可以保存在单独的程序文件中,也可以保存在过程文件中。1、子程序调用与返回调用子程序用DO语句(命令)实现,其语法格式如下:DO子程序名子程序名可以是子程序文件名或子程序过程名,执行该命令时即开始执行子程序,执行完子程序后返回到DO语句之后的语句处继续执行。在子程序中通过RETURN语句返回到调用程序,当执行到子程序中的RETURN语句时结束子程序执行。2、子程序参数传递可以在调用子程序时向子程序传递参数,子程序针对具体参数进行处理。要向子程序传递参数,首先必须在子程序首部说明需要传递的参数,说明参数语句的典型语法格式如下:PARAMETERS|LPARAMETERS参数表参数表为用逗号分隔的变量名,这些变量可以在子程序中引用,变量的值由调用程序传递给子程序。用PARAMETERS指定的参数可以在本子程序及其调用的子程序中引用,其有效范围是子程序及其下级模块。用LPARAMETERS指定的参数则只能在本子程序中引用。调用带参数的子程序时指定传递的参数,调用语句语法格式有如下两种:DO子程序名WITH参数表子程序名(参数表)子程序名可以是子程序文件名或子程序过程名,参数表是用逗号分隔的可求值的表达式列表。子程序中的参数取值是不确定的,这些参数只有形式上的意义,代表着特定类型的量。一般把子程序中的参数叫做形式参数或形参。在调用子程序时指定的参数类型、取值必须是确定的,这些参数可以是常量、变量、函数调用或可以计算求值的表达式。一般把调用子程序时传递的参数叫做实际参数或实参。在调用子程序时,实参的个数、顺序、类型必须与形参一一对应。参数传递方式有两种:引用和传值。参数传递的规则如下:①表达式一律传值,即把表达式的值赋给对应参数;②第一种调用格式:单变量参数不加括号表示引用传递,加括号表示传值;③第二种调用格式:单变量参数不加括号时,按UDFPARMS设置确定传递方式。如果最近执行的是SETUDFPARMSTOVALUE则传值,如果最近执行的是SETUDFPARMSTOREFERENCE则引用。传值传递时,子程序中对参数的操作与实参无关,子程序返回后,实参的值不变。引用传递时,子程序中对参数的操作就是对相应实参的操作,子程序返回后,实参的值可能被子程序改变。应该慎用引用传递。7.4.2自定义函数在程序中可以直接调用系统函数,如果没有对应的系统函数,也可以自己设计一个函数来实现相应的处理,为把这种函数与系统函数相区别,一般把这种函数叫做自定义函数。自定义函数的典型语法结构如下:FUNCTION函数名[PARAMETERS参数表]〈函数体语句序列〉函数必须以FUNCTION开头,其后给出函数名。函数可以有参数,这时用PARAMETERS语句指定参数。函数体语句序列用于进行运算处理。函数体语句序列中用RETURN语句返回处理结果,其语法格式为:RETURN表达式函数调用时将返回表达式运算结果。如果函数中没有RETURN语句,函数返回值为逻辑真(.T.)。函数调用方式与系统函数调用方式相同,即直接在表达式中调用即可。如果有参数,实参是常数、表达式或加括号的变量时,传递方式是传值。当实参为单个变量且没加括号时,传递方式有如下区别:1)实参变量前加@符号时为引用传递;2)实参变量前无@符号时传递方式取决于SETUDFPARMS设置。函数模块可以放在其主程序文件中,也可以放在过程文件中。[例7-8]编写自定义函数,并调用该函数计算s=(m!+n!)/k!。CLEARINPUT请输入m:TOmINPUT请输入n:TOnINPUT请输入k:TOks=(bb(m)+bb(n))/bb(k)?s的值为:,s*函数bbFUNCTIONbbPARAMETERSNS=1FORI=1TONS=S*IENDFORRETURNS7.4.3过程文件1、过程文件中的子程序、函数定义过程文件中的子程序定义格式如下:PROCEDURE子程序名参数说明子程序体语句序列ENDPROC参数说明、子程序体语句序列是子程序的功能定义部分,与前面介绍的子程序结构相同。过程文件中的函数定义格式如下:FUNCTION函数名参数说明函数体语句序列ENDFUNC参数说明、函数体语句序列是函数的功能定义部分,与前面介绍的函数结构相同。2、过程文件中模块的调用要调用过程文件中的子程序、函数,首先需要使系统知道相应的子程序、函数所在的过程文件,这通过SETPROCEDURE命令实现,其典型语法格式如下:SETPROCEDURETO[过程文件名1[,过程文件名2……]]该命令将依次打开指定的过程文件。未指定任何过程文件时将关闭所有已打开的过程文件。在打开过程文件后,执行子程序调用或函数调用时,首先会在主程序文件中查找指定的子程序或函数,如果没找到会继续到已经打开的过程文件中查找。7.4.4变量的作用域在VisualFoxPro应用程序中,变量的作用范围是不同的,所谓变量的作用范围也叫变量的作用域,是指变量起作用的程序代码区间。1、公共变量公共变量是指在程序模块中说明为PUBLIC的变量,也叫全局变量,其说明语法格式如下:PUBLIC变量名列表公共变量在说明语句后调用的所有程序模块中都有效,在执行CLEARMEMORY、RELEASE等操作后,相应的公共变量将失效。变量说明后,其初值为.F.,通过赋值可以改变其数据类型。2、私有变量私有变量包括在程序模块中通过赋值语句生成的变量以及说明为PRIVATE的变量,PRIVATE语句的语法格式如下:PRIVATE变量名列表私有变量在说明它的模块及下级模块内有效。用PRIVATE说明变量后,其初值为.F.,通过赋值可以改变其数据类型。当用PRIVATE说明私有变量时,变量名可以与上级模块说明的私有变量或公共变量同名,这时,在模块内及其下级模块中引用该变量名时,引用的是该模块定义的私有