Discussion:
Using TWebBrowser - loading HTML script from a TStream
(too old to reply)
Daryl
2008-02-12 20:24:21 UTC
Permalink
Hi
I found this code in a post, Could someone convert this Delphi code to C++.

The end aim is to load a StringList with HTML script and use the lists
Stream method to load the HTML into the TWebBrowser. I would like to do
this so I do not have to first save the HTML to disk before using the
WebBrowsers' Navigate method. I am hoping this will do it for me - if I am
on the wrong path please let me know.

thanks
daryl


procedure LoadDocFromStream(WB: TWebBrowser; Stream: TStream);
begin
(WB.Document as IPersistStreamInit).Load(
TStreamAdapter.Create(Stream,soReference));
end;
Remy Lebeau (TeamB)
2008-02-12 20:42:54 UTC
Permalink
Post by Daryl
I found this code in a post, Could someone convert this Delphi code to C++.
Please go to http://www.deja.com and search the newsgroup archives. C++
examples have been posted many times before.


Gambit
Daryl
2008-02-12 21:42:27 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Daryl
I found this code in a post, Could someone convert this Delphi code to C++.
Please go to http://www.deja.com and search the newsgroup archives. C++
examples have been posted many times before.
Thanks for the reply,

I have done this, I spent about 2 hours on and off searching for relevant
information on this topic and could not find anything that describes how to
do it in cBuilder. I did find some information for Delphi. I am using what
you pointed me, this was the outcome of another post "Check for Internet
Access, dated 4 Feb 2008" - in this same group

So, I would really need some assistance on this one - ideally I would like
to see it done in Builder. At the least could you identify some previous
post that contain ideas and code to achieve this?

thanks
daryl
Daryl
2008-02-12 21:44:41 UTC
Permalink
Sorry for this post - wrong response to this one. I thought it was
"Handling script errors from TWebBrowser Control.

daryl
Post by Daryl
Thanks for the reply,
I have done this, I spent about 2 hours on and off searching for relevant
information on this topic and could not find anything that describes how
to do it in cBuilder. I did find some information for Delphi. I am using
what you pointed me, this was the outcome of another post "Check for
Internet Access, dated 4 Feb 2008" - in this same group
So, I would really need some assistance on this one - ideally I would like
to see it done in Builder. At the least could you identify some previous
post that contain ideas and code to achieve this?
thanks
daryl
Remy Lebeau (TeamB)
2008-02-12 22:45:54 UTC
Permalink
Post by Daryl
I have done this, I spent about 2 hours on and off searching
for relevant information on this topic and could not find anything
that describes how to do it in cBuilder.
10 seconds to find with the right search criteria:

http://groups.google.com/groups/search?q=IPersistStreamInit+TStreamAdapter+group%3A*cppbuilder*


Gambit
Daryl
2008-02-14 07:16:20 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Daryl
I have done this, I spent about 2 hours on and off searching
for relevant information on this topic and could not find anything
that describes how to do it in cBuilder.
http://groups.google.com/groups/search?q=IPersistStreamInit+TStreamAdapter+group%3A*cppbuilder*
Thanks for the link. I did find some good information, one question is why
is "about:blank" used in the example shown below?

Also, can you help with the related post "Handling script erros from
TWebBrowser control" directly below the original post from me?

daryl

void LoadHtmlFromStream(TCppWebBrowser* pCppWebBrowser,
TMemoryStream* pMemStream)
{
if(pMemStream && pCppWebBrowser)
{
IPersistStreamInit* pPSI;
pMemStream->Seek(0, 0);
if(!pCppWebBrowser->Document)
{
pCppWebBrowser->Navigate(WideString("about:blank"));
while(!pCppWebBrowser->Document)
Application->ProcessMessages();
}
TStreamAdapter* pStreamAdapter = new TStreamAdapter(
pMemStream, soReference);
if(SUCCEEDED(pCppWebBrowser->Document->QueryInterface(
IID_IPersistStreamInit, (LPVOID*)&pPSI)))
pPSI->Load(*pStreamAdapter);
}
}
Jason Cipriani
2008-02-14 07:39:26 UTC
Permalink
Post by Daryl
Thanks for the link. I did find some good information, one question is
why is "about:blank" used in the example shown below?
As a guess, I'd say since you have to Navigate() before Document is not
NULL, and "about:blank" is a really harmless place to navigate to (the
example is kind of a hack; kind of). I guess that's how you keep document
from being NULL; that's the problem I was having when I tried to test that
original code you posted.

But I have a question about that example code; assuming Daryl posted all of
Post by Daryl
if(SUCCEEDED(pCppWebBrowser->Document->QueryInterface(
IID_IPersistStreamInit, (LPVOID*)&pPSI)))
pPSI->Load(*pStreamAdapter);
Do you not have to release the IPersistStreamInit you get here? If not, is
that something to do with VCL wrappers around COM interfaces?

Jason
Remy Lebeau (TeamB)
2008-02-14 18:34:52 UTC
Permalink
Post by Jason Cipriani
Do you not have to release the IPersistStreamInit you get here?
Yes, you do. The code should have been using a TComInterface or
DelphiInterface wrapper class for it to ensure that Release() gets called
automatically.


Gambit
Daryl
2008-02-14 21:13:23 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Jason Cipriani
Do you not have to release the IPersistStreamInit you get here?
Yes, you do. The code should have been using a TComInterface or
DelphiInterface wrapper class for it to ensure that Release() gets called
automatically.
The code I posted was an example from a web site found using your suggested
Google search criteria. Are you saying that there should be an extra step
that releases IPersistStreamInit ? If so what would that statement look
like?

thanks
daryl
Remy Lebeau (TeamB)
2008-02-14 21:31:21 UTC
Permalink
Post by Daryl
The code I posted was an example from a web site found using
your suggested Google search criteria.
Which posting were you looking at exactly?
Post by Daryl
Are you saying that there should be an extra step that releases
IPersistStreamInit ?
Yes.
Post by Daryl
If so what would that statement look like?
If you continue using IPersistStreamInit by itself, then you have to call
Release() yourself:

if(
SUCCEEDED(pCppWebBrowser->Document->QueryInterface(IID_IPersistStreamInit,
(LPVOID*)&pPSI)) )
{
pPSI->Load(*pStreamAdapter);
pPSI->Release(); // <-- add this
}

Otherwise, change the declaration of pPSI from this:

IPersistStreamInit* pPSI;

To this:

TComInterface<IPersistStreamInit> pPSI;

Or this:

DelphiInterface<IPersistStreamInit> pPSI;

Also, you are not freeing the TStreamAdapter object when you are done with
it, so it will be leaked:

if(
SUCCEEDED(pCppWebBrowser->Document->QueryInterface(IID_IPersistStreamInit,
(LPVOID*)&pPSI)) )
{
TStreamAdapter* pStreamAdapter = new TStreamAdapter(pMemStream,
soReference);
//..
delete pStreamAdapter;
}

Or:

TStreamAdapter* pStreamAdapter = new TStreamAdapter(pMemStream,
soReference);
if(
SUCCEEDED(pCppWebBrowser->Document->QueryInterface(IID_IPersistStreamInit,
(LPVOID*)&pPSI)) )
{
pPSI->Load(*pStreamAdapter);
//..
}
delete pStreamAdapter;


Gambit
Daryl
2008-02-14 21:56:34 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Daryl
The code I posted was an example from a web site found using
your suggested Google search criteria.
Which posting were you looking at exactly?
Your response was:
10 seconds to find with the right search criteria:

http://groups.google.com/groups/search?q=IPersistStreamInit+TStreamAdapter+group%3A*cppbuilder*


Gambit


The site with the example code was:
http://www.bytesandmore.de/rad/index.htm C++ Builder Code Snippet
"TCppWebBrowser: HTML-Code aus einem Stream laden" under section "Netzwerke"
Remy Lebeau (TeamB)
2008-02-14 22:48:37 UTC
Permalink
Post by Remy Lebeau (TeamB)
http://groups.google.com/groups/search?q=IPersistStreamInit+TStreamAdapter+group%3A*cppbuilder*
That is the search results page. I was asking which *specific message*
within those results you are looking at for the example code you quoted.


Gambit

Daryl
2008-02-14 22:32:18 UTC
Permalink
Post by Remy Lebeau (TeamB)
Also, you are not freeing the TStreamAdapter object when you are done with
Gambit,
I used the first example to delete pStreamAdapter and it throws an error
back to the calling method. What that error is I don't know yet as I am
using a catch(...) statement. I will have to check it out some more this
afternoon.

Any idea as to why it would cause an error?

BTW - the required web page is still displayed.

thanks for the help
daryl
Post by Remy Lebeau (TeamB)
if(
SUCCEEDED(pCppWebBrowser->Document->QueryInterface(IID_IPersistStreamInit,
(LPVOID*)&pPSI)) )
{
TStreamAdapter* pStreamAdapter = new TStreamAdapter(pMemStream,
soReference);
//..
delete pStreamAdapter;
}
TStreamAdapter* pStreamAdapter = new TStreamAdapter(pMemStream,
soReference);
if(
SUCCEEDED(pCppWebBrowser->Document->QueryInterface(IID_IPersistStreamInit,
(LPVOID*)&pPSI)) )
{
pPSI->Load(*pStreamAdapter);
//..
}
delete pStreamAdapter;
Remy Lebeau (TeamB)
2008-02-14 18:32:48 UTC
Permalink
Post by Daryl
why is "about:blank" used in the example shown below?
The web browser's Document property is not valid to query or load data into
until the browser is first navigated to a page and it fully loads.
Post by Daryl
Also, can you help with the related post "Handling script erros
from TWebBrowser control" directly below the original post from
me?
I already looked into it earlier but have nothing further to offer in that
area right now, sorry.


Gambit
Daryl
2008-02-14 21:27:57 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Daryl
Also, can you help with the related post "Handling script erros
from TWebBrowser control" directly below the original post from
me?
I already looked into it earlier but have nothing further to offer in that
area right now, sorry.
Thanks Gambit for that feedback.

Would it be possible for you to expand the steps outlined by Mark in my
recent post mentioned above i.e. "Handling script erros from TWebBrowser
control" in this same group?.

I ask this because I don't fully understand Packages or the Delphi
language - more than willing to listen and learn. I don't mind fumbling
around, but I would like some extra information / assistance on how to get
started. It appears that with some extra pointers a modified TWebBrowser
could be developed in Delphi to do the job. I have a Delphi compiler
(BDS2006) but I have not used it - except the other night when I tried to
create the modified TOleControl Mark's mentions in his Step 2. Step 3 I do
not fully understand - does Mark mean to modify the contents of
ShDocVw_OCX.cpp/h to have TWebBrowser inherit from the modified TOleControl?
Step 4 - I can not understand where this code is placed - Is it in the same
Package/Unit as the code from step 2?
I am lost as to how to start ...

I have looked for examples either in Delphi or cBuilder and not very much
available out there. The one you originally pointed my to (the one the
example steps come from) is the best I could find on the subject.

I am keen to get this to work.

thanks
daryl
Remy Lebeau (TeamB)
2008-02-14 22:53:50 UTC
Permalink
Post by Daryl
Would it be possible for you to expand the steps outlined by
Mark in my recent post mentioned above i.e. "Handling script
erros from TWebBrowser control" in this same group?.
No. Like I said earlier, I have nothing to offer regarding that topic.
Post by Daryl
Step 3 I do not fully understand - does Mark mean to modify
the contents of ShDocVw_OCX.cpp/h to have TWebBrowser
inherit from the modified TOleControl?
Basically, yes.
Post by Daryl
Step 4 - I can not understand where this code is placed - Is it
in the same Package/Unit as the code from step 2?
Yes.


Gambit
Jason Cipriani
2008-02-12 22:22:08 UTC
Permalink
Post by Daryl
procedure LoadDocFromStream(WB: TWebBrowser; Stream: TStream);
begin
(WB.Document as IPersistStreamInit).Load(
TStreamAdapter.Create(Stream,soReference));
end;
I don't know Delphi either; and I do not know if VCL does anything behind
the scenes with COM stuff that makes normal COM methods not appropriate, but
this compiled for me with no warnings, at least:

void LoadDocFromStream (TWebBrowser *WB, TStream *Stream) {

IPersistStreamInit *psi;

WB->Document->QueryInterface(IID_IPersistStreamInit, (void **)&psi);
psi->Load(TStreamAdapter(Stream, soReference));
psi->Release();

}
Jason Cipriani
2008-02-12 22:30:47 UTC
Permalink
Ignore me. The TStreamAdapter temporary constructor compiles in Release mode
but not in Debug -- you need to create it with new. And I should have tested
it first, WB->Document is NULL sometimes, anyway.

So... nothing to see here; just move along.
Post by Jason Cipriani
Post by Daryl
procedure LoadDocFromStream(WB: TWebBrowser; Stream: TStream);
begin
(WB.Document as IPersistStreamInit).Load(
TStreamAdapter.Create(Stream,soReference));
end;
I don't know Delphi either; and I do not know if VCL does anything behind
the scenes with COM stuff that makes normal COM methods not appropriate,
void LoadDocFromStream (TWebBrowser *WB, TStream *Stream) {
IPersistStreamInit *psi;
WB->Document->QueryInterface(IID_IPersistStreamInit, (void **)&psi);
psi->Load(TStreamAdapter(Stream, soReference));
psi->Release();
}
Remy Lebeau (TeamB)
2008-02-12 22:47:13 UTC
Permalink
Post by Jason Cipriani
psi->Load(TStreamAdapter(Stream, soReference));
You cannot construct VCL objects on the stack. You must use the 'new'
operator when constructing the TStreamAdapter instance.


Gambit
Loading...