最近一直在想一個特效,如何達到拖一個文件到網頁裏,瀏覽器不自動跳轉,並且讀出這個文件的信息.嗬嗬,原本想用javascript的,但是想了想,實在是沒什麼頭緒啊,貌似單純的javascript很難實現瀏覽器和係統的交互,於是乎我想起了bho這個玩意,以前一直也沒怎麼重視,不過看來這次要靠他了.
我想大家一直對一些特效很感興趣,比如網頁一打開就會彈出一個廣告,或者一點網頁上的某個鏈接,就會自動打開某個程序(比如迅雷),那麼他們是如何實現的呢,其中很多功能的實現都離不開bho.
關於bho,大家可以百度下,這裏就不細說了,那麼談談如何用vb寫bho吧,其實大多的bho都是用c++或者delphi來實現的,vb的長項不是這個,但是也不是不可以,用vb就是用com嘛,嗬嗬,廢話少說,看具體步驟:
先用文本編輯器寫一個odl文件,保存為IObjectWithSiteTLB.odl,內容如下:
[
uuid(CF9D9B76-EC4B-470D-99DC-AEC6F36A9261),
helpstring("VB IObjectWithSite Interface"),
version(1.0)
]
library IObjectWithSiteTLB
{
importlib("stdole2.tlb");
typedef [public] long GUIDPtr;
typedef [public] long VOIDPtr;
[
uuid(00000000-0000-0000-C000-000000000046),
odl
]
interface IUnknownVB
{
HRESULT QueryInterface(
[in] GUIDPtr priid,
[out] VOIDPtr *pvObj
);
long AddRef();
long Release();
}
[
uuid(FC4801A3-2BA9-11CF-A229-00AA003D7352),
odl
]
interface IObjectWithSite:IUnknown
{
typedef IObjectWithSite *LPOBJECTWITHSITE;
HRESULT SetSite([in] IUnknownVB* pSite);
HRESULT GetSite([in] GUIDPtr priid, [in, out] VOIDPtr* ppvObj);
}
}
代碼的大概意思就是導入庫,並且聲明接口,具體的可以查下odl語法參考.
接著將這個文件拖到MKTYPLIB.EXE(這個文件應該在vb的tools裏,沒有的可以從網上下個)上,記下生成的IObjectWithSiteTLB.tlb文件地址.
下麵打開vb6,新建一個activex dll,引用microsoft internet controls和
你剛才生成的IObjectWithSiteTLB.tlb.
編寫下麵代碼:
Implements IObjectWithSiteTLB.IObjectWithSite
Dim WithEvents IE As InternetExplorer
Dim M_Site As IUnknownVB
Private Sub IE_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)
If InStr(IE.LocationURL, "http://") Then
If InStr(CStr(URL), ":\") Then
Cancel = True
IE.Document.body.innerhtml = IE.Document.body.innerhtml + CStr(URL)
End If
End IfEnd Sub
Private Sub IObjectWithSite_GetSite(ByVal Priid As IObjectWithSiteTLB.GUIDPtr, PPVobj As IObjectWithSiteTLB.VOIDPtr)
M_Site.QueryInterface Priid, PPVobj
End Sub
Private Sub IObjectWithSite_SetSite(ByVal pSite As IObjectWithSiteTLB.IUnknownVB)
Set M_Site = pSite
Set IE = pSite
End Sub
第一行就是對IObjectWithSiteTLB.IObjectWithSite的接口繼承,其他的就是定義類型或者實例化,注意Private Sub IE_BeforeNavigate2裏的代碼就是我要處理文件拖到網頁裏的代碼,注意url就是即將跳轉的地址,在這裏就是你拖的文件的文件路徑.
寫完編譯成dll文件,並且用regsvr32注冊,注冊完後在注冊表裏的HKCR\clisd\下找到你注冊的dll的clisd,在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\下新建一下以剛才那個dll的clisd為名稱的項,這樣就算大功告成了,當你再次打開瀏覽器的時候就會看到效果了.
不過話說回來,從注冊到找clisd再到新建的過程是不是有點麻煩啊,其實這些都是可以用代碼搞定的,下麵我給出代碼,一次性解決問題:
在vb6裏新建一個exe工程,引用windows script host object model對象,
然後編寫以下代碼:
Dim wsh As New WshShell
Dim ta As New TLI.TLIApplication, ti As TLI.TypeLibInfo, tc As TLI.CoClassInfo
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Const PROCESS_ALL_ACCESS = &H1F0FFF
Private Sub Form_Load()
On Error Resume Next
Me.Visible = False
Dim cl As String, pid As Long, h As Long
cl = Command
pid = Shell("cmd /c regsvr32 /s " + cl, vbHide)
h = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
WaitForSingleObject h, -1
cl = Replace(cl, """", "")
Set ti = ta.TypeLibInfoFromFile(cl)
Dim clisd As String
For Each tc In ti.CoClasses
clisd = tc.Guid
wsh.RegWrite "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\" + clisd + "\", Null
Next
MsgBox "complete"
End
End Sub
代碼都是關於com的調用,很好理解,編譯成exe,使用的時候隻需將dll文件拖到這個exe上,它便會為你的dll自動注冊成bho,然後你再打開瀏覽器就行了,很方便吧!
當你想刪除這個bho的時候,隻點擊 瀏覽器工具欄裏的 工具-----管理加載項-----啟用或禁用加載項,再裏麵找到你要禁用的bho,點禁用即可.或者直接到注冊表的HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\下刪除相應dll的clisd即可.
有關vb編寫bho就說到這裏了,有什麼好的方法和經驗還望各位多多分享與交流啊,限於本人水平有限,代碼不妥之處,還望賜教.
本文版权:http://www.ndfweb.cn/news-260.html