国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

菜單枚舉記

2024-07-21 02:08:56
字體:
來源:轉載
供稿:網友


菜單枚舉記

 

有一mdi應用程序,現假設要枚舉出其能夠得到系統命令響應所有菜單項的內容:如命令id,資源名稱,所在(子)菜單的句柄等,并對之進行操作。本文對此略述一二,未達意處,望各位海涵之外,以我之深度,唯與諸位共勉而已。

1、  我的迷惑

這幾天修煉english help,悟得些許正果,希望得與世人共超,尚不知是否有效,但為之而已。言歸正傳:

菜單項可以是菜單,反之亦然,此時菜單被稱為子菜單;如果菜單項不是菜單,則它便是’純菜單項’。以前我以為菜單中每一項都是菜單,我的思維中因此不再有菜單項的定義。可能這是個菜鳥級問題,但也可能您尚不甚解,那您不妨紙上談兵一番,將最簡單的菜單畫上一畫,再琢磨琢磨。

2、  菜單枚舉算法

a、 菜單抽象結構之一(樹型抽象):



        現在要訪問到這棵’樹’的所有葉結點并處理之,方法如b所述。

 

b、 枚舉算法(深度遍歷,c++語法)

1.       )求得當前結點的子結點數c;

2.       )循環查詢當前結點的i (0<=i<c)子結點信息:

若該子結點i無下級子結點,則子結點i為葉結點,按需處理后,作i=i+1,重復此步驟;

否則子結點i為分枝結點,置下級子結點為當前結點,轉向1;

              3.)遍歷完畢。

int findmenuitem(hmenu hmenu)//參數hmenu為分支結點資源標識

{

int i,c;

long res;

char* s=new char[33];

menuiteminfo mii;

mii.cbsize=sizeof(menuiteminfo);

mii.fmask=miim_data|miim_id|miim_submenu|miim_type|miim_state|miim_checkmarks;

mii.dwtypedata=s;

 

c=getmenuitemcount(hmenu);//獲取當前菜單所有的菜單項數目

for(i=0;i<c;i++)

{      

mii.cch=32;//注意哦!

res=getmenuiteminfo(hmenu,i,true,&mii);

if (res==0 ) {delete s;return -1;} //如果獲取菜單信息失敗

if (mii.hsubmenu==null)//

          {

               //若該菜單項非子菜單,則在此作相應處理

               }

       else

                {

               //若該菜單項為子菜單,則如此處理

                res=findmenuitem(mii.hsubmenu);//直接遞歸調用

                if(res==-1){delete s;return -1;}

                }

}

delete s;

return 0;

}

 

int enummenuenditems(hwnd hwnd)//開始遍歷窗口菜單項。參數hwnd為菜單所在的窗體。

{

        hmenu hmenu=getmenu(hwnd);

        if(hmenu==null) return –1;

        return findmenuitem(hmenu);

}            

注: 此處代碼僅僅描述算法。若應用到它處,根據不同的需要,function的返回值和結點處理代碼理所當然要發生改變。

     附錄2為上述代碼的pb文本,兩者略有不同,以資參考。

        下面對上述代碼中用到的windows api 及 struct稍作解說。

 

3、  在的所用開發工具中declare 如下windows api及相關struct (標準格式):

hmenu getmenu( hwnd hwnd);//返回值:hwnd所關聯的窗口的菜單句柄

hmenu getsubmenu(hmenu hmenu,int npos);//返回值:hmenu所關聯的菜單中第npos項的子菜單句柄

int getmenuitemcount(hmenu hmenu ); //返回值:hmenu所關聯的菜單中的菜單項數目

bool winapi getmenuiteminfo (

hmenu hmenu,   

uint uitem,

bool fbyposition, //該參數確定uitem為當前菜單項的命令標識還是在所屬菜單中的排序位置號

lpmenuiteminfo lpmii);

bool drawmenubar(hwnd hwnd ); //重繪hwnd所關聯的窗口的菜單

typedef struct tagmenuiteminfo {

    uint          cbsize; //本結構體物理大小,以byte為單位,其值實際上為48

    uint          fmask; //確定想要查詢或設置菜單項的哪能些內容

    uint          ftype; //菜單格式類型

    uint          fstate;// 菜單狀態:enabled、disabled or grayed

    uint          wid; //命令標識符

    hmenu       hsubmenu; //子菜單句柄,若無子菜單則為null

    hbitmap     hbmpchecked; //根據這兩個域值,可以自定義菜單項被選定時的標記,

    hbitmap     hbmpunchecked; //而不一定要是’√’或空白

    dword      dwitemdata;//由english翻譯為:應用程序定義的與菜單項相關的值(我也不明白)

lptstr       dwtypedata; //菜單資源內容指針,指向string or bitmap or separator資源

uint          cch; //若菜單項為mft_string類型,則此項為dwtypedata長度

hbitmap     hbmpitem;//在調試程序時發現有此一項

} menuiteminfo, far *lpmenuiteminfo;

參考資料:    msdn98(microsoft)       ms sdk help files/win32 developer’s references(inprise/borland)

                    (附錄1為上述api在pb中的declare文本)

與menu操作相關的windows api functions還比較多,可適度參考,動態庫:user32.dll。

 

4、  其它:

a、.我在pb7中調用這些windows功能,但在調試至getmenuiteminfo時,單步運行卻停滯不前,約

30小時后,我進行了如下操作:

a1、打開一dos窗口,運行tdump c:/windows ystem/user32.dll>user32.txt(tdump.exe為inprise公司的應用程序)

a2、回到windows中,以記事本打開user32.txt,發現其中并無getmenuiteminfo,但有getmenuiteminfoa,若在vb中調用過win api,則可猜測此為何物。

a3、將getmenuiteminfo改寫(或alias)成getmenuiteminfoa,便ok 了!

b、菜單項命令標識符作用

   在調用getmenuiteminfoa之后,其值保存在menuiteminfo::wid中。

   設現在獲得一菜單項信息存儲于menuiteminfo型結構體mii中,其部分內容為:

   mii.cbsize=48

   mii.dwtypedata=”打開文件”

   mii.wid=10001

   mii.fstate=enabled

          mii.ftype=mft_string      

對應函數引用標識

命令標識符wid

openfile()

10001

closefile()

10002

 


wid=10001
 

 

  

c、在上述getmenuiteminfoa調用時,需對menuiteminfo的如下域賦值:

       menuiteminfo::cbsize

       menuiteminfo::fmask

    menuiteminfo::dwtypedata

    menuiteminfo:: cch

    其中menuiteminfo::fmask可為如下常數值的組合(在相關資料中很難查到這些常數數值)

       miim_state        (= 1)                                          miim_id                   (= 2)

       miim_submenu (= 4)                                           miim_checkmarks  (= 8)

       miim_type         (=16)                                         miim_data                (=32)

         

 

附:

1、  相關api及結構體在pb中的declare

function long getmenu(long hwnd     ) library "user32.dll"

function long getsubmenu(long hmenu,long npos) library "user32.dll"

function long getmenuitemcount(long hmenu) library "user32.dll"

function long enablemenuitem(long hmenu,ulong uidenableitem, ulong uenable)library "user32.dll"

function long getmenuiteminfoa(long hmenu, ulong uitem, long fbyposition,ref menuiteminfo mii)library "user32.dll"

function long drawmenubar(long hwnd) library "user32.dll"

 

global type menuiteminfo from structure

       unsignedlong          cbsize

       unsignedlong          fmask

       unsignedlong          ftype

       unsignedlong          fstate

       unsignedlong          wid

       long        hsubmenu

       long        hbmpchecked

       long        hbmpunchecked

       long        dwitemdata

       string             dwtypedata

       unsignedlong          cch

       long        hbmpitem

end type

 

2、pb代碼,根據需要,不同于c++代碼(節選,有修改)

public function int enummenuenditems (long hwnd,int ins_upd)

long hm

constant int ins=0

if hwnd=0 or isnull(hwnd) then return 0

hm=getmenu(handle(wmdi))

if ins_upd=ins then

       delete from sec_fun using trans;

       if trans.sqlcode=-1 then goto error

end if

 

if ismenu(hm)=0 then return -1

if fun(hm,ins_upd)  =-1 then goto error

if trans.sqlcode=-1 then goto error

commit using trans;

delete from sec_auth where id_fun not in (select id_fun from sec_fun) using trans;//對

if trans.sqlcode=-1 and ins_upd=ins then messagebox("","某些操作可能不再存在,但用戶仍然擁有該項操作權限,請手動刪除!")

return 0

 

error:

rollback using trans;

return –1

end fuction

 

private function int findmenuitem (hmenu hmenu,int ins_upd )

//ins=0

//upd=1

int i,c

long hm,res

 

menuiteminfo mii

mii.cbsize=48

mii.fmask=54

mii.ftype=0

 

c=getmenuitemcount(hmenu)

for i=0 to c -1

       mii.dwtypedata="                                                                  "

       mii.cch=63

       if not isvalid(mii) then return -1

       res=getmenuiteminfoa(hmenu,i,255,mii)

       if res=0 then continue

       if mii.hsubmenu=0 then

              if not isnull(mii.dwtypedata) then

                     choose case ins_upd

                            case 0

insert into sec_fun(id_fun,des_fun,handle) values (:mii.wid,:mii.dwtypedata,:hmenu) using trans;//保存’純’菜單項的信息

                                   if trans.sqlcode=-1 then return -1

                            case 1

                                   update sec_fun set handle=:hmenu where id_fun=:mii.wid using trans;

                                   if trans.sqlcode=-1 then return -2                             

                     end choose

              else

                     continue

              end if

       else

              res= findmenuitem (mii.hsubmenu,ins_upd)

              if res<>0 then return res

       end if  

next

return 0

end function
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 丹阳市| 唐河县| 马尔康县| 阿坝| 揭阳市| 胶州市| 怀仁县| 南阳市| 桂东县| 陆良县| 安乡县| 盖州市| 克拉玛依市| 江阴市| 贵南县| 喜德县| 梅河口市| 黄梅县| 缙云县| 璧山县| 霍州市| 汤阴县| 阿鲁科尔沁旗| 辉南县| 建阳市| 岳池县| 新民市| 高安市| 荔波县| 岳西县| 朔州市| 平泉县| 郑州市| 慈溪市| 吴旗县| 莱州市| 洛川县| 永靖县| 彭水| 麻阳| 北辰区|