🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.internet.web
Article #148

Re: Extracting all the HTMLElements from IHTMLDocument2 ?

#148
From: Remy Lebeau (TeamB)
Date: Mon, 13 Aug 2007 17:30
101 lines
4618 bytes
"Mischa Simmonds" <mischa1.BanSpam@informationdesign.BanSpam.com.au> wrote
in message news:46c061ea$1@newsgroups.borland.com...

> Any ideas?

Since you are trying to get input values, have you tried using the 'forms'
collection instead of the 'all' collection?  The 'forms' collection contains
all of the <FORM> elements of the page, from which you can then get all of
the child <INPUT> elements.

> DelphiInterface<IHTMLElementCollection> *collection;

DO NOT use pointer variables with the DelphiInterface class (or any other
smart wrapper class, such as TComInterface or CComPtr).  They are meant to
be used on the stack, not the heap (hense the 'smart' aspect of them).  They
manage a pointer internally for you, and override the '->' and '&' operators
to access that pointer, so that the rest of your code that operates on a
pointer can stay the same.  So get rid of the '*' in the above declaration,
ie:

    DelphiInterface<IHTMLElementCollection> collection;
    Doc->get_all(&collection);

> long p=collection->get_length(&p);

The return value of get_length() is an HRESULT.  You are overriding your
variable with the wrong value.  Since get_length() is likely to always
succeed on a valid collection, your variable will end up with a value of 0,
and your loop will not do anything.  You need to get of the assignment and
just let the parameter to the work:

    collection->get_length(&p);

> element=collection-> item(i, '') as IHTMLElement;

That is not valid C++ code.  That looks like Delphi code that was not
completely translated.  If you read the documentation for
IHTMLElementCollection, you will see how item() is actually declared in C++:

    IHTMLElementCollection::item Method
    http://msdn2.microsoft.com/en-us/library/Aa703930.aspx

As for the casting, like with any other interface, you must use the
QueryInterface() method to obtain a different interface type from it.  There
is no 'as' operator in C++.

For example:

    collection->get_length(&p);
    for(long i = 0; i < p; ++i)
    {
        TVariant name = i;
        TVariant index = 0;
        DelphiInterface<IDispatch> disp;

        if( SUCCEEDED(collection->item(name, index, &disp)) )
        {
            DelphiInterface<IHTMLElement> element;
            if( SUCCEEDED(disp->QueryInterface(IID_IHTMLElement,
(LPVOID*)&element)) )
            {
                // use element as needed ...

                DelphiInterface<IHTMLInputElement> input;
                if(
SUCCEEDED(element->QueryInterface(IID_IHTMLInputElement), (LPVOID*)&input) )
                    // use input as needed ...
            }
        }
    }

> I want to be able to extract the name/value pairs for each element

You need to query each element for the IHTMLInputElement interface.  If
present, then you can read its 'name' and 'value' properties.

> asHTML = wsHTML.Detach();
> asText = wsText.Detach();
> asURL = wsURL.Detach();

Those are memory leaks.  You are releasing each WideString's ownership of
its inner BSTR, but AnsiString will not pick up those ownerships, and you
are not freeing the BSTRs yourself..  You do not need to call Detach() at
all.  AnsiString knows how to directly copy a WideString without effecting
the WideString's ownership of its BSTR, ie:

    asHTML = wsHTML;
    asText = wsText;
    asURL = wsURL;

> This is an example of Delphi code I found on the web which looks
> close to be providing what I am looking for but I am unable to
> convert the Delphi to C++ in this instance...

For future reference, please search the newsgroup archives at
http://www.deja.com.  Such translations, and other related snippets, have
been posted many times before.


Gambit
Technical Details
Message-ID: <46c09536@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news2.google.com!news2.google.com!news.glorb.com!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mail
References: <46c061ea$1@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: feeec,26c174002c4041d7
X-Google-Attributes: gidfeeec,public,usenet
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Remy Lebeau \(TeamB\)" <no.spam@no.spam.com>
Newsgroups: borland.public.cppbuilder.internet.web
References: <46c061ea$1@newsgroups.borland.com>
Subject: Re: Extracting all the HTMLElements from IHTMLDocument2 ?
Date: Mon, 13 Aug 2007 10:30:19 -0700
Lines: 103
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2800.1409
x-mimeole: Produced By Microsoft MimeOLE V6.00.2800.1409
NNTP-Posting-Host: 75.83.29.61
Message-ID: <46c09536@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1187026230 75.83.29.61 (13 Aug 2007 10:30:30 -0700)
Path: arc1-ca.pugleaf.net!g2news2.google.com!news2.google.com!news.glorb.com!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mail