Link to home
Start Free TrialLog in
Avatar of tillix
tillix

asked on

again: visual basic webbrowser control and framed pages

Well, I 've got the following problem:
I need to get the calling frame of a frameset in webbrowser control to evaluate users input (important topics are HTMLForm-Elements, Links, etc).
This function needs to work with unknown framesets, because the pages change dynamic.
To realize this, I have created an instance of webbrowser control which creates an instance of a class called EventListener.

Here are some important parts of the code:

Dim Listener() As New EventListener
Dim listen As Boolean               'will be true, after the Listener is instantiated
Dim EventCount As Long
Public WithEvents htdoc As HTMLDocument
Dim htdoc2 As HTMLDocument
Dim eventindex As Long

Private Sub Recorder_DownloadComplete()
    'After the Browser receives a DocumentComplete Event, it the Listener is reinstantiated.
    Set htdoc = Recordbrowser.Recordbrowser.Document
       
    ReDim Listener(htdoc.frames.length)
    Listener(0).InitEvent htdoc
   
    For EventCount = 0 To htdoc.frames.length - 1
'    Debug.Print htdoc.activeElement.tagName
        Set htdoc2 = htdoc.frames(EventCount).Document
        Listener(EventCount + 1).InitEvent htdoc.frames(EventCount).Document
        EventCount = EventCount + 1
        If EventCount > 15 Then Exit For
    Next EventCount
    listen = True

 
End Sub

Public Sub Recorder_BeforeNavigate(ByVal URL As String, ByVal Flags As Long, ByVal TargetFrameName As String, PostData As Variant, ByVal Headers As String, Cancel As Boolean)
Dim i%
     For i = 1 To htdoc.frames.length - 1
        If htdoc = Listener(i).getDoc Then Listener(i).checkEvent
       
        'Listener(i).getDoc code:
        '
        'Public Function getDoc() As HTMLDocument
        '    Set getDoc = htmDoc
        'End Function
        'Listener(i).checkEvent code:
        'Public Sub checkEvent()
        'If UCase(htmDoc.activeElement.tagName) = "A" Then
        '  html_link_onclick
        ' ElseIf UCase(htmDoc.activeElement.tagName) = "INPUT" Then
        '  html_form_onsubmit htmDoc.activeElement.tagName
        ' Else
        '     Debug.Print htmDoc.activeElement.tagName
        '     Debug.Print htmDoc.activeElement.outerHTML
        'End If
        'End Sub
     Next i

End Sub
Avatar of Richie_Simonetti
Richie_Simonetti
Flag of Argentina image

Recorder_DownloadComplete is the name of your webbrowser control?
If so, you have a problem:
Downloadcomplete event is raised for EVERY frame in the document.
You need to wait until all frames are downloaded. To do so you need a simple if statement
sub Recorder_DownloadComplete(....)
if (pDisp is recorder.object) then
   ' your actual code goes here.
en if
end sub
Avatar of tillix
tillix

ASKER

- Recorder is instantiated as shdocvwctl.webbrowser_v1
- I think you're right with documentComplete Event (might be that I have turned it round with downloadComplete; I can't answer this at the moment, because I'm at home), but my main problem is that I need access to form-elements in framed pages and have to realize the name, type and value of the element.
E.g. The user fills some form-elements, checks a radio button and finally clicks on a submit button.
greeting
tillix
Ups!, i meant, documentcomplete event and NOT downloadcomplete event:

sub Recorder_DocumentComplete(....)
if (pDisp is recorder.object) then
  ' your actual code goes here.
en if
end sub
Avatar of tillix

ASKER

ok.
but how can I access the form values through the DOM? I have no problems without frames, but with.
Avatar of tillix

ASKER

ok.
but how can I access the form values through the DOM? I have no problems without frames, but with.
i think some like that:
You need an array of HTMLDocument to hold each frame (which is a document itself)

dim IEDocs() as HTMLDocument

in the main DocumentComplete event:

Private Sub WB1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
If (pDisp Is WB1.Object) Then
    Dim i As Integer
    For i = 1 To WB1.Document.frames.length
        ReDim Preserve IEDocs(i)
        Set IEDocs(i) = WB1.Document.frames(i).Document
    Next
End If

End Sub


After that, you have access to every single document in the array and use the DOM to locate objects in each of them.
Please, change to this (it is better ;)

Private Sub WB1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
If (pDisp Is WB1.Object) Then
    Dim i As Integer
    For i = 0 To WB1.Document.frames.length - 1
        ReDim Preserve IEDocs(i)
        Set IEDocs(i) = WB1.Document.frames(i).Document
    Next
End If

End Sub
Avatar of tillix

ASKER

Sorry for the late comment.
Well, finally I did it with a method called "recurse Frames". The original version of this method can be found at http://www.microsoft.com/mind/0898/dom.asp.
It shows how to walk through the frames. At least I have to modify this method a bit instead of the fillTree call I used my own method, which checks for the values of a htmlform.
That page is already known. What i don't understand is the diference between

...
...
for each frame in doc. frames
....
....
posted at that site with

for i= 0 to doc. frames.length-1

I know that one use an object and other and index but, besides that.. what?
Hi tillix,
This old question (QID 20553330) needs to be finalized -- accept an answer, split points, or get a refund.  Please see http://www.cityofangels.com/Experts/Closing.htm for information and options.
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

-->PAQ - with points refunded

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

GPrentice00
EE Cleanup Volunteer
ASKER CERTIFIED SOLUTION
Avatar of PashaMod
PashaMod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial