MSHTML event trapping

Cas
05-05-2008, 10:59 AM
Hi forum,

I'm attempting to use VBA to open a local HTML file, parse and modify it, display it and react to document events. MSHTML seemed like the way to go, but the relevant MSDN documentation is somewhat sparse so that I keep having to google for usage examples.
I've now got a basic file import and event trapping functionality working, but keep thinking that there has to be an easier way to do something as un-exotic as this.
Below my code outline, if any of this would be significantly easier using a different approach please tell me. The event approach is from here (http://msdn.microsoft.com/en-us/library/aa752045(VS.85).aspx), made a little cleaner by using an Interface instead of CallByName, the default-method-hack is from here (http://64.233.183.104/search?q=cache:WuOEpzq3e-AJ:www.experts-exchange.com/Microsoft/Development/MS_Access/Q_10547824.html+%22default+procedure%22+vba&hl=en&ct=clnk&cd=3).

Class DocWrapper

Option Explicit

Implements IEventSink

Private myMSHTML As HTMLDocument
Private myDoc As HTMLDocument 'no need to declare WithEvents, events can't be trapped using standard VB handlers (apparently)

Private Sub Class_Initialize()
Set myMSHTML = New HTMLDocument
End Sub

Private Function dHexEncode(whichPath As String) As String
'...
End Function

Public Property Let dPath(whichPath As String)

Set myDoc = myMSHTML.createDocumentFromUrl("file:///" & dHexEncode(whichPath), "")

Dim thisEvent As EventWrapper: Set thisEvent = New EventWrapper
With thisEvent
Set .eEventContainer = myDoc.parentWindow: Set .eEventSink = Me
End With
myDoc.onreadystatechange = thisEvent 'e.g.

End Property

Private Sub IEventSink_eEvent(whichEvent As HTMLEventObj)
Select Case whichEvent.Type
Case "readystatechange": '...
End Select
End Sub

Class EventWrapper - eEvent made default member by manually setting the ID attribute in the .cls file

Option Explicit

Private myEventContainer As HTMLWindowProxy
Private myEventSink As IEventSink

Public Property Set eEventContainer(whichContainer As HTMLWindowProxy)
Set myEventContainer = whichContainer
End Property
Public Property Set eEventSink(whichSink As IEventSink)
Set myEventSink = whichSink
End Property

Public Sub eEvent()
Call myEventSink.eEvent(myEventContainer.event)
End Sub

Cas
05-07-2008, 08:37 AM
Mods,

I posted this here because one part of it (creating the default member) is VBA-specific, though the rest of it is not - if you feel this might be more likely to be answered in a different forum (Comm or General or sunnink), maybe you could move it there?

Thanks. :)

Never mind, there actually is a much simpler way - declaring the HTMLDocument WithEvents works just fine, I just messed up at first by failing to make the Wrapper class persistent, so it simply wasn't there any more when the events were being raised. Due to the issues discussed here (http://www.xtremevbtalk.com/showthread.php?t=296283), creating a circular reference (DocWrapper references Document, Document references EventWrapper, EventWrapper references DocWrapper) had the side effect of taking care of persistency as well.
I'm just wondering now why the MSDN page I linked to in the intro to my OP was promoting the complicated way... :confused:

EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum