开发BHO插件,如何在页面载入完之前就修改

lengchen1217 2011-10-31 02:41:25
我现在能够实现对网页内容的替换,但是有延迟,举个例子,我比如想把网页上的淘宝替换成QQ两字,页面打开后,确实能实现替换,但是却是先显示出“淘宝”之后,然后再把“淘宝”字样的内容替换成“QQ”,然而这样修改页面已经失去了意义(因为早看到修改前的页面了)请问大家如何解决这个问题:
以下是源码:

unit UIEMonitor;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
Windows, ActiveX, Classes, ComObj, SHDOCVW, Dialogs, SysUtils, Forms,
Admin, Admin2,mshtml;

type
TIEMonitor = class(TComObject, IDispatch, IObjectWithSite)
public
function GetTypeInfoCount(out Count:Integer):HResult;stdcall;
function GetTypeInfo(Index,LocaleID:Integer;out TypeInfo):HResult;stdcall;
function GetIDsOfNames(const IID:TGUID;Names:Pointer;
NameCount,LocaleID:Integer;DispIDs:Pointer):HResult;stdcall;
function SetSite(const pUnkSite:IUnknown):HResult;stdcall;
function GetSite(const riid:TIID;out site:IUnknown):HResult;stdcall;
function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
private
IEThis:IWebBrowser2;
Cookie:Integer;
protected
end;

const
Class_IEMonitor: TGUID = '{47CFDDF9-6FBD-4C06-8752-24FEFBA10D51}';
HasQuit=888;//标志已经退出

var
isStart:Integer;//标志是否正在退出
WIMS:TWIMS;

implementation

uses ComServ;

procedure DoBeforeNavigate2(const pDisp:IDispatch;var URL:OleVariant;
var Flags:OleVariant;var TargetFrameName:OleVariant;var PostData:OleVariant;
var Headers:OleVariant;var Cancel:WordBool);
var
i: Integer;
Links: Variant;
F_Exception: TextFile;
DisHTML: IHTMLDocument2;
ExceptionFile,Str,LinkStr,JSValue,JSType,strue,son: string;
begin
if(isStart<>hasQuit)then
begin
if(not Assigned(WIMS))then
begin
WIMS:=TWIMS.Create(Application);
//ShowMessage('创建了TWIMS!');
end;
//ShowMessage('执行DoBeforeNavigate2事件!');
i:=WIMS.ChkUrl(URL);//同时判断是否重新加载参数
if((WIMS.SysEnable=eEnable)and(WIMS.IPEnable=eEnable)//系统启用
and((i=eUnable)or((WIMS.FilterType=eEnable)and(i=eUnknown))))then
begin
if(WIMS.DealMode=DEAL_REPLACE)then
begin
URL:=(WIMS.ReplaceFile);
(pDisp as IWebBrowser2).Navigate2(URL,Flags,TargetFrameName,PostData,Headers);
end else
//ShowMessage(WIMS.WarnInfo);
end;//
end;
end;

procedure DoDownloadComplete(IEThis:IWebBrowser2);
var
i: Integer;
Links: Variant;
F_Exception: TextFile;
ExceptionFile,Str,LinkStr,JSValue,JSType,strue,son: string;
begin
//可以在该函数中处理网页文本以及图象等信息
try
if IEThis.ReadyState = 3 then
begin
Links:= (IEThis.Document as IHTMLDocument2).all.tags('Div');
for i:= 0 to Links.Length -1 do
begin
Linkstr:= Links.Item(i).innerHtml;
if Pos('淘宝',Linkstr) > 0 then
begin
Linkstr:= StringReplace(Linkstr,'淘宝','QQ',[rfReplaceAll]);
Links.Item(i).innerHtml:= Linkstr;
end;
end;
end;
except
on e:Exception do
begin
ExceptionFile:= 'E:\MYDELPHI\source\Err.txt';
AssignFile(F_Exception,ExceptionFile);
Rewrite(F_Exception);
Append(F_Exception);
Writeln(F_Exception,e.message);
CloseFile(F_Exception);
end;
end;
end;

procedure DoOnQuit;
begin
if(Assigned(WIMS))then
begin
WIMS.Free;
//ShowMessage('释放了TWIMS!');
end;//}
//ShowMessage('执行DoOnQuit事件!'+IntToStr(isStart));
isStart:=HasQuit;//标志已经退出
end;

procedure BuildPositionalDispIDs(pDispIDs:PDispIDList;const dps:TDispParams);
var
i:Integer;
begin
Assert(pDispIDs<>nil);
for i:=0 to dps.cArgs-1 do
pDispIDs^[i]:=dps.cArgs-1-i;
if(dps.cNamedArgs<=0)then
Exit;
for i:=0 to dps.cNamedArgs-1 do
pDispIDs^[dps.rgdispidNamedArgs^[i]]:=i;
end;

function TIEMonitor.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;
type
POleVariant=^OleVariant;
var
dps:TDispParams absolute Params;
bHasParams:Boolean;
pDispIDs:PDispIDList;
iDispIDsSize:Integer;
begin
Result:=DISP_E_MEMBERNOTFOUND;
pDispIDs:=nil;
iDispIDsSize:=0;
bHasParams:=(dps.cArgs>0);
if(bHasParams)then
begin
iDispIDsSize:=dps.cArgs*SizeOf(TDispID);
GetMem(pDispIDs,iDispIDsSize);
end;
try
if(bHasParams)then BuildPositionalDispIDs(pDispIDs,dps);
case DispID of
104:begin
DoDownLoadComplete(IEThis);
//if Pos('淘宝',(IEThis.Document as IHTMLDocument2).body.innerHTML) > 0 then Exit;
Result:=S_OK;
end;
250:begin
DoBeforeNavigate2(IDispatch(dps.rgvarg^[pDispIDs^[0]].dispVal),
POleVariant(dps.rgvarg^[pDispIDs^[1]].pvarVal)^,
POleVariant(dps.rgvarg^[pDispIDs^[2]].pvarVal)^,
POleVariant(dps.rgvarg^[pDispIDs^[3]].pvarVal)^,
POleVariant(dps.rgvarg^[pDispIDs^[4]].pvarVal)^,
POleVariant(dps.rgvarg^[pDispIDs^[5]].pvarVal)^,
dps.rgvarg^[pDispIDs^[6]].pbool^);
Result:=S_OK;
end;
253:begin
DoOnQuit();
Result:=S_OK;
end;
end;//end of case DispID of
finally
if(bHasParams)then
FreeMem(pDispIDs,iDispIDsSize);
end;
end;

function TIEMonitor.GetTypeInfo(Index,LocaleID:Integer;out TypeInfo):HResult;
begin
Result:=E_NOTIMPL;
Pointer(TypeInfo):=nil;
end;

function TIEMonitor.GetTypeInfoCount(out Count:Integer):HResult;
begin
Result:=E_NOTIMPL;
Count:=0;
end;

function TIEMonitor.GetIDsOfNames(const IID:TGUID;Names:Pointer;
NameCount,LocaleID:Integer;DispIDs:Pointer):HResult;
begin
Result:=E_NOTIMPL;
end;

function TIEMonitor.GetSite(const riid:TIID;out site:IUnknown):HResult;
begin
//ShowMessage('执行了GetSite事件!');
if(Assigned(IEThis))then
Result:=IEThis.QueryInterface(riid,site)
else Result:=E_FAIL;
end;

function TIEMonitor.SetSite(const pUnkSite:IUnknown):HResult;
var
cmdTarget:IOleCommandTarget;
Sp:IServiceProvider;
CPC:IConnectionPointContainer;
CP:IConnectionPoint;
begin
//ShowMessage('执行了SetSite事件!');
if(Assigned(pUnkSite))then
begin
cmdTarget:=(pUnkSite as IOleCommandTarget);
Sp:=(CmdTarget as IServiceProvider);
if(Assigned(Sp))then//获得IE的WebBrowser接口,
Sp.QueryService(IWebBrowserApp,IWebBrowser2,IEThis);
if(Assigned(IEThis))then
begin
IEThis.QueryInterface(IConnectionPointContainer,CPC);//寻找连接点
CPC.FindConnectionPoint(DWEBBrowserEvents2,CP);
CP.Advise(Self,Cookie);//通过Advise方法建立Com自身与连接点的连接
end;
end;
Result:=S_OK;
end;


...全文
249 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
lengchen1217 2011-10-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 ansunny 的回复:]

用indy控件,idhttp,有个get函数,
s: string;
s := idhtp1.Get(URL);
取得数据后用stringreplace替换,,存入一个文件,例如保存成c:\temp.html,替换之后,再把把本地路径c:\temp.html作为url传入(后缀要跟你URL的相同,例如如果你url的是html就是.html)
[/Quote]

如何作为URL传入IE呢,我这个是在IE里实现的,而不是自写的浏览器,
某某某 2011-10-31
  • 打赏
  • 举报
回复
用indy控件,idhttp,有个get函数,
s: string;
s := idhtp1.Get(URL);
取得数据后用stringreplace替换,,存入一个文件,例如保存成c:\temp.html,替换之后,再把把本地路径c:\temp.html作为url传入(后缀要跟你URL的相同,例如如果你url的是html就是.html)
lengchen1217 2011-10-31
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 ansunny 的回复:]

先用http.get把页面下载到本地,例如保存成c:\temp.html,替换之后,再把把本地路径c:\temp.html作为url传入。就ok了。
[/Quote]

给个详细的说明或者代码?试过好像不行啊
某某某 2011-10-31
  • 打赏
  • 举报
回复
先用http.get把页面下载到本地,例如保存成c:\temp.html,替换之后,再把把本地路径c:\temp.html作为url传入。就ok了。
lengchen1217 2011-10-31
  • 打赏
  • 举报
回复
有没有哪位大大帮帮忙啊,急求啊

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧