介紹
IE除了允許我們添加自定義的主菜單外,還允許在右鍵菜單中添加自定義的菜單,。很多著名的網(wǎng)絡(luò)軟件如網(wǎng)絡(luò)螞蟻,、網(wǎng)
際快車等都在右鍵菜單中添加了可以用來下載文件的快捷菜單。IE的右鍵菜單擴(kuò)展同其它COM擴(kuò)展不太一樣,其它擴(kuò)展只要在注冊表中填寫一定的配置信息就可
以使用了,而右鍵菜單擴(kuò)展必須由一個JavaScript腳本來創(chuàng)建并調(diào)用其中的方法。由于我們的COM組件必須能從腳本語言中創(chuàng)建,因此右鍵菜單擴(kuò)展的
必須是一個Automation(自動化)組件,也就是說除了IUnknown接口外,還必須支持IDispatch接口。幸好,Delphi提供了內(nèi)置
的自動化COM組件的支持,我們只需要從TAutoObject而不是標(biāo)準(zhǔn)的TComObject派生COM組件就可以了。
經(jīng)常使用IE復(fù)制粘貼網(wǎng)頁上的信息,我發(fā)現(xiàn)IE右鍵菜單中的復(fù)制命令不是很方便,比如當(dāng)在一個超鏈接上激活右鍵菜單,會發(fā)現(xiàn)只有復(fù)制快捷方式可以使用,而
復(fù)制菜單為灰色被禁用狀態(tài),而有時我不僅想復(fù)制超鏈接本身,還想復(fù)制它的文本,這時我只能是選中鏈接的文本,然后再點(diǎn)復(fù)制,這很不方便。下面我們就來創(chuàng)建
一個右鍵菜單擴(kuò)展,允許復(fù)制超級鏈接的文本。
創(chuàng)建COM組件
新建一個ActiveX Library項(xiàng)目,保存為IEContext.dpr,然后使用命令 File |
New … | ActiveX | Automation
Object創(chuàng)建一個名為TIEContextMenu的自動化對象,保存為CIEContextMenu.pas文件。接下來選中Tools |
Environment Options命令,激活I(lǐng)DE配置管理界面,切換到Type Library頁面,設(shè)定類型庫語言為Pascal,見下圖:

設(shè)定為Language選項(xiàng)為Pascal后,則Type Library編輯器會使用我們熟悉的Pascal語言而不是IDL語言來描述COM的接口定義。
然后使用View | Type Library激活COM組件的類型庫編輯器,添加接口方法CopyUrlText,如下圖所示:

CopyUrlText將被用來把連接只有一個參數(shù),就是UrlText,這個參數(shù)會由后面我們編寫的腳本語句傳遞過來。完成的COM組件實(shí)現(xiàn)如下:
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
//將鏈接文本復(fù)制到剪貼板上
Clipboard.AsText:=UrlText;
end;
注冊擴(kuò)展
要想使右鍵菜單擴(kuò)展生效,必須填寫下列注冊表項(xiàng):
1.
在HKEY_CURRENT_USER\Software\Microsoft\Internet
Explorer\MenuExt關(guān)鍵字下添加內(nèi)容為要創(chuàng)建的右鍵擴(kuò)展菜單項(xiàng)的標(biāo)題文本關(guān)鍵字。文本中可以包含&字符用來指定菜單的快捷方式。
2. 設(shè)定標(biāo)題文本關(guān)鍵字的默認(rèn)值為包含腳本語句的html文件,當(dāng)用戶點(diǎn)擊菜單項(xiàng)時,IE會執(zhí)行html文件中的腳本,而我們將在腳本中創(chuàng)建自動化對象,并將鏈接文本作為參數(shù)調(diào)用自動化對象的方法。
3.
復(fù)制鏈接文本只對鏈接有意義,而對于其它html頁面中的元素?zé)o意義,我們可以在注冊表中HKEY_CURRENT_USER\Software
\Microsoft\Internet
Explorer\MenuExt\<菜單標(biāo)題>關(guān)鍵字下添加一個可選的二進(jìn)制值Contexts值來指定菜單擴(kuò)展顯示的上下文。下表是上下
文的列表:
上下文
|
值(16進(jìn)制)
|
默認(rèn)
|
0x1
|
圖像
|
0x2
|
控制
|
0x4
|
表格
|
0x8
|
文本選區(qū)
|
0x10
|
錨點(diǎn)
|
0x20
|
超級鏈接屬于上下文中的錨點(diǎn),所以需要設(shè)定contexts的值為32(等于16進(jìn)制的20)。
下面就是實(shí)現(xiàn)注冊的類工廠的實(shí)現(xiàn):
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('
¸′復(fù)制鏈接文本', ExtractFilePath(GetDllName)+'copyurl.htm',32)
else
RemoveExtMenuItem('
¸′復(fù)制鏈接文本');
end;
initialization
TIEContextMenuFactory.Create(ComServer, TIEContextMenu, Class_IEContextMenu,
ciMultiInstance, tmApartment);
end.
腳本語句
完成了COM組件的編寫,剩下的任務(wù)就是編寫驅(qū)動COM組件的VBScript語句的編寫了,下面是copyurl.htm的內(nèi)的VBScript的內(nèi)容:
<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>
簡單介紹一下腳本的處理流程,當(dāng)IE加載copyurl.htm時,會自動調(diào)用OnContextMenu過程,在這個過程中,我們可以通過變量
external.menuArguments獲得IE的IDispatch接口,通過external.menuArguments.event可以進(jìn)
一步獲得IE的點(diǎn)擊事件的信息,包括用戶點(diǎn)擊的位置(X,Y坐標(biāo)可以通過ClientX和ClientY屬性獲得)。同時可以從IE的當(dāng)前頁面中通過
external.menuArguments.document.elementFromPoint方法獲得被點(diǎn)中的HTML元素,如果元素類型為
HTMLAnchorElement,則表示它是一個鏈接對象,則元素的innerText屬性就對應(yīng)的鏈接的標(biāo)題文本,這時就調(diào)用CopyLink子過
程,在CopyLink中調(diào)用CreateObject(‘IEContext.IEContextMenu’)
來創(chuàng)建我們的菜單擴(kuò)展對象,其中IEContext.IEContextMenu是擴(kuò)展對象的ProgID,是由項(xiàng)目的名稱+去掉T的擴(kuò)展對象的類名組合
出來的。最后將獲得的Url文本作為參數(shù)調(diào)用擴(kuò)展對象的CopyUrlText就可以了,菜單對象會完成將文本放到系統(tǒng)的剪貼板中的工作。
總結(jié)
使用菜單命令Run | Register ActiveX
Server注冊復(fù)制鏈接文本擴(kuò)展,然后打開光盤中的download.htm文本,選中一個鏈接,點(diǎn)擊右鍵菜單,執(zhí)行“復(fù)制鏈接文本”后,將復(fù)制的結(jié)果
粘貼到記事本中,然后在執(zhí)行復(fù)制快捷方式,同樣將復(fù)制的結(jié)果粘貼到剪貼板中,得到的結(jié)果見下圖:

原文:http://www.codesky.net/article/doc/200801/2008011610823724.htm
新浪微博:http://t.sina.com.cn/androidguy 昵稱:李寧_Lining