BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Help with TCppWebBrowser - Find and click a button
Goto page Previous  1, 2
 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Internet Web)
View previous topic :: View next topic  
Author Message
Hans Galema
Guest





PostPosted: Mon Jan 08, 2007 5:09 pm    Post subject: Re: Help with TCppWebBrowser - Find and click a button Reply with quote



mike wrote:

Quote:
Well I am clearly not understanding why the button is not found. I am using
the following code and I thought the button would have been found as I am
taking into account the 2 frames, I think.

Yes. But the second frame contains a doc ( a html-page ) that contains
again a frameset. So you should make the code recursive.

Every TComInterface<IHTMLDocument2> Doc; you should investigate for
TComInterface<IHTMLFramesCollection2> Frames;. Then every frame from
that collection contains a Doc again.

Hans.

Back to top
Hans Galema
Guest





PostPosted: Mon Jan 08, 2007 6:14 pm    Post subject: Re: Help with TCppWebBrowser - Find and click a button Reply with quote



Hans Galema wrote:

Quote:
... So you should make the code recursive.

In order to do that start at the begin. I first took Remy's code to
click a button if the webbrowsercontrol contains a document without
a frameset. I first made a function of it. ( I keep functions concerning
T(Cpp)WebBrowser in a separate file which is easy added to a project
with the browsercomponent).

To click a certain button then only a few lines are needed. In your
case:

AnsiString ButtonName = "secure_exit" ;

if ( ! WBClickButton ( WebBrowser1, ButtonName) )
ShowMessage ( ButtonName + "\n\nbutton not clicked");

Here is the function:

bool __fastcall WBClickButton ( TWebBrowser *WebBrowser, AnsiString ButtonName )
{
bool done = false;

if( WebBrowser->Document )
{
TComInterface<IHTMLDocument2> Doc;
WebBrowser->Document->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&Doc);

if( Doc )
{
TComInterface<IHTMLElementCollection> All;
Doc->get_all(&All);

if( All )
{
TComInterface<IDispatch> Disp;
All->item(TVariant(WideString(ButtonName)), TVariant(0), &Disp);

if( Disp )
{
TComInterface<IHTMLElement> Element;
Disp->QueryInterface(IID_IHTMLElement, (LPVOID*)&Element);

if( Element )
{
Element->click();

done = true;
}

}
}
}
}

return done;
}

Then realising that traversing frames we need a function that finds
a button in a IHTMLDocument2 I made another version which puts all
the code in two functions:

bool __fastcall WBClickButton2 ( TWebBrowser *WebBrowser, AnsiString ButtonName )
{
bool clicked = false;

if( WebBrowser->Document )
{
TComInterface<IHTMLDocument2> Doc;
WebBrowser->Document->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&Doc);

if( Doc )
{
clicked = DocClickButton2 ( Doc, ButtonName ); // see code below
}
}

return clicked;
}


bool __fastcall DocClickButton2 ( TComInterface<IHTMLDocument2> Doc, AnsiString ButtonName )
{
bool clicked = false;

TComInterface<IHTMLElementCollection> All;
Doc->get_all(&All);

if( All )
{
TComInterface<IDispatch> Disp;

All->item(TVariant(WideString(ButtonName)), TVariant(0), &Disp);

if( Disp )
{
TComInterface<IHTMLElement> Element;
Disp->QueryInterface(IID_IHTMLElement, (LPVOID*)&Element);

if( Element )
{
Element->click();

clicked = true;
}
}
}

return clicked;
}

AnsiString ButtonName = "secure_exit" ;

if ( ! WBClickButton2 ( WebBrowser1, ButtonName) )
ShowMessage ( ButtonName + "\n\nbutton not clicked");

Now we can use DocClickButton2() also on the documents for every frame when
traversing Frames.

That has to be done yet.

Hans.
Back to top
Hans Galema
Guest





PostPosted: Mon Jan 08, 2007 7:00 pm    Post subject: Re: Help with TCppWebBrowser - Find and click a button Reply with quote

Hans Galema wrote:

Quote:
That has to be done yet.

OK. I got it working.

void __fastcall TForm4::SpeedButton10Click(TObject *Sender)
{
AnsiString URL = "http://rpa.tblc.org/rpa/webauth.exe?lb=PALM";

WebBrowser1->Navigate ( URL );

// You have to manually fill in BorrowerID and click the
// Login button;
// After that click SpeedButton13
}


void __fastcall TForm4::SpeedButton13Click(TObject *Sender)
{
AnsiString ButtonName = "secure_exit";

if ( ! WBClickButton3 ( WebBrowser1, ButtonName ) )
ShowMessage ( ButtonName + "\n\nbutton not clicked");
}

The code:

static bool __fastcall DocClickButton2 ( TComInterface<IHTMLDocument2> Doc, AnsiString ButtonName )
{
bool clicked = false;

TComInterface<IHTMLElementCollection> All;
Doc->get_all(&All);

if( All )
{
TComInterface<IDispatch> Disp;

All->item(TVariant(WideString(ButtonName)), TVariant(0), &Disp);

if( Disp )
{
TComInterface<IHTMLElement> Element;
Disp->QueryInterface(IID_IHTMLElement, (LPVOID*)&Element);

if( Element )
{
Element->click();

clicked = true;
}
}
}

return clicked;
}


int level = 0; // for testing purposes

static bool __fastcall DocClickButton3 ( IHTMLDocument2 *Doc, AnsiString ButtonName )
{
level++;

bool clicked = false;

long cnt = 0;

TComInterface<IHTMLFramesCollection2> Frames;

Doc->get_frames(&Frames);

if( Frames )
{
Frames->get_length(&cnt);

ShowMessage ( "level: " + IntToStr ( level ) + "\n\ncnt: " + IntToStr ( (int)cnt ) );
}

if ( cnt > 0 )
{
for(long l = 0; l < cnt; ++l)
{
// TVariant IndexOrName = WideString("frame name");
// or:
TVariant IndexOrName = l;
TVariant Frame;

Frames->item(&IndexOrName, &Frame);

if( (V_VT(&Frame) == VT_DISPATCH) && (V_DISPATCH(&Frame) != NULL) )
{
TComInterface<IHTMLWindow2> Window;

V_DISPATCH(&Frame)->QueryInterface(IID_IHTMLWindow2,(LPVOID*)&Window);

if( Window )
{
TComInterface<IHTMLDocument2> FrameDoc;
Window->get_document(&FrameDoc);

if( FrameDoc )
{
// use FrameDoc as needed ...

clicked = DocClickButton3 ( FrameDoc, ButtonName );

if ( clicked )
break;
}
}
}
}
}
else
clicked = DocClickButton2 ( Doc, ButtonName );

level --;

return clicked;
}


bool __fastcall WBClickButton3 ( TWebBrowser *WebBrowser, AnsiString ButtonName )
{
bool clicked = false;

if( WebBrowser->Document )
{
TComInterface<IHTMLDocument2> Doc;
WebBrowser->Document->QueryInterface(IID_IHTMLDocument2,(LPVOID*)&Doc);

if( Doc )
{
clicked = DocClickButton3 ( Doc, ButtonName );
}
}

return clicked;
}

Hans.
Back to top
Hans Galema
Guest





PostPosted: Mon Jan 08, 2007 7:14 pm    Post subject: Re: Help with TCppWebBrowser - Find and click a button Reply with quote

Hans Galema wrote:

Quote:
for(long l = 0; l < cnt; ++l)
{
// TVariant IndexOrName = WideString("frame name");
// or:
TVariant IndexOrName = l;

Oh that is terrible! I left the L!

And JD: I left the for too! To honour the original poster. You know
that I will never use a for myself.

Hans.
Back to top
mike
Guest





PostPosted: Mon Jan 08, 2007 8:46 pm    Post subject: Re: Help with TCppWebBrowser - Find and click a button Reply with quote

Hans,

I have tested the code on my side and it does work absolutely fantastic.

I cannot thank you enough for all the help you have provided. I know you
have spent your own personal time in looking at this for me and I appreciate
it very much.

Again, thank you and have a wonderful day.

Mike
"Hans Galema" <notused (AT) notused (DOT) nl> wrote in message
news:45a240c7 (AT) newsgroups (DOT) borland.com...
Quote:
Hans Galema wrote:

That has to be done yet.

OK. I got it working.

void __fastcall TForm4::SpeedButton10Click(TObject *Sender)
{
AnsiString URL = "http://rpa.tblc.org/rpa/webauth.exe?lb=PALM";

WebBrowser1->Navigate ( URL );

// You have to manually fill in BorrowerID and click the
// Login button;
// After that click SpeedButton13
}


void __fastcall TForm4::SpeedButton13Click(TObject *Sender)
{
AnsiString ButtonName = "secure_exit";

if ( ! WBClickButton3 ( WebBrowser1, ButtonName ) )
ShowMessage ( ButtonName + "\n\nbutton not clicked");
}

The code:

static bool __fastcall DocClickButton2 ( TComInterface<IHTMLDocument2
Doc, AnsiString ButtonName )
{
bool clicked = false;

TComInterface<IHTMLElementCollection> All;
Doc->get_all(&All);

if( All )
{
TComInterface<IDispatch> Disp;

All->item(TVariant(WideString(ButtonName)), TVariant(0), &Disp);

if( Disp )
{
TComInterface<IHTMLElement> Element;
Disp->QueryInterface(IID_IHTMLElement, (LPVOID*)&Element);

if( Element )
{
Element->click();

clicked = true;
}
}
}

return clicked;
}


int level = 0; // for testing purposes

static bool __fastcall DocClickButton3 ( IHTMLDocument2 *Doc, AnsiString
ButtonName )
{
level++;

bool clicked = false;

long cnt = 0;

TComInterface<IHTMLFramesCollection2> Frames;

Doc->get_frames(&Frames);

if( Frames )
{
Frames->get_length(&cnt);

ShowMessage ( "level: " + IntToStr ( level ) + "\n\ncnt: " + IntToStr (
(int)cnt ) );
}

if ( cnt > 0 )
{
for(long l = 0; l < cnt; ++l)
{
// TVariant IndexOrName = WideString("frame name");
// or:
TVariant IndexOrName = l;
TVariant Frame;

Frames->item(&IndexOrName, &Frame);

if( (V_VT(&Frame) == VT_DISPATCH) && (V_DISPATCH(&Frame) != NULL) )
{
TComInterface<IHTMLWindow2> Window;

V_DISPATCH(&Frame)->QueryInterface(IID_IHTMLWindow2,(LPVOID*)&Window);

if( Window )
{
TComInterface<IHTMLDocument2> FrameDoc;
Window->get_document(&FrameDoc);

if( FrameDoc )
{
// use FrameDoc as needed ...

clicked = DocClickButton3 ( FrameDoc, ButtonName );

if ( clicked )
break;
}
}
}
}
}
else
clicked = DocClickButton2 ( Doc, ButtonName );

level --;

return clicked;
}


bool __fastcall WBClickButton3 ( TWebBrowser *WebBrowser, AnsiString
ButtonName )
{
bool clicked = false;

if( WebBrowser->Document )
{
TComInterface<IHTMLDocument2> Doc;
WebBrowser->Document->QueryInterface(IID_IHTMLDocument2,(LPVOID*)&Doc);

if( Doc )
{
clicked = DocClickButton3 ( Doc, ButtonName );
}
}

return clicked;
}

Hans.
Back to top
Michael Harris
Guest





PostPosted: Tue Jan 09, 2007 1:05 am    Post subject: Re: Help with TCppWebBrowser - Find and click a button Reply with quote

get source is similar to below.

As Hans pointed out. the html being parser in your iter. function is not
finding the actual html you are seeing on the page.
Hans also provided source to iter the frames in the various framesets.

--

Michael

AnsiString GetSource ( TCppWebBrowser *CppWebBrowser )
{
AnsiString Source = "";

IHTMLDocument2 *htm = NULL; // #include <mshtml.h>

if(CppWebBrowser->Document
&&
SUCCEEDED(CppWebBrowser->Document->QueryInterface(IID_IHTMLDocument2,
(LPVOID*)&htm))
)
{
IPersistStreamInit *spPsi = NULL; // ocidl.h

if(SUCCEEDED(htm->QueryInterface(IID_IPersistStreamInit,
(LPVOID*)&spPsi)) &&spPsi)
{
IStream *spStream = NULL; // objidl.h
OleCheck(CreateStreamOnHGlobal(NULL, true, &spStream));
if(spStream)
{
__int64 nSize = 0;
STATSTG ss;
LARGE_INTEGER nMove;
nMove.QuadPart = 0;
OleCheck(spPsi->Save(spStream, true));
OleCheck(spStream->Seek(nMove, STREAM_SEEK_SET,
(ULARGE_INTEGER*)&nSize));
OleCheck(spStream->Stat(&ss, STATFLAG_NONAME));
nSize = ss.cbSize.QuadPart;

Source.SetLength(nSize);
OleCheck(spStream->Read((void *)Source.data(), nSize,
(ULONG*)&nSize));
OleCheck(spStream->Release());
}

spPsi->Release();
}
htm->Release();
}

return Source;
}

"mike" wrote in message

Quote:
Can you point out what I am not understanding or where I have gone
wrong.





Back to top
Michael Harris
Guest





PostPosted: Tue Jan 09, 2007 1:20 am    Post subject: Re: Help with TCppWebBrowser - Find and click a button Reply with quote

If you are interested in seeing what I am talking about.
***** add abutton to your form.
void __fastcall TForm1::Button9Click(TObject *Sender)
{
AnsiString ButtonName = "secure_exit";

if ( ! WBClickButton3 ( FBrowser, ButtonName ) )
ShowMessage ( ButtonName + "\n\nbutton not clicked");
}

******* alter DocClickButton3
if( FrameDoc )
{
// ****** add this line to view the actual source
ShowMessage(GetDocSource ( (_id_IHTMLDocument2) FrameDoc ));
clicked = DocClickButton3 ( FrameDoc, ButtonName );

if ( clicked )
break;
}

*******change the get source method as below.
typedef CComPtr<IHTMLDocument2> _id_IHTMLDocument2; // or tcominterface
typedef CComPtr<IPersistStreamInit> _id_IPersistStreamInit;

AnsiString GetDocSource ( _id_IHTMLDocument2 htm )
{
AnsiString Source = "";

_id_IPersistStreamInit spPsi = NULL; // ocidl.h

if(SUCCEEDED(htm->QueryInterface(IID_IPersistStreamInit,
(LPVOID*)&spPsi)) &&spPsi)
{
IStream *spStream = NULL; // objidl.h
OleCheck(CreateStreamOnHGlobal(NULL, true, &spStream));
if(spStream)
{
__int64 nSize = 0;
STATSTG ss;
LARGE_INTEGER nMove;
nMove.QuadPart = 0;
OleCheck(spPsi->Save(spStream, true));
OleCheck(spStream->Seek(nMove, STREAM_SEEK_SET,
(ULARGE_INTEGER*)&nSize));
OleCheck(spStream->Stat(&ss, STATFLAG_NONAME));
nSize = ss.cbSize.QuadPart;

Source.SetLength(nSize);
OleCheck(spStream->Read((void *)Source.data(), nSize,
(ULONG*)&nSize));
OleCheck(spStream->Release());
}
}
return Source;
}


as Han's Iter functions enumerate the frames, the html source should show.

--
Michael
Back to top
Hans Galema
Guest





PostPosted: Tue Jan 09, 2007 9:10 am    Post subject: Re: Help with TCppWebBrowser - Find and click a button Reply with quote

Michael Harris wrote:

Quote:
as Han's Iter functions enumerate the frames, the html source should show.

Indeed.

Nice to see that you experimented with the code to extract all the sources.

Hans.
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Wed Jan 10, 2007 1:19 am    Post subject: Re: Help with TCppWebBrowser - Find and click a button Reply with quote

"mike" <mfbrowne (AT) earthlink (DOT) nnet> wrote in message
news:459fbc29$2 (AT) newsgroups (DOT) borland.com...

Quote:
Now because I suspected there might be frames, and did find 2 frames
located on the web page. So I tried the second code sample and added
the

TComInterface<IHTMLElementCollection> All;

for the framedoc reteived. However the button again was not found. I
tried this on both frame 0 and frame 1.

Then you are likely still not looking in the right page for the
button. Please show the exact starting URL that you are trying to
access the button from.

Quote:
I then decided to get the source of the frames and save them to a
file
where I could see what was actually within the framedoc. Upon this
review I did not see the button source in either frame doc.

What exactly did you see? Are there other frames that you are not
accounting for yet?

Quote:
If I do a view source over the area that does contain the button I
do see it in notepad.


Then all the more reason that you are not handling the frames 100%
correctly yet.

Quote:
So I am totally confused on where this button definition could be
within the web page, and I am not sure how to find this information
out.


Then again, please show the original URL so someone else can look at
it.


Gambit
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Wed Jan 10, 2007 1:24 am    Post subject: Re: Help with TCppWebBrowser - Find and click a button Reply with quote

"mike" <mfbrowne (AT) earthlink (DOT) nnet> wrote in message
news:45a02ab5$1 (AT) newsgroups (DOT) borland.com...

Quote:
In my test application I have inserted a test for frames and it does
that
there are 2 frames.

The top-level page has 2 frames in it, yes. But the bottom frame has
*2 MORE* frames inside of it. The button you seek is inside the left
inner frame. That is what you have not taken into account properly
yet. Which is why your code can't find it yet. You are not going
deep enough.


Gambit
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Wed Jan 10, 2007 1:25 am    Post subject: Re: Help with TCppWebBrowser - Find and click a button Reply with quote

"Hans Galema" <notused (AT) notused (DOT) nl> wrote in message
news:45a0c612$1 (AT) newsgroups (DOT) borland.com...

Quote:
So there are two framesets. I think that the code that Remy
posted only takes one frameset in account. You have to
make that code recursive so that it finds the second frameset too.

It does not need to be recursive.


Gambit
Back to top
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Internet Web) All times are GMT
Goto page Previous  1, 2
Page 2 of 2

 
 


Powered by phpBB © 2001, 2006 phpBB Group
.