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

首頁 > 系統(tǒng) > Linux > 正文

基于COM接口的Shell擴(kuò)展技術(shù)應(yīng)用

2024-08-27 23:57:46
字體:
供稿:網(wǎng)友

前言:隨著技術(shù)的不斷完善,微軟Windows操作系統(tǒng)已成為當(dāng)前個人計算機(jī)應(yīng)用領(lǐng)域的主流操作系統(tǒng)。Windows操作系統(tǒng)提供了頗受用戶喜愛的圖形用戶界面(GUI),微軟為Windows的這個戶界面保留了可擴(kuò)充性,它使得基于32位的Windows應(yīng)用程序可以通過多種方式來增強(qiáng)系統(tǒng)所提供的操作環(huán)境(也稱為外殼,英文名稱:Shell)。 通過對外殼的擴(kuò)展,開發(fā)人員可以為用戶提供其他的文件對象操作方式,或者簡化文件系統(tǒng)和網(wǎng)絡(luò)的瀏覽,或者使用戶能更方便地調(diào)用文件系統(tǒng)中對各種對象進(jìn)行處理的工具。為了說明基于COM接口技術(shù)的外殼擴(kuò)展技術(shù),本文首先編寫一個簡單的音頻播放器,然后編寫幾個外殼擴(kuò)展處理程序方便用戶對指定文件的操作。

一、外殼編程的方法

編寫外殼擴(kuò)展(以下簡稱Shell)的應(yīng)用程序有兩種方法,第一種外殼擴(kuò)展是指無需編程即可實(shí)現(xiàn)的Shell擴(kuò)展,只需要修改相應(yīng)的注冊表?xiàng)l目就可以讓Shell按照我們的意愿行事。第二種Shell擴(kuò)展需要編程來實(shí)現(xiàn),它的功能比第一種Shell擴(kuò)展要強(qiáng)大得多,在本文中提到的Shell擴(kuò)展所指的就是這一種。

Windows中Shell擴(kuò)展處理程序都是基于COM接口,它通過特定的COM接口與Windows Shell進(jìn)行正常的交互。為了讓W(xué)indows Shell能找到擴(kuò)展處理程序并與之交互,Windows Shell擴(kuò)展處理程序需要遵循一定的規(guī)則,這個規(guī)則也是編寫Windows Shell擴(kuò)展處理程序時所要遵循的設(shè)計思路。這個規(guī)則包括兩個方面:(1)Windows Shell擴(kuò)展處理程序應(yīng)該在注冊表中預(yù)先設(shè)定的位置登記自己,以便Windows Shell能找到它;

(2)Windows Shell擴(kuò)展處理程序應(yīng)該實(shí)現(xiàn)Windows Shell知道的幾個特定的COM接口,以便與Windows Shell進(jìn)行正常的交互。

編程實(shí)現(xiàn)Shell擴(kuò)展一般按如下步驟:(1)創(chuàng)建一個服務(wù)器項(xiàng)目(通常為DLL);(2)為項(xiàng)目添加一個實(shí)現(xiàn)特定Shell接口的COM類;(3)為該COM類實(shí)現(xiàn)一個類工廠;(4)為服務(wù)器實(shí)現(xiàn)一些框架性的代碼;(5)編譯鏈接以生成COM服務(wù)器;(6)編輯需要的注冊文件;(7)測試和調(diào)試Shell擴(kuò)展程序。

二、外殼擴(kuò)展編程實(shí)例

由于編寫外殼擴(kuò)展處理程序的基本步驟是相同的,所以本文僅給出了編寫上下文相關(guān)菜單處理程序的詳細(xì)編寫過程。關(guān)于文件類的上下文相關(guān)菜單,當(dāng)用戶用鼠標(biāo)右鍵單擊Shell名字空間中某個元素時(如某文件、目錄、服務(wù)器、工作組等,本文中特指AC-3音頻文件),Shell將生成此類元素的缺省上下文相關(guān)菜單(注意不同的文件對象生成缺省菜單是不一樣的),Shell會搜索注冊表,裝載此類文件對象所登記的上下文相關(guān)菜單擴(kuò)展,以便讓這些擴(kuò)展程序向已生成的上下文相關(guān)菜單中加入另外一些定制的菜單項(xiàng)。如果要為某個文件類對象增加一個上下文相關(guān)菜單擴(kuò)展程序,需要在Windows注冊表的下列位置進(jìn)行注冊:

HKEY_CLASSES_ROOT

<.擴(kuò)展名>=<文件類描述>

...... 

<文件類描述> 

Shellex

ContextMenuHandlers

ContextMenuHandler_Name={該上下文相關(guān)菜單處理程序GUID }

需要說明的是,還需要為上下文相關(guān)菜單處理程序進(jìn)行登記,以便Shell能夠知道在哪里找到處理程序:

HKEY_CLASS_ROOT 

CLSID

 {該上下文相關(guān)菜單處理程序GUID}=<處理程序描述>

  InProcServer32=<服務(wù)器所在完整路徑>

 "Threading Model"="Apartment"

解決這個問題后,剩下的問題就是Windows Shell與上下文相關(guān)菜單處理程序交互問題,這就需要上下文相關(guān)菜單處理程序在代碼中實(shí)現(xiàn)兩個Shell知道的接口,即IContextMenu接口和IShellExtInit接口。IShellExtInit接口只有一個成員函數(shù),即Initialize,當(dāng)Shell決定對選定調(diào)用上下文相關(guān)菜單處理程序時,它會首先調(diào)用IshellExtInit接口的Initialize方法,以要求處理程序?qū)ψ约哼M(jìn)行初始化。IContexMenu接口中定義了三個方法,它們分別是QueryContexMenu、InvokeCommand和GetCommandString()。當(dāng)用戶用鼠標(biāo)右鍵單擊文件對象時,Shell將要顯示出其上下文相關(guān)菜單。

這時系統(tǒng)將此文件對象的上下文相關(guān)菜單的地址傳給此上下文相關(guān)菜單處理程序。但在處理程序中只應(yīng)用此地址來向上下文相關(guān)菜單中加入菜單項(xiàng),而不應(yīng)修改或刪除已有的菜單項(xiàng),因?yàn)榭赡苓€會有其他處理程序在此前或此后向菜單中加入菜單項(xiàng)。最后,當(dāng)所有的上下文相關(guān)菜單處理程序都被調(diào)用后,Shell再向此菜單中加入它的菜單選項(xiàng)。菜單中的菜單項(xiàng)可以是與特定類相關(guān)的(即適用于某種類型的所有文件),也可以是與某特定事例相關(guān)的(即只適用于單個文件對象)。

當(dāng)Windows Shell將要為某文件對象顯示其上下文相關(guān)菜單(或顯示菜單條上的File菜單)時,系統(tǒng)將調(diào)用上下文相關(guān)菜單處理程序中IContextMenu接口的QueryContexMenu成員函數(shù)。此時上下文相關(guān)菜單處理程序可通過調(diào)用InsertMenu函數(shù)按位置(MF_POSITION)直接將想要加入的菜單選項(xiàng)加入列上下文相關(guān)菜單中。加入的菜單項(xiàng)可以是通常的字符串(MF_STRING),也可以是位圖(MF_BITMAP)。當(dāng)用戶選中某個由上下文相關(guān)菜單處理程序維護(hù)的菜單選項(xiàng)時,Shell將調(diào)用此處理程序IContextMenu接口的InvokeCommand成員函數(shù)以使處理程序有機(jī)會處理用戶選擇的命令。若對某類文件登記有多個上下文相關(guān)菜單處理程序,則各命令的順序是由文件類下的ContextMenuHandlers關(guān)鍵字決定。

上下文相關(guān)菜單處理程序的具體的編寫過程如下:

(1)創(chuàng)建一個空的DLL項(xiàng)目

上下文相關(guān)菜單處理程序仍將以進(jìn)程內(nèi)COM服務(wù)器的形態(tài)存在,因此需要用為上下文相關(guān)菜單處理程序創(chuàng)建應(yīng)該空的DLL項(xiàng)目,本文將項(xiàng)目命名為ContextMenuExt;

(2)為項(xiàng)目添加一個類CContextMenuExt

首先還是來考慮DLL需要實(shí)現(xiàn)的功能,上下文相關(guān)菜單處理程序需要一個類來實(shí)現(xiàn)COM接口IContextMenu和IShellExtInit。為此,筆者給項(xiàng)目添加一個類CContextMenuExt。添加了CContextMenuExt類之后,從項(xiàng)目的文件視圖可以看出項(xiàng)目中多了兩個文件,它們分別是類CContextMenuExt的頭文件(CContextMenuExt.h)和源代碼文件(CcontextMenuExt.cpp)。接下來修改CContextMenuExt的類聲明,使之繼承IContextMenu和IShellExtInit接口,并添加3個成員變量m_cRef、m_pDataObj、m_szFileName和一個受保護(hù)的成員函數(shù)。在CContextMenuExt類的公有聲明部分,定義了類的構(gòu)造函數(shù)、析構(gòu)函數(shù)以及為了實(shí)現(xiàn)IUnknown、IContextMenu和IShellExtInit接口而設(shè)的成員函數(shù)。之所以要實(shí)現(xiàn)IUnknown接口,是因?yàn)镮Unknown接口是一切接口的祖先。除繼承了IUnknown接口的3個基本方法之外,IContextMenu接口還定義了真正實(shí)現(xiàn)菜單擴(kuò)展的QueryContextMenu、InvokeCommand和GetCommandString方法,關(guān)于這些方法的作用,前面已經(jīng)做了簡要的說明,這里不在贅述。

在CContextMenuEx類的受保護(hù)部分,聲明了一個成員函數(shù)ClickSample,這個函數(shù)正是為了處理添加的菜單命令而設(shè)的。定義了一個數(shù)組m_szFileName用以保存選中文件的完整路徑;

(3)為類CContextMenuExt添加實(shí)現(xiàn)代碼

為了清楚起見,筆者將逐步給出其各個成員函數(shù)的說明。首先來看看CContextMenuExt類的構(gòu)造函數(shù)。在構(gòu)造函數(shù)中對兩個成員變量進(jìn)行了初始化,其中m_cRef表示對該類的引用計數(shù),m_pDataObj則表示系統(tǒng)傳送過來的IDataObject接口的指針,將在后面使用。g_nDllRefCount是DLL中需要定義的一個全局變量,用來記錄整個DLL被引用的次數(shù),并將以此決定是否運(yùn)行Shell對DLL服務(wù)器進(jìn)行卸載。當(dāng)用戶選中了某個AC3文件類的上下文菜單DLL服務(wù)器維護(hù)的菜單選項(xiàng)時,Shell將調(diào)用CContextMenuExt類中IContextMenu接口的InvokeCommand成員函數(shù)來處理用戶的選擇。此處CContextMenuExt的做法是通過參數(shù)lpcmi的lpVerb找到用戶選擇的菜單的標(biāo)志符,并調(diào)用相應(yīng)的成員函數(shù)進(jìn)行處理。在本文中這個成員函數(shù)啟動AC3播放器播放存放在m_szFileName數(shù)組中的文件;

(4)為項(xiàng)目添加另一個類CcontextMenuExtFactory。Dll中有了CContextMenuExt類之后,還需要一種手段來創(chuàng)建DLL中的這個功能類。于是便需要添加另一個類CContextMenuExtFactory來作為類CContextMenuExt類工廠。所謂"類工廠",是專門用來生產(chǎn)別的功能類的COM對象。它需要實(shí)現(xiàn)IClassfactory接口,當(dāng)然也需要實(shí)現(xiàn)IUnknown接口。其中的CreateInstance和LockServer兩個成員函數(shù)是IClassFactory接口要求其實(shí)現(xiàn)類必須實(shí)現(xiàn)的方法;

(5)為服務(wù)器實(shí)現(xiàn)一些框架性代碼

需要為整個DLL定義一個引用計數(shù)變量g_nDllRefCount和一個用來記錄DLL的模塊句柄的變量g_hThisDll。作為Win32的動態(tài)鏈接庫,需要為DLL實(shí)現(xiàn)幾個標(biāo)準(zhǔn)函數(shù),如DLLMain、DLLCanUnloadNow、DLLGet ClassObject等,首先為這些函數(shù)添加原型。函數(shù)DllMain是所有Win32動態(tài)鏈接庫的入口函數(shù)。在DLL的全局變量g_hThisDll中保存進(jìn)程的實(shí)例標(biāo)識hInstance以備后用。當(dāng)系統(tǒng)的進(jìn)程或線程初始化或者被終止時,Dll中的DllMain函數(shù)即被系統(tǒng)以相應(yīng)的參數(shù)調(diào)用。此外,當(dāng)別的進(jìn)程或者線程調(diào)用LoadLibrary函數(shù)裝載Dll或者調(diào)用FreddLibray函數(shù)卸載Dll時,DllMain函數(shù)也會被系統(tǒng)調(diào)用。函數(shù)DllCanUnloadNow通過全局變量g_nDllRefCount來決定實(shí)現(xiàn)該函數(shù)的DLL是否正在使用之中,如果不是,調(diào)用者就可以將該DLL安全地從內(nèi)層中卸載。DllGetClassObject函數(shù)被用來獲取DLL中定義的類的對象實(shí)例。DllGetClassObject函數(shù)通常在CoGetClassObject函數(shù)中被調(diào)用。

(6)編輯上下文菜單處理程序的注冊文件制作一個 .reg文件,按照一定的格式書寫完后,在操作系統(tǒng)中雙擊這個文件,文件表的注冊條目被合并到注冊表中,這里需要強(qiáng)調(diào)的是該處理程序的類和接口的全局唯一標(biāo)志符是使用Visual C++6.0提供的UUIDGEN實(shí)用工具生成的。還需要說明的,由于筆者使用的操作系統(tǒng)是Windows2000,所以編譯連接好的ContextMenuExt.dll文件應(yīng)放到C:WINNTSystem下.

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 仁布县| 富顺县| 寻乌县| 扎囊县| 葫芦岛市| 渝北区| 永登县| 高阳县| 浠水县| 乐都县| 文登市| 同心县| 福建省| 阿瓦提县| 双峰县| 黄龙县| 建德市| 美姑县| 施秉县| 宁城县| 贺兰县| 赤水市| 射阳县| 正蓝旗| 麻江县| 瑞安市| 广丰县| 买车| 莱阳市| 陇西县| 昌乐县| 龙南县| 乌兰察布市| 南溪县| 北安市| 奎屯市| 中方县| 抚顺县| 海口市| 辽中县| 卢龙县|