由于客户需要,WebBrowser动态更改里面的html内容后,本来的网址 比如 http://www.qq.com ,
在更改源码后,WebBrowser的当前页面的url 变成了 about:blank 了。
我现在需要的 更改 WebBrowser 里的内容后 原来的页面 url 不要发生变化。
请问各位有什么好的方法么?
在更改源码后,WebBrowser的当前页面的url 变成了 about:blank 了。
我现在需要的 更改 WebBrowser 里的内容后 原来的页面 url 不要发生变化。
请问各位有什么好的方法么?
没有效果,使用截取数据流的方式 更改了 源码后,测试当前页面的 url 还是 about:blank
用protocol协议应该可以解决楼主的问题.
应该不是吧.
如果是防篡改,就该不允许直接修改内容.修改后的内容是无法再回写到原网页上让其他人看到的.
我觉得可能是因为装载来源的原因.因为修改了源,它就不再是指向XXX.COM了,那是指向哪里呢?因为是直接修改的流,MS又搞不清,所以就当它是BLANK了.
如果我的猜测是对的,用protocol应该是可以的.
如何用protocol?能举一个例子么?
分不够可再加,谢谢。不过我觉的 更改流的方式不是 在数据流返回的过程中修改的,而是在数据返回后再使用流的方式修改。
所以问题就出在这里。
如果能够在数据没返回前,就直接修改流中的内容,应该行,但这可能涉及到网络封包了,不知道大家有什么好的方法。谢谢
Protocols我以前用过,但你的要求现在没有测试,只是认为应该可以.
------------------------------------------------------------------------
用IE支持的Asynchronous Pluggable Protocols实现直接从数据库取得信息显示在WebBrowser中作者 : xianjun
标题 : 用IE支持的Asynchronous Pluggable Protocols实现直接从数据库取得信息显示在WebBrowser中
关键字: WebBrowser 数据库 Asynchronous Pluggable Protocols
分类 : 开发技巧
密级 : 公开
(评分: , 回复: 1, 阅读: 128) »»
实现了下面两个组件: TWebShower 及 TDBWebShower
后者可实现WebBrowser直接显示数据库中的html,图片等信息而不用生成临时文件。
完整的代码及示例可从 http://xianjun.vicp.net/ 下载 WebShower.rar
下面是组件的全部源代码:
{***************************************************************
*
* Project Name: XJGTest -- WebShower
* Typist: XJG([email protected])
* Purpose: 手工载入数据到WebBrowser
* http://msdn.microsoft.com/library/default.asp?url=/workshop/networking/pluggable/pluggable.asp
* Comment Time: 2003-5-3 11:54:50
* History: Create by xjg. 2003-5-3 11:54:50
*
****************************************************************}unit WebShower;interfaceuses
Classes, Windows, SysUtils, ActiveX, UrlMon;type
TGetStreamEvent = procedure(const AUrl, AFile: string; const AStream: TMemoryStream;
var AHandled: Boolean) of object;
TWebShower = class(TComponent, IInternetProtocol)
private
{ Private declarations }
Factory: IClassFactory;
InternetSession: IInternetSession;
FNameSpace: string;
FActive: Boolean;
FOnGetStream: TGetStreamEvent;
procedure SetNameSpace(const Value: string);
procedure SetActive(const Value: Boolean);
private
FUrl: string;
Written, TotalSize: Integer;
ProtSink: IInternetProtocolSink;
DataStream: IStream;
function GetDataStream(var DataStream: IStream): Integer;
protected
// IInternetProtocol Methods
function Start(szUrl: PWideChar; OIProtSink: IInternetProtocolSink;
OIBindInfo: IInternetBindInfo; grfPI, dwReserved: DWORD): HRESULT; stdcall;
function Continue(const ProtocolData: TProtocolData): HRESULT; stdcall;
function Abort(hrReason: HRESULT; dwOptions: DWORD): HRESULT; stdcall;
function Terminate(dwOptions: DWORD): HRESULT; stdcall;
function Suspend: HRESULT; stdcall;
function Resume: HRESULT; stdcall;
function Read(pv: Pointer; cb: ULONG; out cbRead: ULONG): HRESULT; stdcall;
function Seek(dlibMove: LARGE_INTEGER; dwOrigin: DWORD;
out libNewPosition: ULARGE_INTEGER): HRESULT; stdcall;
function LockRequest(dwOptions: DWORD): HRESULT; stdcall;
function UnlockRequest: HRESULT; stdcall;
protected
procedure GetWebContent(const AUrl, AFile: string; const AStream: TMemoryStream); virtual;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
published
property Active: Boolean read FActive write SetActive;
property NameSpace: string read FNameSpace write SetNameSpace;
property OnGetStream: TGetStreamEvent read FOnGetStream write FOnGetStream;
end; TWebShowerClass = class of TWebShower;var
G_WSClass: TWebShowerClass = TWebShower;implementationuses
AxCtrls, ComObj, ComServ;const
IID_NSHandler: TGUID = '{A562A5BC-F3C8-4968-8FA8-996B45223990}';var
G_WebShower: TWebShower;type
TNSHandler = class(TComObject, IInternetProtocol)
private
FWebShower: TWebShower;
protected
// IInternetProtocol Methods
function Start(szUrl: PWideChar; OIProtSink: IInternetProtocolSink;
OIBindInfo: IInternetBindInfo; grfPI, dwReserved: DWORD): HRESULT; stdcall;
function Continue(const ProtocolData: TProtocolData): HRESULT; stdcall;
function Abort(hrReason: HRESULT; dwOptions: DWORD): HRESULT; stdcall;
function Terminate(dwOptions: DWORD): HRESULT; stdcall;
function Suspend: HRESULT; stdcall;
function Resume: HRESULT; stdcall;
function Read(pv: Pointer; cb: ULONG; out cbRead: ULONG): HRESULT; stdcall;
function Seek(dlibMove: LARGE_INTEGER; dwOrigin: DWORD;
out libNewPosition: ULARGE_INTEGER): HRESULT; stdcall;
function LockRequest(dwOptions: DWORD): HRESULT; stdcall;
function UnlockRequest: HRESULT; stdcall;
public
destructor Destroy; override;
procedure Initialize; override;
end; { TNSHandler }function TNSHandler.Start(szUrl: PWideChar; OIProtSink: IInternetProtocolSink;
OIBindInfo: IInternetBindInfo; grfPI, dwReserved: DWORD): HRESULT; stdcall;
begin
Result := FWebShower.Start(szUrl, OIProtSink, OIBindInfo, grfPI, dwReserved);
end;function TNSHandler.Read(pv: Pointer; cb: ULONG; out cbRead: ULONG): HRESULT;
begin
Result := FWebShower.Read(pv, cb, cbRead);
end;function TNSHandler.Terminate(dwOptions: DWORD): HRESULT; stdcall;
begin
Result := FWebShower.Terminate(dwOptions);
end;function TNSHandler.LockRequest(dwOptions: DWORD): HRESULT; stdcall;
begin
Result := FWebShower.LockRequest(dwOptions);
end;function TNSHandler.UnlockRequest: HRESULT;
begin
Result := FWebShower.UnlockRequest;
end;function TNSHandler.Continue(const ProtocolData: TProtocolData): HRESULT;
begin
Result := FWebShower.Continue(ProtocolData);
end;function TNSHandler.Abort(hrReason: HRESULT; dwOptions: DWORD): HRESULT; stdcall;
begin
Result := FWebShower.Abort(hrReason, dwOptions);
end;function TNSHandler.Suspend: HRESULT; stdcall;
begin
Result := FWebShower.Suspend;
end;function TNSHandler.Resume: HRESULT; stdcall;
begin
Result := FWebShower.Resume;
end;function TNSHandler.Seek(dlibMove: LARGE_INTEGER; dwOrigin: DWORD;
out libNewPosition: ULARGE_INTEGER): HRESULT;
begin
Result := FWebShower.Seek(dlibMove, dwOrigin, libNewPosition);
end;destructor TNSHandler.Destroy;
begin
FWebShower.Free;
inherited;
end;procedure TNSHandler.Initialize;
begin
inherited;
FWebShower := G_WSClass.Create(nil);
FWebShower.Assign(G_WebShower);
end;{ TWebShower }function TWebShower.Abort(hrReason: HRESULT; dwOptions: DWORD): HRESULT;
begin
Result := E_NOTIMPL;
end;procedure TWebShower.Assign(Source: TPersistent);
begin
if Source is TWebShower then
begin
with TWebShower(Source) do
begin
Self.NameSpace := NameSpace;
Self.OnGetStream := OnGetStream;
end;
end
else
inherited;
end;
begin
Result := S_OK;
end;constructor TWebShower.Create(AOwner: TComponent);
begin
inherited;
FNameSpace := 'test';
if G_WebShower = nil then
G_WebShower := Self;
end;destructor TWebShower.Destroy;
begin
if Active then
Active := False;
if G_WebShower = Self then
G_WebShower := nil;
inherited;
end;function TWebShower.GetDataStream(var DataStream: IStream): Integer;
var
F: TMemoryStream;
Dummy: Int64;
AFileName, AErrorMsg: string;
AHandled: Boolean;
begin
F := TMemoryStream.Create;
try
try
AFileName := Copy(FUrl, Pos(FNameSpace, FUrl) + Length(FNameSpace) + 1, Length(FUrl));
AHandled := False;
if Assigned(FOnGetStream) then
FOnGetStream(FUrl, AFileName, F, AHandled);
if not AHandled then
GetWebContent(FUrl, AFileName, F);
except
on E: Exception do
begin
AErrorMsg := Format('<html><body><font style="font-size:11pt;color:red;bold">%s</font></body></html>',
[E.Message]);
F.Size := Length(AErrorMsg);
Move(Pointer(AErrorMsg)^, F.Memory^, F.Size);
end;
end;
CreateStreamOnHGlobal(0, True, DataStream);
F.Position := 0;
TOleStream.Create(DataStream).CopyFrom(F, F.Size);
DataStream.Seek(0, STREAM_SEEK_SET, Dummy);
Result := F.Size;
finally
F.Free;
end;
end;procedure TWebShower.GetWebContent(const AUrl, AFile: string;
const AStream: TMemoryStream);
begin
//
end;function TWebShower.LockRequest(dwOptions: DWORD): HRESULT;
begin
Result := S_OK;
end;function TWebShower.Read(pv: Pointer; cb: ULONG;
out cbRead: ULONG): HRESULT;
begin
if (totalSize = 0) or (DataStream = nil) then
begin
Result := S_FALSE;
Exit;
end;
{Read Data from DataStream to Browser/URLMON }
DataStream.Read(pv, cb, @cbRead);
Inc(written, cbRead);
if (written = totalSize) then
Result := S_FALSE
else
Result := HRESULT(E_PENDING);
end;function TWebShower.Resume: HRESULT;
begin
Result := E_NOTIMPL;
end;function TWebShower.Seek(dlibMove: LARGE_INTEGER; dwOrigin: DWORD;
out libNewPosition: ULARGE_INTEGER): HRESULT;
begin
Result := E_NOTIMPL;
end;procedure TWebShower.SetActive(const Value: Boolean);
begin
if FActive <> Value then
begin
if Value then
begin
CoGetClassObject(IID_NSHandler, CLSCTX_SERVER, nil, IClassFactory, Factory);
CoInternetGetSession(0, InternetSession, 0);
InternetSession.RegisterNameSpace(Factory, IID_NSHandler, 'http', 0, nil, 0);
end
else
InternetSession.UnregisterNameSpace(Factory, 'http');
FActive := Value;
end;
end;procedure TWebShower.SetNameSpace(const Value: string);
begin
FNameSpace := Value;
end;function TWebShower.Start(szUrl: PWideChar;
OIProtSink: IInternetProtocolSink; OIBindInfo: IInternetBindInfo; grfPI,
dwReserved: DWORD): HRESULT;
begin
if Pos(Format('http://%s/', [LowerCase(FNameSpace)]), szUrl) <> 1 then
Result := INET_E_USE_DEFAULT_PROTOCOLHANDLER
else
begin
FUrl := SzUrl;
written := 0;
ProtSink := OIProtSink; //Get interface to Transaction handlers IInternetnetProtocolSink
{ Now get the data and load it in DataStream }
TotalSize := GetDataStream(DataStream);
{Inform Transaction handler that all data is ready }
ProtSink.ReportData(BSCF_FIRSTDATANOTIFICATION or
BSCF_LASTDATANOTIFICATION or BSCF_DATAFULLYAVAILABLE, TotalSize, TotalSize);
{ -> Here our Read Method is called by transaction handler}
ProtSink.ReportResult(S_OK, S_OK, nil);
{ Report result to transaction handler. Our Terminate method will be called }
Result := S_OK;
end;
end;function TWebShower.Suspend: HRESULT;
begin
Result := E_NOTIMPL;
end;function TWebShower.Terminate(dwOptions: DWORD): HRESULT;
begin
if Assigned(DataStream) then
DataStream._Release;
if Assigned(Protsink) then
Protsink._Release;
Result := S_OK;
end;function TWebShower.UnlockRequest: HRESULT;
begin
Result := S_OK;
end;initialization
TComObjectFactory.Create(ComServer, TNSHandler, IID_NSHandler,
'NSHandler', 'NSHandler', ciMultiInstance, tmApartment);end.
{***************************************************************
*
* Project Name: XJGTest -- DBWebShower
* Typist: XJG([email protected])
* Purpose: 从数据库中载入数据到WebBrowser
* Comment Time: 2003-5-3 14:25:17
* History: Create by xjg. 2003-5-3 14:25:17
*
****************************************************************}unit DBWebShower;interfaceuses
SysUtils, Classes, DB, WebShower;type
TDBWebShower = class(TWebShower)
private
FDataSource: TDataSource;
FFileNameField: string;
FFileContentField: string;
procedure SetDataSource(const Value: TDataSource);
function PropertyIsReady: Boolean;
procedure GetRecordContent(const AName: string; const AStream: TMemoryStream);
procedure SetFileContentField(const Value: string);
procedure SetFileNameField(const Value: string);
protected
procedure GetWebContent(const AUrl, AFile: string; const AStream: TMemoryStream); override;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
procedure Assign(Source: TPersistent); override;
published
property DataSource: TDataSource read FDataSource write SetDataSource;
property FileNameField: string read FFileNameField write SetFileNameField;
property FileContentField: string read FFileContentField write SetFileContentField;
end;implementation{ TDBWebShower }procedure TDBWebShower.Assign(Source: TPersistent);
begin
if Source is TDBWebShower then
begin
inherited;
with TDBWebShower(Source) do
begin
Self.DataSource := DataSource;
Self.FileNameField := FileNameField;
Self.FileContentField := FileContentField;
end;
end
else
inherited;
end;constructor TDBWebShower.Create(AOwner: TComponent);
begin
inherited;
G_WSClass := TDBWebShower;
end;procedure TDBWebShower.GetRecordContent(const AName: string;
const AStream: TMemoryStream);
begin
with FDataSource.DataSet do
begin
if Locate(FileNameField, AName, [loCaseInsensitive]) then
TBlobField(FieldByName(FileContentField)).SaveToStream(AStream);
end;
end;procedure TDBWebShower.GetWebContent(const AUrl, AFile: string;
const AStream: TMemoryStream);
begin
if PropertyIsReady then
GetRecordContent(AFile, AStream);
end;procedure TDBWebShower.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited;
if Operation = opRemove then
if AComponent = FDataSource then
FDataSource := nil;
end;function TDBWebShower.PropertyIsReady: Boolean;
begin
Result := Assigned(FDataSource) and Assigned(FDataSource.DataSet) and
FDataSource.DataSet.Active;
end;procedure TDBWebShower.SetDataSource(const Value: TDataSource);
begin
if FDataSource <> Value then
begin
FDataSource := Value;
if Assigned(Value) then
Value.FreeNotification(Self);
end;
end;procedure TDBWebShower.SetFileContentField(const Value: string);
begin
FFileContentField := Value;
end;procedure TDBWebShower.SetFileNameField(const Value: string);
begin
FFileNameField := Value;
end;end.
我需要的是 在我访问了一个页面 如 www.163.com 后,更改/截取HTML源码后,webbrowser的页面属性 不要变成 blank,还保留 www.163.com 的效果,
我看了 Asynchronous Pluggable Protocols 实现直接从数据库取得信息显示在WebBrowser中 ,好像也不能指定 我需要的的 url 不变的特征。
哎,难啊,思路方向错了?
但http://www.163.com这样的形式,在网络上是解析到一个页面,protocols能不能,我就不清楚了.
你也可以用HTML文档的IPersistMoniker从你自己的IMoniker实现载入数据。你需要模拟一个URL的IMoniker实现。关于URL Moniker,参考http://msdn.microsoft.com/en-us/library/aa741006(VS.85).aspx。