C++Builder創(chuàng)建上下文菜單擴(kuò)展處理器

字號(hào):

當(dāng)用戶右擊一個(gè)shell對(duì)象時(shí),shell會(huì)顯示它的上下文菜單。文件系統(tǒng)對(duì)象有大量的標(biāo)準(zhǔn)菜單項(xiàng),如"剪切"和"拷貝",這些都是缺省的菜單項(xiàng)。如果對(duì)象是一個(gè)文件,是文件類的成員,就能夠在注冊(cè)表里指定附加的菜單項(xiàng)。Shell檢查注冊(cè)表,看看文件類型是否與一些上下文菜單handler相關(guān)聯(lián),如果是,shell會(huì)咨詢這些handler是否添加額外的菜單項(xiàng)。
    上下文菜單handler是一種shell擴(kuò)展handler,它添加命令到已有的上下文菜單中。上下文菜單handler都與特定的文件類相關(guān)聯(lián),并且在顯示這類文件的成員的上下文菜單時(shí)調(diào)用。通過(guò)實(shí)現(xiàn)和注冊(cè)這樣一個(gè)handler,能夠動(dòng)態(tài)地添加菜單項(xiàng)到對(duì)象的上下文菜單上,從而為特殊的對(duì)象定制菜單。
    上下文菜單Handler的工作原理
    作為一種shell擴(kuò)展handler,上下文菜單handler同所有其它handler一樣, 是進(jìn)程內(nèi)COM 對(duì)象,即對(duì)象作為動(dòng)態(tài)連接庫(kù) (DLL)實(shí)現(xiàn)。除了IUnknown接口外,上下文菜單還必須導(dǎo)出IShellExtInit和IContextMenu接口,作為選擇,上下文菜單也能導(dǎo)出IContextMenu2和IContextMenu3,這些接口可以實(shí)現(xiàn)自畫(huà)菜單項(xiàng)。
    IShellExtInit接口僅僅被shell用來(lái)初始化handler,主要的操作通過(guò)handler的IContextMenu接口進(jìn)行。Shell首先調(diào)用IContextMenu::QueryContextMenu,傳送一個(gè)HMENU句柄,這個(gè)方法用它來(lái)增加上下文菜單。如果用戶亮選了這些新添加的某個(gè)命令項(xiàng), IContextMenu::GetCommandString將被調(diào)用,以取得這條菜單的幫助信息,把它顯示在資源管理器的狀態(tài)條上。如果用戶單擊了handler的條目,shell調(diào)用IContextMenu::InvokeCommand,從而handler能夠執(zhí)行合適的操作。
    實(shí)現(xiàn)IContextMenu接口
    1、實(shí)現(xiàn)QueryContextMenu方法
    Shell通過(guò)調(diào)用IContextMenu::QueryContextMenu,允許handler把它的菜單項(xiàng)添加到菜單中。QueryContextMenu共有5個(gè)參數(shù),各參數(shù)作用如下:
    1) Hmenu:HMENU類型,表示上下文菜單的句柄。
    2) IndexMenu:第一個(gè)被添加的菜單索引。
    3) IdCmdFirst:添加的菜單ID初值。
    4) idCmdLast:添加的菜單ID值。
    5) uFlags:與上下文菜單相關(guān)的狀態(tài)標(biāo)志,共有3種,如下:
    CMF_DEFAULTONLY 用戶選擇了缺省的命令,通常是通過(guò)雙擊對(duì)象產(chǎn)生。QueryContextMenu 在把控制返回給shell前不應(yīng)該修改菜單。
    CMF_NODEFAULT 菜單沒(méi)有缺省的條目,這個(gè)方法應(yīng)該把它的命令加到菜單中。
    CMF_NORMAL 上下文菜單將被正常顯示,這個(gè)方法應(yīng)該把它的命令加到菜單中。
    必須注意的是,任何添加的菜單項(xiàng)的ID必須落在idCmdFirst和idCmdLast兩個(gè)參數(shù)中間,通常,添加的第一個(gè)菜單項(xiàng)ID設(shè)為idCmdFirst,以后每添加一個(gè)菜單項(xiàng),就把ID加1,這樣,即使shell調(diào)用了不止一個(gè)handler,也可以確保菜單項(xiàng)的ID不超過(guò)idCmdLast和可能的ID值。
    在ID和idCmdFirst之間,菜單項(xiàng)ID的command offset(命令偏移)是不同的,應(yīng)該保存handler添加到上下文菜單中的每個(gè)菜單項(xiàng)的offset,因?yàn)槿绻鹲hell按順序調(diào)用GetCommandString或者InvokeCommand,可以使用它來(lái)鑒別菜單項(xiàng)的ID.
    還應(yīng)該為每一個(gè)添加的命令賦予一個(gè)verb.Verb是語(yǔ)言獨(dú)立的字符串,當(dāng)調(diào)用InvokeCommand時(shí),常常用verb來(lái)代替偏移以鑒別命令。
    QueryContextMenu 方法使用InsertMenu或InsertMenuItem 添加新的菜單項(xiàng),然后返回一個(gè)嚴(yán)格設(shè)置為SEVERITY_SUCCESS的HRESULT值,把它的值設(shè)置為被分配的的命令I(lǐng)D.例如,假如idCmdFirst是5,添加了3個(gè)菜單項(xiàng),ID分別是5,7,8,則返回值應(yīng)該是MAKE_HRESULT(SEVERITY_SUCCESS, 0, 8 - 5 + 1)。