隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0
          數據加載中……

          IE菜單擴展

          介紹

          向IE中添加的自定義菜單,可以被用來執行可執行文件,腳本語言和COM對象的方法,對于前兩種執行方式,相對比較簡單,只需要對注冊表進行編程就 可以了,但是能夠執行的功能非常有限,而使用COM組件擴展IE菜單則相對復雜,但是能夠執行的功能也相對是最強大的,所以下面我就主要介紹基于COM的 菜單擴展方式,還要注意的一點是只有IE5及以后的版本才支持菜單的擴展。

          創建COM組件

          對于一個IE菜單項COM組件來說,它最少需要實現IOleCommandTargetCOM接口,如果COM組件還想要對當前IE中顯示的頁面進 行操作的話,就還需要實現IObjectWithSite接口,對于IObjectWithSite接口,我將在后面的工具條按鈕擴展中討論它的實現。

          首先在Delphi中用New | Other命令調出New Items對話框,然后在ActiveX頁面中選擇創建一個新的ActiveX Library,將項目保存為IEMenu.dpr,然后再次調用New | Other | ActiveX命令,新建一個名為TIEHelloWorld的Com Object對象,然后添加IOleCommandTarget接口的方法實現,完成的類的定義如下:

          type
            TIEHelloWorld = class(TComObject, IOleCommandTarget)
            protected
              //IOleCommandTarget方法接口
              function QueryStatus(CmdGroup: PGUID; cCmds: Cardinal;
                prgCmds: POleCmd; CmdText: POleCmdText): HResult; stdcall;
              function Exec(CmdGroup: PGUID; nCmdID, nCmdexecopt: DWORD;
                const vaIn: OleVariant; var vaOut: OleVariant): HResult; stdcall;
            end;

          IOleCommandTarget包含QueryStatusExec兩 個方法,其中文檔上說QueryStatus方法會被IE調用來獲得當前菜單的狀態,我們需要返回OLECMDF_ENABLED或者其它值來表示是否允 許點擊,但是在實際當中,我發現IE從來沒有調用過我的菜單擴展的QueryStatus方法,不過不管怎么說,還是按正常的來實現。

          function TIEHelloWorld.QueryStatus(CmdGroup: PGUID; cCmds: Cardinal;
            prgCmds: POleCmd; CmdText: POleCmdText): HResult;
          begin
            //允許點擊菜單
            prgCmds^.cmdf:=OLECMDF_ENABLED;
            Result := S_OK;
          end;

          當用戶點擊菜單后,IE會調用IOleCommandTarget接口的Exec方法來執行用戶自定義的操作。

          function TIEHelloWorld.Exec(CmdGroup: PGUID; nCmdID, nCmdexecopt: DWORD;
            const vaIn: OleVariant; var vaOut: OleVariant): HResult;
          begin
            Result := S_OK;
            //nCmdI為0時,表示菜單和工具條按鈕被點擊了
            try
              ShowMessage('Hello IE');
            except
              Result:=E_FAIL;
            end;
            //注意下面的話語句會導致AV,不知道為什么?
            //vaOut := Null;
          end;

          Exec方法帶有很多參數,其中IE在調用菜單擴展和工具條按鈕擴展組件的的Exec方法時,會設定nCmdI為0,其它參數對于我們來說,都不需 要關心,只要在成功執行代碼后,返回S_OK,在失敗時返回E_Fail就可以了。實現了IOleCommandTarget接口之后,一個最簡單的IE 菜單擴展就完成了。

          注冊組件

          要想讓IE在啟動后能夠發現菜單擴展COM組件,并加載菜單進行顯示,需要在注冊表中填寫一些配置信息。

          1、 要在HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Extensions\項目下新建一個關鍵字,名為菜單擴展的Guid的字符串形式。

          2、 然后在新建的HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Extensions\<菜單擴展Guid>關鍵字下再創建一個名為ClsidExtension的項目,值也為擴展的Guid。

          3、 然后HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Extensions\<菜單擴展Guid>關鍵字下添加名為MenuText的字符串字段,寫入IE用來顯示菜單擴展的菜單項標題文本。

          4、 我們還可以創建一個MenuStatusBar,IE會在鼠標停留在我們的擴展對應的菜單項時,在IE的狀態條上顯示MenuStatusBar的文本。這個注冊表項不是必須項目,可以省略。

          5、 通常 情況下,IE會在工具菜單下顯示我們的擴展菜單,但是我們也可以創建一個MenuCustomize字段,設定其值為help。這時IE會將我們的菜單放 到幫助主菜單下面。如果我們的菜單擴展是用來向IE中添加上下文幫助的,可以設定這個選項。這個注冊表項同樣也是可以忽略的。

          注意:如果將注冊表位置由HKEY_LOCAL_MACHINE改成HKEY_CURRENT_USER,則菜單擴展會對所有該機器上用戶生效。

          為了實現添加必要的注冊表信息,編寫AddMenuItem方法來實現注冊功能:

          //添加IE菜單
          procedure AddMenuItem(MenuText, StatusBarText, Guid:
            string; HelpMenu: Boolean);
          var
            Reg: TRegistry;
          begin
            Reg := TRegistry.Create;
            with Reg do
            begin
              RootKey := HKEY_LOCAL_MACHINE;
              OpenKey('\Software\Microsoft\Internet Explorer\Extensions\' + Guid, True);
              if HelpMenu then
                WriteString('MenuCostumize', 'help');
              WriteString('CLSID', '{1FBA04EE-3024-11d2-8F1F-0000F87ABD16}');
              WriteString('MenuText', MenuText);
              WriteString('MenuStatusBar', StatusBarText);
              WriteString('ClsidExtension', Guid);
              CloseKey;
              CloseKey;
              Free;
            end;
          end;

          同時我們還要注銷菜單擴展的功能,方法RemoveMenuItem被用來刪除注冊表項,刪除注冊表項是Guid來進行的,因為Guid可以保證唯一

          //刪除IE菜單
          procedure RemoveMenuItem(Guid: string);
          var
            Reg: TRegistry;
          begin
            Reg := TRegistry.Create;
            with Reg do
            begin
              RootKey := HKEY_LOCAL_MACHINE;
              DeleteKey('\Software\Microsoft\Internet Explorer\Extensions\' + Guid);
              free;
            end;

          end;

          最后,我們定義TIEHelloMenuFactory的TComObjectFactory派生類來調用上面的方法實現COM的組件的注冊和注銷:

          type
            TIEHelloMenuFactory = class(TComObjectFactory)
            public
              procedure UpdateRegistry(Register: Boolean); override;
            end;
          { TIEHelloMenuFactory }
           
          procedure TIEHelloMenuFactory.UpdateRegistry(Register: Boolean);
          begin
            inherited;
            if Register then
          //添加到Tools菜單下
          AddMenuItem('HelloIE', 'Hello IE MenuItem', GuidToString(ClassID), False)
            else
              //Todo: 通過Guid進行刪除
              RemoveMenuItem(GuidToString(ClassID));
          end;
           
          initialization
            TIEHelloMenuFactory.Create(ComServer, TIEHelloWorld, Class_IEHelloWorld,
              'IEHelloWorld', '', ciMultiInstance, tmApartment);
          end.

          完成程序后,我們可以在Delphi IDE中使用菜單 Run | Register ActiveX Server和UnRegister ActiveX Server來注冊創建好的菜單擴展,然后啟動IE,運行后的效果示意圖:

          總結

          上面我們介紹了如何創建一個最簡單的菜單擴展,接下來我將探討IE擴展的一些更為高級的技術。





          Android開發完全講義(第2版)(本書版權已輸出到臺灣)

          http://product.dangdang.com/product.aspx?product_id=22741502



          Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


          新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

          posted on 2010-10-02 21:23 銀河使者 閱讀(874) 評論(0)  編輯  收藏 所屬分類: delphi

          主站蜘蛛池模板: 乌拉特前旗| 石林| 临城县| 灵寿县| 通海县| 阿尔山市| 石屏县| 关岭| 东丰县| 南召县| 开鲁县| 阳东县| 鄯善县| 简阳市| 廉江市| 长宁县| 普安县| 武陟县| 青田县| 新源县| 延庆县| 礼泉县| 重庆市| 武陟县| 正镶白旗| 林周县| 珲春市| 双城市| 高陵县| 锡林郭勒盟| 陵川县| 开封市| 吕梁市| 绿春县| 中卫市| 镇康县| 贡山| 高雄县| 新营市| 武乡县| 密云县|