使用Delphi開發(fā)IE右鍵菜單擴展
介紹
IE除了允許我們添加自定義的主菜單外,還允許在右鍵菜單中添加自定義的菜單,。很多著名的網絡軟件如網絡螞蟻,、網
際快車等都在右鍵菜單中添加了可以用來下載文件的快捷菜單。IE的右鍵菜單擴展同其它COM擴展不太一樣,其它擴展只要在注冊表中填寫一定的配置信息就可
以使用了,而右鍵菜單擴展必須由一個JavaScript腳本來創(chuàng)建并調用其中的方法。由于我們的COM組件必須能從腳本語言中創(chuàng)建,因此右鍵菜單擴展的
必須是一個Automation(自動化)組件,也就是說除了IUnknown接口外,還必須支持IDispatch接口。幸好,Delphi提供了內置
的自動化COM組件的支持,我們只需要從TAutoObject而不是標準的TComObject派生COM組件就可以了。
經常使用IE復制粘貼網頁上的信息,我發(fā)現IE右鍵菜單中的復制命令不是很方便,比如當在一個超鏈接上激活右鍵菜單,會發(fā)現只有復制快捷方式可以使用,而 復制菜單為灰色被禁用狀態(tài),而有時我不僅想復制超鏈接本身,還想復制它的文本,這時我只能是選中鏈接的文本,然后再點復制,這很不方便。下面我們就來創(chuàng)建 一個右鍵菜單擴展,允許復制超級鏈接的文本。
創(chuàng)建COM組件
新建一個ActiveX Library項目,保存為IEContext.dpr,然后使用命令 File | New … | ActiveX | Automation Object創(chuàng)建一個名為TIEContextMenu的自動化對象,保存為CIEContextMenu.pas文件。接下來選中Tools | Environment Options命令,激活IDE配置管理界面,切換到Type Library頁面,設定類型庫語言為Pascal,見下圖:
設定為Language選項為Pascal后,則Type Library編輯器會使用我們熟悉的Pascal語言而不是IDL語言來描述COM的接口定義。
然后使用View | Type Library激活COM組件的類型庫編輯器,添加接口方法CopyUrlText,如下圖所示:
CopyUrlText將被用來把連接只有一個參數,就是UrlText,這個參數會由后面我們編寫的腳本語句傳遞過來。完成的COM組件實現如下:
type
TIEContextMenu = class(TAutoObject, IIEContextMenu)
protected
procedure CopyUrlText(const UrlText: WideString); safecall;
end;
implementation
uses ComServ, Clipbrd, Dialogs, Sysutils, Windows, Registry;
procedure TIEContextMenu.CopyUrlText(const UrlText: WideString);
begin
//將鏈接文本復制到剪貼板上
Clipboard.AsText:=UrlText;
end;
注冊擴展
要想使右鍵菜單擴展生效,必須填寫下列注冊表項:
1. 在HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt關鍵字下添加內容為要創(chuàng)建的右鍵擴展菜單項的標題文本關鍵字。文本中可以包含&字符用來指定菜單的快捷方式。
2. 設定標題文本關鍵字的默認值為包含腳本語句的html文件,當用戶點擊菜單項時,IE會執(zhí)行html文件中的腳本,而我們將在腳本中創(chuàng)建自動化對象,并將鏈接文本作為參數調用自動化對象的方法。
3. 復制鏈接文本只對鏈接有意義,而對于其它html頁面中的元素無意義,我們可以在注冊表中HKEY_CURRENT_USER\Software \Microsoft\Internet Explorer\MenuExt\<菜單標題>關鍵字下添加一個可選的二進制值Contexts值來指定菜單擴展顯示的上下文。下表是上下 文的列表:
上下文 |
值(16進制) |
默認 |
0x1 |
圖像 |
0x2 |
控制 |
0x4 |
表格 |
0x8 |
文本選區(qū) |
0x10 |
錨點 |
0x20 |
超級鏈接屬于上下文中的錨點,所以需要設定contexts的值為32(等于16進制的20)。
下面就是實現注冊的類工廠的實現:
type
TIEContextMenuFactory = class(TAutoObjectFactory)
public
procedure UpdateRegistry(Register: Boolean); override;
end;
procedure AddExtMenuItem(MenuText, Url: string; Contexts:DWord);
var
reg: TRegistry;
begin
Reg := TRegistry.Create;
with Reg do try
RootKey := HKEY_CURRENT_USER;
OpenKey('\Software\Microsoft\Internet Explorer\MenuExt\' + MenuText, True);
WriteString('', Url);
WriteInteger('contexts', contexts);
CloseKey;
finally
Free;
end;
end;
procedure RemoveExtMenuItem(MenuText: string);
var
reg: TRegistry;
begin
Reg := TRegistry.Create;
with Reg do try
RootKey := HKEY_CURRENT_USER;
DeleteKey('\Software\Microsoft\Internet Explorer\MenuExt\' + MenuText);
finally
Free;
end;
end;
…
procedure TIEContextMenuFactory.UpdateRegistry(Register: Boolean);
begin
inherited;
if Register then
AddExtMenuItem('
¸′復制鏈接文本', ExtractFilePath(GetDllName)+'copyurl.htm',32)
else
RemoveExtMenuItem('
¸′復制鏈接文本');
end;
initialization
TIEContextMenuFactory.Create(ComServer, TIEContextMenu, Class_IEContextMenu,
ciMultiInstance, tmApartment);
end.
腳本語句
完成了COM組件的編寫,剩下的任務就是編寫驅動COM組件的VBScript語句的編寫了,下面是copyurl.htm的內的VBScript的內容:
<script language="VBScript">
Sub CopyLink(UrlText)
On Error Resume Next
set CopyUrl=CreateObject("IEContext.IEContextMenu")
if err<>0 then
MsgBox("CopyUrl not properly installed!"+ vbCrLf+"Please register CopyUrl ")
else
call CopyUrl.CopyUrlText(UrlText)
end if
end sub
Sub OnContextMenu()
set srcEvent = external.menuArguments.event
set EventElement = external.menuArguments.document.elementFromPoint ( srcEvent.clientX, srcEvent.clientY )
if srcEvent.type = "MenuExtAnchor" then
set srcAnchor = EventElement
do until TypeName(srcAnchor)="HTMLAnchorElement"
set srcAnchor=srcAnchor.parentElement
Loop
Call CopyLink(srcAnchor.innerText)
elseif srcEvent.type="MenuExtUnknown" then
set srcAnchor = EventElement
do until TypeName(srcAnchor)="HTMLAnchorElement"
set srcAnchor=srcAnchor.parentElement
if TypeName(srcAnchor)="Nothing" then
Call CopyLink(EventElement.innerText)
exit sub
end if
Loop
Call CopyLink(srcAnchor.innerText)
elseif 1=1 then
MsgBox("Unknown Event Source """ + srcEvent.type + """" + vbCrLf + "Please send description of error to hubdog@263.net")
end if
end sub
call OnContextMenu()
</script>
簡單介紹一下腳本的處理流程,當IE加載copyurl.htm時,會自動調用OnContextMenu過程,在這個過程中,我們可以通過變量 external.menuArguments獲得IE的IDispatch接口,通過external.menuArguments.event可以進 一步獲得IE的點擊事件的信息,包括用戶點擊的位置(X,Y坐標可以通過ClientX和ClientY屬性獲得)。同時可以從IE的當前頁面中通過 external.menuArguments.document.elementFromPoint方法獲得被點中的HTML元素,如果元素類型為 HTMLAnchorElement,則表示它是一個鏈接對象,則元素的innerText屬性就對應的鏈接的標題文本,這時就調用CopyLink子過 程,在CopyLink中調用CreateObject(‘IEContext.IEContextMenu’) 來創(chuàng)建我們的菜單擴展對象,其中IEContext.IEContextMenu是擴展對象的ProgID,是由項目的名稱+去掉T的擴展對象的類名組合 出來的。最后將獲得的Url文本作為參數調用擴展對象的CopyUrlText就可以了,菜單對象會完成將文本放到系統(tǒng)的剪貼板中的工作。
總結
使用菜單命令Run | Register ActiveX Server注冊復制鏈接文本擴展,然后打開光盤中的download.htm文本,選中一個鏈接,點擊右鍵菜單,執(zhí)行“復制鏈接文本”后,將復制的結果 粘貼到記事本中,然后在執(zhí)行復制快捷方式,同樣將復制的結果粘貼到剪貼板中,得到的結果見下圖:

原文:http://www.codesky.net/article/doc/200801/2008011610823724.htm
《Android高薪之路:Android程序員面試寶典 》http://book.360buy.com/10970314.html
新浪微博:http://t.sina.com.cn/androidguy 昵稱:李寧_Lining
posted on 2010-10-02 21:22 銀河使者 閱讀(880) 評論(0) 編輯 收藏 所屬分類: delphi