1、用 PB 做一个通用右键菜单对象被右键单击就弹出一个功能菜单是 Windows 应用程序一项不可缺少的功能。在 PowerBuilder 应用开发中,可在需弹出右键菜单对象的 rbuttondown事件中调用该菜单的 Popmenu( )方法实现这一功能。但多数情况下,应用中有多处要用到不同的弹出式菜单,如一一用这种方法就需要做大量的工作。能不能做一个通用的菜单,可以用任何对象的 rbuttondown 事件激发弹出,并在弹出前动态改变弹出菜单项的内容,当点击菜单项时又可执行被右击对象的相应用户事件?由于这一技术最大的特点是当函数创建成功后,可在任何应用的任何对象中随心所欲的使用,随时随地弹出
2、自己想要显示的菜单项,并执行相应的自己需要的功能脚本,但目前各种资料上鲜有系统、成型的介绍。一、 创建弹出菜单 m_popup 1、创建一个菜单 m_popup,定义菜单条 m_main,其下有十五个菜单项,分别命名为 m_item1,m_item2,m_item1,各项的显示文本(text)分别为item1,item2, item15; 2、为 m_popup 菜单定义一个 Powerobject 类型的 Instance Variables 变量:Anyobject , 脚本为: Powerobject Anyobject 3、给 m_item1,m_item2,m_item15 各菜单项
3、的 Clicked 事件下分别输入脚本: Anyobject.triggerevent(“ue_item1“) /m_item1 的 clicked 事件Anyobject.triggerevent(“ue_item2“) Anyobject.triggerevent(“ue_item15“)4、定义几个菜单函数:- 1) setmenuitem(string itemstring),返回值为 Null。/参数 Itemstring 是由多个子串组成的。各个子串间用“|”间隔,每个子串为一个菜单项的显示文本(text)。 /该函数功能是把 itemstring 分解为多个子串,并把子串赋给相应
4、菜单项的 text。脚本如下: int itempos,itemorder=1,li string currentitem /messagebox(“len(itemstring)“,string(len(itemstring)if len(itemstring)=0 then return elseitempos=pos(itemstring,“|“)/messagebox(“itempos“,string(itempos)DO WHILE itempos0 / itempos 为间隔符“|“的位置currentitem=left(itemstring,itempos -1) /取出子串 /
5、 messagebox(“currentitem“,string(currentitem)itemstring=mid(itemstring,itempos+1) this.m_main.itemitemorder.text=currentitemitempos=pos(itemstring,“|“) /messagebox(“itempos=pos(itemstring“,string(itempos)itemorder=itemorder+1 /messagebox(“itemorder+“,string(itemorder)LOOPthis.m_main.itemitemorder.te
6、xt=itemstring for li=1 to itemorderthis.m_main.itemli.visible=true this.m_main.itemli.enabled=true nextend if for li=itemorder+1 to 15 this.m_main.itemli.visible=false next /2)setitemdisable(integer itemorder) 返回值 Null。 /该函数把第 itemorder 菜单项置灰(disable)。 脚本如下: if itemorder15 then return elsethis.m_mai
7、n.itemitemorder.enabled=false end if3)popupmenu(integer x, integer y) 返回值 Null。/该函数弹出菜单条 m_main。 脚本如下:this.m_main.popmenu(x,y)二、 rbuttondown 事件激发弹出菜单 m_popup至此,我们就可以在窗口中任意对象如 DataWindow、 Picture、 SingleLineEdit、 ListBox、PictureListBox、 DropDownPictureListBox、 MultiLineEdit、 ListView、 TreeView 等的 rbu
8、ttondown 事件中写脚本调用m_popup 的函数来实现右键单击弹出一个菜单。下面以数据窗口 dw_1 为例,在其 rbuttondown 事件下写入脚本,使得右击dw_1 可弹出菜单:刷新/插入/删除/修改。步骤如下: 1、事先给窗口定义一个 m_popup 型 Instance 变量 om_1: m_popup om_1 2、dw_1 的 rbuttondown 事件脚本:if not isvalid(om_1) then/m_popup om_1om_1= CREATE m_popupend if/把菜单的 anyobject 指向被右击的对象(dw_1)om_1.Anyobjec
9、t=thism_popup.setmenuitem(“刷新|插入|删除|修改|标签打印“)/可在此调用 om_1.setitemdisable(itemorder)函数 disable 某菜单项。m_popup.popupmenu(this.x+ this.pointerx(),this.y+this.pointery()3、 给 dw_1 定义用户事件 ue_item1、ue_item2、 ue_item3 及 ue_item4。返回值全为默认的 NULL 事件 ue_item1 脚本:dw_1.retrieve() 事件 ue_item2 脚本:long newrow newrow=dw_
10、1.insertrow(0) dw_1.scrolltorow(newrow)事件 ue_item3 脚本:dw_1.deleterow(0) 事件 ue_item4 脚本: dw_1.update()这样,只要用户单击 dw_1 弹出的右键菜单,就可完成对 dw_1 的插入、删除、修改等功能。三、 推广为全程函数 - 如果应用中有许多地方要用此功能,我们可以把 dw_1 的 rbuttondown 事件脚本改造成一个全程函数。- 1、将变量 om_1 定义为 global 变量: - m_popup om_1 - 2、定义一个全程函数 - pupmenu(powerobject sender
11、,string itemstring,integer x,integer y) 返回值 Null。其中参数 sender 为被右击的对象,itemstring 为弹出菜单的菜单项字符串,x、y 为菜单弹出的坐标位置。 脚本如下:if not isvalid(om_1) thenom_1= CREATE m_popupend ifom_1.anyobject=senderom_1.setmenuitem(itemstring)sender.triggerevent(“ue_beforepop“)/激活 sender 用户事件。om_1.popupmenu(x,y)这样,上述 dw_1 的 rbu
12、ttondown 事件脚本就可改写为:string items=“刷新插入删除修改“popmenu(this, items ,this.x+this.pointerx(),this.y+this.pointery()注意:在 MDI 应用中,popmenu()函数需要改为:popmenu(this, items ,w_frame.pointerx(),w_frame.pointery()其中 w_frame 为 MDI 主窗口名。- 在函数 popmenu 中,又激活了被右击对象的 ue_beforepop 用户事件。如有必要,你可以给被右击对象定义一个 ue_beforepop 事件,在该事件中可调用 om_1.setitemdisable()函数来屏蔽某个菜单项。 - 最后,别忘了在应用的 close 事件里加上下列语句,及时释放系统内存。 - if isvalid(om_1) then destroy om_1 - 以上代码在 WindowsXP 和 Powerbuilder9.0 平台上开发,并在多个大型系统中应用,效果很好。