利用Delphi编写IE扩展 在自己的程序中使用过WebBrowser控件的朋友都知道,WebBrowser控件定义了诸如BeforeNavigate、DownloadComplete 等事件,我们可以通过编写事件处理代码实现对WebBrowser控件的操作。那么如何实现对IE的事件响应和处理呢?同建立IE面板一样。我们需要建立一个实现IObjectWithSite接口的COM组件,不同的是,我们还需要实现IDispatch接口,在IObjectWithSite接口的SetSite方法中获得IE的WebBrowser接口并建立自身与WebBrowser的连接,然后如果在IE的Webbrowser对象中发生什么事件的话,那么IE就会回调连接的IDispatch接口的Invoke方法。我们通过在Invoke方法中编写代码就可以获得IE事件了。这个利用的是COM编程的回调接口原理。 下面我们首先来实现代码。点击Delphi菜单 File | New 。在 ActiveX 页面中选择Active Library ,然后点击 OK 按钮。然后用同样的方法建立一个COM Object。在COM Object Wizard 窗口中,将复选框 Included type library 去掉。然后在Class Name中输入IEHelper,在Implemented Interface 中输入:IDispatch;IObjectwithSite 。然后点击 OK 按钮建立一个COM组件。 保存工程,将工程保存为IEHelper.dpr,将Unit1保存为IEHelperUnit.pas。下面是IEHelperUnit.pas的具体代码: unit iehelperunit; interface uses WIndows, Comobj, ActiveX, SHDOCVW, MSHTML,Dialogs; type TIEHelperFactory = class(TComObjectFactory) private procedure AddKeys; procedure RemoveKeys; public procedure UpdateRegistry(Register: Boolean); override; end; TIEHelper = 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 Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall; function SetSite(const pUnkSite: IUnknown): HResult; stdcall; function GetSite(const riid: TIID; out site: IUnknown): HResult; stdcall; private IE: IWebbrowser2; Cookie: Integer; end; const Class_IEHelper: TGUID = ’{3D898C55-74CC-4B7C-B5F1-45913F368388}’; implementation uses ComServ, Registry, SysUtils; procedure DoStatusTextChange(const Text: WideString); begin end; procedure DoProgressChange(Progress: Integer; ProgressMax: Integer); begin end; procedure DoCommandStateChange(Command: Integer; Enable: WordBool); begin end; procedure DoDownloadBegin; begin end; procedure DoDownloadComplete; begin end; procedure DoTitleChange(const Text: WideString); begin end; procedure DoPropertyChange(const szProperty: WideString); begin end; procedure DoBeforeNavigate2(const pDisp: IDispatch; var URL: OleVariant; var Flags: OleVariant; var TargetFrameName: OleVariant; var PostData: OleVariant; var Headers: OleVariant; var Cancel: WordBool); begin if URL<>’http://www.applevb.com/’then begin Showmessage(’你不可以浏览其它站点’); Cancel:=True; URL:=’http://www.applevb.com’; (pDisp as IWebbrowser2).Navigate2(URL,Flags,TargetFrameName,PostData,Headers); end; end; procedure DoNewWindow2(var ppDisp: IDispatch; var Cancel: WordBool); begin end; procedure DoNavigateComplete2(const pDisp: IDispatch; var URL: OleVariant); begin end; procedure DoDocumentComplete(const pDisp: IDispatch; var URL: OleVariant); begin end; procedure DoOnQuit; begin end; procedure DoOnVisible(Visible: WordBool); begin end; procedure DoOnToolBar(ToolBar: WordBool); begin end; procedure DoOnMenuBar(MenuBar: WordBool); begin end; procedure DoOnStatusBar(StatusBar: WordBool); begin end; procedure DoOnFullScreen(FullScreen: WordBool); begin end; procedure DoOnTheaterMode(TheaterMode: WordBool); begin 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 TIEHelper.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 102: begin DoStatusTextChange(dps.rgvarg^[pDispIds^[0]].bstrval); Result := S_OK; end; 108: begin DoProgressChange(dps.rgvarg^[pDispIds^[0]].lval, dps.rgvarg^[pDispIds^[1]].lval); Result := S_OK; end; 105: begin DoCommandStateChange(dps.rgvarg^[pDispIds^[0]].lval, dps.rgvarg^[pDispIds^[1]].vbool); Result := S_OK; end; 106: begin DoDownloadBegin(); Result := S_OK; end; 104: begin DoDownloadComplete(); Result := S_OK; end; 113: begin DoTitleChange(dps.rgvarg^[pDispIds^[0]].bstrval); Result := S_OK; end; 112: begin DoPropertyChange(dps.rgvarg^[pDispIds^[0]].bstrval); 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; 251: begin DoNewWindow2(IDispatch(dps.rgvarg^[pDispIds^[0]].pdispval^), dps.rgvarg^[pDispIds^[1]].pbool^); Result := S_OK; end; 252: begin DoNavigateComplete2(IDispatch(dps.rgvarg^[pDispIds^[0]].dispval), POleVariant(dps.rgvarg^[pDispIds^[1]].pvarval)^); Result := S_OK; end;
259: begin DoDocumentComplete(IDispatch(dps.rgvarg^[pDispIds^[0]].dispval), POleVariant(dps.rgvarg^[pDispIds^[1]].pvarval)^); Result := S_OK; end; 253: begin DoOnQuit(); Result := S_OK; end; 254: begin DoOnVisible(dps.rgvarg^[pDispIds^[0]].vbool); Result := S_OK; end; 255: begin DoOnToolBar(dps.rgvarg^[pDispIds^[0]].vbool); Result := S_OK; end; 256: begin DoOnMenuBar(dps.rgvarg^[pDispIds^[0]].vbool); Result := S_OK; end; 257: begin DoOnStatusBar(dps.rgvarg^[pDispIds^[0]].vbool); Result := S_OK; end; 258: begin DoOnFullScreen(dps.rgvarg^[pDispIds^[0]].vbool); Result := S_OK; end; 260: begin DoOnTheaterMode(dps.rgvarg^[pDispIds^[0]].vbool); Result := S_OK; end; end; finally if (bHasParams) then FreeMem(pDispIds, iDispIdsSize); end; end; function TIEHelper.GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; begin Result := E_NOTIMPL; end; function TIEHelper.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; begin Result := E_NOTIMPL; pointer(TypeInfo) := nil; end; function TIEHelper.GetTypeInfoCount(out Count: Integer): HResult; begin Result := E_NOTIMPL; Count := 0; end; function TIEHelper.GetSite(const riid: TIID; out site: IUnknown): HResult; begin // Result := S_OK; if Assigned(IE) then result:=IE.QueryInterface(riid, site) else Result:= E_FAIL; end; function TIEHelper.SetSite(const pUnkSite: IUnknown): HResult; var cmdTarget: IOleCommandTarget; Sp: IServiceProvider; CPC: IConnectionPointContainer; CP: ICOnnectionPoint; begin if Assigned(pUnkSite) then begin cmdTarget := pUnkSite as IOleCommandTarget; Sp := CmdTarget as IServiceProvider; if Assigned(Sp)then Sp.QueryService(IWebbrowserApp, IWebbrowser2, IE); if Assigned(IE) then begin IE.QueryInterface(IConnectionPointContainer, CPC); CPC.FindConnectionPoint(DWEBbrowserEvents2, CP); CP.Advise(Self, Cookie) end; end; Result := S_OK; end; procedure TIEHelperFactory.AddKeys; var S: string; begin S := GUIDToString(CLASS_IEHelper); with TRegistry.Create do try RootKey := HKEY_LOCAL_MACHINE; if OpenKey(’Software\Microsoft\Windows\CurrentVersion\explorer\Browser Helper Objects\’ + S, TRUE) then CloseKey; finally free; end; end; procedure TIEHelperFactory.RemoveKeys; var S: string; begin S := GUIDToString(CLASS_IEHelper); with TRegistry.Create do try RootKey := HKEY_LOCAL_MACHINE; DeleteKey(’Software\Microsoft\Windows\CurrentVersion\explorer\Browser Helper Objects\’ + S); finally free; end; end; procedure TIEHelperFactory.UpdateRegistry(Register: Boolean); begin inherited UpdateRegistry(Register); if Register then AddKeys else RemoveKeys; end; initialization TIEHelperFactory.Create(ComServer, TIEHelper, Class_IEHelper, ’IEHelper’, ’’, ciMultiInstance, tmApartment); end. 代码很长,但是关键的是TIEHelper.SetSite方法以及TIEHelper.Invoke方法。在TIEHelper.SetSite方法中注意以下语句: if Assigned(Sp)then Sp.QueryService(IWebbrowserApp, IWebbrowser2, IE); if Assigned(IE) then begin IE.QueryInterface(IConnectionPointContainer, CPC); CPC.FindConnectionPoint(DWEBbrowserEvents2, CP); CP.Advise(Self, Cookie) 上面的语句作用是,首先获得IE的Webbrowser接口,然后寻找到连接点。并通过Advise方法建立COM自身与连接点的连接。 当连接建立成功后,IE在有事件引发后,会调用连接到自身的IDispatch接口对象的Invoke方法。不同的事件对应不同的DispID编码,我们可以在程序中判断DispID并做相应的处理。在上面的程序中,我们只处理了BeforeNavigate2 事件,处理函数是DoBeforeNavigate2,在该函数中,如果浏览的站点不是’http://www.applevb.com/’的话,程序会提示:’你不可以浏览其它站点’并强行转到http://www.applevb.com。 很多的软件,象“护花使者”以及“3721”一类的中文网址”都是利用上面的原理来实现对IE浏览器事件响应的,例如3721,当用户输入一个中文词并浏览时,COM组件可以在BeforeNavigate2 事件中编写代码访问服务器并转到正确的站点上去。 以上程序在Win2K、Delphi 5下编写 Win98、Win2K下编辑通过,如果大家需要源程序或者对于COM编程需要有什么的指教的话,欢迎到我的主页 http://www.applevb.com 访问,我愿意同大家一起探讨。
to technofantasy(www.applevb.com): 我说的就是http://www.csdn.net/Develop/read_article.asp?id=6351中的例子,如何在DocumentComplete中得到页面源码呀,Document属性好象不行,请问还有具体的方法吗?
Document.Body.InnerHTML应该可以的,我下班后看一下我的程序。
to technofantasy(www.applevb.com): Document.Body.InnerHTML不行的,根据没有body属性。
http://www.csdn.net/Develop/read_article.asp?id=6351
IE上添加工具栏的范例:
http://www.csdn.net/Develop/read_article.asp?id=7099
基本你可以利用第一种方法即时获得页面地代码,使用第二种方法将页面显示在你自己添加的IE面板上。
利用Delphi编写IE扩展
在自己的程序中使用过WebBrowser控件的朋友都知道,WebBrowser控件定义了诸如BeforeNavigate、DownloadComplete 等事件,我们可以通过编写事件处理代码实现对WebBrowser控件的操作。那么如何实现对IE的事件响应和处理呢?同建立IE面板一样。我们需要建立一个实现IObjectWithSite接口的COM组件,不同的是,我们还需要实现IDispatch接口,在IObjectWithSite接口的SetSite方法中获得IE的WebBrowser接口并建立自身与WebBrowser的连接,然后如果在IE的Webbrowser对象中发生什么事件的话,那么IE就会回调连接的IDispatch接口的Invoke方法。我们通过在Invoke方法中编写代码就可以获得IE事件了。这个利用的是COM编程的回调接口原理。
下面我们首先来实现代码。点击Delphi菜单 File | New 。在 ActiveX 页面中选择Active Library ,然后点击 OK 按钮。然后用同样的方法建立一个COM Object。在COM Object Wizard 窗口中,将复选框 Included type library 去掉。然后在Class Name中输入IEHelper,在Implemented Interface 中输入:IDispatch;IObjectwithSite 。然后点击 OK 按钮建立一个COM组件。
保存工程,将工程保存为IEHelper.dpr,将Unit1保存为IEHelperUnit.pas。下面是IEHelperUnit.pas的具体代码:
unit iehelperunit;
interface
uses
WIndows, Comobj, ActiveX, SHDOCVW, MSHTML,Dialogs;
type
TIEHelperFactory = class(TComObjectFactory)
private
procedure AddKeys;
procedure RemoveKeys;
public
procedure UpdateRegistry(Register: Boolean); override;
end;
TIEHelper = 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 Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
function SetSite(const pUnkSite: IUnknown): HResult; stdcall;
function GetSite(const riid: TIID; out site: IUnknown): HResult; stdcall;
private
IE: IWebbrowser2;
Cookie: Integer;
end;
const
Class_IEHelper: TGUID = ’{3D898C55-74CC-4B7C-B5F1-45913F368388}’;
implementation
uses ComServ, Registry, SysUtils;
procedure DoStatusTextChange(const Text: WideString);
begin
end;
procedure DoProgressChange(Progress: Integer; ProgressMax: Integer);
begin
end;
procedure DoCommandStateChange(Command: Integer; Enable: WordBool);
begin
end;
procedure DoDownloadBegin;
begin
end;
procedure DoDownloadComplete;
begin
end;
procedure DoTitleChange(const Text: WideString);
begin
end;
procedure DoPropertyChange(const szProperty: WideString);
begin
end;
procedure DoBeforeNavigate2(const pDisp: IDispatch; var URL: OleVariant; var Flags: OleVariant; var TargetFrameName: OleVariant; var PostData: OleVariant; var Headers: OleVariant; var Cancel: WordBool);
begin
if URL<>’http://www.applevb.com/’then begin
Showmessage(’你不可以浏览其它站点’);
Cancel:=True;
URL:=’http://www.applevb.com’;
(pDisp as IWebbrowser2).Navigate2(URL,Flags,TargetFrameName,PostData,Headers);
end;
end;
procedure DoNewWindow2(var ppDisp: IDispatch; var Cancel: WordBool);
begin
end;
procedure DoNavigateComplete2(const pDisp: IDispatch; var URL: OleVariant);
begin
end;
procedure DoDocumentComplete(const pDisp: IDispatch; var URL: OleVariant);
begin
end;
procedure DoOnQuit;
begin
end;
procedure DoOnVisible(Visible: WordBool);
begin
end;
procedure DoOnToolBar(ToolBar: WordBool);
begin
end;
procedure DoOnMenuBar(MenuBar: WordBool);
begin
end;
procedure DoOnStatusBar(StatusBar: WordBool);
begin
end;
procedure DoOnFullScreen(FullScreen: WordBool);
begin
end;
procedure DoOnTheaterMode(TheaterMode: WordBool);
begin
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 TIEHelper.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
102:
begin
DoStatusTextChange(dps.rgvarg^[pDispIds^[0]].bstrval);
Result := S_OK;
end;
108:
begin
DoProgressChange(dps.rgvarg^[pDispIds^[0]].lval, dps.rgvarg^[pDispIds^[1]].lval);
Result := S_OK;
end;
105:
begin
DoCommandStateChange(dps.rgvarg^[pDispIds^[0]].lval, dps.rgvarg^[pDispIds^[1]].vbool);
Result := S_OK;
end;
106:
begin
DoDownloadBegin();
Result := S_OK;
end;
104:
begin
DoDownloadComplete();
Result := S_OK;
end;
113:
begin
DoTitleChange(dps.rgvarg^[pDispIds^[0]].bstrval);
Result := S_OK;
end;
112:
begin
DoPropertyChange(dps.rgvarg^[pDispIds^[0]].bstrval);
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;
251:
begin
DoNewWindow2(IDispatch(dps.rgvarg^[pDispIds^[0]].pdispval^), dps.rgvarg^[pDispIds^[1]].pbool^);
Result := S_OK;
end;
252:
begin
DoNavigateComplete2(IDispatch(dps.rgvarg^[pDispIds^[0]].dispval), POleVariant(dps.rgvarg^[pDispIds^[1]].pvarval)^);
Result := S_OK;
end;
begin
DoDocumentComplete(IDispatch(dps.rgvarg^[pDispIds^[0]].dispval), POleVariant(dps.rgvarg^[pDispIds^[1]].pvarval)^);
Result := S_OK;
end;
253:
begin
DoOnQuit();
Result := S_OK;
end;
254:
begin
DoOnVisible(dps.rgvarg^[pDispIds^[0]].vbool);
Result := S_OK;
end;
255:
begin
DoOnToolBar(dps.rgvarg^[pDispIds^[0]].vbool);
Result := S_OK;
end;
256:
begin
DoOnMenuBar(dps.rgvarg^[pDispIds^[0]].vbool);
Result := S_OK;
end;
257:
begin
DoOnStatusBar(dps.rgvarg^[pDispIds^[0]].vbool);
Result := S_OK;
end;
258:
begin
DoOnFullScreen(dps.rgvarg^[pDispIds^[0]].vbool);
Result := S_OK;
end;
260:
begin
DoOnTheaterMode(dps.rgvarg^[pDispIds^[0]].vbool);
Result := S_OK;
end;
end;
finally
if (bHasParams) then FreeMem(pDispIds, iDispIdsSize);
end;
end;
function TIEHelper.GetIDsOfNames(const IID: TGUID; Names: Pointer;
NameCount, LocaleID: Integer; DispIDs: Pointer): HResult;
begin
Result := E_NOTIMPL;
end;
function TIEHelper.GetTypeInfo(Index, LocaleID: Integer;
out TypeInfo): HResult;
begin
Result := E_NOTIMPL;
pointer(TypeInfo) := nil;
end;
function TIEHelper.GetTypeInfoCount(out Count: Integer): HResult;
begin
Result := E_NOTIMPL;
Count := 0;
end;
function TIEHelper.GetSite(const riid: TIID; out site: IUnknown): HResult;
begin
// Result := S_OK;
if Assigned(IE) then result:=IE.QueryInterface(riid, site)
else
Result:= E_FAIL;
end;
function TIEHelper.SetSite(const pUnkSite: IUnknown): HResult;
var
cmdTarget: IOleCommandTarget;
Sp: IServiceProvider;
CPC: IConnectionPointContainer;
CP: ICOnnectionPoint;
begin
if Assigned(pUnkSite) then begin
cmdTarget := pUnkSite as IOleCommandTarget;
Sp := CmdTarget as IServiceProvider;
if Assigned(Sp)then
Sp.QueryService(IWebbrowserApp, IWebbrowser2, IE);
if Assigned(IE) then begin
IE.QueryInterface(IConnectionPointContainer, CPC);
CPC.FindConnectionPoint(DWEBbrowserEvents2, CP);
CP.Advise(Self, Cookie)
end;
end;
Result := S_OK;
end;
procedure TIEHelperFactory.AddKeys;
var S: string;
begin
S := GUIDToString(CLASS_IEHelper);
with TRegistry.Create do
try
RootKey := HKEY_LOCAL_MACHINE;
if OpenKey(’Software\Microsoft\Windows\CurrentVersion\explorer\Browser Helper Objects\’ + S, TRUE)
then CloseKey;
finally
free;
end;
end;
procedure TIEHelperFactory.RemoveKeys;
var S: string;
begin
S := GUIDToString(CLASS_IEHelper);
with TRegistry.Create do
try
RootKey := HKEY_LOCAL_MACHINE;
DeleteKey(’Software\Microsoft\Windows\CurrentVersion\explorer\Browser Helper Objects\’ + S);
finally
free;
end;
end;
procedure TIEHelperFactory.UpdateRegistry(Register: Boolean);
begin
inherited UpdateRegistry(Register);
if Register then AddKeys else RemoveKeys;
end;
initialization
TIEHelperFactory.Create(ComServer, TIEHelper, Class_IEHelper,
’IEHelper’, ’’, ciMultiInstance, tmApartment);
end.
代码很长,但是关键的是TIEHelper.SetSite方法以及TIEHelper.Invoke方法。在TIEHelper.SetSite方法中注意以下语句:
if Assigned(Sp)then
Sp.QueryService(IWebbrowserApp, IWebbrowser2, IE);
if Assigned(IE) then begin
IE.QueryInterface(IConnectionPointContainer, CPC);
CPC.FindConnectionPoint(DWEBbrowserEvents2, CP);
CP.Advise(Self, Cookie)
上面的语句作用是,首先获得IE的Webbrowser接口,然后寻找到连接点。并通过Advise方法建立COM自身与连接点的连接。
当连接建立成功后,IE在有事件引发后,会调用连接到自身的IDispatch接口对象的Invoke方法。不同的事件对应不同的DispID编码,我们可以在程序中判断DispID并做相应的处理。在上面的程序中,我们只处理了BeforeNavigate2 事件,处理函数是DoBeforeNavigate2,在该函数中,如果浏览的站点不是’http://www.applevb.com/’的话,程序会提示:’你不可以浏览其它站点’并强行转到http://www.applevb.com。
很多的软件,象“护花使者”以及“3721”一类的中文网址”都是利用上面的原理来实现对IE浏览器事件响应的,例如3721,当用户输入一个中文词并浏览时,COM组件可以在BeforeNavigate2 事件中编写代码访问服务器并转到正确的站点上去。
以上程序在Win2K、Delphi 5下编写 Win98、Win2K下编辑通过,如果大家需要源程序或者对于COM编程需要有什么的指教的话,欢迎到我的主页 http://www.applevb.com 访问,我愿意同大家一起探讨。
http://www.euromind.com/iedelphi/
里面都是关于Delphi的IE扩展编程的。
unit MA;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
OleCtrls, SHDocVw, StdCtrls, Psock, ComObj;type
TForm1 = class(TForm)
WB1: TWebBrowser;
b1: TButton;
urltext: TEdit;
listurl: TEdit;
Memo1: TMemo; procedure b1Click(Sender: TObject);
procedure WB1DocumentComplete(Sender: TObject;
const pDisp: IDispatch; var URL: OleVariant); private
{ Private declarations }
public
{ Public declarations }
end;{ IPersistStream interface }{$EXTERNALSYM IPersistStream}
IPersistStream = interface(IPersist)
['{00000109-0000-0000-C000-000000000046}']
function IsDirty: HResult; stdcall;function Load(const stm: IStream): HResult; stdcall;
// 从流中载入
function Save(const stm: IStream;
fClearDirty: BOOL): HResult; stdcall;
// 保存到流
function GetSizeMax(out cbSize: Largeint):
HResult; stdcall; // 取得保存所需空间大小
end;{ IPersistStreamInit interface }{$EXTERNALSYM IPersistStreamInit}
IPersistStreamInit = interface(IPersistStream)
['{7FD52380-4E07-101B-AE2D-08002B2EC713}']
function InitNew: HResult; stdcall; // 初始化
end;
var
Form1: TForm1;implementation{$R *.DFM}
function GetHtml(const WebBrowser:
TWebBrowser): string;
const
BufSize = $10000;
var
Size: Int64;
Stream: IStream;
hHTMLText: HGLOBAL;
psi: IPersistStreamInit;
begin
if not Assigned(WebBrowser.Document) then Exit;OleCheck(WebBrowser.Document.QueryInterface
(IPersistStreamInit, psi));
try
//OleCheck(psi.GetSizeMax(Size));
hHTMLText := GlobalAlloc(GPTR, BufSize);
if 0 = hHTMLText then RaiseLastWin32Error;OleCheck(CreateStreamOnHGlobal(hHTMLText,
True, Stream));
try
OleCheck(psi.Save(Stream, False));Size := StrLen(PChar(hHTMLText));
SetLength(Result, Size);
CopyMemory(PChar(Result), Pointer(hHTMLText),
Size);
finally
Stream := nil;
end;
finally
psi := nil;
end;
end;procedure TForm1.b1Click(Sender: TObject);
begin
WB1.Navigate(urltext.text);
end;procedure TForm1.WB1DocumentComplete(Sender: TObject;
const pDisp: IDispatch; var URL: OleVariant);
var
p:Ansistring;beginp:=WB1.LocationURL;
listurl.text:=p;
Memo1.text:=GetHtml(Wb1);end;
end.
如何在程序中取得多frame的每个Frame中的内容
单个Frame的页面可用
wb_DataInfo.OleObject.document.documentelement.innerhtml;
wb_DataInfo.OleObject.document.documentelement.innerText;
WebBrowser1.oleobject.document.links.item(i).href
等取得内容或联接,但如果是多Frame,则只能得到主页面的内容,如何取得Frames的数量及每个Frame的内容?
不知你是取TEXT还是HTML不过没关系全可以实现。
当页面下载到浏览器中以后,
procedure TForm1.BitBtn1Click(Sender: TObject);
var
i,j:integer;
begin
memo1.Clear;
i:=webbrowser1.oleobject.document.documentelement.document.frames.length;//得到frame的数量。
memo1.Lines.Add('have Frames: '+inttostr(i));
for j:=0 to i-1 do
begin
memo1.lines.add('');
memo1.Lines.Add('Frame '+inttostr(j+1)+' from here');
memo1.Lines.Add(webbrowser1.oleobject.document.
documentelement.document.frames.item(j).document.
documentelement.innerHtml);//取得每个Frame中的HTML内容
end;
end;
IE的历史记录保存为文件格式,如何获得这些文件的建立时间和访问次数?首先在uses部分包括WinInet单元,你会发现里面有这样一个函数:
function GetUrlCacheEntryInfo(lpszUrlName: PAnsiChar;
var lpCacheEntryInfo: TInternetCacheEntryInfo;
var lpdwCacheEntryInfoBufferSize: DWORD): BOOL; stdcall;
但这种声明方式不易使用(你可以试一下),但可以改成如下声明:
function MyGetUrlCacheEntryInfo(lpszUrlName: PAnsiChar;
lpCacheEntryInfo: PInternetCacheEntryInfo;
lpdwCacheEntryInfoBufferSize: PDWORD): BOOL; stdcall; external 'wininet.dll' name 'GetUrlCacheEntryInfoA';下面是一个简单的范例,希望能对你有所帮助。procedure ShowCacheInfo;
var
dwCacheEntryInfoBufferSize: DWORD;
lpCacheEntryInfo: PInternetCacheEntryInfo;
begin
//第一次调用,返回需要的字节数在dwCacheEntryInfoBufferSize中
dwCacheEntryInfoBufferSize := 0;
MyGetUrlCacheEntryInfo('http://www.scmp.net/', lpCacheEntryInfo,
@dwCacheEntryInfoBufferSize); //由第一次调用得到的返回值,分配足够的内存空间,然后第二次调用
GetMem(lpCacheEntryInfo, dwCacheEntryInfoBufferSize);
try
//如果调用成功,返回的信息在lpCacheEntryInfo中
if MyGetUrlCacheEntryInfo('http://www.scmp.net/', lpCacheEntryInfo,
@dwCacheEntryInfoBufferSize) then
begin
//lpCacheEntryInfo是指向INTERNET_CACHE_ENTRY_INFOA结构的指针,参考WinInet
//单元内INTERNET_CACHE_ENTRY_INFOA结构的定义,那里面有你想要的一切,下面将
//显示点击次数。
ShowMessage(IntToStr(lpCacheEntryInfo.dwHitRate));
end;
finally
freemem(lpCacheEntryInfo);
end;
end;end.请问如何获得ie中历史的信息用IUrlHistoryStd2 接口可以实现,在VC的文档中没有这个接口的描述,不过你可以取看VC的源程序和头文件。 如下面是在记录中添加50条 IUrlHistoryStg2* pUrlHistoryStg2 = NULL;
HRESULT hr = CoCreateInstance(CLSID_CUrlHistory,
NULL, CLSCTX_INPROC, IID_IUrlHistoryStg2,
(void**)&pUrlHistoryStg2);
if (SUCCEEDED(hr))
{
char a[200];
char b[200];
strcpy(a,"www.csdn.net");
strcpy(b,"test");
hr=pUrlHistoryStg2->AddUrl((LPCOLESTR)(&a),(LPCOLESTR)(&b),0);
pUrlHistoryStg2->Release();
type
TSTATURL = record
cbSize: DWORD;
pwcsUrl: DWORD;
pwcsTitle: DWORD;
ftLastVisited: FILETIME;
ftLastUpdated: FILETIME;
ftExpires: FILETIME;
dwFlags: DWORD;
end;type
IEnumSTATURL = interface(IUnknown)
['{3C374A42-BAE4-11CF-BF7D-00AA006946EE}']
function Next(celt: Integer; out elt; pceltFetched: PLongint): HRESULT; stdcall;
function Skip(celt: Longint): HRESULT; stdcall;
function Reset: HResult; stdcall;
function Clone(out ppenum: IEnumSTATURL): HResult; stdcall;
function SetFilter(poszFilter: PWideChar; dwFlags: DWORD): HResult; stdcall;
end;type
IUrlHistoryStg = interface(IUnknown)
['{3C374A41-BAE4-11CF-BF7D-00AA006946EE}']
function AddUrl(pocsUrl: PWideChar; pocsTitle: PWideChar; dwFlags: Integer): HResult; stdcall;
function DeleteUrl(pocsUrl: PWideChar; dwFlags: Integer): HResult; stdcall;
function QueryUrl(pocsUrl: PWideChar; dwFlags: Integer; var lpSTATURL: TSTATURL): HResult; stdcall;
function BindToObject(pocsUrl: PWideChar; var riid: TGUID; out ppvOut: Pointer): HResult; stdcall;
function EnumUrls(out ppenum: IEnumSTATURL): HResult; stdcall;
end;type
IUrlHistoryStg2 = interface(IUrlHistoryStg)
['{AFA0DC11-C313-11D0-831A-00C04FD5AE38}']
function AddUrlAndNotify(pocsUrl: PWideChar; pocsTitle: PWideChar; dwFlags: Integer;
fWriteHistory: Integer; var poctNotify: Pointer;
const punkISFolder: IUnknown): HResult; stdcall;
function ClearHistory: HResult; stdcall;
end;function ClearIEHistory:integer;
const
CLSID_CUrlHistory: TGUID = '{3C374A40-BAE4-11CF-BF7D-00AA006946EE}';
var
IEHistory:IUrlHistoryStg2;
begin
IEHistory:=CreateComObject(CLSID_CUrlHistory) as IUrlHistoryStg2;
IEHistory.ClearHistory;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
ClearIEHistory;
end;
**********************
uses wininet;procedure TForm1.Button1Click(Sender: TObject);
var
cache_info:PInternetCacheEntryInfo;
cbSizeOf_Cache_info:dword;
hw:hwnd;
buf:tstrings;
begin
// buf:=tstringlist.Create;
new(cache_info);
hw:=FindFirstUrlCacheEntryEx(nil,0,NORMAL_CACHE_ENTRY or URLHISTORY_CACHE_ENTRY,0,cache_info,@cbSizeOf_Cache_info,nil,nil,nil);
if hw<>0 then
begin
DeleteUrlCacheEntry(cache_info.lpszSourceUrlName);
// buf.Add(cache_info.lpszSourceUrlName);
while FindNextUrlCacheEntryEx(hw,cache_info,@cbSizeOf_Cache_info,nil,nil,nil) do
// buf.Add(cache_info.lpszSourceUrlName);
DeleteUrlCacheEntry(cache_info.lpszSourceUrlName);
end;
FindCloseUrlCache(hw);
dispose(cache_info);
// showmessage(buf.Text);
// buf.Free;
Document.Body.InnerHTML不行的,根据没有body属性。