作者:balloonman2002 2004年6月26日
本文擬結合powerbuilder語言,簡述如何實現動態添加菜單效果。在實際開發過程當中很多時候會因為權限控制的需要,根據用戶的不同權限來動態添加菜單項目,如何避免使用繁瑣的api函數(如:createmenu、insertmenu、insertmenuitem、appendmenu等),利用powerbuilder語言自身功能達到這一目的呢?本文將就此問題簡單予以論述。
一、基本思路
在pb幫助的menu object一節當中,關于其properties描述當中有一項:
item[ ] menu specifies the menu objects under a menu object.
這看似簡單的一句話其實包含了三層含義:
1、這句話說明menu對象有一個屬性為數組類型,它其中的各個元素記錄了其所有的具體子item項目,可以借助這個數組中各元素來訪問底層的各子菜單;
2、這些子item項目仍是menu類型,因此可以按照第一點的邏輯繼續向下層推廣,借助該子item的item[]屬性可以進而訪問其所屬下層的第二層子菜單,推而廣之,即可全面遍歷整個菜單體系的所有子菜單項目;
3、既然該屬性是一個數組類型,那么就可以按照數組類型變量來處理,我們可以對其進行upperbound()、lowerbound()等函數操作,還可以進行數組的擴展,即添加新項目,這一點很重要,它是我們整篇文章的核心,如何利用pb實現動態添加菜單,說白了就是添加這個數組元素(讀者必須對此有一個清晰的認識),同時期間有一些配套具體的實現技巧,詳見下文。
二、具體實現
(一)基本工作
創建一個window窗口和二個menu菜單,其中一個菜單命名為m_main,用作窗口的基本主菜單,新增菜單將在其上添加,該菜單初始可以包含一些基本菜單,如:文件、添加、刪除、保存、退出等;另外一個菜單命名為m_new,該菜單只有主菜單一個item,其下沒有進一步的子菜單,因此該菜單其實就是一個菜單item。
在主窗口中聲明實例變量(instance variables):
menu im_new[] //聲明一菜單數組用于引用新增菜單
integer ii_count //聲明一變量記錄總共新增菜單個數
(二)具體代碼
1、添加一級菜單功能的實現:
//////////////////////////////////////////////
//
//用途:在最后一項以及菜單之后新增一項一級菜單
//時間:2003-6-1
//
//////////////////////////////////////////////
integer li_itemcount //聲明變量記錄當前一級菜單總個數;
//新創建一個菜單對象,并將其放到菜單數組im_new[]當中;
ii_count++
im_new[ii_count]=create m_new
//此處對新創建的菜單對象獲取引用;
li_itemcount=upperbound(m_main.item[])
m_main.item[li_itemcount + 1]=im_new[ii_count].item[1]
//下面是設置新生成菜單的text屬性,這個屬性可以從數據庫中取,但此處省略簡化掉了;
m_main.item[li_itemcount + 1].text="新增一級-" + string(li_itemcount + 1)
//下面是設置新生成菜單的tag屬性,這個屬性可以從數據庫中取,但此處省略簡化掉了;
//通過這個tag可以當作功能號等來使用,通過gf_menumessage()函數來予以公共處理;
//m_main.item[li_itemcount + 1].tag="xxxxxxxxx"
//此處來將新生成的菜單對象顯示出來;
m_main.item[1].hide()
m_main.item[1].show()
2、添加二級菜單功能的實現:
//////////////////////////////////////////////
//
//用途:在最后一項一級菜單下新增一項二級菜單
//時間:2003-6-1
//
//////////////////////////////////////////////
//聲明變量記錄當前一級菜單總個數、最后一項一級菜單對應的二級菜單總個數;
integer li_precount,li_itemcount
//新創建一個菜單對象,并將其放到菜單數組im_new[]當中;
ii_count++
im_new[ii_count]=create m_new
//此處對新創建的菜單對象獲取引用;
li_precount=upperbound(m_main.item[])
li_itemcount=upperbound(m_main.item[li_precount].item[])
m_main.item[li_precount].item[li_itemcount + 1]=im_new[ii_count].item[1]
//下面是設置新生成菜單的text屬性,這個屬性可以從數據庫中取,但此處省略簡化掉了;
m_main.item[li_precount].item[li_itemcount + 1].text="新增二級-" + string(li_precount) + "-" + string(li_itemcount + 1)
//下面是設置新生成菜單的tag屬性,這個屬性可以從數據庫中取,但此處省略簡化掉了;
//通過這個tag可以當作功能號等來使用,通過gf_menumessage()函數來予以公共處理;
//m_main.item[li_precount].item[li_itemcount + 1].tag="xxxxxxxxx"
//此處來將新生成的菜單對象顯示出來;
m_main.item[1].hide()
m_main.item[1].show()
3、添加三級菜單功能的實現:
//////////////////////////////////////////////
//
//用途:在最后一項二級菜單下新增一項三級菜單
//時間:2003-6-1
//
//////////////////////////////////////////////
//聲明變量記錄當前一級菜單總個數、最后一項一級菜單對應的二級菜單總個數;
integer li_fircount,li_precount,li_itemcount
//新創建一個菜單對象,并將其放到菜單數組im_new[]當中;
ii_count++
im_new[ii_count]=create m_new
//此處對新創建的菜單對象獲取引用;
li_fircount=upperbound(m_main.item[])
li_precount=upperbound(m_main.item[li_fircount].item[])
if li_precount = 0 then
messagebox("提示","請先點擊-添加二級菜單-按鈕創建一個二級菜單,:)")
return
end if
li_itemcount=upperbound(m_main.item[li_fircount].item[li_precount].item[])
m_main.item[li_fircount].item[li_precount].item[li_itemcount + 1]=im_new[ii_count].item[1]
//下面是設置新生成菜單的text屬性,這個屬性可以從數據庫中取,但此處省略簡化掉了;
m_main.item[li_fircount].item[li_precount].item[li_itemcount + 1].text="新增三級-" + string(li_fircount) &
+ "-" + string(li_precount) + "-" + string(li_itemcount + 1)
//下面是設置新生成菜單的tag屬性,這個屬性可以從數據庫中取,但此處省略簡化掉了;
//通過這個tag可以當作功能號等來使用,通過gf_menumessage()函數來予以公共處理;
//m_main.item[li_precount].item[li_itemcount + 1].tag="xxxxxxxxx"
//此處來將新生成的菜單對象顯示出來;
m_main.item[1].hide()
m_main.item[1].show()
4、處理動態生成菜單的clicked事件:
總體思想是采用參數化思想,借助統一的函數,根據函數參數不同來予以不同處理。
(1)處理m_new對象的clicked事件:
////////////////////////////////////////////////////////////////////////
//
//用途:根據新生成的各菜單所對應的功能號,即從數據庫中取出的tag屬性
// 來調用gf_menumessage()全局函數來實現不同的系統功能;
//時間:2003-6-1
//
////////////////////////////////////////////////////////////////////////
//此處本應該去調用gf_menumessage()全局函數來處理不同功能所對應要處理的功能號,
//但此處均略掉了,具體內容可參見 gf_menumessage() 函數;
//此處僅僅演示一個messagebox()功能,如下;
//integer li_ret
//li_ret = gf_menumessage(this.tag)
//下面代碼是避免點擊含有下一級子菜單的菜單時會彈出對話框,導致無法顯示下一級菜單的情況;
if upperbound(this.item[]) > 0 then
return
end if
messagebox("動態菜單演示","您當前點擊的菜單是:" + this.text)
(2)編寫gf_menumessage函數:
////////////////////////////////////////////////////////////////////////
//
//用途:根據新生成的各菜單所對應傳進來的功能號,即從數據庫中取出的tag屬性
// 來動態判斷所要進行的操作;
//時間:2003-6-1
//輸入:string 型 as_funcode:對應傳進來的菜單要實現的功能號;
//輸出:integer型 1:成功
// -1:失敗
//
////////////////////////////////////////////////////////////////////////
//注:根據新生成的各菜單所對應傳進來的功能號,即從數據庫中取出的tag屬性
// 來動態判斷所要進行的操作;此操作需要連接數據庫,故此處簡列思路,具體略
string ls_funcode //聲明一變量用于記錄傳進來的功能號;
ls_funcode = as_funcode
choose case ls_funcode
case "1"
//......比如 1 代表入庫管理,則去調用入庫管理函數 gf_rk()等等
case "2"
//......比如 1 代表出庫管理,則去調用出庫管理函數 gf_ck()等等
//......
case else
return -1
end choose
return 1
至此,動態添加菜單效果全部完成,效果圖見:
http://blog.csdn.net/images/blog_csdn_net/balloonman2002/17312/r_add_menu.jpg
如需要進一步資料,請聯系qq:27855043,msn:[email protected]
如有不當之處,敬盼您的指點。
新聞熱點
疑難解答