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
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