[返回]
软件世界2000年第1期

利用递归技术实现powerbuider下的通用菜单设计

李淑华 李建东

  摘要:本文通过对powerbuider下菜单属性的灵活运用,结合递归技术来实现菜单对象的有效与无效显示,具有一定的通用性与实用性

  关键词:菜单 菜单对象 递归


  一、问题的提出


  使用powerbuilder开发大型数据库的软件开发人员都知道其菜单的设计与建立比较容易:只要我们打开menu画板,添加菜单对象,并对各菜单对象属性在属性标签页中进行定义,便可指定菜单对象的外观与行为。然而,我们在用powerbuilder开发大型数据库应用程序时,对菜单的使用不仅仅是简单的利用画板的建立,往往需要根据用户的权限来显示菜单对象,即菜单中哪些菜单对象为有效,哪些菜单对象为无效,视用户权限的不同而不同。怎样灵活方便地实现此功能呢?我们采用了如下的设计方法。此方法当菜单发生改动时,脚本中的程序并不必改动,因此具有较强的灵活性与通用性。


  二、设计思想


  我们知道菜单对象的有效与否是靠属性enabled来实现的,在menu画板的style属性标签页中,若选中enabled则菜单对象有效,否则菜单对象变灰,即为无效。此属性的设置既可在画板中完成,也可在执行时通过编写脚本来修改。我们又注意到菜单的结构就象一棵树,这种树型结构用递归方法来遍历是十分行之有效的。因此,我们利用item属性递归遍历菜单对象,在遍历过程中,以每一菜单对象的tag属性值为依据,设置菜单对象的enabled属性为false还是true,这样就动态的实现了菜单对象的有效与无效显示。


  三、所涉及的菜单对象的属性说明


  我们会用到如下属性:

  1)enabled:为逻辑型,其值为true时菜单对象有效,其值为false时菜单对象无效。

  2)tag:类型为string型,指定菜单对象的值,此属性值默认为空,一般较少使用。注意我们在此要灵活使用它。

  3)item[]:类型为menu型,指定菜单下的菜单对象,用upperbound(item)可得到菜单对象的数目。


  四、设计举例


  我们以《邮政转运微机处理系统》下的主菜单m_menu为例加以说明。

  此系统用户共分为三个级别:系统管理员、维护员、操作员,他们的权限值依次设为1、2、3,若某菜单对象对某用户为不可用,则将其权限值加空格符后填入对应菜单项的tag属性中。具体tag属性设置如下。

  1)菜单m_menu的菜单对象按其层次如下建立:

  (注:它们的属性都取建立时的默认值,只有tag属性按如下提示填写,未标注tag值者其tag内容为空)

  1.数据录入

  2.打印处理

   ·汇封路单

   ·总包路单

   ·地名信息

   ·经转关系(重件、轻件、快件)

  3.查询修改

   ·浏览数据

   ·浏览路单

  4.系统维护

   ·转口局(重件(tag:3 )、轻件(tag:3 )、 快件(tag:3 ))

   ·航空计划(tag:3 ) /*将3+" "键入航空计划的tag属性中表示此菜单对象对操作员不可用*/

   ·邮件种类(tag:3 )

   ·航站总单(tag:3 )

   ·附单单头(tag:3 )

   ·单头种类(tag:3 )

   ·保装标志(tag:3 )

   ·地名信息(tag:3 )

   ·备注(tag:3 )

   ·路别(tag:3 )

   ·口令(tag:2 3) /*将2+" "+3+" "键入口令的tag属性中,表示此菜单对操作员和维护员不可用*/

   ·管理级别(tag:2 3)

   ·本地参数(tag:2 3)

  5.综合处理

   ·计划配发

   ·挑对处理

   ·接收传送

  6.业务统计

   ·交接班报表

   ·日平衡合拢表

  7.帮助

  8.退出系统

  2)创建一窗口w_menu,并将以上建立的菜单m_menu挂在窗口w_menu上

  3)在w_menu上建立一窗口函数wf_menable

  窗口函数原形为wf_menable(menu mname,integer right),返回值无。

   wf_menable函数体内容如下:

   integer i

   String m_tag

   if upperbound(mname.item) 〉 0 then /*upperbound(mname.item)取得本级菜单下的

   菜单对象数目*/

   for i = 1 to upperbound(mname.item)

   wf_menable(mname.item[i],right)

   /*递归调用函数wf_menable,mname.item[i]取得本级菜单的第i菜单对象名*/

   next

   return

   end if

   m_tag = trim(mname.tag)

   if m_tag = "" then return

   if pos(mname.tag,trim(string(right))+' ')=0 then /*判断权限值是否包含在tag中, 若不包含则返回,否则enabled设为false*/

   return

   else

   mname.enabled=false

   end if

  4)在菜单所属窗口w_menu的open事件中调用wf_menable函数

   /*right为全局变量,值可为1,2,3 (假设权限由权限判断程序已得到,权限判断程序略),m_menu为菜单名称*/

   wf_menable(m_menu,right)


  五、结束语


  以上代码在windows98,powerbuilder6.0下运行通过。