Announcement

Collapse
No announcement yet.

Links Collection

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Links Collection

    Hi all,


    based upon basic code from my previous post (Create a BHO with pb) i´m now trying to
    retrieve all links of the current page. My Code is as follows:



    Code:
    CLASS CDWebBrowserEvents2 $CLSID_DWEBBROWSEREVENTS2 AS EVENT
    '***********************************************************************************************
    ' catch webrowser event here (not all possible events listed, save if inherits from IDispatch)
    '***********************************************************************************************
    INSTANCE document  AS IHTMLDocument2
    
    
      INTERFACE DWebBrowserEvents2 $IID_DWEBBROWSEREVENTS2 AS EVENT
      INHERIT IDISPATCH
    
    
        METHOD Form1_WebBrowser1_DocumentComplete <&H00000103> (BYVAL pDisp AS DISPATCH, URL AS VARIANT)
    '***********************************************************************************************
    ' document is available now '
    '  MSGBOX "DocumentComplete" + $CRLF + VARIANT$(URL)
    '***********************************************************************************************
    LOCAL ie  AS IWebBrowser2                     ' Microsoft WebBrowser Object
    LOCAL col AS IHTMLElementCollection
    LOCAL l   AS IHTMLLinkElement
    LOCAL n   AS LONG
    LOCAL i   AS LONG
    LOCAL d$
    LOCAL u$
    
    
        ie=pDisp
    
        IF ISFALSE(ISOBJECT(ie)) THEN
          MSGBOX "Unable to create an object reference to the document interface."
          EXIT METHOD
        END IF
    
        document = ie.document                      'get document object
    
        col = document.links                        'get element collection 
    
        n = col.length         'property get
    '    MSGBOX STR$(n)
    
    
    LOCAL pd AS IDISPATCH
    LOCAL vi AS VARIANT
    
        i=1                                         'retrieve second link 
        vi=i
        pd = col.item(BYVAL vi, BYVAL vi)           'pd is a valid object !!
    '    l = col.item(BYVAL vi, BYVAL vi)          
    
    
    'LOCAL riid        AS GUID
    'LOCAL hr          AS LONG
    '
    '        riid = $IID_MSHTML_IHTMLLinkElement
    '        hr = pd.QueryInterface(riid, BYVAL VARPTR(l))
    
        l = pd                                      'get link element
    
    
        IF ISFALSE(ISOBJECT(l)) THEN
          MSGBOX "Unable to create an object reference to the link element."
          EXIT METHOD
        END IF
    
        u$ = l.href                                 'get link url  
    
    
    '      for i=0 to n                              'enumerate all links
    '        vi=i
    '        pd = col.item(byval vi, byval vi)
    '        l = pd
    '        u$ = l.href
    '        d$=d$+u$+$crlf
    '      next i
    
    MSGBOX d$
    
    
        END METHOD
    
    
        METHOD Form1_WebBrowser1_OnQuit <&H000000FD> ()       ' PURPOSE:   Fired when application is quiting.
    '      EVENTS END docevents
        END METHOD
    
    
      END INTERFACE
    
    
    END CLASS

    Doesn´t work ! I used sample C code from SDK to port this to pb
    It works until here:

    l = pd -> l is not an object

    if i try (commenting out l = pd):

    l = col.item(BYVAL vi, BYVAL vi) -> gpf at u$ = l.href


    Still struggling with Objects. What am i doing wrong ?


    Thanks in advance,


    Guenther

  • #2
    Problem solved

    Hi all,


    after some more research found out IHTMLElementCollection.item doesn´t return a
    IHTMLLinkElement, it must be IHTMLAnchorElement or just IHTMLElement.



    Code:
    CLASS CDWebBrowserEvents2 $CLSID_DWEBBROWSEREVENTS2 AS EVENT
    '***********************************************************************************************
    ' catch webrowser event here (not all possible events listed, save if inherits from IDispatch)
    '***********************************************************************************************
    INSTANCE document  AS IHTMLDocument2
    
    
      INTERFACE DWebBrowserEvents2 $IID_DWEBBROWSEREVENTS2 AS EVENT
      INHERIT IDISPATCH
    
    
        METHOD Form1_WebBrowser1_DocumentComplete <&H00000103> (BYVAL pDisp AS DISPATCH, URL AS VARIANT)
    '***********************************************************************************************
    ' document is available now '
    '  MSGBOX "DocumentComplete" + $CRLF + VARIANT$(URL)
    '***********************************************************************************************
    LOCAL ie  AS IWebBrowser2                             ' Microsoft WebBrowser Object
    LOCAL col AS IHTMLElementCollection
    LOCAL a   AS IHTMLAnchorElement
    LOCAL e   AS IHTMLElement
    LOCAL n   AS LONG
    LOCAL i   AS LONG
    LOCAL d$
    LOCAL u$
    LOCAL pd AS IDISPATCH
    LOCAL vi AS VARIANT
    
    
          ie = pDisp
    
          IF ISFALSE(ISOBJECT(ie)) THEN
            MSGBOX "Unable to create an object reference to the document interface."
            EXIT METHOD
          END IF
    
          document = ie.document                          'get document object
          col = document.links                            'get links collection
    
          n = col.length
    '      MSGBOX STR$(n)
    
    
          FOR i=0 TO n-1                                  'zero based n elements -> last element id = n-1
            vi=i
            pd = col.item(BYVAL vi, BYVAL vi)
            e = pd
    '        a = pd
            u$ = e.toString                               'element.toString
    '        u$ = a.href                                   'anchorelement. href (both are working !)
            u$=ACODE$(u$)                                 'returned string is unicode
            d$=d$+u$+$CRLF
          NEXT i
    
          MSGBOX d$
    
    
        END METHOD
    
        METHOD Form1_WebBrowser1_OnQuit <&H000000FD> ()   ' PURPOSE:   Fired when application is quiting.
    
        END METHOD
    
    
      END INTERFACE
    
    
    END CLASS


    Works now !


    Where could be found better information abbout object hierarchy and what interface to retrieve in
    what circumstances from what received dispatch interface than in SDK ? The most difficult part in
    this was, to choose the correct interface (the obvious for me - IHTMLLinkElemnet - didn´t work)?



    Guenther

    Comment


    • #3
      You can also use the standard enumerator offered by COM to do this.
      By using an enumerator, you don't have to worry about names, IDs, or indices.
      The standard enumerator is defined in the stdole2.tlb(OLE Automation) type library.

      The following code uses the interfaces generated by my Type Library Browser.

      The standard enumerator.
      Code:
      ' ****************************************************************************************
      ' Interface:      IEnumVARIANT
      ' uuid:           {00020404-0000-0000-C000-000000000046}
      ' Type Flags:     [hidden]
      ' ****************************************************************************************
      
      $IID_IENUMVARIANT = GUID$("{00020404-0000-0000-C000-000000000046}")
      
      INTERFACE IEnumVARIANT $IID_IENUMVARIANT
        INHERIT IUNKNOWN
        Method Next(IN BYVAL celt AS DWORD, IN BYREF rgvar AS VARIANT, OUT BYREF pceltFetched AS DWORD) AS LONG
        Method Skip(IN BYVAL celt AS DWORD) AS LONG
        Method Reset() AS LONG
        Method Clone(OUT BYREF ppenum AS IEnumVARIANT) AS LONG
      END INTERFACE
      Code to use the standard enumerator.
      Code:
      '-------------------------------------------------------------------------------
      '
      ' PROCEDURE: Form1_WebBrowser1_DocumentComplete
      ' PURPOSE:   Fired when the document being navigated to reaches
      '            ReadyState_Complete.
      '
      '-------------------------------------------------------------------------------
      
      METHOD Form1_WebBrowser1_DocumentComplete <&H00000103>_
        ( _
        BYVAL pDisp   AS DISPATCH, _        ' [in] IDispatch
              URL     AS VARIANT _          ' [in]
        )
      
        LOCAL oBrowser    AS ShellWebBrowser
        LOCAL oDocument   AS IHTMLDocument2
      
        LOCAL oLinks      AS IHTMLElementCollection
        LOCAL oElement    AS IHTMLElement
        LOCAL vItem       AS VARIANT
        LOCAL cLinks      AS LONG
        LOCAL oEnum       AS IEnumVARIANT
        LOCAL cFetched    AS DWORD
        LOCAL hr          AS LONG
        
        MSGBOX "DocumentComplete" + $CRLF + VARIANT$(URL)
      
        ' Get a reference to the IWebBrowser2 interface
        oBrowser = pDisp
        IF ISOBJECT(oBrowser) THEN
          ' Get a reference to the IHTMLDocument2 interface
          oDocument = oBrowser.Document
          ' Get a collection of the links
          oLinks = oDocument.links
          IF ISOBJECT(oLinks) THEN
            ' Retrieve an enumerator for the collection
            ' Note: the standard enumerator, IEnumVARIANT, offered by COM is used
            oEnum = oLinks.newEnum
            IF ISOBJECT(oEnum) THEN
      
              DO    
                ' Fetch one element  
                oEnum.Next 1, vItem, cFetched
                IF cFetched = 0 THEN EXIT DO
                oElement = vItem
                IF ISOBJECT(oElement) THEN
                  MSGBOX ACODE$(oElement.toString)        
                END IF
              LOOP  
      
            END IF
          END IF
        END IF  
      
      END METHOD
      Where could be found better information abbout object hierarchy and what interface to retrieve in
      what circumstances from what received dispatch interface than in SDK ? The most difficult part in
      this was, to choose the correct interface (the obvious for me - IHTMLLinkElemnet - didn´t work)?
      Unfortunately, with the Document Object Model(DOM) you will have to resort to what you did.
      MSDN and lots of research on the Web.
      Dominic Mitchell
      Phoenix Visual Designer
      http://www.phnxthunder.com

      Comment


      • #4
        Dominic,

        i read about the newEnum property and wondered how to implement it.
        Thanks for showing me !


        Unfortunately, with the Document Object Model(DOM) you will have to resort to what you did.
        MSDN and lots of research on the Web

        Sounds very promising indeed ...


        Guenther

        Comment

        Working...
        X