隨筆 - 312, 文章 - 14, 評(píng)論 - 1393, 引用 - 0
          數(shù)據(jù)加載中……

          使用Delphi開發(fā)IE按鈕擴(kuò)展

          介紹

          除了可以向IE中添加自定義菜單外,我們還可以向IE的工具條上添加自定義的按鈕。自定義按鈕同自定義菜單COM擴(kuò)展的實(shí)現(xiàn)幾乎一樣, 除了在注冊(cè)時(shí)需要添加的注冊(cè)表項(xiàng)不同。 注意:同菜單擴(kuò)展一樣,自定義的按鈕擴(kuò)展也必須IE5及以后的版本才支持。

           

          創(chuàng)建COM組件

           

          下面我們要?jiǎng)?chuàng)建的IE工具條按鈕要稍微復(fù)雜一些,當(dāng)點(diǎn)擊時(shí),不再只是顯示一個(gè)簡(jiǎn)單的對(duì)話框了,而是讓當(dāng)前瀏覽器瀏覽我的個(gè)人網(wǎng)站 http://hubdog.csdn.net。同前一節(jié)一樣, 首先創(chuàng)建ActiveX Library,保存為IEButton.dpr,然后再新建一個(gè)名為TIEHomeButton的 COM Object,保存向?qū)傻奈募镃IEButton.pas。

           

          同樣的按鈕擴(kuò)展也需要實(shí)現(xiàn)IOleCommandTarget接口,同時(shí)為了能夠調(diào)用IE的功能,能調(diào)用瀏覽器瀏覽指定的網(wǎng)址,我們還需要實(shí)現(xiàn) IObjectWithSite接口。完成的類的定義如下:

          type
            TIEHomeButton = class(TComObject, IOleCommandTarget, IObjectWithSite)
            private
              ShellBrowser: IShellBrowser;
              IE:IWebBrowser;
            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;
              //IObjectWithSite接口定義
              function SetSite(const pUnkSite: IUnknown): HResult; stdcall;
              function GetSite(const riid: TIID; out site: IUnknown): HResult; stdcall;
            end;
           

           

          其中IObjectWithSite接口有SetSite和GetSite方法。其中IE會(huì)在第一次加載工具條按鈕擴(kuò)展時(shí)調(diào)用SetSite,將瀏覽器的
          IShellBrowser作為pUnkSite參數(shù)傳遞進(jìn)來, 我們可以從pUnkSite參數(shù)獲得IServiceProvider接口,并調(diào)用IServiceProvider接口的QueryService獲得 瀏覽器的IWebBrower2接口,然后將IE的接口保存起來,后 面在點(diǎn)擊按鈕時(shí),
          我們需要調(diào)用IWebBrowser2接口的Navigate方法瀏覽我的哈巴狗的小窩網(wǎng)站。

           

          function TIEHomeButton.SetSite(const pUnkSite: IInterface): HResult;
          var
            Service:IServiceProvider;
          begin
            ShellBrowser := pUnkSite as IShellBrowser;
            Service:=ShellBrowser as IServiceProvider;
            Service.QueryService(IWebBrowserApp,IWebBrowser2, IE);
            Result := S_OK;
          end;

           

          IE同時(shí)還會(huì)不時(shí)的調(diào)用GetSite方法來從我們保存的pUnkSite接口獲得指定的riid的接口,

          function TIEHomeButton.GetSite(const riid: TIID;
            out site: IInterface): HResult;
          begin
            if Supports(ShellBrowser, riid, site) then
              Result := S_OK
            else
              Result := E_NOTIMPL;
          end;

           

          如果pUnkSite指針支持該接口,則返回S_OK,否則返回E_ NOTIMPL表示不支持該接口。

          最后,我們需要在IOleCommandTarget接口中實(shí)現(xiàn)Exec方法來執(zhí)行瀏覽網(wǎng)站的功能,IWebBrowser2接口的Navigate方法可以多個(gè)參數(shù), 這里我們只需要指定要瀏覽的Url就可以了,其它參數(shù)都設(shè)置為空(使用EmptyParam預(yù)定義值)。

          function TIEHomeButton.Exec(CmdGroup: PGUID; nCmdID, nCmdexecopt: DWORD;
            const vaIn: OleVariant; var vaOut: OleVariant): HResult;
          begin
            Result := S_OK;
            IE.Navigate('http://hubdog.csdn.net', emptyParam,emptyParam,emptyParam,emptyParam);
          end;

           

          注冊(cè)擴(kuò)展

           

          要想讓IE能夠在啟動(dòng)后正確顯示自定義的工具條按鈕擴(kuò)展,需要在注冊(cè)表中填寫一些配置信息。

          1.         首先要在HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Extensions\項(xiàng)目下新建一個(gè)關(guān)鍵字,名為擴(kuò)展的Guid的字符串形式。

          2.         然后在新建的HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Extensions\<擴(kuò)展的Guid>關(guān)鍵字下再創(chuàng)建一個(gè)名為CLSID 項(xiàng)目,設(shè)定值為{1FBA04EE-3024-11d2-8F1F-0000F87ABD16}。

          3.         然后在HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Extensions\<擴(kuò)展Guid>關(guān)鍵字下添加名為ClsidExtension的字段,這回值為按鈕擴(kuò)展的 Guid的字符串形式。

          4.         默認(rèn)時(shí),一個(gè)新加的擴(kuò)展按鈕不會(huì)馬上顯示在工具條上,但是我們可以在HKEY_LOCAL_MACHINE\Software\Microsoft \Internet Explorer\Extensions\<擴(kuò)展Guid>關(guān)鍵字下添加Default Visible字段,并設(shè)定其值為Yes,這樣IE啟動(dòng)時(shí)會(huì)自動(dòng)顯示我們添加的按鈕,但是要注意如果用戶在添加按鈕前使用了工具條 右鍵菜單中的自定義…命令調(diào)整過工具條按鈕的顯示設(shè)置,則我們的擴(kuò)展按鈕不會(huì)自動(dòng)出現(xiàn)了,必須是通過自定義對(duì)話框來手工添加或者調(diào)用重置按鈕恢復(fù)默認(rèn)設(shè)置 來顯示添加的按鈕,見下圖:

          5.         每個(gè)按鈕都要有一個(gè)顯示字符串,在HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer
          \Extensions\<擴(kuò)展Guid>關(guān)鍵字下添加ButtonText項(xiàng)目,設(shè)定其值為按鈕的標(biāo)題。同時(shí)按鈕還需要指定兩個(gè)
          圖標(biāo),一個(gè)是熱點(diǎn)圖標(biāo)當(dāng)鼠標(biāo)停留在按鈕上時(shí)顯示,一個(gè)正常圖標(biāo)用于平時(shí)顯示。圖標(biāo)的文件和路徑需要寫到
          HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Extensions\<擴(kuò)展Guid>關(guān)鍵字下的HotIcon和
          Icon字段中,值對(duì)應(yīng)于Ico文件,或者可執(zhí)行文件中的圖標(biāo)資源,如果圖標(biāo)是可執(zhí)行文件的資源,還需要指定
          圖標(biāo)資源索引值。結(jié)果示例如下:

          C:\PROGRA~1\AbcSoft\IEPlugin.dll,209或者 c:\IE.ico

           
          創(chuàng)建工具條圖標(biāo)
           

          工具條需要的圖標(biāo)文件是有一定要求的。首先是尺寸要求,每個(gè)按鈕都需要提供20X20和16X16個(gè)像素的圖標(biāo),其中
          20X20的大圖標(biāo)用于平時(shí)顯示, 16X16的圖標(biāo)是用于IE處于全屏幕顯示狀態(tài)時(shí)的界面顯示,見下表示例:

          大小(像素)

          示例

          20x20

          16x16

          其次有顏色上的要求,當(dāng)圖標(biāo)處于熱點(diǎn)狀態(tài)時(shí),推薦使用彩色圖標(biāo),而當(dāng)圖標(biāo)為正常顯示狀態(tài)時(shí),推薦設(shè)定Icon字段
          對(duì)應(yīng)的圖標(biāo)為灰度圖標(biāo)。 同時(shí)微軟推薦提供的圖標(biāo)即有256色的,也有16色的。這里為了簡(jiǎn)便起見,我只使用一個(gè)圖
          標(biāo)用于熱點(diǎn)和正常顯示。

          圖標(biāo)的創(chuàng)建可以使用專業(yè)的圖標(biāo)設(shè)計(jì)器來創(chuàng)建,不推薦使用Delphi自帶的Image Editor工具,因?yàn)镮mage Editor只能
          創(chuàng)建16X16, 32X32大小的圖標(biāo), 不能創(chuàng)建20X20大小的圖標(biāo)。我一般是使用Icon Cool Editor來創(chuàng)建圖標(biāo)。

          這就是我創(chuàng)建的20X20的圖標(biāo),把它保存為Home.ico,為了能將圖標(biāo)文件編譯進(jìn)最后生成COM Server的Dll文件中,
          編寫一個(gè)資源腳本文件Home.rc:

          1234       ICON   Home.ICO

          注意:這里我使用1234作為圖標(biāo)的標(biāo)識(shí)而不是使用一個(gè)更好記的文本串比如Home是因?yàn)镮E只能使用數(shù)字標(biāo)識(shí)的圖標(biāo)
          作為按鈕的圖標(biāo)。使用brcc32 編譯Home.rc為Home.res。注意,在IEButton.dpr中已經(jīng)有了{$R *.RES}這句話表示編
          譯COM Server時(shí)會(huì)將所有的資源文件編譯進(jìn)生成的DLL中。
           
          注冊(cè)過程

          接下來是編寫后的注冊(cè)代碼,都是一些對(duì)注冊(cè)表的操作,注意刪除時(shí)是根據(jù)Guid進(jìn)行刪除的,因?yàn)镚uid是唯一的值:

          //添加工具條按鈕 
          procedure AddToolbarBtn(Visible: Boolean; BtnText, HotIcon,
            Icon, Guid: string);
          var
            Reg: TRegistry;
          begin
            Reg := TRegistry.Create;
            with Reg do
            try
              RootKey := HKEY_LOCAL_MACHINE;
              OpenKey('\Software\Microsoft\Internet Explorer\Extensions\' + Guid, True);
              if Visible then
                WriteString('Default Visible', 'Yes')
              else
                WriteString('Default Visible', 'No');
              WriteString('ButtonText', BtnText);
              WriteString('HotIcon', HotIcon);
              WriteString('Icon', Icon);
              WriteString('CLSID', '{1FBA04EE-3024-11d2-8F1F-0000F87ABD16}');
              WriteString('ClsidExtension', Guid);
              CloseKey;
            finally
              Free;
            end;
          end;
           
          //按Guid刪除按鈕
          procedure RemoveToolbarBtn(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;

          然后編寫COM組件工廠類,調(diào)用注冊(cè)和刪除注冊(cè)表項(xiàng)的方法來實(shí)現(xiàn)COM組件的注冊(cè)和反注冊(cè):

          type
            TIEHomeButtonFactory = class(TComObjectFactory)
            public
              procedure UpdateRegistry(Register: Boolean); override;
            end;
          function GetDllName: string;
          var
            Buffer: array[0..261] of Char;
          begin
            GetModuleFileName(HInstance, Buffer, SizeOf(Buffer));
            Result := string(Buffer);
          end;
           
          procedure TIEHomeButtonFactory.UpdateRegistry(Register: Boolean);
          begin
            inherited;
            if Register then
              AddToolbarBtn(true, 'HomeButton', GetDllName+',1234', GetDllName+',1234', GuidToString(classid))
            else
              RemoveToolbarBtn(GuidToString(classid));
          end;

          上面的GetDllName函數(shù)會(huì)返回編譯后的Dll名稱,在Dll名稱加上',1234'表示使用Dll中標(biāo)識(shí)為1234的圖標(biāo)作為
          按鈕圖標(biāo),這里為了簡(jiǎn)便起見,
          HotIconIcon使用的是同一個(gè)圖標(biāo)。

          至此,我們的按鈕擴(kuò)展算是大功告成了,注冊(cè)擴(kuò)展后,運(yùn)行IE,點(diǎn)擊我們的按鈕,效果如下:

           

          總結(jié)

          本節(jié)中我們主要討論了如何可以同擴(kuò)展的宿主IE瀏覽器進(jìn)行交互,調(diào)用瀏覽器的功能完成我們的需要,通過調(diào)用瀏覽器的接口我們可以實(shí)現(xiàn)一些更加實(shí)用更加復(fù)雜的功能,后面我們將進(jìn)一步探討。





          Android開發(fā)完全講義(第2版)(本書版權(quán)已輸出到臺(tái)灣)

          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:27 銀河使者 閱讀(1399) 評(píng)論(0)  編輯  收藏 所屬分類: delphi

          主站蜘蛛池模板: 茶陵县| 宽城| 金沙县| 临清市| 玉屏| 类乌齐县| 绥江县| 商丘市| 西乡县| 象山县| 伊金霍洛旗| 三台县| 通河县| 兰溪市| 淮滨县| 西充县| 马山县| 泸溪县| 许昌县| 宜阳县| 淮滨县| 金溪县| 漠河县| 易门县| 鹤峰县| 龙南县| 广宗县| 大悟县| 肃南| 新乡县| 顺义区| 长沙县| 综艺| 夹江县| 枣强县| 金乡县| 蒙自县| 正镶白旗| 涡阳县| 高碑店市| 望城县|