Everything You Never Wanted to Know About the Access WebBrowser Control

The Access WebBrowser control is one of the greatest and most frustrating controls available to any Access developer!

The beauty of this control is it enables you to gain the power of the web within your database. On the other hand, I have found it very frustrating to program as many properties/methods available to the WebBrowser control in other platforms are simply not implemented in Access’ WebBrowser control. I have also found documentation and concrete advanced examples to be a rare commodity making development more frustrating than it should normally be.

Looking For Information About The New Modern 'Edge'/'WebView2'/'Chromium' Web Browser Control?
If you are looking for information about the new Modern ‘Edge’/’WebView2’/’Chromium’ Web Browser control then take a look at the following instead:

So I thought I’d put ‘pen to paper’, in a manner of speaking, to share some of what I’ve learnt.

In the this article I will touch upon

WebBrowser Control Limitations!

Before going any further you should be aware of one major limitation of Access’ WebBrowser control and that is that it doesn’t exist for reports!!! That’s right, Microsoft, for God knows what reason, made the control available in forms, but not reports?! As far as I’m concerned, this makes it a half-implemented control. Just one more glaring hole in Access! How can you have a control (and I think it might be the only control like this) that you judge people want to see within a form, but won’t also want to see in the resulting report? The logic eludes me.

That said, you can however, insert a form with a WebBrowser control into a report and link the two, but this will only render in Report and Layout views (and only for the 1st record) and not in Print Preview. Furthermore, even in Report and Layout views the WebBrowser control will not show up when printed!

I have a couple ideas for workarounds, but haven’t had the time to work on them. I’ll keep you posted.

Warning
Also one word of caution as I’ve discovered a bug while doing work with the WebBrowser control. If you include a form with a WebBrowser control within a report, open the report in Report or Layout view and then try to switch to Print Preview, Access will crash every single time. The issue has already been passed along to Microsoft.

Also, in the same report as above, scrolling within Layout View or Report View causes the Access to crash.

So moral of the story, although you can fenagle a WebBrowser control in a Report, DON’T do it, it just doesn’t work!

URLs From A Table

In the most basic form, you could have a simple table with a field that stored the URL of various websites and then use the field as the WebBrowser’s Control Source. That’s it, as you navigate between records, the WebBrowser will automatically navigate to the URL.

URLs From VBA

Pushing things a little further, what if we wanted to use a VBA string variable to navigate the WebBrowser. Nothing could be easier once again.

Me.WebBrowser0.ControlSource = "=""www.google.ca"""

Or

Const sURL = "www.google.ca"
Me.WebBrowser0.ControlSource = "=""" & sURL & """"

Or

Dim sURL                  As String
sURL = Me.URLControlName
Me.WebBrowser0.ControlSource = "=""" & sURL & """"

Content From a Local File

Taking things up a small notch, sometimes we simply want to load a local file into the WebBrowser. This can be done by doing

Me.WebBrowser0.ControlSource = "=""M:\Databases\CARDA\Demos\HTML Editor\html\index.html"""

Or

Const sFile = "M:\Databases\CARDA\Demos\HTML Editor\html\index.html"
Me.WebBrowser0.ControlSource = "=""" & sFile & """"

Or

Dim sFile                 As String
sFile = Me.FileControlName
Me.WebBrowser0.ControlSource = "=""" & sFile & """"

Dynamic Content on the Fly

One of the most recent things I was trying to do was create web pages dynamically, based on HTML stored in a table. Initially, I was taking the table value and pushing it to a file on the PC and then loading the file, but I didn’t like that approach as it makes unnecessary I/Os calls by continually writing to the hard drive.

I thought to myself there had to be a way to do this all in memory.

Now, the WebBrowser exposes all sort of ways to alter the head tag content, the body tag content, but nothing to completely alter the entire document itself. I won’t bore you with all the variations I attempted and will get straight to the point. There were 2, very similar, approaches that work at the end of the day.

With Me.WebBrowser0.Object.Document
    .Open
    .Write "

Some content.

" .Close End With

Or

Dim sCmd                  As String
sCmd = "javascript:document.open('text/html');document.write('

Some content.

');document.close();" Me.WebBrowser0.Object.Document.parentWindow.execScript (sCmd)

In my specific case, I was pulling my HTML from a table, so I ended using the form’s current event and doing

With Me.WebBrowser0.Object.Document
    .Open
    .Write Me.HTMLFieldName
    .Close
End With

Absolute Paths a Must

Also note that when creating webpages on the fly you can’t use relative paths for any resources: css, js, images, … since the webpage has no reference point to use for building relative paths from. As such, you must always use absolute paths. So let say you have a template html file that you read into memory, modify and then use dynamically, then you would need to also use some Replace statement to perform any necessary path updates. It could be as simple as

Replace(GetHTML, """./", """" & Replace(CurrentProject.Path, "\", "/") & "/")

assuming the resources are all found in the same directory as the current database. If you don’t perform such replacements, you will end up with missing content and errors, to the point that the page itself may not display.

Opening a Blank Page

It may be useful at times to show a blank page (perhaps to avoir the “The address is not valid” page) and nothing could be easier! You would simply use “about:blank” as the WebBrowser’s control source, such as:

Me.WebBrowser0.ControlSource = "about:blank"

The above didn’t work when I recently tested in Access 2019 and instead I needed to do:

Me.WebBrowser0.ControlSource = "=""about:blank"""

Working With the WebPage

It is one thing to render a webpage, but what about working with it.

One important thing to note is that to avoid errors and code not working, you need to always ensure the browser is finished working/processing/loading the page. To do so, after setting the ControlSource, or writing content, or whatever else you may do, you need to do something along the lines of

Do While Me.WebBrowser0.Object.Busy Or Me.WebBrowser0.Object.ReadyState <> 4
    DoEvents
Loop

This will guarantee that the code doesn’t move on to other things until the browser is done and ready.

Also, if you are doing this at the initial opening of a form, be sure to use the Load event, not the Open event (it won’t work).

Retrieving the Current Page’s URL

If ever you wanted to allow your user’s to freely navigate and then capture the URL they are on, it is remarkably simple to do. The code would look like:

Me.WebBrowser0.LocationURL

Retrieving a Page’s HTML Source Code

Another thing I found hard to find any instruction on was retrieving the web page’s entire HTML source code.

You can easily retrieve the HTML between body tags (<body>…this stuff here…</body>) by simply doing

Me.WebBrowser0.Object.Document.body.innerHTML

but I was, yet again, surprised at how hard it was to find any information on retrieving the entire page’s HTML source code. Once again, I won’t bore you with all my attempts, here’s the solution! Simply do

Me.WebBrowser0.Object.Document.documentElement.outerHTML

Executing Code on the Webpage

Sometimes you might need to execute code on the webpage, say run a javascript function, this can be done quite easily using execScript. This was somewhat demonstrated, but not elaborated, in the ‘Dynamic Content on the Fly’ section above.

Below is an example of how this is done
Let’s display a simple alert dialog to the user

Me.WebBrowser0.Object.Document.parentWindow.execScript ("alert('Hello World!');")

Let’s post a value to the console (this can be very useful during development!)

Me.WebBrowser0.Object.Document.parentWindow.execScript ("console.log('Hello World!');")

Now, let’s say we wanted to run one of the webpage’s javascript function, one called highlightRow, then we’d do something like

Me.WebBrowser0.Object.Document.parentWindow.execScript ("highlightRow();")

Don’t forget that after running such code, it is a good idea to add

Do While Me.WebBrowser0.Object.Busy Or Me.WebBrowser0.Object.ReadyState <> 4
    DoEvents
Loop

to ensure that the page finishes processing before moving on to the next thing in your code.

This can be an effective way to pass data from your database to a webpage. You can create a javascript/jQuery/… function on the webpage, or entirely in your VBA code, that accepts input variable(s) and then when you call execScript you simply pass the data along as the appropriate input variable(s). A very simple example to demonstrate this would be (using the built-in alert method) to display a message to the user with the current database’s name (this could just as easily have been data from a form, query, table, …).

Me.WebBrowser0.Object.Document.parentWindow.execScript ("alert('Your Access Database " & Application.CurrentProject.Name & " rocks!');")
Caution
Note that the current WebBrowser control, even using the Browser Emulation hack, cannot support certain modern day code.

For instance, it cannot support any JS Promise code, nor can it support HTML5 Canvas. So before spending too much time developing a functional solution in HTML/JS/… and then dropping it into the Access WebBrowser control, validate things at an early stage! (learn from my mistake 🙁 )

When developing html/js/… be sure to do all your testing in IE. Even if it works in every other browser, if it doesn’t run safely in IE, it most probably will not work in the WebBrowser control! (once again, learn from my mistake 🙁 ) and don’t ask me what we’re supposed to do once they retire IE in June, we’ll have no means to properly develop/test anymore.

Form Current Event

So what if you want to perform an action, say run some JS, when the user switches records?

Your instinct would be to use the form’s current event, and that would be right, and wrong at the same time!

In a general sense, that might work with the exception of the initial load! When the form loads, in my experience, the current event fires before the web browser control is fully loaded…

So what’s the solution?

It to use a combination of events and log when the control is initialized. This is the basic concept

Private bPageInitialized As Boolean


Private Sub Form_Current()
    If bPageInitialized Then Call SomeProcedure
End Sub

Private Sub Form_Open(Cancel As Integer)
    bPageInitialized = False ' Not strictly necessary
End Sub

Private Sub WebBrowser0_DocumentComplete(ByVal pDisp As Object, URL As Variant)
    If pDisp.ReadyState = READYSTATE_COMPLETE Then
        bPageInitialized = True
        Call SomeProcedure
    End If
End Sub


Private Sub SomeProcedure()
    'Some code
End Sub

Refreshing the Webpage

Sometimes it can be useful to refresh the webbrowser page. To do so through code you simply do:

Me.WebBrowser0.Object.Refresh

Printing the Webpage

Printing is another one of those common tasks that can easily be accomplished in a variety of ways using simple VBA. Below are a few examples illustrating how you can use a button within Access to do so:

'Opens print dialog
Me.WebBrowser0.Object.Document.parentWindow.execScript ("window.print();")
'Opens print dialog
Me.WebBrowser0.Object.Document.execCommand "Print"
'Provide print preview window and the print dialog from there
Me.WebBrowser0.Object.ExecWB OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_DONTPROMPTUSER
'Print directly without dialogs or print preview
Me.WebBrowser0.Object.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER

Another option is to include the print button directly in your HTML and use standard JS to automate the process. Thus bypassing the need to do any coding within your database application and having it part of the native webpage. This can be a useful solution only if you are the creator of the webpage.

Saving the Webpage

If you want to save the currently displayed webpage there are a number of ways to do so.

Using ExecWB (this requires a Reference to Microsoft Internet Controls)

Me.WebBrowser0.Object.ExecWB OLECMDID_SAVEAS, OLECMDEXECOPT_DONTPROMPTUSER, "C:\Users\Dev\Desktop\TestSave.html"
Me.WebBrowser0.Object.ExecWB 4, 2, "C:\Users\Dev\Desktop\TestSave.html" 'With no reference

Using execCommand

Me.WebBrowser0.Object.Document.execCommand "SaveAs", False, "C:\Users\Dev\Desktop\TestSave.html"

What is bothersome with the above approaches is there doesn’t seem to be a way to avoid the SaveAs pop-up dialog (for one thing, the ExecWB completely ignores the DONTPROMPTUSER option). That said, perhaps the best and easiest solution would be to simply capture the active WebBrowser Control’s HTML since we already have it and save it!

Call OverwriteTxt("C:\Users\Dev\Desktop\TestSave.html", Me.WebBrowser0.Object.Document.documentElement.outerHTML)

Which requires a copy of my OverwriteTxt() functions which can be found at: VBA – Export to Text File

Retrieving Information From The WebPage

The WebBrowser control also enables us to interact with the given webpage to execute code and/or retieve information from it. Here are a couple examples of techniques to retrieve information from various controls on a webpage.

Use JS to pass the src of an image to a JS variable and then retrieve the variable’s value.

Dim oWebBrowserObject As Object
Dim sSrc As String

Set oWebBrowserObject = Me.WebBrowser0.Object
oWebBrowserObject.Document.parentWindow.execScript ("var imgSrc = $('img')[0].src;")
sSrc = oWebBrowserObject.Document.Script.imgSrc

Here’s another approach to the same problem using getElementsByTagName

Dim oWebBrowserObject As Object
Dim sSrc As String

Set oWebBrowserObject = Me.WebBrowser0.Object
sSrc = oWebBrowserObject.Document.getElementsByTagName("img")(0).src

Here’s yet another approach to the same problem using getElementById

Dim oWebBrowserObject As Object
Dim sSrc As String

Set oWebBrowserObject = Me.WebBrowser0.Object
sSrc = oWebBrowserObject.Document.getElementById("ItemPic").src

Retrieve the id of the 1st img control on the page

Dim oWebBrowserObject As Object
Dim sId As String

Set oWebBrowserObject = Me.WebBrowser0.Object
sId = WebBrowserObject.Document.getElementsByTagName("img")(0).id

Or as a single line of code you could do:

Dim sId As String

sId = Me.WebBrowser0.Object.Document.getElementsByTagName("img")(0).id

If you look in the VBE Object Browser under the MSHTML library, under the HTMLDocument class, you will see all the functions, methods, … at your disposition for working with the webpage, notably:

  • getElementById
  • getElementsByClassName
  • getElementsByName
  • getElementsByTagName

So, as you can see, using typical JS techniques we can retrieve information quite easily.

Where’s Intellisense?

One of the annoying things working with the WebBrowser control was that intellisense only worked 1 element deep meaning that typing Me.WebBrowser0 would provide intellisense, but the minute you went to a 2nd element deep (me.WebBrowser0.Object), or a 3rd element deep (me.WebBrowser0.Object.Document), … you no longer had any intellisense making development that much more complicated and frustrating.

Thankfully, there is a trick to get it back where it counts most (the Document). If you set a reference to the Microsoft HTML Object Library (mshtml.tlb) and declare a variable for the HTML Document as MSHTML.HTMLDocument, then you regain intellisense for your Document coding. So, I typically end up doing something along the lines of

Sub SomeSub()
    #Const Dev = True    'True  -> Early Binding, Ref Library Req'd
                         'False -> Use Late Binding, No Ref Libraries

    Dim oWebBrowser           As Object
    Dim oWebBrowserObject     As Object
    #If Dev = True Then
        Dim oHTMLDoc          As MSHTML.HTMLDocument    'Req Ref to Microsoft HTML Object Library
    #Else
        Dim oHTMLDoc          As Object
    #End If

    On Error GoTo Error_Handler

    Set oWebBrowser = Me.WebBrowser0
    Set oWebBrowserObject = oWebBrowser.Object
    Set oHTMLDoc = oWebBrowserObject.Document

    'oHTMLDoc... 'Your code starts here with Intellisense now!

Error_Handler_Exit:
    On Error Resume Next
    If Not oHTMLDoc Is Nothing Then Set oHTMLDoc = Nothing
    If Not oWebBrowserObject Is Nothing Then Set oWebBrowserObject = Nothing
    If Not oWebBrowser Is Nothing Then Set oWebBrowser = Nothing
    Exit Sub

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: SomeSub" & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Sub

in which I use Condition Compilation Directives to use Early Binding during development to gain use of Intellisense and then switch to Late Binding (by simply switching Const Dev to False, and removing any added Reference Libraries) to not require any reference libraries as runtime (when I distribute it to my users).

So now you get
VBA AutoComplete
Depending on your needs, you can define many other object variables to simplify your programming. For instance, if you’re going to be working with the webpage it can be useful to define a body object variable and this can easily be done:

Sub SomeSub()
    #Const Dev = True    'True  -> Early Binding, Ref Library Req'd
                         'False -> Use Late Binding, No Ref Libraries
 
    Dim oWebBrowser           As Object
    Dim oWebBrowserObject     As Object
    #If Dev = True Then
        Dim oHTMLDoc          As MSHTML.HTMLDocument    'Req Ref to Microsoft HTML Object Library
        Dim oHTMLDocBody      As MSHTML.HTMLBody
    #Else
        Dim oHTMLDoc          As Object
        Dim oHTMLDocBody      As Object
    #End If
 
    On Error GoTo Error_Handler
 
    Set oWebBrowser = Me.WebBrowser0
    Set oWebBrowserObject = oWebBrowser.Object
    Set oHTMLDoc = oWebBrowserObject.Document
    Set oHTMLDocBody = oHTMLDoc.body
 
    'Your code goes here
    
Error_Handler_Exit:
    On Error Resume Next
    If Not oHTMLDocBody Is Nothing Then Set oHTMLDocBody = Nothing
    If Not oHTMLDoc Is Nothing Then Set oHTMLDoc = Nothing
    If Not oWebBrowserObject Is Nothing Then Set oWebBrowserObject = Nothing
    If Not oWebBrowser Is Nothing Then Set oWebBrowser = Nothing
    Exit Sub
 
Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: SomeSub" & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Sub

and so on. You can define any object variable you’d like to not have to carry along statements like

Me.WebBrowser0.Object.Document.body...

every time you want to refer to an element, loop through some tag, find some class, id, …

For a one off situation it doesn’t simplify things much, but when you get into serious automation, such object variables will save you a ton of typing and make your code easier to read/troubleshoot and you get the added bonus of gaining intellisense!

Feature Browser Emulation

By default, it would seem that, Access WebBrowser runs as an instance of Internet Explorer (IE) 7 regardless of what you have installed on your PC. This can cause major compatibility with any more recent code implementations. Quite often this manifests itself as Javascript errors.

Luckily, there is a relatively easy fix, in that we can actually control the ‘Emulation’ used. So we can actually tell Access to run as IE 8 … IE 11 and on new PCs even Edge guaranteeing the greatest compatibility possible.

This is all controlled by a registry key names ‘FEATURE_BROWSER_EMULATION’.

Previously, refer to my original post on the subject http://www.devhut.net/2013/10/18/webbrowser-activex-control-google-maps-invalid-character-scripting-error/, I was creating this entry in the HKEY_LOCAL_MACHINE (HKLM) registry hive, and it worked just fine. However, some time between when I originally did this and now, this no longer works. This actually turned out to be a blessing in disguise, because when you do so in the HKLM you need to determine the bitness (32 or 64) to write the value in the appropriate key.

However, now, we can simply make the entry in the HKEY_CURRENT_USER (HKCU) registry hive and need now not even be concerned with bitness at all!

We need only make a DWord value entry in the

HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION

registry key for the exe of interest, so in our case msaccess.exe. This therefore implies that the emulation mode will apply to all Access databases, not just the current one.

DWord Decimal Value   DWord Hexadecimal Value   Corresponding Emulation   Corresponding JS navigator.userAgent
7000   1b58   IE7 Emulation   Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; NMTE; wbx 1.0.0; Zoom 3.6.0)
8000   1f40   IE8 Emulation   Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; NMTE; wbx 1.0.0; Zoom 3.6.0)
8888   22b8   Force IE8 Emulation   Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; NMTE; wbx 1.0.0; Zoom 3.6.0)
9000   2328   IE9 Emulation   Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 10.0; WOW64; Trident/7.0; NMTE)
9999   270f   Force IE9 Emulation   Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 10.0; WOW64; Trident/7.0; NMTE)
10000   2710   IE10 Emulation   Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 10.0; WOW64; Trident/7.0; NMTE)
10001   2711   Force IE10 Emulation   Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 10.0; WOW64; Trident/7.0; NMTE)
11000   2af8   IE11 Emulation   Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; NMTE; rv:11.0) like Gecko
11001   2af9   Force IE11 Emulation   Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; NMTE; rv:11.0) like Gecko
12001, 13000, 13001, 14000, 140001, …   2ee1, 32c8, 32c9, 36b0, 36b1   Emulate the most recent version installed on the local computer (this is between Internet Explorer and Edge)
Note: Be careful, a value of 12000 (2ee0) emulates IE11!
  Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19044

So at the end of the day, unless there is a very particular reason for a specific emulation mode (because you need to support some legacy webpage for instance) you should simply create a DWord value for msaccess.exe with a value of 12000 (or higher) so your WebBrowser control is always running the latest and greatest version available.

Also, although I recommend using the HKCU, keep in mind the Feature Browser Emulation can also be set in either

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION

Or

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION

So if ever your settings don’t seem to be taking effect, check those registry keys as well as they be interfering with your value.

If you want to validate the version that your WebBrowser control is actually emulating, the simplest method is to navigate your WebBrowser control to https://www.whatsmybrowser.org/.

Special Note
One special note regarding setting the FEATURE_BROWSER_EMULATION value and Access. For the change to take effect, all instances of the exe (msaccess.exe in the case of Access) must be closed and restarted. So that means that a Compact and Repair will not suffice (I learnt this the hard way), you must close Access and restart it for the FEATURE_BROWSER_EMULATION to take effect.

If you like to live on the edge, what I’ve discovered is, if you open a your database, but don’t open the form containing the WebBrowser control, you can still change the FEATURE_BROWSER_EMULATION value and it will take effect when you open your form. That said, once the form/WebBrowser control has been initialized any changes to the FEATURE_BROWSER_EMULATION do not take effect until you complete close and restart Access.

Feature Browser Emulation – Alternative

Not Reliable
After some testing I have come to the conclusion that this isn’t reliable with the WebBrowser control. I created a simple HTML file and include the header meta
[code language=”html”]<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE11" />[/code] Opening the file in IE properly renders using Emulation Mode IE11 and JS confirms this. However, loading the sample file in the WebBrowser control render in IE7.

All that to say the Feature Browser Emulation remains the way to handle this!

After a brief discussion with one of my fellow MVPs, I thought I’d share an alternative to setting up the registry hack FEATURE_BROWSER_EMULATION which, let’s be serious, can be a PITA.

IE has a X-UA-Compatibility Meta Tag available to us that allows a web developer to tell the web browser the version of IE that it was designed for and the browser is supposed to adjust itself to that version for best compatibility.

So, it is possible, in the raw HTML to instruct the web browser to change version, thus bypassing the need for the registry hack.

You can learn more about all the X-UA-Compatibility Meta Tag options by consulting the official documentation: [MS-IEDOCO]: X-UA-Compatibility Meta Tag and HTTP Response Header | Microsoft Docs

But basically, you can try to include the following line in the header of every single webpage you will use and it should get the browser to emulate the specified IE version.

<meta http-equiv="X-UA-Compatible" content="IE=edge" />

The above pushes the webbroser to emulate the highest version available.

That said, I have found this to be, at times, unreliable (this is why I didn’t include this when I first created this article), so be sure to test things out, but it might just save you needing to mess around with registry settings!

So think of the Feature Browser Emulation as a one time global fix and the X-UA-Compatible as a individual page fix. So, X-UA-Compatible is only good if you control the webpage(s) you are viewing with the webbrowser control, otherwise, if you are navigating to outside website/webpages, the solution remains to implement the Feature Browser Emulation regisrty hack.

If you want to learn more regarding X-UA-Compatibility, here is a good thread on the subject:

Mark of the Web (MOTW)

Another thing I learnt the hard way was that local files don’t just work. IE, and apparently Edge, using security zones to lock web pages. So, normally, by default, webpages will see code locked down. For instance, my javascript wouldn’t run when I first loaded the pages as is. After some research I found out that you needed to apply the MOTW to the files so as to authorize the pages to run locally.

What does that mean exactly? Say your html file start off like

<!DOCTYPE html>
<html>
	<head>

to get my pages to run properly I ended up with

<!DOCTYPE html>
<!-- saved from url=(0016)http://localhost -->
<html>
	<head>

by simply adding the line

<!-- saved from url=(0016)http://localhost -->

following the beginning <html> tag, my files were now trusted and allowed to run uninhibited. Life was good once again!

Working with Local Resources

If you are planning on using local resources within your HTML: script files, images, … you are best to prefix the src attributes with file://

So, instead of:

<img src="C:\temp\sunflower.jpg" alt="Picture of a Sunflower" width="300" height="400">

Do:

<img src="file://C:\temp\sunflower.jpg" alt="Picture of a Sunflower" width="300" height="400">

With regards to script files in particular, it seems that Microsoft has blocked local scripts from running via webbrowser control by default and you must now add a DWORD Registry entry to

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BLOCK_LMZ_SCRIPT

for msaccess.exe with a value of 0. Then close and restrat Access.

So if you have html that renders fine in a web browser, but gives you a scripting error when run via Access’ webbrowser control, try making the above addition you your registry.

Simply Ignoring Script Errors

WebBrowser_GoogleMaps_Script_Error
While not the approach I’d typically recommend, if you don’t want to get into hacking the registry by adjusting the FEATURE_BROWSER_EMULATION value, but would like to make those pesky Script Errors go away, there is a simple fix, you can simply do:

Me.WebBrowser0.Object.Silent = True

What this does is basically stop the script errors from being displayed. The errors are still there, you haven’t actually resolved whatever the actual problem is, but they aren’t being displayed anymore.

Obviously, ignoring the error may load the page (or may not if the script is part of the loading process), but does not garantee functionality. So the page may not work as intended since there are issues with the various scripts used by the webpage. This is why, IMHO, you are better with implementing the FEATURE_BROWSER_EMULATION registry hack.

HTML Template

Based on all of the above, if you control the HTML file being used, below would be the starting point I would use for build the HTML Page.

<!DOCTYPE html>
<!-- saved from url=(0016)http://localhost -->
<html>
	<head>
		<title>YourTitle</title>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" />
	</head>
	<body>

	</body>
</html>

Some might ask why I use

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

instead of the newer

<meta charset="utf-8">

because it is newer and by default the WebBrowser emulates older versions of IE (unless you override it). So to maximize compatibility and hopefully avoid issues I prefer to stick with the older form. Now if I was build a public site, I’d use the new HTML5 format.

Also, when the new WebBrowser control sees daylight, then it could be good practice to swicth as well.

Sample Database

Below you can download a sample database which illustrates most of what is covered in this article.

Disclaimer/Notes:

If you do not have Microsoft Access, simply download and install the freely available runtime version (this permits running MS Access databases, but not modifying their design):

Microsoft Access 2010 Runtime
Microsoft Access 2013 Runtime
Microsoft Access 2016 Runtime
Microsoft 365 Access Runtime

All code samples, download samples, links, ... on this site are provided 'AS IS'.

In no event will Devhut.net or CARDA Consultants Inc. be liable to the client/end-user or any third party for any damages, including any lost profits, lost savings or other incidental, consequential or special damages arising out of the operation of or inability to operate the software which CARDA Consultants Inc. has provided, even if CARDA Consultants Inc. has been advised of the possibility of such damages.

Download a Demo Database

Feel free to download a 100% unlocked copy by using the link provided below:

Download “Access - Playing With The WebBrowser Control” PlayingWithTheWebBrowserControl.zip – Downloaded 11743 times – 81.64 KB

Resources on the Subject

Documentation on the Subject

Demos and Examples to Learn From

The best thing to learn is to simply dive in and dissect demos and examples, so feel free to check out

Special Thanks

During exploration of this control, I’ve had several back and forths with fellow MVPs to get help and ideas. I’d like to thank them for their continued support. It is in part their knowledge and willingness to share that makes this article and demo databases possible. I hope I’m not overlooking anyone, but I’d like to thank, in no particular order:

  • Gustav Brock
  • Jack Leach
  • Ben Clothier
  • James Dettman
  • Tom Wickerath
  • Adrian Bell

Page History

Date Summary of Changes
2019-10-18 Initial Release
2019-10-31 Added the Executing Code on the Webpage section
Added a ‘table of contents’ to the beginning of the page
Added more information to the Feature Browser Emulation section
2019-11-03 Added the Where’s Intellisense? section
2020-01-07 Added the Opening a Blank Page and Simply Ignoring Script Errors sections
2020-04-26 Added the Refreshing the Webpage section
Added explanations to the Dynamic Content on the Fly section regarding relative/absolute paths
2020-11-07 Added Hexadecimal values to the Feature Browser Emulation table
Added Demos and Examples to Learn From section to Other Resources
2021-10-07 Added the Feature Browser Emulation – Alternative section
2022-03-18 Updated the Emulation value for Edge based on comments and testing.
2022-05-29 Added the Working with Local Resources section.
2022-09-01 Added the Printing the Webpage section.
2022-09-01 Added the HTML Template section.
2022-09-20 Added the Retrieving Information From The WebPage section.
2022-09-22 Added a link to the new supporting YouTube video
Added the Sample Database section.
2022-09-22 Added the Saving the Webpage section.
Added the Corresponding JS navigator.userAgent column to the Feature Browser Emulation table.
2022-12-05 Added the Retrieving the Current Page’s URL section.

88 responses on “Everything You Never Wanted to Know About the Access WebBrowser Control

  1. Llewelyn

    Hello Daniel,
    I tried to use the web browser emulation with the HKEY_CURRENT_USER trick and it worked fine on my personally owned laptop but NOT on the laptop issued by my company. Both are using Win 10 and Access 365.
    I was thinking HKEY_CURRENT_USER would work alone since no admin rights are needed. Is there another set-up that I should do? Is it because I’m logged in to a network domain that the emulation doesn’t work?
    Thanks!
    Lou

  2. Mark

    Hi Daniel – excellent excellent work as ever

    Just a thought on your Dynamic creation of web forms – have you considered writing a database that links to SQL Azure db and then dynamically creates a simple WEB CRUD form from selected fields which can be selected through Access – using a bootstrap theme.

    undoubtedly some security issues but I think you could probably do it!!!
    Its something I have considered giving a go but not quite as advanced as yourself.

    M

    1. Daniel Pineault Post author

      It is most certainly possible and I had thought of it, BUT I already create proper Web based Web Applications and thus I don’t see it as a smart investment of my time presently.

      For me, if I want a web based CRUD application I will simply create it using the proper web technologies, and not Access.

      Also, don’t forget you can simply link to Azure tables directly and use standard Access forms, queries, reports, … so going through a webbrowser control is simply not necessary.

      But, I too had thought of it at one point in time.

      1. Mark

        pps

        Probably not needed by you but I bet your readership would be very interested and might introduce them to web programming.

  3. Tom

    Keep in mind it is an MS product. Built in the ’90’s. (anyone got a mix tape I can borrow LOL)
    Like so many MS products, the idea was great, but implementation falls short.
    When I have to deal with MS Access, I try to keep in mind, “we are supposed to only think INSIDE the box”.
    There has been so many times in the past that I have hung Access without even touching the keyboard. No code, just using menus. LOL

  4. Tom

    I would like to thank you very much for taking the time to do the research and write this article. It is extremely useful for me at the moment. MS Access falls short (in many ways) of being able to format a ‘page’ or ‘report’ the way I want and this HTML allows me to do what Access fails at so badly for my purpose.
    By the way, the project is not big enough to bother with the install and maintenance of a web server. But HTML can format the data in a nice and well structured manor.

    Again, thank you for your research and this write-up.

  5. Richard

    Thanks Mark.
    whatsmybrowser reported my system as IE11 even with none of the mentioned keys.

    However screen size, browser size, color depth etc were not shown and one site telstra.com did not render correctly .

    After adding the user key whatsmybrowser shows the sizes and telstra.com renders correctly.

  6. Nick Auger

    Thank you or this article; very helpful.

    I have noticed that when I open an MS Access form with an embedded webbrowsercontrol, the system’s memory usage grows dramatically (approx 100MB each time I open the form). What’s more, the memory is not released when you close the form. The only way to clear the memory is to exit the application.

    I cannot find a VBA equivalent of Garbage Collection and can find no alternative. Have you any experience of this?

  7. Graeme Couves

    Hi Daniel,
    really great page. I got tripped up when I copied your code from “Dynamic Content on the Fly”
    .write “Some content.”
    Took me ages to work out why VBA didn’t like it – your double quotes are the slanted type (66 99) rather than the normal ones. Once I had changed them it now parses ok.
    .Write “Some content.”

    1. Graeme Couves

      I see that in publishing my comment the HTML (html, head, body and p) I copied from above has been interpreted and the double quotes changed to the slanted type. I hope you understand what I was trying to say, if not I’m happy to clarify via email.

      I’m hoping this helps towards solving my issue I have been having where first time in I need to assign inner html 2 or 3 times before the web control shows what I want it to (Is form load the wrong place to do this?) but subsequent assignments then work ok. I have been using the loop from “Working With the WebPage” to check status, first time in it seems to stick at 3 (I have waited minutes for it to change)

      1. Graeme Couves

        Great, all now works ok with this change.
        Happy for you to reject my comments, but preferably (for other peoples sakes) fix the double quotes in the sample code.
        Also noticed, in the same section, .write Me.HTMLFieldName the w in Write is not capitalised (as if it has not parsed in Access)

        1. Daniel Pineault Post author

          Not rejecting anything. It’s the weekend and I usually don’t deal with work and try to concentrate on family time as much as possible. This blog is a work of love, not a job. When I have time I contribute. It can go days, weeks without me logging in.

          That all said, thank you for flagging the issue. Not too sure how this happened as I usually copy the code directly from the VBA editor into the blog’s text editor? That said, the minute you copy/paste it into VBA the erred quote get flagged in red and the code doesn’t compile.

          As for capitalization, this does occurs if Intellisense isn’t enabled which could have been the case during my development, and/or it also does act funny at times (I have dbs in which many variables get capitalized for no reason, or vice versa) which has been reported to MS in the past but nothing ever came of it. Luckily, unlike many other languages, the Case of the code has no impact on its functionality, so it is merely a visual thing, nothing to worry about.

  8. JB Richter

    Have you had any issues with “loosing” the Class Object to the Form? I have created a simple form, added the web browser control to display pdf files. When i edit the form, the Class Object Form_(form name) disappears, MS access prompts to override the (form name) to save. When I give it (form name1) it saves (form name1) but the original form does not have any Class Objects associated with it.

  9. Gustav Brock

    Great reference, Daniel. Thanks!
    That “bogus” value could simply be 0 (zero) – a little neater than 1234 which might look as some magic number.

    Bonus tip:
    After setting MSACCESS.EXE to your preferred value, do check the setting for OUTLOOK.EXE. Adjusting that will probably make most of your received e-mail newsletters render as intended.

  10. rcarmo

    The tips you gave above were really helpful to me, thanks a lot.

    After hours of research through the internet, I didn’t find any direct solution to “route” a DOM element event to a Sub or Function in VBA, for example, to know when a button has been clicked in the HTML document.

    I was able to work around it by using this simple lines of code:

    Private Sub WebBrowser0_Click()
    On Error Resume Next
    Dim e As IHTMLElement
    Set e = hdoc.activeElement
    If Not (e Is Nothing) Then
    If e.getAttribute(“type”) = “button” Then
    Exec (e.getAttribute(“id”))
    End If
    End If
    End Sub

    Private Sub Exec(str As String)
    Text4.value = “Button with ID:” & str & ” was clicked!”
    End Sub

    I hope it may be useful for anyone out there.

  11. rcarmo

    I just found out one more interesting thing to get rid of the script errors and get your html/css/js properly rendered in the WebBrowser object. I followed the steps mentioned above to set the FEATURE_BROWSER_EMULATION to the last version (Microsoft Edge 87. on my case) and tried to use the UIKit web framework (https://getuikit.com) on my application, and (as expected) besides not rendering the controls correctly it started triggering script error notifications due to the js of UIKit.

    The solution was to explicitly declare the tag , as show below:

    Title

    All controls are now rendering correctly and not a single script errors is being shown anymore.

    You’ll find more info at: https://stackoverflow.com/questions/6771258/what-does-meta-http-equiv-x-ua-compatible-content-ie-edge-do

  12. Andres Dominicci

    For some reason when assign the control source to the web browser and it has unicode characters it replaces them with ?.

    I ran the code in debug mode and the variable has the unicode characters. Any ideas?

    B?nkformarev?gen 7,V?rnamo,Sweden,331 91

    Here is my actual variable:
    =”https://www.bing.com/maps/default.aspx?where1=Bänkformarevägen%207,Värnamo,Sweden,331%2091&sty=c”

  13. Mike

    Thanks a lot for sharing all these experiences!

    It helped me quite a bit. I wonder why MS does not provide any useful documentation.

    I use the webbrowser control in VBA Excel. However, it seems to be somewhat different.
    In Excel it seems not possible to use commands with the word “Object” like in “Me.WebBrowser0.Object.Document”. Shouldn`t it be similar to Access?
    Thanks again!

    1. Daniel Pineault Post author

      The lack of standardization throughout Office & Office VBA is mind-numbing. The fact that MS couldn’t even standardize something like retrieve the current application’s Hwnd, set visibility, … is incomprehensible, but that is life.

  14. Michael Krispin

    Hi Daniel,
    thanks a lot for this tutorial.
    I open PDFs in this WebBrowserControl which is in a sub form and when I move the main form I load a new path into the control source. That works fine.
    Now I look for a possibility to mark text in that WebBrowserControl after it loads.
    Do you know if that is possible? I searched a lot in internet but could not find a solution for MSAccess.
    Thank You and Best Regards
    Michael

  15. Anthony

    For Feature Browser Emulation, don’t forget the following key.

    HKEY_USERS\\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION

    During troubleshooting of an oracle plugin within microsoft, we found that as well.

  16. Ozair Khalid

    Hi Daniel,

    Thanks for this wonderful tutorial, I am actually interested in Dynamic Content on the Fly.
    Unfortunately its not working in my file.
    All I see is “Object variable or With block variable not set”
    Can you please help?
    Copied Code
    Private Sub Form_Current()
    With Me.MyWebBrowserControl.Object.Document
    .Open ‘ << error appears on this line [Object variable or With block variable not set]
    .Write " hello world! ”
    .Close
    End With

    End Sub

    System Detail
    Office 2016 64 Bit
    Windows 10 64 Bit
    Not sure if it was needed but I already added Reference for “Microsoft HTML Object Library” anyway.

    1. Daniel Pineault Post author

      It depends on the event you use. For instance On Open is to early, you have to ensure the control exists and is fully loaded before you can manipulate it. It did work for me in the On Load and On Current events though. I tested in Access 2013 x32 and Access 2019 x64.

      You’re using the ‘Web Browser Control’ and not the ‘Microsoft Web Browser’ ActiveX Control?

      Also, no references are require for this to work.

  17. Jim B

    in MS Access form, web browser control …views pdf files ok – – except for 2 PCs and although their default is definitely the Foxit PDF reader like all the other PCs – for some reason their browser control always uses the Adobe Reader – and then the app crashes… am perplexed… any thoughts?

  18. Walter van der Geest

    Dear Daniel, thanks for this excellent summary. As a long-time Access Developper, I use the WebBrowserControl heavily, mostly fed by HTML-Files I save in the Resource-Table (MSysResources) so I do not have the hassel with security settings.

    What I would like to share is some troubles you can run into with the FEATURE_BROWSER_EMULATION: The Opera browser delivers a utility called browser_assistant.exe, which is installed by default and gracefully deletes ALL your entries in this key every time it is started. Users should be aware of that, and as you described, in your MSAccess-Program, it is too late to reset the value.

    I wanted to ask you what you see for the future of the WebBrowserControl – MS is stating since 2016 that it discontinues Internet Explorer, but WebBrowserControl is in fact IE. Have you anything heard about plans in that direction?

      1. Marco van den Berg

        Hi Daniel,

        I tried to make the webcontrol work for LOCAL FILES.
        the webcontrol works beautifully for external webaddresses, but when I want to load a local file, like c:\temp\index.html > it won’t work! Do you know how to fix this?
        Thx in advance.

        1. Daniel Pineault Post author

          You haven’t provided me any information to be able to offer any advice.

          How have you loaded the local file? What is the HTML file’s content? Can you provided a sample on an online shared drive for me to look over?

          1. Marco van den Berg

            Hi Daniel,

            I wanted to get your example file working and also the QR-code: index.html file. This is a local file, which won’t load in the WebBrowser control.
            When inspecting te page it only shows:

            When using an online webpage everything works fine in the Webbrowsercontrol.

            It seems Microsoft fixed the bug. It is suddenly working again now. Thx. anyway

  19. Neil Humphris

    Everything!? How about Zoom Level.
    How can I get a WebBrowser to display at 50% (yeah, yeah, I know I can use the keyboard; but Ctrl + – (Minus) also wants to delete a record…. (that was a new discovery for me)

  20. Neil Humphris

    Ay-oup… here it is

    PageZoom = 66
    Me.WebBrowser4.Object.ExecWB OLECMDID_OPTICAL_ZOOM, _
    OLECMDEXECOPT_DONTPROMPTUSER, _
    CLng(PageZoom), vbNull

  21. Alex

    Hello,

    first up, this is a great article and very helpful. However I still run into problems.
    I’m currently building a webapp using Vue.js and now I’m trying to include it in my access project using the webbrowser control. Even though I changed the browser version using the emulation method, as well as adding a MOTW, I still get script error messages. I’ve tried setting the key value to 0, which resulted in Edge version 18, as well as the value 11000, which is IE11. Even on other websites that do not use frameworks, I still get script errors.
    Do you know anything about that?

    Best regards 🙂

  22. Griet De Groote

    Hello ,

    i ‘ ve used webbrowser control a long time to view a local file in an access form. all of a sudden i can not see the file anymore, it stays blank. i did not change anything … what could be th reasin ?

  23. Ian J.

    It appears that after setting ‘about:blank’ in the web browser control on Form.Open that it’s not possible to write on the fly HTML to the control. I suspect that the ‘about:blank’ isn’t a document and therefore can’t be manipulated.

  24. Ian Vale

    Hi Daniel,

    I don’t know if this might be an IE or Edge bug, or if it’s specific to the web browser control, but I haven’t been able to get SPAN tags to work with classes defined in a CSS style section in the HEAD. They work with inline style information, just not with a class name referenced in the style section.

    Any ideas?

    Thanks in advance,

    Ian J.

    1. Ian Vale

      Scratch this one. I’ve just found a couple of places in my css section where the brackets were wrong. Unfortunately when I started writing the css I was using a plain text format and couldn’t see that something was amiss. When I changed it to a .css extension and opened it in Notepad++ then the errors were more visible.

  25. Daniel Chen

    Hi
    this is by far better than going to Microsoft site for knowledge on access webbrowser control.
    looks like you have mastered it
    i have a simple question
    if a user enter a search box just words like “google” or “ping” etc.
    how do i change search box string to search in user default engine?
    thank you

  26. David L

    Great post and your site in general.
    I have needed to change from just displaying images on a form stored locally to on the web with via a URL. I have the images into webbroswer from URL, so no problem there. But I have to things that I am trying to find more information on but have not been successful.
    1. I have a Webbroswer object for an image in a form. Some of the images are larger and other smaller than the window. When the image displays, it presents full size, so I need to scroll to see the whole thing. I need to make the whole image visible in the space available. I tried the image zoom described above and it works. But I don’t know the amount to zoom as I don’t know the image size ahead of time. Is there a way to either fit to the window or read the image size without saving locally?
    2. I would like to be able to change the size of the Webbroswer window based on the number of images I need to display in the form. I can do this with image objects with .height, but I have not found out how to do it Webbroswer objects.
    Any suggestions appreciated

    1. Daniel Pineault Post author

      Some of this is hard to answer without seeing the database, HTML …

      For item 1. you can specify a width and height for images in HTML, so simply add those attributes as it will be resized automatically to fit the specified dimensions.
      For item 2., I may be misunderstanding the question, but you should be able to re-dimension the control dynamically without issue. I did a very quick test and code like the following worked for me

      Me.YourWebBrowserControlName.Height = 5 *1440
      Me.YourWebBrowserControlName.Width = 8 * 1440
      1. David L

        Hi Daniel,
        Second item first. The re-demensioning worked fine. I had two Web Browser controls next to each other and I did not hide the second one first.
        Back to the first item. I have the image displaying directly with navigate. But I want to create a dynamic HTML to give me more flexibility. But when I tried to insert the HTLM as you showed above.

        With Me.WebBrowser0.Object.Document
        .Open
        .Write “Some content.”
        .Close
        End With

        I got an error on Open like Ozair asked about in May. I already loaded and image in the WebBrowser and waited for it to complete before I tried to write the HTML code to the same object. Is there a library that I need to load first to use it with ‘Microsoft Web Browser’ ActiveX for HTML support?

  27. David L

    I manged to get it to work with the following
    With Me.WebBrowser1
    .Navigate “about:blank”
    Do While .Object.Busy Or .Object.ReadyState 4
    DoEvents
    Loop
    .Document.Open “text/html”
    .Document.Write strHTMLtext
    .Document.Close
    End With

    One of the things that was wrong was with the URL to the images. It contained a space. It works if you navigate directly, but does not work for HTML, you need to replace spaces with %20.

    But one thing is that IE does a terrible job down scaling the images. Does not seem to be a fix for it. Edge is a bit better, but is is also not as good as Firefox for Chrome.
    I tried all of the css settings that I could find and nothing made it better in IE, or the WebBrowser control. I was testing on standalone browsers to make sure the HTML/CSS worked fine before incorporating it into Access.

  28. Indigo

    Thank you for this article !

    For anyone having issues with the cursor flickering between “loading” (blue circle) and “normal” when moving the mouse inside a WebBrowserControl, I was able to fix it by setting the Screen.MousePointer property to anything other than 0 (see https://docs.microsoft.com/en-us/office/vba/api/access.screen.mousepointer).

    The best approach would be to set it inside got/lostFocus events, like so:

    Private Sub WebBrowser1_GotFocus()
    Screen.MousePointer = 1
    End Sub
    Private Sub WebBrowser1_LostFocus()
    Screen.MousePointer = 0
    End Sub

    1. Dave

      Indigo, after searching the internet for a long time, your simple tip is what solved my similar issue with the mouse pointer flickering. Thank you!

  29. Robert Newingham

    I am doing something very simple with the web browser control.
    It is in a form. The control source for the control is a text box.
    You open a file picker window and what you select populates the text box that is the control source for the web browser control.
    These files are pdf and are on a network drive
    Has worked without issue for 2 years. Suddenly the process stopped working properly.
    Some pdfs show in the browser control properly…and some give an error message of
    ‘There is a problem with Adobe Acrobat/Reader. If it is running please exit and try again(0:521)
    I can find no pattern regarding the pdfs the open properly and those that do not.
    Any thoughts

  30. Andreas

    Hi Daniel,

    thanks for you great post. Du you know how to play mp4 videos from the file system inside the webbroweser control. Each time when I try it a separate window playing the video pops up

    Thank you

    BR
    Andreas

  31. tony@stp.cards

    I am opening PDF files and I can seem to find a way to page down form Vba. We are doing data entry off of PDF’s and I am trying to get it so that after we enter the last value the PDF pages down on the on exit event of the last text box. I have tried using both the MS access option and the ActiveX one.

    I have tried multiple different versions of
    Me.WebBrowser3.Document.Window.ScrollTo(0, 200)
    Me.WebBrowser3.Object.Document.parentwindow.Scroll 1000, 200
    Me.WebBrowser3.Document.parentwindow.Scroll 0, 99999

    but I can’t seem to figure it out. I also struck out using the Activex controls for Adobe.

  32. Shayne

    I’d like to be able to set the default view of the web browser to “List” when using it to view local files.

    Best!

  33. Daniel Bragg

    Thank you for this. We had just about given up hope on this, as our calls to the Google Maps JavaScript API started returning “You are using a browser that is not supported”, but setting all three 3 registry keys with “12001” (2EE1) allows https://www.whatsmybrowser.org/ to identify the Web Browser Control as using Edge 18! Woot!

    Google Maps JavaScript API now runs again! Thanks!

    1. Daniel Bragg

      Please consider updating the article to include 12000/12001 (2EE0/2EE1) as valid Edge 18 values. 11000/11001 will not work for Google APIs anymore.

      Although it was buried within the comments, I had almost given up until I found it on a *DIFFERENT* blog post. Once I found it worked, I came back here to day Thanks, and found that the answer was here also, buried under pages of comments…

  34. Philipp

    @Daniel, thank you for all this valuable info!
    Can you please clarify in the text whether “Edge” applies to the original Microsoft Edge browser introduced with Windows 10, and/or also to the new Chromium based Edge browser that is current now?
    The previous comment mentions “Edge 18”, but the current version of Chromium Edge is 99!

    1. Daniel Pineault Post author

      Just apply the hack and test for yourself as indicated by navigating to a site such as https://www.whatsmybrowser.org/.

      By setting the emulation to 12001, 18001, …, you’ll see that the webbrowser control seems to always indicate Edge 18. Until we get a proper update or MS actually releases the new webbrowser control this seems to be the limit of how ‘up-to-date’ we can simulate things (using emulation to pretend we’re running a version released October 2018)!

  35. Steve Halder

    Excellent article, and the tool would be very useful if it worked and was supported, but a really keen broken tool is not of much use.

  36. Richard Rost

    Hi Daniel. Have there been any updates on this? I’ve tried everything, and I still can’t get rid of the damn script errors. I tried the WB.Object.Silent command (in multiple places), disabling script debugging, the browser emulation hack, you name it. I still keep getting “Message from webpage. ERROR: Script error.” And it’s Google Ads’ script generating the error too (which works FINE in the actual browser). /js/adsbygoogle.js.

  37. George

    Hi Daniel. Thanks for this article and for keeping it up to date, otherwise there would be hardly any info to be found on this subject. In the lower row in the “Feature Browser Emulation”-table you list the decimal values 12001, 13000 etc., but the first hexadecimal value listed is 2ee0 which equals to 12000. So maybe you want to add 12000 to the decimal values, or remove 2ee0 from the hex values.

  38. HWeintraub

    Hi Daniel, thanks for this info. After updating to the latest W11 and Office versions, my WebBrowser control no longer displays Adobe PDFs within the control, and instead open them outside of the control in an Adobe window. Any thoughts on this? Is this related to IE11 no being supported anymore? Thanks!

  39. Greg

    Hi Daniel,
    Thank you for the information (not only in this post but your others have helped me greatly). From the comments, I know I am not the only one having this issue. I created a form with the Wed Browser Control that opens a preview of documents so users can fill in fields about the documents. Around 1 out of 5 PDF’s randomly fail in recent Access versions with an Adobe PDF Document error of “There is a problem with Adobe Acrobat/Reader. If it is running, please exit and try again. (0: 104)”
    OR “There is a problem with Adobe Acrobat/Reader. If it is running, please exit and try again. (0:521)”
    OR “A running instance of Acrobat has caused an error. (no error code)”

    I have tried four different scenarios where two of them work:
    Access 2010 – 32 bit – Windows 10 – Only Acrobat Reader installed – Works
    Access 2010 – 32 bit – Windows Server 2008 R2 -Both Acrobat Reader and Pro installed – Works
    Access 2013 – 64 bit – Windows 10 – Only Acrobat Reader installed – Does NOT work
    Access 2016 – 64 bit – Windows Server 2016 – Both Acrobat Reader and Pro installed – Does NOT work

    All four of them list Internet Explorer 11 as their browser (even though I have tried the registry modification and while it updated to Edge 18, the issue remained on the 64 bit versions).

    Any thoughts/suggestions would be greatly appreciated!

  40. Mark

    Hi Daniel,

    Thanks for the comprehensive information.
    I am trying to build a completely self contained Access DB without any dependencies on external files.
    Is it possible to build the Control Source HTML on the fly and set it during the onLoad event?

    I have been trying by building the HTML code as a text string and then setting the Control souce to that text string but thus far have not had any luck

    Thanks

      1. Mark

        Thanks Daniel,
        I got hung up on making it the ControlSource

        That worked like a charm.. Guess I should have paid closer attention during my inital read through.

        Thank again

  41. Daniel Dillon

    My maps don’t display anymore.
    Windows 11, Current Office365.
    I edited the registry key to 11001.
    “You are using a browser that is not supported by the Google Maps JavaScript API. Please consider changing your browser.”
    I set Edge to use IE mode.
    What is missing?

  42. Djeno

    Greetings Daniel,
    As many have already stated, your efforts here are greatly appreciated. THANK YOU!

    After a year of using the technics you’ve brilliantly explained above, I accidentally set a webbroswer controlsource to a local folder containing images stored by my database.

    strFilePath = “D:\MyDatabase\Images”
    Me!WebBrowse1.ControlSource = “='” & strFilePath & “‘”

    I was pleasantly surprised that the browser displayed thumbnails of the images and provided similar file management functions as when using file explorer!

    I think some commenters have mentioned using the webbrowsser control to work with the file system, but many casual readers, or those who don’t read comments, may miss out on this functionality.

    Finally, I wonder if you or any other readers have any further insights into using this control to work with the file system. If you think this worthy enough to update your article, perhaps you would consider adding a few lines about it and a screenshot of the result.

    Best Regards

    1. Daniel Pineault Post author

      I must admit I’ve never tried using it to work with the local file system. I’ve done it with other technologies, but never an Access Web Browser control. Thank you for sharing.

  43. Carlos Castillo

    Hello Daniel,
    thanks for the great job you does, that help a lot.
    I my Access database, i would like to read local html files in a web browser control. I have downloaded the demo base. I use WebBrowser_ContentFromLocalFile form , have modified the path in the vba code to my first page
    (C:\Users\33646\Documents\Astro\Ressources\Devenir astrologue2-Aubier-frameset\Devenir astrologue2-Aubier-TOC.html)
    and it works. This page is a Table of contents, with links to other pages of the document. I click to a link and the new page opens in IExplorer7 instead of on the access web control.

    Could you help me ?
    Thanks
    Carlos
    (PS: I am french . Please excuse my english)

      1. Carlos Castillo

        Good morning Daniel,
        before going further, here are the Access tools & versions I am using.
        Win11 to the last update
        Access 2016
        I have implemented the reg key to set the browser to IE 11
        I have a set of HTML files on my PC used as help to some forms and controls. I use the native activeX web control to view the help file. It runs pretty well. Nevertheless, the font used by access web browser is for me too small and heavy, so I changed the CSS to: font Calibri, lighter.
        The result is good on both IE and Firefox, but there is no change on access web browser.
        It is like the CSS is not used. I have read most of your post but didn’t find a solution.
        Could you help me?
        Thanks a lot
        Regards.
        Carlos

        1. Daniel Pineault Post author

          I’m not a 100% sure, but I’d think you’d want to run a JS command once the page is fully loaded, such as:

          document.body.style.fontFamily = "Calibri, sans-serif";

          If you have styles defined and need to overrule them, then you might need to do something more like:

          var allElements = document.querySelectorAll('*');
          for (var i = 0; i < allElements.length; i++) {
            allElements[i].style.fontFamily = '';
          }
          document.body.style.fontFamily = 'Calibri, sans-serif'; 
          

          or you could also try injecting the following CSS:

          * {
            font-family: Calibri !important;
          }
          

          via JS it might look a little like:

          var style = document.createElement('style');
          style.type = 'text/css';
          var css = '* { font-family: Calibri !important; }';
          
          if (style.styleSheet) {
            style.styleSheet.cssText = css;
          } else {
            style.appendChild(document.createTextNode(css));
          }
          
          document.getElementsByTagName('head')[0].appendChild(style);
          

          That said, why not simply update the HTML files themselves?