BHO 中 HTMLDocumentEvents2 是怎样使用的?(200分)

  • 主题发起人 主题发起人 payer
  • 开始时间 开始时间
P

payer

Unregistered / Unconfirmed
GUEST, unregistred user!
有例子代码吗?我想获取 MouseDown 事件,来决定是否可以使用 NewWindow2
 
http://www.euromind.com/iedelphi/app.htm
 
用BHO可能会好一些
 
BHO怎样监听下载的东西?
 
unit uKiller;<br><br>{$WARN SYMBOL_PLATFORM OFF}<br><br>interface<br><br>uses<br> &nbsp;Windows, ActiveX, Classes, ComObj, Shdocvw, Dialogs, Variants;<br><br>type<br> &nbsp;TAdKillerBHO = class(TComObject, IObjectWithSite, IDispatch)<br> &nbsp;private<br> &nbsp; &nbsp;FIESite: IUnknown;<br> &nbsp; &nbsp;FIE: IWebBrowser2;<br> &nbsp; &nbsp;FCPC: IConnectionPointContainer;<br> &nbsp; &nbsp;FCP: IConnectionPoint;<br> &nbsp; &nbsp;FCookie: Integer;<br> &nbsp;protected<br> &nbsp; &nbsp;function SetSite(const pUnkSite: IUnknown): HResult; stdcall;<br> &nbsp; &nbsp;function GetSite(const riid: TIID; out site: IUnknown): HResult; stdcall;<br> &nbsp; &nbsp;function GetTypeInfoCount(out Count: Integer): HResult; stdcall;<br> &nbsp; &nbsp;function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult;<br> &nbsp; &nbsp; &nbsp;stdcall;<br> &nbsp; &nbsp;function GetIDsOfNames(const IID: TGUID; Names: Pointer;<br> &nbsp; &nbsp; &nbsp;NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;<br> &nbsp; &nbsp;function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;<br> &nbsp; &nbsp; &nbsp;Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;<br> &nbsp; &nbsp; &nbsp;stdcall;<br> &nbsp; &nbsp;procedure DoBeforeNavigate2(const pDisp: IDispatch; var URL: OleVariant; var Flags: OleVariant;<br> &nbsp; &nbsp; &nbsp;var TargetFrameName: OleVariant; var PostData: OleVariant;<br> &nbsp; &nbsp; &nbsp;var Headers: OleVariant; var Cancel: WordBool);<br> &nbsp;end;<br><br>const<br> &nbsp;AdKillerBHO: TGUID = '{A692062A-11A1-461B-BE98-B520F01F96FC}';<br><br>implementation<br><br>uses ComServ, Sysutils, ComConst;<br><br>var<br> &nbsp;WM_ADKILLER: Cardinal;<br><br>{ TAdKillerBHO }<br><br>procedure TAdKillerBHO.DoBeforeNavigate2(const pDisp: IDispatch; var URL,<br> &nbsp;Flags, TargetFrameName, PostData, Headers: OleVariant; var Cancel: WordBool);<br>var<br> &nbsp;hOwner: THandle;<br>begin<br> &nbsp;if FIE.ToolBar = 0 then<br> &nbsp;begin<br> &nbsp; &nbsp;hOwner := FindWindow('TfrmAdKiller', PAnsiChar('秋风网页广告拦截器1.2'));<br> &nbsp; &nbsp;if hOwner &lt;&gt; 0 then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;FIE.Quit;<br> &nbsp; &nbsp; &nbsp;PostMessage(hOwner, WM_ADKILLER, 0, GlobalAddAtom(PAnsiChar(VarToStrDef(URL, ''))));<br> &nbsp; &nbsp;end;<br> &nbsp;end;<br>end;<br><br>function TAdKillerBHO.GetIDsOfNames(const IID: TGUID; Names: Pointer;<br> &nbsp;NameCount, LocaleID: Integer; DispIDs: Pointer): HResult;<br>begin<br> &nbsp;Result := E_NOTIMPL;<br>end;<br><br>function TAdKillerBHO.GetSite(const riid: TIID;<br> &nbsp;out site: IInterface): HResult;<br>begin<br> &nbsp;if Supports(FIESite, riid, site) then<br> &nbsp; &nbsp;Result := S_OK<br> &nbsp;else<br> &nbsp; &nbsp;Result := E_NOINTERFACE;<br>end;<br><br>function TAdKillerBHO.GetTypeInfo(Index, LocaleID: Integer;<br> &nbsp;out TypeInfo): HResult;<br>begin<br> &nbsp;Result := E_NOTIMPL;<br> &nbsp;pointer(TypeInfo) := nil;<br>end;<br><br>function TAdKillerBHO.GetTypeInfoCount(out Count: Integer): HResult;<br>begin<br> &nbsp;Result := E_NOTIMPL;<br> &nbsp;Count := 0;<br>end;<br><br>procedure BuildPositionalDispIds(pDispIds: PDispIdList; const dps: TDispParams);<br>var<br> &nbsp;i: integer;<br>begin<br> &nbsp;Assert(pDispIds &lt;&gt; nil);<br> &nbsp;for i := 0 to dps.cArgs - 1 do<br> &nbsp; &nbsp;pDispIds^ := dps.cArgs - 1 - i;<br> &nbsp;if (dps.cNamedArgs &lt;= 0) then<br> &nbsp; &nbsp;Exit;<br> &nbsp;for i := 0 to dps.cNamedArgs - 1 do<br> &nbsp; &nbsp;pDispIds^[dps.rgdispidNamedArgs^] := i;<br>end;<br><br>function TAdKillerBHO.Invoke(DispID: Integer; const IID: TGUID;<br> &nbsp;LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo,<br> &nbsp;ArgErr: Pointer): HResult;<br>var<br> &nbsp;dps: TDispParams absolute Params;<br> &nbsp;bHasParams: boolean;<br> &nbsp;pDispIds: PDispIdList;<br> &nbsp;iDispIdsSize: integer;<br>begin<br> &nbsp;pDispIds := nil;<br> &nbsp;iDispIdsSize := 0;<br> &nbsp;bHasParams := (dps.cArgs &gt; 0);<br> &nbsp;if (bHasParams) then<br> &nbsp;begin<br> &nbsp; &nbsp;iDispIdsSize := dps.cArgs * SizeOf(TDispId);<br> &nbsp; &nbsp;GetMem(pDispIds, iDispIdsSize);<br> &nbsp;end;<br> &nbsp;try<br> &nbsp; &nbsp;if (bHasParams) then<br> &nbsp; &nbsp; &nbsp;BuildPositionalDispIds(pDispIds, dps);<br> &nbsp; &nbsp;Result := S_OK;<br> &nbsp; &nbsp;case DispId of<br> &nbsp; &nbsp; &nbsp;250:<br> &nbsp; &nbsp; &nbsp; &nbsp;DoBeforeNavigate2(IDispatch(dps.rgvarg^[pDispIds^[0]].dispval),<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;POleVariant(dps.rgvarg^[pDispIds^[1]].pvarval)^,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;POleVariant(dps.rgvarg^[pDispIds^[2]].pvarval)^,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;POleVariant(dps.rgvarg^[pDispIds^[3]].pvarval)^,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;POleVariant(dps.rgvarg^[pDispIds^[4]].pvarval)^,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;POleVariant(dps.rgvarg^[pDispIds^[5]].pvarval)^,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dps.rgvarg^[pDispIds^[6]].pbool^);<br> &nbsp; &nbsp; &nbsp;253:<br> &nbsp; &nbsp; &nbsp; &nbsp;FCP.Unadvise(FCookie);<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp;Result := DISP_E_MEMBERNOTFOUND;<br> &nbsp; &nbsp;end;<br> &nbsp;finally<br> &nbsp; &nbsp;if (bHasParams) then FreeMem(pDispIds, iDispIdsSize);<br> &nbsp;end;<br>end;<br><br>function TAdKillerBHO.SetSite(const pUnkSite: IInterface): HResult;<br>begin<br> &nbsp;Result := E_FAIL;<br> &nbsp;FIESite := pUnkSite;<br> &nbsp;if not Supports(FIESite, IWebBrowser2, FIE) then Exit;<br> &nbsp;if not Supports(FIE, IConnectionPointContainer, FCPC) then Exit;<br> &nbsp;FCPC.FindConnectionPoint(DWebBrowserEvents2, FCP);<br> &nbsp;FCP.Advise(Self, FCookie);<br> &nbsp;Result := S_OK;<br>end;<br><br>procedure DeleteRegKeyValue(Root: DWORD; Key: string; ValueName: string = '');<br>var<br> &nbsp;KeyHandle: HKEY;<br>begin<br> &nbsp;if ValueName = '' then<br> &nbsp; &nbsp;RegDeleteKey(Root, PChar(Key));<br> &nbsp;if RegOpenKey(Root, PChar(Key), KeyHandle) = ERROR_SUCCESS then<br> &nbsp;try<br> &nbsp; &nbsp;RegDeleteValue(KeyHandle, PChar(ValueName));<br> &nbsp;finally<br> &nbsp; &nbsp;RegCloseKey(KeyHandle);<br> &nbsp;end;<br>end;<br><br>procedure CreateRegKeyValue(Root: DWORD; const Key, ValueName, Value: string);<br>var<br> &nbsp;Handle: HKey;<br> &nbsp;Status, Disposition: Integer;<br>begin<br> &nbsp;Status := RegCreateKeyEx(ROOT, PChar(Key), 0, '',<br> &nbsp; &nbsp;REG_OPTION_NON_VOLATILE, KEY_READ or KEY_WRITE, nil, Handle,<br> &nbsp; &nbsp;@Disposition);<br> &nbsp;if Status = 0 then<br> &nbsp;begin<br> &nbsp; &nbsp;Status := RegSetValueEx(Handle, PChar(ValueName), 0, REG_SZ,<br> &nbsp; &nbsp; &nbsp;PChar(Value), Length(Value) + 1);<br> &nbsp; &nbsp;RegCloseKey(Handle);<br> &nbsp;end;<br> &nbsp;if Status &lt;&gt; 0 then<br> &nbsp; &nbsp;raise EOleRegistrationError.CreateRes(@SCreateRegKeyError);<br>end;<br><br>type<br> &nbsp;TIEAdvBHOFactory = class(TComObjectFactory)<br> &nbsp;public<br> &nbsp; &nbsp;procedure UpdateRegistry(Register: Boolean); override;<br> &nbsp;end;<br><br>{ TIEAdvBHOFactory }<br><br>procedure TIEAdvBHOFactory.UpdateRegistry(Register: Boolean);<br>begin<br> &nbsp;inherited;<br> &nbsp;if Register then<br> &nbsp; &nbsp;CreateRegKeyValue(HKEY_LOCAL_MACHINE, 'Software/Microsoft/Windows/CurrentVersion/explorer/Browser Helper Objects/' + GuidToString(ClassID), '', '')<br> &nbsp;else<br> &nbsp; &nbsp;DeleteRegKeyValue(HKEY_LOCAL_MACHINE, 'Software/Microsoft/Windows/CurrentVersion/explorer/Browser Helper Objects/' + GuidToString(ClassID), '');<br>end;<br><br>initialization<br> &nbsp;TIEAdvBHOFactory.Create(ComServer, TAdKillerBHO, AdKillerBHO,<br> &nbsp; &nbsp;'TAdKillerBHO', '', ciMultiInstance, tmApartment);<br> &nbsp;WM_ADKILLER := RegisterWindowMessage('AdKiller');<br>end.
 
弹出窗口我用了另外一个方法,通过 CanOpen 变量决定 NewWindow2 的值<br>缺点是任务未停止就不能开新窗口了,所以我还想观察 document 的鼠标点击事件,但不会<br>我现在的问题主要是想过滤一些图片或Flash或其它网页内容<br><br> &nbsp; &nbsp;DISPID_NAVIGATECOMPLETE2: begin<br> &nbsp; &nbsp; if FWebBrowser.LocationURL=TDispParams(Params).rgvarg[0].pvarVal^ then<br> &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp;for m:=0 to 254 do<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; if MyTask[m]=0 then<br> &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp;F_Time[m] :=Time();<br> &nbsp; &nbsp; &nbsp; &nbsp;while F_Time[m]=0 do<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; SLEEP(100);<br> &nbsp; &nbsp; &nbsp; &nbsp; F_Time[m] :=Time();<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp; &nbsp; &nbsp;UrlTask[m]:=FWebBrowser.LocationURL;<br> &nbsp; &nbsp; &nbsp; &nbsp;StrTemp &nbsp; :='开始任务'+IntToStr(m)+':'+UrlTask[m];<br> &nbsp; &nbsp; &nbsp; &nbsp;InternalLogEvent(StrTemp);<br> &nbsp; &nbsp; &nbsp; &nbsp;MyTask[m] :=1;<br> &nbsp; &nbsp; &nbsp; &nbsp;CanOpen:=False;<br> &nbsp; &nbsp; &nbsp; &nbsp;Break;<br> &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp; &nbsp;if MyTask[254]=1 then FEventsDlg.ClearLog_BtnClick(nil);<br> &nbsp; &nbsp; end;<br> &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp;DISPID_DOCUMENTCOMPLETE: begin<br> &nbsp; &nbsp; &nbsp;for m:=0 to 254 do<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; if UrlTask[m]=TDispParams(Params).rgvarg[0].pvarVal^ then<br> &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp;E_Time[m]:=Time();<br> &nbsp; &nbsp; &nbsp; &nbsp;while E_Time[m]=0 do<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; SLEEP(100);<br> &nbsp; &nbsp; &nbsp; &nbsp; E_Time[m] :=Time();<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp; &nbsp;DecodeTime(E_Time[m]-F_Time[m], Hour, Min, Sec, MSec);<br> &nbsp; &nbsp; &nbsp; &nbsp;StrTemp:='结束任务'+IntToStr(m)+':'+TimeToStr(F_Time[m])+' - '+TimeToStr(E_Time[m])<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+' 使用了 '+IntToStr(3600*Hour+60*Min+Sec)+'.'+IntToStr(MSec)+'秒 ';<br> &nbsp; &nbsp; &nbsp; &nbsp;InternalLogEvent(StrTemp);<br> &nbsp; &nbsp; &nbsp; &nbsp;MyTask[m]:=0;<br> &nbsp; &nbsp; &nbsp; &nbsp;CanOpen:=True;<br> &nbsp; &nbsp; &nbsp; &nbsp;Break;<br> &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp;DISPID_NewWindow2: begin<br> &nbsp; &nbsp; &nbsp;if NOT(CanOpen) then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;InternalLogEvent('过滤了弹出窗口!');<br> &nbsp; &nbsp; &nbsp; &nbsp;TDispParams(Params).rgvarg[0].pvarVal^:= False;<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;end;
 
找到了一份笔记,调试通过了<br>http://www.delphibbs.com/keylife/iblog_show.asp?xid=606<br><br>我现在想把下载的路径改掉,有什么方法?
 
路径就是start方法的第一个参数
 
我把第一个参数改了,但还是不行
 
成功获取了 HTMLDocumentEvents2, 网页事件,如鼠标点击等<br>HTMLDocument:= FWebBrowser.Document as IHTMLDocument2;<br>InterfaceConnect(HTMLDocument, HTMLDocumentEvents2, Self, FConnection);<br><br>看了源码,事件相对的 ID,然后在 Invoke 里定义要处理的东西就好了<br>我加了<br>-600: begin<br> CanOpen:= True;<br> Sleep(100);<br> CanOpen:= False;<br>end;<br><br> &nbsp;HTMLDocumentEvents2 = dispinterface<br> &nbsp; &nbsp;['{3050F613-98B5-11CF-BB82-00AA00BDCE0B}']<br> &nbsp; &nbsp;function &nbsp;onhelp(const pEvtObj: IHTMLEventObj): WordBool; dispid -2147418102;<br> &nbsp; &nbsp;function &nbsp;onclick(const pEvtObj: IHTMLEventObj): WordBool; dispid -600;<br> &nbsp; &nbsp;function &nbsp;ondblclick(const pEvtObj: IHTMLEventObj): WordBool; dispid -601;<br> &nbsp; &nbsp;procedure onkeydown(const pEvtObj: IHTMLEventObj); dispid -602;<br> &nbsp; &nbsp;procedure onkeyup(const pEvtObj: IHTMLEventObj); dispid -604;<br> &nbsp; &nbsp;function &nbsp;onkeypress(const pEvtObj: IHTMLEventObj): WordBool; dispid -603;<br> &nbsp; &nbsp;procedure onmousedown(const pEvtObj: IHTMLEventObj); dispid -605;<br> &nbsp; &nbsp;procedure onmousemove(const pEvtObj: IHTMLEventObj); dispid -606;<br> &nbsp; &nbsp;procedure onmouseup(const pEvtObj: IHTMLEventObj); dispid -607;<br> &nbsp; &nbsp;procedure onmouseout(const pEvtObj: IHTMLEventObj); dispid -2147418103;<br> &nbsp; &nbsp;procedure onmouseover(const pEvtObj: IHTMLEventObj); dispid -2147418104;<br> &nbsp; &nbsp;procedure onreadystatechange(const pEvtObj: IHTMLEventObj); dispid -609;<br> &nbsp; &nbsp;function &nbsp;onbeforeupdate(const pEvtObj: IHTMLEventObj): WordBool; dispid -2147418108;<br> &nbsp; &nbsp;procedure onafterupdate(const pEvtObj: IHTMLEventObj); dispid -2147418107;<br> &nbsp; &nbsp;function &nbsp;onrowexit(const pEvtObj: IHTMLEventObj): WordBool; dispid -2147418106;<br> &nbsp; &nbsp;procedure onrowenter(const pEvtObj: IHTMLEventObj); dispid -2147418105;<br> &nbsp; &nbsp;function &nbsp;ondragstart(const pEvtObj: IHTMLEventObj): WordBool; dispid -2147418101;<br> &nbsp; &nbsp;function &nbsp;onselectstart(const pEvtObj: IHTMLEventObj): WordBool; dispid -2147418100;<br> &nbsp; &nbsp;function &nbsp;onerrorupdate(const pEvtObj: IHTMLEventObj): WordBool; dispid -2147418099;<br> &nbsp; &nbsp;function &nbsp;oncontextmenu(const pEvtObj: IHTMLEventObj): WordBool; dispid 1023;<br> &nbsp; &nbsp;function &nbsp;onstop(const pEvtObj: IHTMLEventObj): WordBool; dispid 1026;<br> &nbsp; &nbsp;procedure onrowsdelete(const pEvtObj: IHTMLEventObj); dispid -2147418080;<br> &nbsp; &nbsp;procedure onrowsinserted(const pEvtObj: IHTMLEventObj); dispid -2147418079;<br> &nbsp; &nbsp;procedure oncellchange(const pEvtObj: IHTMLEventObj); dispid -2147418078;<br> &nbsp; &nbsp;procedure onpropertychange(const pEvtObj: IHTMLEventObj); dispid -2147418093;<br> &nbsp; &nbsp;procedure ondatasetchanged(const pEvtObj: IHTMLEventObj); dispid -2147418098;<br> &nbsp; &nbsp;procedure ondataavailable(const pEvtObj: IHTMLEventObj); dispid -2147418097;<br> &nbsp; &nbsp;procedure ondatasetcomplete(const pEvtObj: IHTMLEventObj); dispid -2147418096;<br> &nbsp; &nbsp;procedure onbeforeeditfocus(const pEvtObj: IHTMLEventObj); dispid 1027;<br> &nbsp;end;
 
第一个参数是系统传给你的,告诉你他要获得那个url,你根据这儿url去判断到那里去取数据,比如告诉你http://www.google.com,在你的算法里,这个对应c:/google.htm,你就去读c:/google.htm,然后传回系统(使用start传给你的OIProtSink)
 
to satanmonkey, 有例程吗?不是很明白
 
app的资料看这里<br><br>http://www.euromind.com/iedelphi/app.htm
 
过滤网页元素,是否定时循环网页元素,然后替换?
 
一次应该就够了.不过如果人家是用循环来检查是否被你屏蔽的话.你也需要循环.
 
等页面下载完成再比较?其实用什么方法替换广告内容好?<br>我看了一下MYIE的原码,找不到相应的位置<br><br>终于找到相应的位置了,是在 IE 的 OnProgressChange 里面处理的<br>每发生一次这个事件,就执行一次 javascript
 
不下载完是 得不到IHTMLDocument2的<br><br>你要在下载过程中,可以用app,不过难度就不是一般的大.
 
app 只能禁止下载和替换下载的路径。如果我想在那个位置的内容<br>例如 &lt;img src=x&gt; 改为‘被过滤的广告’文字来表示<br>这样就不能用 app 吧?
 
http://www.euromind.com/iedelphi/app/mimefilter.htm<br><br>例子将网页中的字符Delphi替换为Borland Inprise<br>例子中的page1.htm在IE中打开最下面的链接是 IE & Delphi使用例子程序打开变成 IE & Borland Inprise。经测试对HTML标签同样有效
 
我刚看了一下源码,好象是通过ReportData来取数据的,然后替换字符串<br>这样替换起来比较复杂<br>如果用元素的方法比较方便
 
后退
顶部