請問如何由Stream填入資料給TWebBrowser?(100分)

  • 主题发起人 主题发起人 ktleemas
  • 开始时间 开始时间
K

ktleemas

Unregistered / Unconfirmed
GUEST, unregistred user!
請問如何由Stream填入資料給TWebBrowser?
請教各位大俠,小生有一WebBrowser的使用問題求助!
如何將.HTML/.JPG...等多個流覽文件,不要透過產生實體檔案的方式填入WebBrowser中,
我的目的是希望將一些網頁文件(可能為多個HTML與多個JPG關聯圖檔),
直接填入webbrowser中,如此才不會被解出html檔!
小生已知道如何填入單一個html格式的Stream給WebBrowser,但若此Html格式中有引用其它的
JPG/或是連結至其HTML文件時,WebBrowser如何填入?
謝謝各位高手賜教!
 
procedure SetHtml(const WebBrowser:
TWebBrowser; const Html: string);
var
Stream: IStream;
hHTMLText: HGLOBAL;
psi: IPersistStreamInit;
begin
if not Assigned(WebBrowser.Document) then Exit;

hHTMLText := GlobalAlloc(GPTR, Length(Html) + 1);
if 0 = hHTMLText then RaiseLastWin32Error;

CopyMemory(Pointer(hHTMLText),
PChar(Html), Length(Html));

OleCheck(CreateStreamOnHGlobal
(hHTMLText, True, Stream));
try
OleCheck(WebBrowser.Document.
QueryInterface(IPersistStreamInit, psi));
try
OleCheck(psi.InitNew);
OleCheck(psi.Load(Stream));
finally
psi := nil;
end;
finally
Stream := nil;
end;
end;
 
謝謝您的回答,但這不是我要的,
我要的是,比如:index.html檔內容如下
this is a test.
<img src="test.jpg">
另有一圖檔test.jpg
這兩個檔都是存在資料庫中的欄位,
我是想透過stream的方式將這兩個檔傳給webbrowser,
但是不要在硬盤上產生實際的檔案,
是為了保密這兩個文件不被拷貝出來,但又可以用webbrowser看的!
謝謝各位先進指教!


 
算你运气好,我刚刚完成一套制作这类应用的工具,可以用来编制这样的应用。
从本质上来说,这类应用就是模拟webserver,要是你想简单,用Delphi6里面自带的Indy
做一个真的WebServer,就能达到你的要求,不过可能会引起端口冲突,而且程序体积太
大,这叫杀鸡用牛刀。好处就是可以享受可视化编程的快乐,调试也较为简单。至于保密
功能就说不上,原则上只要Webbrowser能看到的东西,就能被保存下来。
如果你不愿意这么干,只好在协议上面下点功夫了。ie是通过urlmon.dll来和数据打交道
urlmon负责将url地址指定的资料传回ie(或者其他需要用到url的程序),只要让urlmon
将资料重新定向到自己的内容,就能够实现这个功能。
urlmon是通过协议这一级别来区分url,并调用相应的功能传输资料的。常用协议有http
https、file、about、res等等。你可以自定义协议,或重载常用的协议都可以,从win98
开始urlmon就支持自定义协议扩展。
说了一大堆,是希望你能够明白这种应用的原理。编程方面不是特别困难,如果你熟悉
com编程,一个下午就可以写出满足你上面需要的应用来。
你所需要做的工作仅仅就是实现一个IInternetProtocol,有关IInternetProtocol的内容
请参阅msdn,我在这里就不多说了。源代码篇幅太长,也不好贴在这里。
 
謝謝jojo的指導,
我也曾看過類似的軟體也是自創協定它是將網址連結給為
internal:index.html
可否請jojo大俠在給小生一些相關資料的網頁網址,
謝謝您!
 
相信已经各位搞定了.
下面是一段例程(摘自: http://www.nssoft.net/showdoc.asp?did=440 )
给那些还在找解决此类问题的人:
想用 WEBbrowser 显示一些内容, 这些内容不是来自固定文件或资源, 可能是需从数据库里读取图片或其它信息. 也就可以用这种自定义的 InternetProtocol 来完成.(废话不多说,看例子吧! 有问题请 Email: gear1023@163.com )

-------------------------------------------------------------------------------
这是源程序,我自己测试了一下,OK!
-------------------------------------------------------------------------------
unit DynamicNS_D3;

{
[yellow]
Dynamic Protocol For Delphi 3 or High.

--------------------------------------------

Create Time : 2001.12.6
Update Time : 2002.7.9
Version : Release 3
Author : JoJo

--------------------------------------------
Copyright 1996-2001 Think Space Soft
--------------------------------------------

Note : If use in Delphi 3, you must update urlmon unit.[/yellow]
}

interface

uses

Classes, Windows, Forms, Axctrls, dialogs, SysUtils, ComObj, ActiveX, UrlMon;

const

Class_DynamicNS: TGUID = '{C379EAD1-CB34-4B09-AF6B-7E587F8BCD80}';

type

TDynamicNS = class(TComObject, IInternetProtocol)
private
Url: string;
HaveData : Boolean;
Written, TotalSize: Integer;
ProtSink: IInternetProtocolSink;
DataStream: IStream;

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;

//Load Data Function
function LoadData(URL:String):Boolean;

end;

TAcceptEvent = procedure (const URL:String;var Accept:Boolean) of object;
TContentEvent = procedure (const URL:String;var Stream:TStream) of object;

TDynamicProtocol = class(TObject)
private

Factory: IClassFactory;
InternetSession: IInternetSession;
FOnAccept : TAcceptEvent;
FOnGetContent : TContentEvent;
FProtocolName : String;
FEnabled : Boolean;

function GetProtocolName : String;
procedure SetProtocolName(const Value:String);
function GetEnabled : Boolean;
procedure SetEnabled(const Value:Boolean);
procedure StartProtocol;
procedure StopProtocol;
protected

function Accept(const URL:String):Boolean;
function LoadContent(const URL:String):TStream;

public

constructor Create;
destructor Destroy; override;
property ProtocolName : String read GetProtocolName write SetProtocolName;
property Enabled : Boolean read GetEnabled write SetEnabled;
property OnAccept : TAcceptEvent read FOnAccept write FOnAccept;
property OnGetContent : TContentEvent read FOnGetContent write FOnGetContent;

end;

var
DynamicProtocol : TDynamicProtocol;

implementation

uses

comserv;

function TDynamicNS.Start(szUrl: PWideChar; OIProtSink: IInternetProtocolSink;
OIBindInfo: IInternetBindInfo; grfPI, dwReserved: DWORD): HResult; stdcall;
begin
Url := SzUrl;
written := 0;
HaveData := False;
// ShowMessage(URL);
//Load data here
if not LoadData(URL) then Result := S_FALSE else begin
HaveData := True;
ProtSink := OIProtSink;
ProtSink.ReportData(BSCF_FIRSTDATANOTIFICATION or
BSCF_LASTDATANOTIFICATION or BSCF_DATAFULLYAVAILABLE, TotalSize, TotalSize);
ProtSink.ReportResult(S_OK, S_OK, nil);
Result := S_OK;
end;
end;

function TDynamicNS.Read(pv: Pointer; cb: ULONG; out cbRead: ULONG): HResult;
begin
DataStream.Read(pv, cb, @cbRead);
Inc(written, cbread);
if (written = totalSize) then result := S_FALSE else Result := E_PENDING;
end;

function TDynamicNS.Terminate(dwOptions: DWORD): HResult; stdcall;
begin
if HaveData then
begin
DataStream._Release;
Protsink._Release;
end;

result := S_OK;
end;

function TDynamicNS.LockRequest(dwOptions: DWORD): HResult; stdcall;
begin
result := S_OK;
end;

function TDynamicNS.UnlockRequest: HResult;
begin
result := S_OK;
end;

function TDynamicNS.Continue(const ProtocolData: TProtocolData): HResult;
begin
result := S_OK;
end;

function TDynamicNS.Abort(hrReason: HResult; dwOptions: DWORD): HResult; stdcall;
begin
result := E_NOTIMPL;
end;

function TDynamicNS.Suspend: HResult; stdcall;
begin
result := E_NOTIMPL;
end;

function TDynamicNS.Resume: HResult; stdcall;
begin
result := E_NOTIMPL;
end;

function TDynamicNS.Seek(dlibMove: LARGE_INTEGER; dwOrigin: DWORD;
out libNewPosition: ULARGE_INTEGER): HResult;
begin
result := E_NOTIMPL;
end;

function TDynamicNS.LoadData(URL:String): Boolean;
var
F:TStream;
Dummy: LONGLONG;
begin
Result := False;

if Assigned(DynamicProtocol) then

begin
Result := DynamicProtocol.Accept(URL);
if Result then
begin

F := DynamicProtocol.LoadContent(URL);
CreateStreamOnHGlobal(0, True, DataStream);
TOleStream.Create(DataStream).CopyFrom(F, F.Size);
DataStream.Seek(0, STREAM_SEEK_SET, Dummy);
TotalSize := F.Size;
F.Free;
end;
end;

end;

{ TDynamicProtocol }

function TDynamicProtocol.Accept(const URL: String): Boolean;
begin
Result := False;
if Assigned(FOnAccept) then
FOnAccept(URL,Result);
end;

constructor TDynamicProtocol.Create;
begin
inherited;
FEnabled := False;
FProtocolName := 'local';
end;

destructor TDynamicProtocol.Destroy;
begin
if FEnabled then
StopProtocol;
inherited;
end;

function TDynamicProtocol.GetEnabled: Boolean;
begin
Result := FEnabled;
end;

function TDynamicProtocol.GetProtocolName: String;
begin
Result := FProtocolName;
end;

function TDynamicProtocol.LoadContent(const URL: String):TStream;
begin

//²»¿ÉÒÔ·µ»Ø¿ÕµÄÁ÷

if Assigned(FOnGetContent) then
begin
Result := TStringStream.Create('');
FOnGetContent(URL,Result);
Result.Position :=0;
if Result.Size = 0 then
(Result as TStringStream).WriteString(Format('<html><body><h3>Load %s Error.</h3></body></html>',)); end else Result := TS... wb.Navigate('myhttp://hello'); end; end.
 

Similar threads

I
回复
0
查看
656
import
I
I
回复
0
查看
800
import
I
I
回复
0
查看
618
import
I
I
回复
0
查看
747
import
I
后退
顶部