Access Modern Web Browser Control – Dynamic Content

Access Modern Web Browser Control

I’ve spent a lot of time messing around with the Modern Web Browser control and specifically trying to dynamically render content.  My most recent adventure relating to this allowed me to finally finish a project I had tried developing years earlier, but was limited by the ‘original’ Web Browser control’s functionality (or lack thereof):

 

Once again, Microsoft has no documentation whatsoever on this aspect of programming the Modern Web Browser control!  So this was a massive trial and error type of development and being too stubborn to give up, I eventually found a way.  What is nice here is  the fact that the final solution is very straightforward (although getting there was not).

Below is an example of how you can read the content of a file and then render it (this allows you the ability to modify the HTML prior to rendering):

    Dim sFile                 As String
    Static sSrcHTML           As String
    Dim sHTML                 As String
    Dim sJSCmd                As String
    Dim sImgFile              As String

    sFile = CurrentProject.Path & "\html\Index-dynamic.html" 'Template file
    If sSrcHTML = "" Then sSrcHTML = ReadFile(sFile)         'Only read the Template file once per session!
    'convert all relative paths to absolute paths!
    sHTML = Replace(sSrcHTML, "./", "https://msaccess/" & Replace(CurrentProject.Path, "\", "/") & "/html/")
    sHTML = Replace(sHTML, "'", "\'") 'escape single quotes in the HTML string
    
    'update the HTML here if required
    
    sHTML = Replace(sHTML, vbCrLf, "") 'This is a critical step!!!!!!!!!!!

    sJSCmd = "document.open();" & _
             "document.write('" & sHTML & "');" & _
             "document.close();"
    Me.EdgeBrowser0.ExecuteJavascript sJSCmd

Similarly, you can generate all your HTML via VBA by simply doing something like:

Private Sub RegenPage()
    Dim sHTML                 As String
    Dim sJSCmd                As String

    sHTML = "<html>"
    sHTML = sHTML & "<body>"
    sHTML = sHTML & "<h1>Dynamic Content Generation Test</h1>"
    sHTML = sHTML & "<img src=""" & "https://msaccess/" & Replace(CurrentProject.Path, "\", "/") & "/html/images/picture.jpg"" />"
    sHTML = sHTML & "</body>"
    sHTML = sHTML & "</html>"

    sJSCmd = "document.open();" & _
             "document.write('" & sHTML & "');" & _
             "document.close();"
    Me.EdgeBrowser0.ExecuteJavascript sJSCmd
End Sub
Warning!
Be forewarned, because of the limitation of the Modern Web Browser control not supporting mixed content, refer to my article:

to be able to render such content and use local resources, you must first have initialized the control by navigating to a local file. I simply create a blank HTML file and navigate to it when the form opens. After that I can dynamically generate content as I see fit.

 

Critical Coding Considerations

There are a couple important things to be aware when trying to dynamically generate code to render in the Modern Web Browser control, such as:

  • You must always convert/use absolute paths for all resource and media files.
  • You must prefix all resource and media files with the https://msaccess/ protocol string.
  • You must eliminate/replace all VbCrLf instances in your HTML string being passed to the Modern Web Browser control
  • As mentioned above, you must have already navigated to another local file first.
  • There seems to be an issue when pushing HTML that contains ‘ (single quotes) and thus you must replace all ‘ (single quote) with ” (double quotes) or escape the character throughout your HTML string.

With the above information, you should now be in a position to read in any file, and/or generate HTML on the fly to render in Microsoft Access’ Modern Web Browser control.

That said, one of the biggest issues with local content, and/or dynamic content, is CORS (Cross-Origin Resource Sharing ) restrictions. Sadly, there is no fix/workaround for this PITA and can be a complete deal breaker for several projects I have tried to port to Access.