ILiteView2Ctrl — 270+ VBA WebView2 Methods for Access, Excel, Word, and VB6 Registered Mode — drop the ActiveX on an Access, Excel, or VB6 form
Works in VBA (Excel, Access, Word, Outlook, PowerPoint, Visio, Project), VB6, VB.NET, C#, C++, Delphi, Python, PowerShell, AutoIt — and any COM host.
Default interface: ILiteView2Ctrl | Event source: _DLiteView2CtrlEvents
Me.LiteView2Ctrl1.<dot> does not show LiteView2 methods in the VBA editor's autocomplete — only Access's generic control properties (Name, Top, Left, …). This is universal Access behavior for any ActiveX control on a form (Microsoft DatePicker, TreeView, the legacy WebBrowser control — same gap). Access wraps form ActiveX controls in a generic Control object; calls forward to the underlying ActiveX at runtime via IDispatch::Invoke, but the wrapper's type info hides the methods from IntelliSense.
To get full IntelliSense on every method listed below, use a typed module-level reference and peel Access's wrapper with .Object:
' One-time setup: VBA editor → Tools → References →
' check "LiteView2 1.0 Type Library", then OK.
Private m_lv As LiteView2Lib.LiteView2Ctrl
Private Sub Form_Load()
' .Object peels Access's wrapper and returns the underlying ActiveX.
' Without .Object the assignment raises "Type mismatch".
Set m_lv = Me.LiteView2Ctrl1.Object
End Sub
Private Sub LiteView2Ctrl1_WebViewReady()
' Full IntelliSense on m_lv. — every method below shows up after the dot.
m_lv.Navigate "https://lv2.example/index.html"
End Sub
Late-bound (Private m_lv As Object) still works at runtime — you just give up IntelliSense. See the Cookbook → Boilerplate — Registered Mode for the full pattern, plus the Access form-button "first-click does nothing" caveat and its MouseDown workaround.
Canonical lifecycle template — Registered Mode
The lifecycle pattern below eliminates the friction every customer hits the first time they drop a LiteView2 control on a form. The Quick Start gets a browser running in 30 seconds; the full template adds buttons (with the first-click MouseDown mirror), host objects, error handlers, and inline comments explaining each line.
Quick Start (30 seconds)
- Drop a
LiteView2CtrlActiveX on the form (Access keeps the default nameLiteView2Ctrl1). - Tools → References → check LiteView2 1.0 Type Library.
- Create a NEW standard module called
modLV2License(Insert → Module in the VBA editor). Paste its entire content from the listing below the template, and editLV2_COMPANY+LV2_KEYONCE at the top of that module — every form then picks it up. - Paste this into the form's code module:
Option Explicit
Private m_lv As LiteView2Lib.LiteView2Ctrl
Private Sub Form_Load()
Set m_lv = Me.LiteView2Ctrl1.Object
EnsureLicensed m_lv ' from modLV2License -- once per process
End Sub
Private Sub LiteView2Ctrl1_WebViewReady()
m_lv.SetLocalContentRoot CurrentProject.Path
m_lv.Navigate "https://lv2.example/index.html"
End Sub
If your form just needs to display a page, the Quick Start is enough. Otherwise the full template below adds the rest. The activation key never appears in per-form code — it lives in modLV2License.bas once, and every form inherits it.
modLV2License — new shared license module (you create it, once per project)
In the VBA editor: Insert → Module, set the module's (Name) property to modLV2License, then paste the block below. The block is the entire module — start at Option Explicit, end at the final End Sub. Nothing else goes in this module. Edit LV2_COMPANY and LV2_KEY ONCE here; forms call EnsureLicensed and activation happens process-wide on the first call. Rotating the key means editing one file, not every form.
' ===== modLV2License -- START =================================================
Option Explicit
' ============================================================================
' LiteView2 license activation -- shared across all forms in the process.
' Edit LV2_COMPANY and LV2_KEY ONCE here. Forms call EnsureLicensed.
' Leave LV2_KEY empty to keep the 30-day Trial Period.
' ============================================================================
Private Const LV2_COMPANY As String = "Your Company"
Private Const LV2_KEY As String = "" ' "V1|..."
Private m_activated As Boolean
' Activate the runtime license against any LiteView2 control instance.
' Safe to call from every form's Form_Load -- only the first call does
' the work; later calls are a no-op. Activation is process-wide.
Public Sub EnsureLicensed(ByVal ctrl As Object)
If m_activated Then Exit Sub
If ctrl Is Nothing Then Exit Sub
If Len(LV2_KEY) = 0 Then Exit Sub
ctrl.ActivateLicense LV2_COMPANY, LV2_KEY
m_activated = True
End Sub
' ===== modLV2License -- END ===================================================
Per-form code — full canonical template
' ============================================================================
' Registered Mode — canonical lifecycle template (per form)
' ============================================================================
' Form prerequisite:
' - A LiteView2Ctrl ActiveX named LiteView2Ctrl1 (Access's default name)
'
' Project prerequisites:
' - modLV2License.bas imported (holds the activation key)
' - Tools -> References -> check "LiteView2 1.0 Type Library"
'
' When you add buttons users may click while focus is inside the browser,
' mirror Click into MouseDown — see the focus-transfer section below.
' ============================================================================
Option Compare Database
Option Explicit
' Typed reference gives IntelliSense on every m_lv.* call.
' ".Object" in Form_Load below peels Access's wrapper; without it, Set raises Type mismatch.
Private m_lv As LiteView2Lib.LiteView2Ctrl
Private Sub Form_Load()
On Error GoTo ErrH
Set m_lv = Me.LiteView2Ctrl1.Object
' Single call -- activation key lives in modLV2License.bas, not here.
' Safe to call from every form: only the first call does real work.
EnsureLicensed m_lv
Exit Sub
ErrH:
MsgBox "Form_Load: " & Err.Number & " " & Err.Description, vbCritical
End Sub
Private Sub LiteView2Ctrl1_WebViewReady()
On Error GoTo ErrH
' Order matters: virtual host first, then host objects, then Navigate.
m_lv.SetLocalContentRoot CurrentProject.Path
m_lv.AreHostObjectsAllowed = True
m_lv.AddHostObjectToScript "vba", Me
m_lv.Navigate "https://lv2.example/index.html"
Exit Sub
ErrH:
MsgBox "WebViewReady: " & Err.Number & " " & Err.Description, vbCritical
End Sub
' Called by the page via window.chrome.webview.hostObjects.sync.vba.OnReady()
Public Sub OnReady()
' Page is ready to talk to VBA. Put your post-page-load logic here.
End Sub
Private Sub Form_Close()
On Error Resume Next
If Not m_lv Is Nothing Then
m_lv.Stop ' halt any in-flight navigation before teardown
Set m_lv = Nothing ' release the reference; Access destroys the control next
End If
End Sub
Lifecycle rules
- The activation key lives in
modLV2License.bas, not in per-form code. Each form'sForm_LoadcallsEnsureLicensed m_lv. The helper activates once per process; later calls are a no-op. - Everything else waits for the ready event.
SetLocalContentRoot, host-object registration, and the firstNavigatebelong inLiteView2Ctrl1_WebViewReady. Calling them inForm_Loadis a silent no-op or fails. - Host objects must be added before the navigation that uses them. Order inside the ready handler:
SetLocalContentRoot→AreHostObjectsAllowed→AddHostObjectToScript→Navigate. - Buttons need a
MouseDownmirror when focus may be inside the browser. KeepClickfor keyboard activation; addMouseDownso the first physical mouse click also fires the action. - Cleanup is simple.
Set m_lv = NothinginForm_Close. No explicit teardown call needed.
Activation key placement
- ✅ The activation key is a
Constat the top ofmodLV2License.bas. Forms callEnsureLicensed m_lvinForm_Load— no key string in the form. - ❌ Never paste the activation string into per-form code. Rotating the key would mean editing every form.
- ❌ Never call
ActivateLicenseAFTER the firstNavigate. The watermark may already have rendered. - ❌ Never call
ActivateLicenseinsideWebViewReady. By then the navigation decision has already used the license state.
Multiple browser instances
ActivateLicense is process-wide, not per-form and not per-browser:
- ONE successful
ActivateLicensecall activates every LiteView2 browser created afterwards in the same Access (or Office) session. - Activation does not persist across Access restarts. Each fresh process must call
ActivateLicenseonce — that's whatEnsureLicensedhandles for you on the first form that opens.
That is why the recommended pattern is a shared module: the activation key lives in modLV2License.bas exactly once, and every form simply calls EnsureLicensed m_lv. Whichever form opens first triggers the real activation; every later form's EnsureLicensed call is a cheap no-op (an early return on an internal flag). You change the key once, in one file, and every form picks it up automatically.
Never do this in Form_Load
' ❌ WRONG — Form_Load runs BEFORE WebView2 is ready.
' These calls silently no-op, race with init, or cause a stuck watermark.
Private Sub Form_Load()
Set m_lv = Me.LiteView2Ctrl1.Object
m_lv.SetLocalContentRoot CurrentProject.Path ' ❌ wait for WebViewReady
m_lv.AddHostObjectToScript "vba", Me ' ❌ wait for WebViewReady
m_lv.Navigate "https://lv2.example/index.html" ' ❌ wait for WebViewReady
End Sub
' ✅ CORRECT — Form_Load gets the typed reference + activates via the shared module.
Private Sub Form_Load()
Set m_lv = Me.LiteView2Ctrl1.Object
EnsureLicensed m_lv ' from modLV2License -- key lives there, once
End Sub
Private Sub LiteView2Ctrl1_WebViewReady()
m_lv.SetLocalContentRoot CurrentProject.Path
m_lv.AreHostObjectsAllowed = True
m_lv.AddHostObjectToScript "vba", Me
m_lv.Navigate "https://lv2.example/index.html"
End Sub
Lifecycle timeline
TIME EVENT WHAT YOUR CODE DOES HERE
──── ───────────────────────────────── ──────────────────────────────────────────
t0 Form_Load Set m_lv = Me.LiteView2Ctrl1.Object
EnsureLicensed m_lv (from modLV2License)
↓
(WebView2 starts up — async) (you do nothing; message loop runs)
↓
t1 LiteView2Ctrl1_WebViewReady m_lv.SetLocalContentRoot CurrentProject.Path
m_lv.AreHostObjectsAllowed = True
m_lv.AddHostObjectToScript "vba", Me
m_lv.Navigate "https://lv2.example/index.html"
↓
t2 Page loads → DOMContentLoaded JavaScript runs in the page
Page calls window.chrome.webview
.hostObjects.sync.vba.OnReady()
↓
t3 Public Sub OnReady() in VBA Your post-page-load logic runs
↓
(user interacts...)
↓
tN Form_Close m_lv.Stop
Set m_lv = Nothing
Exit lifecycle — closing the form safely
The loading sequence has a clear order; the unloading sequence does too. Following it cleanly prevents two real problems:
- A navigation in flight at the moment the form closes can fire
NavigationCompletedagainst a half-destroyed control. - An exception popped during teardown (from leftover state) can leave the form half-stuck and hard for the user to dismiss.
Private Sub Form_Close()
On Error Resume Next
If Not m_lv Is Nothing Then
m_lv.Stop ' halt any in-flight navigation before teardown
Set m_lv = Nothing ' release the reference; Access destroys the control next
End If
End Sub
What each line does:
m_lv.Stop— halts a navigation that might still be loading when the user closes the form. Without it, the page can fireNavigationCompletedwhile the control is being destroyed.Set m_lv = Nothing— releases your VBA reference. Access then destroys the ActiveX control as part of normal form teardown; LiteView2's internal destructor drains pending callbacks and releases the WebView2.On Error Resume Next— if the form is closing because of an earlier error, we still want the teardown attempt to complete; we don't want a second error to pop a second MsgBox during shutdown.
Registered Mode does NOT need DestroyBrowserSync — that's a pool-only API for Reg-Free Mode. The control's own destructor handles the equivalent work when Access tears the form down.
SetLocalContentRoot path mapping
SetLocalContentRoot folder maps a folder on disk to the https://lv2.example/ virtual host. The mapping is one-to-one: the folder you pass becomes the URL root.
| Disk path you pass | URL root | Example file on disk | URL to navigate to |
|---|---|---|---|
C:\Apps\MyDB\ | https://lv2.example/ | C:\Apps\MyDB\index.html | https://lv2.example/index.html |
C:\Apps\MyDB\ | https://lv2.example/ | C:\Apps\MyDB\pages\admin.html | https://lv2.example/pages/admin.html |
CurrentProject.Path | https://lv2.example/ | the form's folder | https://lv2.example/<any-file> |
Common path-mapping mistakes:
- Wrong root level. You map
C:\Apps\but your HTML lives inC:\Apps\MyDB\index.html. The URL must then behttps://lv2.example/MyDB/index.html, not/index.html. Pick the folder that DIRECTLY contains your HTML. - Subfolder confusion. You pass
CurrentProject.Path & "\html"and then navigate tohttps://lv2.example/html/index.html. The\htmlpart already became the new root — the correct URL ishttps://lv2.example/index.html. - Backslash in URL.
https://lv2.example/index.htmlworks;https://lv2.example\index.htmldoes not. Use forward slashes in URLs only. - Missing target file. The mapping is correct but
index.htmldoesn't actually exist in the mapped folder. WebView2 shows its own "page can't be reached" error — verify the file is there before blaming the control.
Minimal HTML page (the bridge from the page side)
What index.html should look like to successfully call back into VBA:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>LiteView2 page</title>
</head>
<body>
<h1>Page loaded</h1>
<p id="status"></p>
<button onclick="notifyVBA()">Tell VBA hello</button>
<script>
// "vba" matches the first argument of AddHostObjectToScript in VBA.
// Calling sync.vba.<name>() invokes a Public Sub on the VBA form.
function notifyVBA() {
try {
window.chrome.webview.hostObjects.sync.vba.OnReady();
document.getElementById('status').textContent = 'Reached VBA.';
} catch (e) {
document.getElementById('status').textContent = 'Bridge error: ' + e.message;
}
}
</script>
</body>
</html>
The VBA AddHostObjectToScript "vba", Me call (in WebViewReady) registered the form as the host object named vba. The page's sync.vba.OnReady() then invokes the form's Public Sub OnReady().
Access form-button "first-click does nothing" caveat
When focus is inside an embedded ActiveX control (the LiteView2 control, the legacy WebBrowser, Microsoft DatePicker, TreeView — all the same), Access uses the FIRST click on any form button to move focus to that button. The button's Click event does NOT fire on that click; only the second click runs the handler. This is long-standing Access behavior, not a LiteView2 bug.
Mirror Click into MouseDown — MouseDown fires the instant the mouse goes down regardless of focus state. Keep Click for keyboard activation. The full template above shows the pattern on cmdGo; apply the same pattern to any form button reachable while focus is inside the browser.
Copy-Paste Checklist
Before reporting a problem, verify each of these:
- ☐
modLV2License.basis imported into the VBA project, withLV2_KEYset to yourV1|...activation string - ☐ The form's
Form_LoadcallsEnsureLicensed m_lv - ☐ LiteView2 1.0 Type Library is checked in Tools → References
- ☐
index.html(or whatever filename the code navigates to) physically exists in the folder you pass toSetLocalContentRoot - ☐
SetLocalContentRootis called BEFORE the firstNavigate - ☐
AddHostObjectToScriptis called BEFORE theNavigatethat loads the page that uses the host object - ☐ The form has a
WebViewReadyhandler — that handler is where the setup calls live, notForm_Load - ☐ Every Public Sub the page calls via
hostObjects.sync.vba.<name>()exists in the form's code module (includingOnReadyif your page calls it) - ☐ Any button reachable while focus is inside the WebView2 has BOTH a
Clickhandler AND aMouseDownmirror that runs the same action
If all boxes are checked and the symptom persists, the troubleshooting table below maps the most likely remaining causes.
Troubleshooting
| Symptom | Most likely cause | Fix |
|---|---|---|
| Watermark renders despite a valid key | Activation didn't happen before the first navigation. Either EnsureLicensed isn't called from Form_Load, OR modLV2License's LV2_KEY constant is empty. | Confirm modLV2License.bas is imported AND Form_Load calls EnsureLicensed m_lv. Check LV2_KEY holds your V1|... string. |
| Local files don't load — "Can't reach this page" or 404 | SetLocalContentRoot not called, called with the wrong folder, or the URL points outside the mapped folder | Map CurrentProject.Path; verify index.html exists in that folder; the URL must use forward slashes. See path-mapping table above. |
| Local files exist but still won't load | Navigate executed before SetLocalContentRoot | Call SetLocalContentRoot BEFORE the first Navigate inside WebViewReady. |
window.chrome.webview.hostObjects.sync.vba is undefined in JS | AddHostObjectToScript was called AFTER Navigate. Host objects only bind on the NEXT navigation. | Inside the ready handler the order must be: SetLocalContentRoot → AreHostObjectsAllowed → AddHostObjectToScript → Navigate. |
| First click on a form button does nothing; second click works | Access uses the first click on an external button to move focus to that button. The Click event doesn't fire on that click. | Mirror Click into a MouseDown handler for any button reachable while focus is inside the browser. Keep Click for keyboard activation. |
IntelliSense doesn't show LiteView2 methods after m_lv. | "LiteView2 1.0 Type Library" not checked in Tools → References, OR m_lv declared As Object (late-bound) | Tools → References → check the LiteView2 type library; declare Private m_lv As LiteView2Lib.LiteView2Ctrl. |
Set m_lv = Me.LiteView2Ctrl1 raises "Type mismatch" | Missing .Object — Access's form-control wrapper is not QueryInterface-compatible with the typed coclass. | Set m_lv = Me.LiteView2Ctrl1.Object. The .Object peels Access's wrapper to expose the underlying ActiveX. |
Map local folders and custom URI schemes to virtual hostnames for secure local content serving.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| SetLocalContentRoot | folderPath As String | Map local folder to https://lv2.local/ virtual hostname | |
| SetVirtualHostNameToFolderMapping | hostName, folderPath As String, accessKind As Long | Map any hostname to local folder | |
| ClearVirtualHostNameToFolderMapping | hostName As String | Remove virtual hostname mapping | |
| AddCustomSchemeRegistration | schemeName As String, treatAsSecure As Boolean | Register custom URI scheme (e.g., myapp://) |
Per-Member Usage
' SetLocalContentRoot � map folder to https://lv2.local/
m_lv.SetLocalContentRoot CurrentProject.Path & "\demos"
m_lv.Navigate "https://lv2.local/index.html"
' SetVirtualHostNameToFolderMapping � map any hostname
m_lv.SetVirtualHostNameToFolderMapping "assets.local", "C:\MyApp\Assets", 0
' accessKind: 0=Deny, 1=Allow, 2=DenyCors
' Now use: https://assets.local/images/logo.png
' ClearVirtualHostNameToFolderMapping � remove mapping
m_lv.ClearVirtualHostNameToFolderMapping "assets.local"
' AddCustomSchemeRegistration � register custom URI scheme
m_lv.AddCustomSchemeRegistration "myapp", True
' Now myapp://resource/path will be handled by WebResourceRequested event
Read-only and read/write properties reflecting the current state of the WebView2 browser instance.
| Property | Type | R/W | Description |
|---|---|---|---|
| Url | String | R/W | Current URL (default property) |
| DocumentTitle | String | R | Current page title |
| IsLoading | Boolean | R | Whether page is currently loading |
| CanGoBack | Boolean | R | Whether back navigation is available |
| CanGoForward | Boolean | R | Whether forward navigation is available |
| LastError | String | R | Last error message |
| LastErrorCode | Long | R | Last error code (numeric) |
| ContainsFullScreenElement | Boolean | R | Whether page has fullscreen element |
| StatusBarText | String | R | Current status bar text |
| WebViewCreated | Boolean | R | Whether WebView has been created and is ready |
| InPrivateMode | Boolean | R | Whether browser is in InPrivate mode |
| FaviconUri | String | R | Favicon URI of current page |
| BrowserProcessId | Long | R | Browser subprocess PID |
| BrowserProcessIDLong | Long | R | VB6-friendly alias for BrowserProcessId |
Per-Member Usage
' Url (R/W) � current URL; also the default property
Debug.Print m_lv.Url ' "https://lv2.local/page.html"
m_lv.Url = "https://www.example.com" ' same as Navigate
' DocumentTitle (R) � page <title>
Debug.Print "Title: " & m_lv.DocumentTitle
' IsLoading (R) � True while page is loading
If m_lv.IsLoading Then m_lv.Stop
' CanGoBack / CanGoForward (R) � history state
btnBack.Enabled = m_lv.CanGoBack
btnFwd.Enabled = m_lv.CanGoForward
' LastError / LastErrorCode (R) � last error info
If m_lv.LastErrorCode <> 0 Then
MsgBox "Error " & m_lv.LastErrorCode & ": " & m_lv.LastError
End If
' ContainsFullScreenElement (R) � fullscreen video etc.
Debug.Print "Fullscreen: " & m_lv.ContainsFullScreenElement
' StatusBarText (R) � hover-link text
lblStatus.Caption = m_lv.StatusBarText
' WebViewCreated (R) � True after WebView2 is ready
If m_lv.WebViewCreated Then m_lv.Navigate "https://example.com"
' InPrivateMode (R) � InPrivate browsing
Debug.Print "InPrivate: " & m_lv.InPrivateMode
' FaviconUri (R) � page favicon URL
Debug.Print "Favicon: " & m_lv.FaviconUri
' BrowserProcessId / BrowserProcessIDLong (R) � PID
Debug.Print "PID: " & m_lv.BrowserProcessId
Debug.Print "PID (VB6): " & m_lv.BrowserProcessIDLong ' same value, VB6-friendly
Check whether the WebView2 engine has been fully initialized.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| IsReady | Boolean | Check if WebView2 is ready |
Primary readiness signal is the WebViewReady event. Use IsReady only as a guard clause or polling fallback.
Timer Fallback Pattern
Source: frmCustomerDetail_Code.txt
' Timer fallback pattern (optional — not needed on correctly registered OCX)
Private Sub tmrReady_Timer()
If m_lv.IsReady Then
tmrReady.Enabled = False
LoadCustomerData
End If
End Sub
Execute JavaScript in the WebView2 browser and retrieve results.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| ExecuteScript | script As String | String | Execute JS synchronously, return result |
| ExecuteScriptAsync | script As String | Execute JS asynchronously (fire and forget) | |
| ExecuteScriptWithArgs | functionName As String, arguments As Variant | String | Call JS function with VBA arguments (Array, Recordset, or scalar). Auto-serializes to JSON. |
| ExecuteScriptWithResult | script As String | resultAsJson As String, succeeded As Boolean, exceptionMessage As String | Execute script with detailed result + exception info |
| AddScriptToExecuteOnDocumentCreated | script As String | String (scriptId) | Inject JS that runs on every page load |
| RemoveScriptToExecuteOnDocumentCreated | id As String | Remove injected script |
Per-Member Usage
' ExecuteScript � run JS synchronously, get return value
Dim title As String
title = m_lv.ExecuteScript("document.title")
' ExecuteScriptAsync � fire-and-forget (no return value)
m_lv.ExecuteScriptAsync "console.log('Hello from VBA')"
' ExecuteScriptWithArgs � call JS function with auto-serialized VBA args
Dim result As String
result = m_lv.ExecuteScriptWithArgs("testFunction", Array("Hello", 42, True))
' ExecuteScriptWithResult � detailed result + exception info (ByRef params)
Dim resultJson As String, succeeded As Boolean, exMsg As String
m_lv.ExecuteScriptWithResult "1 + 2", resultJson, succeeded, exMsg
If succeeded Then Debug.Print resultJson ' "3"
' AddScriptToExecuteOnDocumentCreated � inject JS on every page load
Dim scriptId As String
scriptId = m_lv.AddScriptToExecuteOnDocumentCreated("document.title += ' [LV2]';")
' RemoveScriptToExecuteOnDocumentCreated � remove injected script by ID
m_lv.RemoveScriptToExecuteOnDocumentCreated scriptId
Send data from VBA to JavaScript. Includes native recordset serialization and JSON messaging.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| PostWebMessageAsJson | webMessageAsJson As String | Post JSON message to JS. JS receives via window.chrome.webview.addEventListener('message', ...) | |
| PostWebMessageAsString | webMessageAsString As String | Post string message to JS | |
| PushRecordset | recordset As Object, jsCallback As String | Push DAO/ADO Recordset as JSON array. Calls window[jsCallback](jsonArray) in JS. | |
| BuildJson | inputData As Variant | String | Convert VBA data to JSON string. See JSON Helpers. |
| FireJsEvent | eventName As String, jsonData As String | Fire a CustomEvent in the page. JS listens with addEventListener or window.lv.on() | |
| CallJsFunction | funcPath As String, jsonArgs As String | Call JS function by dot-path with JSON args | |
| SetJsVariable | path As String, jsonValue As String | Set a JS variable |
Per-Member Usage
' PostWebMessageAsJson � send JSON to JS (received via chrome.webview message event)
m_lv.PostWebMessageAsJson "{""type"":""update"",""id"":42}"
' PostWebMessageAsString � send plain string to JS
m_lv.PostWebMessageAsString "Hello from VBA"
' PushRecordset � push DAO/ADO Recordset as JSON array to a JS callback
Dim rs As DAO.Recordset
Set rs = db.OpenRecordset("SELECT * FROM tblSales", dbOpenSnapshot)
m_lv.PushRecordset rs, "onSalesData" ' JS: window.onSalesData(jsonArray)
rs.Close
' BuildJson � convert VBA value/array to JSON string (no WebView2 needed)
Dim json As String
json = m_lv.BuildJson(Array("apple", "banana")) ' '["apple","banana"]'
' FireJsEvent � dispatch a CustomEvent in the page
m_lv.FireJsEvent "vbaDataReady", "{""source"":""VBA""}"
' JS: document.addEventListener("vbaDataReady", e => console.log(e.detail))
' CallJsFunction � call JS function by dot-path with JSON args
m_lv.CallJsFunction "app.handlers.onData", "{""action"":""refresh""}"
' SetJsVariable � set a JS variable from VBA
m_lv.SetJsVariable "window.vbaConfig", "{""theme"":""dark""}"
Enable or check the window.lv global JavaScript facade for simplified messaging.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| EnableLvFacade | enabled As Boolean | Inject window.lv global JS facade. Call BEFORE first Navigate. | |
| IsLvFacadeEnabled | Boolean | Whether window.lv facade is active |
Facade Example
Source: frmScriptBridge_Code.txt
' Enable the window.lv facade BEFORE first Navigate
m_lv.EnableLvFacade True
m_lv.Navigate "https://lv2.local/my_page.html"
' Check if facade is active
If m_lv.IsLvFacadeEnabled Then Debug.Print "window.lv is available in JS"
These methods work without WebView2 — pure VBA JSON utilities.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| BuildJson | inputData As Variant | String | Convert VBA value/array to JSON |
| JsonGetValue | jsonString As String, path As String | Variant | Extract value by JSONPath |
| JsonGetArrayLength | jsonString As String, path As String | Long | Get array length at path |
| JsonGetArrayItem | jsonString As String, path As String, index As Long | String | Get array item as JSON string |
| JsonGetKeys | jsonString As String, path As String | String | Get all keys from object at path |
| JsonIsValid | jsonString As String | Boolean | Validate JSON syntax |
| JsonToArray | jsonArrayString As String | Variant (String) | Validate and return JSON string. For 2D array output, use JsonToRowArray instead. Respects JsonToArrayMaxSize (default 50 MB). |
All JSON helper methods work without WebView2 — safe to call from any context, including inside event handlers such as WebMessageReceived.
JsonGetValue — Return Type Mapping
JsonGetValue returns a typed Variant whose VBA type depends on the JSON value:
| JSON Value | VBA Type | Example |
|---|---|---|
| String | String | "Jane" → "Jane" |
| Integer | Long | 42 → 42 |
| Decimal | Double | 3.14 → 3.14 |
| Boolean | Boolean | true → True |
| Null | Null | null → Null (use IsNull() to check) |
| Object / Array | String | {"a":1} → raw JSON string |
| Key not found | Null | (path absent) → Null |
JsonGetValue behaves differently on each interface:
- ILiteView2Ctrl (design-time OCX) → returns typed
Variant(Long,Double,Boolean,Null,String) - IBrowserPool (reg-free) → always returns
String
This affects type checking, Null handling, and numeric comparisons. When using IBrowserPool, use CLng() or CDbl() to convert numeric results.
Per-Member Usage
' BuildJson � convert VBA value/array to JSON string
Dim j As String
j = m_lv.BuildJson(Array(1, 2, 3)) ' "[1,2,3]"
j = m_lv.BuildJson("hello") ' "\"hello\""
' JsonGetValue � extract value by JSONPath
Dim v As Variant
v = m_lv.JsonGetValue("{""name"":""Jane"",""age"":30}", "name") ' "Jane"
v = m_lv.JsonGetValue("{""a"":{""b"":5}}", "a.b") ' 5
' JsonGetArrayLength � count elements at path
Dim count As Long
count = m_lv.JsonGetArrayLength("[10,20,30]", "") ' 3
' JsonGetArrayItem � get array element as JSON string
Dim item As String
item = m_lv.JsonGetArrayItem("[{""id"":1},{""id"":2}]", "", 0) ' '{"id":1}'
' JsonGetKeys � list all keys from a JSON object
Dim keys As String
keys = m_lv.JsonGetKeys("{""name"":""Jane"",""age"":30}", "") ' '["name","age"]'
' JsonIsValid � check if string is valid JSON
If m_lv.JsonIsValid(myJson) Then Debug.Print "Valid!"
' JsonToArray � validate JSON and return as String
Dim validated As Variant
validated = m_lv.JsonToArray("[{""name"":""Alice""},{""name"":""Bob""}]")
' Returns the validated JSON string (not a 2D array)
' For 2D array output, use JsonToRowArray instead
All JSON mutation functions follow a fail-safe contract:
- Never throw COM errors to the caller
- Return the original JSON string unchanged on any failure
- Error details are available via the
LastErrorproperty - All work without WebView2 — they can be called even before the browser is created
On IBrowserPool, three methods have historical 2-suffix aliases: JsonSetValue2, JsonRemoveKey2, JsonToRowArray2. Both names work — the non-suffix versions (JsonSetValue, JsonRemoveKey, JsonToRowArray) are preferred and match the names shown here.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| JsonCreateObject | String | Returns "{}" | |
| JsonCreateArray | String | Returns "[]" | |
| JsonSetValue | jsonString As String, path As String, value As Variant | String | Set or create a value at path. Auto-creates intermediate objects/arrays. |
| JsonRemoveKey | jsonString As String, path As String | String | Remove a key or array element by path |
| JsonExists | jsonString As String, path As String | Boolean | Check if a path exists in JSON |
| JsonAppend | jsonString As String, path As String, value As Variant | String | Append value to array at path. Auto-creates array if missing. |
| JsonInsert | jsonString As String, path As String, index As Long, value As Variant | String | Insert value at specific array position |
| JsonMerge | json1 As String, json2 As String, deepMerge As Boolean | String | Merge two JSON objects. deepMerge=True for recursive merge. |
| JsonCount | jsonString As String, path As String | Long | Count keys (object) or elements (array) at path |
| JsonClear | jsonString As String, path As String | String | Empty a container at path ({} or []) |
| JsonPrettyPrint | jsonString As String | String | Format JSON with 2-space indentation (max 5 MB input) |
| JsonFlatten | jsonString As String | String | Flatten nested JSON to dot-notation keys |
| JsonUnflatten | jsonString As String | String | Unflatten dot-notation keys back to nested JSON |
| JsonToRowArray | jsonString As String | Variant (2D array) | Convert JSON array of objects to 2D VBA array (row 1 = headers, typed values). Respects JsonToArrayMaxSize. |
| JsonUnwrapString | jsonValue As String | String | If jsonValue is a JSON string literal (double-encoded by ExecuteScriptWithResult), unwrap one layer and unescape all sequences. Otherwise return unchanged. |
| JsonCompact | jsonString As String, path As String | String | Remove null entries from a JSON array at path. Pass empty string for root array. |
Reading: JsonGetValue, JsonGetArrayLength, JsonGetArrayItem, JsonGetKeys, JsonExists, JsonCount
Building: JsonCreateObject / JsonCreateArray → JsonSetValue, JsonAppend, JsonInsert
Modifying: JsonRemoveKey, JsonClear, JsonMerge
Converting: BuildJson (VBA→JSON), JsonToRowArray (JSON→2D array), JsonFlatten / JsonUnflatten, JsonUnwrapString (unwrap double-encoded strings)
Cleaning: JsonCompact (remove nulls from arrays)
Debugging: JsonPrettyPrint, JsonIsValid
Per-Member Usage
' -- Create --
' JsonCreateObject / JsonCreateArray � starting points
Dim json As String
json = m_lv.JsonCreateObject() ' "{}"
' -- Set Values --
' JsonSetValue � set or create value at any path
json = m_lv.JsonSetValue(json, "name", "Imran")
json = m_lv.JsonSetValue(json, "address.city", "London")
' {"name":"Imran","address":{"city":"London"}}
' Overwrite existing value
json = m_lv.JsonSetValue(json, "name", "Ali")
' Auto-create array with null padding
json = m_lv.JsonSetValue(json, "scores[2]", 95)
' scores = [null, null, 95]
' -- Remove --
' JsonRemoveKey � remove key or array element
json = "{""name"":""Imran"",""age"":30,""temp"":true}"
json = m_lv.JsonRemoveKey(json, "temp")
' {"name":"Imran","age":30}
' Remove array element (remaining elements shift)
json = "{""items"":[10,20,30]}"
json = m_lv.JsonRemoveKey(json, "items[1]")
' {"items":[10,30]}
' -- Exists --
' JsonExists � check if path exists
json = "{""user"":{""name"":""Imran""}}"
If m_lv.JsonExists(json, "user.name") Then Debug.Print "Found"
If Not m_lv.JsonExists(json, "user.email") Then
json = m_lv.JsonSetValue(json, "user.email", "imran@example.com")
End If
' -- Append / Insert --
' JsonAppend � push to end of array (auto-creates if missing)
json = "{""tags"":[]}"
json = m_lv.JsonAppend(json, "tags", "vba")
json = m_lv.JsonAppend(json, "tags", "com")
' {"tags":["vba","com"]}
' JsonInsert � insert at specific position
json = "[""a"",""c"",""d""]"
json = m_lv.JsonInsert(json, "", 1, "b")
' ["a","b","c","d"]
' -- Merge --
' JsonMerge � combine two objects
Dim base As String, overlay As String
base = "{""name"":""Imran"",""settings"":{""theme"":""dark"",""lang"":""en""}}"
overlay = "{""age"":30,""settings"":{""theme"":""light""}}"
' Shallow � settings completely replaced
json = m_lv.JsonMerge(base, overlay, False)
' Deep � settings.theme updated, settings.lang preserved
json = m_lv.JsonMerge(base, overlay, True)
' -- Count / Clear --
' JsonCount � count keys (object) or elements (array)
Dim n As Long
n = m_lv.JsonCount("{""a"":1,""b"":2,""c"":3}", "") ' 3
n = m_lv.JsonCount("{""items"":[10,20,30]}", "items") ' 3
' JsonClear � empty a container
json = "{""cache"":{""a"":1},""tags"":[""x""]}"
json = m_lv.JsonClear(json, "cache") ' cache becomes {}
json = m_lv.JsonClear(json, "tags") ' tags becomes []
' -- Pretty Print --
' JsonPrettyPrint � format for debugging (max 5 MB)
Debug.Print m_lv.JsonPrettyPrint("{""name"":""Imran"",""scores"":[95,88]}")
' -- Flatten / Unflatten --
' JsonFlatten � nested to dot-notation
Dim flat As String
flat = m_lv.JsonFlatten("{""user"":{""name"":""Imran"",""address"":{""city"":""London""}}}")
' {"user.name":"Imran","user.address.city":"London"}
' JsonUnflatten � dot-notation back to nested
Dim nested As String
nested = m_lv.JsonUnflatten(flat)
' {"user":{"name":"Imran","address":{"city":"London"}}}
' -- JsonToRowArray � JSON array ? 2D VBA array --
' Row 1 = headers, Rows 2+ = typed data, 1-based indexing
json = "[{""name"":""Imran"",""age"":30},{""name"":""Ali"",""age"":25,""city"":""London""}]"
Dim arr As Variant
arr = m_lv.JsonToRowArray(json)
' arr(1,1)="name" arr(1,2)="age" arr(1,3)="city" ? headers
' arr(2,1)="Imran" arr(2,2)=30 arr(2,3)=Null ? row 1
' arr(3,1)="Ali" arr(3,2)=25 arr(3,3)="London" ? row 2
' Paste into Excel range
' ws.Range("A1").Resize(UBound(arr,1), UBound(arr,2)).Value = arr
' -- Unwrap --
' JsonUnwrapString � fix double-encoded string from ExecuteScriptWithResult
Dim raw As String, ok As Boolean, errMsg As String
m_lv.ExecuteScriptWithResult "document.body.dataset.config", raw, ok, errMsg
' raw = """{\""name\"":\""Apple\""}""" (double-encoded by WebView2)
Dim clean As String
clean = m_lv.JsonUnwrapString(raw)
' clean = "{""name"":""Apple""}" (usable JSON)
Debug.Print m_lv.JsonGetValue(clean, "name") ' "Apple"
' -- Compact --
' JsonCompact � remove null entries from padded arrays
Dim padded As String
padded = "[null,null,{""id"":1},null,{""id"":2}]"
Debug.Print m_lv.JsonCompact(padded, "")
' ? [{"id":1},{"id":2}]
' Path-based compact � only compact array inside nested object
Dim nested As String
nested = "{""data"":[null,{""v"":1},null,{""v"":2}]}"
Debug.Print m_lv.JsonCompact(nested, "data")
' ? {"data":[{"v":1},{"v":2}]}
JsonToRowArray — Type Mapping
| JSON Type | VBA Type | Example |
|---|---|---|
| String | String | "hello" → "hello" |
| Integer | Long | 42 → 42 |
| Decimal | Double | 3.14 → 3.14 |
| Boolean | Boolean | true → True |
| Null | Null | null → Null |
| Object / Array | String (raw JSON) | {"a":1} → "{""a"":1}" |
| Missing key | Null | (key absent) → Null |
Limits: Max 100,000 rows, 1,000 columns. Input size limited by JsonToArrayMaxSize (default 50 MB).
Get and set element values, attributes, and HTML content without writing JavaScript.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| GetElementValueById | elementId As String | String | Get element value by ID |
| SetElementValueById | elementId As String, value As String | Set element value by ID | |
| GetElementValueByName | elementName As String | String | Get element value by name |
| SetElementValueByName | elementName As String, value As String | Set element value by name | |
| ClickElementById | elementId As String | Click element by ID | |
| ClickElementByName | elementName As String | Click element by name | |
| ClickElementBySelector | cssSelector As String | Click element by CSS selector | |
| GetInnerHtmlById | elementId As String | String | Get innerHTML |
| SetInnerHtmlById | elementId As String, html As String | Set innerHTML | |
| GetOuterHtmlById | elementId As String | String | Get outerHTML |
| SetOuterHtmlById | elementId As String, html As String | Set outerHTML | |
| GetOuterHtmlByName | elementName As String | String | Get outerHTML by name |
| SetOuterHtmlByName | elementName As String, html As String | Set outerHTML by name | |
| GetPageHtml | String | Get complete page HTML | |
| GetPageText | String | Get page text (no tags) | |
| ElementExistsById | elementId As String | Boolean | Check if element exists |
| ElementExistsBySelector | cssSelector As String | Boolean | Check if element exists by selector |
| GetElementTextById | elementId As String | String | Get text content (not HTML) |
| SetElementTextById | elementId As String, text As String | Set text content | |
| GetElementAttributeById | elementId, attrName As String | String | Get attribute value |
| SetElementAttributeById | elementId, attrName, value As String | Set attribute value | |
| RemoveElementAttributeById | elementId, attrName As String | Remove attribute | |
| FocusElementById | elementId As String | Focus element | |
| ScrollToElementById | elementId As String | Scroll element into view |
Per-Member Usage
' -- Get/Set Values --
' GetElementValueById / SetElementValueById � by element id
m_lv.SetElementValueById "firstName", "John"
Dim val As String: val = m_lv.GetElementValueById("firstName")
' GetElementValueByName / SetElementValueByName � by name attribute
m_lv.SetElementValueByName "address", "123 Main St"
val = m_lv.GetElementValueByName("address")
' -- Click --
' ClickElementById � click by id
m_lv.ClickElementById "submitBtn"
' ClickElementByName � click by name attribute
m_lv.ClickElementByName "resetButton"
' ClickElementBySelector � click by CSS selector
m_lv.ClickElementBySelector "form#regForm button[type='submit']"
' -- innerHTML / outerHTML --
' GetInnerHtmlById / SetInnerHtmlById
Dim inner As String: inner = m_lv.GetInnerHtmlById("header")
m_lv.SetInnerHtmlById "header", "<strong>Updated!</strong>"
' GetOuterHtmlById / SetOuterHtmlById
Dim outer As String: outer = m_lv.GetOuterHtmlById("myDiv")
m_lv.SetOuterHtmlById "myDiv", "<div id='myDiv' class='new'>Replaced</div>"
' GetOuterHtmlByName / SetOuterHtmlByName
outer = m_lv.GetOuterHtmlByName("address")
m_lv.SetOuterHtmlByName "address", "<input name='address' value='New'>"
' -- Page Content --
' GetPageHtml � full page HTML
Dim html As String: html = m_lv.GetPageHtml
' GetPageText � text only (no tags)
Dim txt As String: txt = m_lv.GetPageText
' -- Existence Checks --
' ElementExistsById
If m_lv.ElementExistsById("loginForm") Then Debug.Print "Found"
' ElementExistsBySelector
If m_lv.ElementExistsBySelector("div.error-message") Then Debug.Print "Error visible"
' -- Text Content --
' GetElementTextById / SetElementTextById � textContent (not HTML)
Dim t As String: t = m_lv.GetElementTextById("heading")
m_lv.SetElementTextById "heading", "New Heading Text"
' -- Attributes --
' GetElementAttributeById
Dim attrVal As String: attrVal = m_lv.GetElementAttributeById("email", "placeholder")
' SetElementAttributeById
m_lv.SetElementAttributeById "email", "style", "border-color: green;"
' RemoveElementAttributeById
m_lv.RemoveElementAttributeById "email", "disabled"
' -- Focus / Scroll --
' FocusElementById
m_lv.FocusElementById "email"
' ScrollToElementById � scroll element into view
m_lv.ScrollToElementById "footer"
High-level form helpers for checkboxes, dropdowns, and form submission.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| SubmitFormById | formId As String | Submit form | |
| SetCheckboxById | elementId As String, checked As Boolean | Set checkbox state | |
| GetCheckboxById | elementId As String | Boolean | Get checkbox state |
| SelectOptionById | elementId As String, optionValue As String | Select dropdown option | |
| GetSelectedOptionById | elementId As String | String | Get selected option value |
Per-Member Usage
' SubmitFormById � submit a <form> by its id
m_lv.SubmitFormById "regForm"
' SetCheckboxById � set checkbox checked/unchecked
m_lv.SetCheckboxById "agreeTerms", True
' GetCheckboxById � read checkbox state
Dim agreed As Boolean
agreed = m_lv.GetCheckboxById("agreeTerms") ' True / False
' SelectOptionById � select <option> in a <select> dropdown
m_lv.SelectOptionById "country", "us"
' GetSelectedOptionById � read selected option value
Dim country As String
country = m_lv.GetSelectedOptionById("country") ' "us"
Print pages, generate PDFs, and capture screenshots.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| PrintPage | Print to default printer | ||
| ShowPrintDialog | Show system print dialog | ||
| PrintToPdf | filePath As String | Print to PDF file (async, fires PrintToPdfCompleted) | |
| PrintWithSettings | Print using current print settings | ||
| PrintToPdfWithSettings | filePath As String | Print to PDF using current print settings | |
| CaptureScreenshot | filePath As String | Long | Capture screenshot (fires CaptureScreenshotCompleted) |
Per-Member Usage
' PrintPage � send to default printer (no dialog)
m_lv.PrintPage
' ShowPrintDialog � open the system print dialog
m_lv.ShowPrintDialog
' PrintToPdf � export PDF (async, fires PrintToPdfCompleted event)
m_lv.PrintToPdf Environ("USERPROFILE") & "\Desktop\Report.pdf"
' PrintWithSettings � print using current Print Settings properties
m_lv.PrintOrientation = 1 ' Landscape
m_lv.PrintWithSettings
' PrintToPdfWithSettings � PDF with current Print Settings
m_lv.PrintScaleFactor = 0.85
m_lv.PrintToPdfWithSettings "C:\Reports\output.pdf"
' CaptureScreenshot � save page image (fires CaptureScreenshotCompleted)
m_lv.CaptureScreenshot "C:\Screenshots\page.png"
Configure page layout, margins, headers/footers, and other print parameters before calling PrintWithSettings or PrintToPdfWithSettings.
| Property | Type | R/W | Description |
|---|---|---|---|
| PrintOrientation | LV2_PRINT_ORIENTATION | R/W | Portrait (0) or Landscape (1) |
| PrintScaleFactor | Double | R/W | Scale factor |
| PrintMarginTop | Double | R/W | Top margin (inches) |
| PrintMarginBottom | Double | R/W | Bottom margin (inches) |
| PrintMarginLeft | Double | R/W | Left margin (inches) |
| PrintMarginRight | Double | R/W | Right margin (inches) |
| PrintPageWidth | Double | R/W | Page width (inches) |
| PrintPageHeight | Double | R/W | Page height (inches) |
| PrintShouldPrintBackgrounds | Boolean | R/W | Print background graphics |
| PrintShouldPrintSelectionOnly | Boolean | R/W | Print selection only |
| PrintShouldPrintHeaderAndFooter | Boolean | R/W | Print header and footer |
| PrintHeaderTitle | String | R/W | Header title text |
| PrintFooterUri | String | R/W | Footer URI text |
| PrintCopies | Long | R/W | Number of copies |
| PrintPagesPerSide | Long | R/W | Pages per side |
| PrintPageRanges | String | R/W | Page ranges (e.g. "1-3,5,7") |
| HasPrintToPdf | Boolean | R | Whether PrintToPdf is supported by runtime |
| HasCapturePreview | Boolean | R | Whether CapturePreview is supported |
Per-Member Usage
' PrintOrientation � 0=Portrait, 1=Landscape
m_lv.PrintOrientation = 1
' PrintScaleFactor � scale (1.0 = 100%, 0.5 = 50%)
m_lv.PrintScaleFactor = 0.85
' PrintMarginTop/Bottom/Left/Right � margins in inches
m_lv.PrintMarginTop = 0.5
m_lv.PrintMarginBottom = 0.5
m_lv.PrintMarginLeft = 0.75
m_lv.PrintMarginRight = 0.75
' PrintPageWidth / PrintPageHeight � page size in inches
m_lv.PrintPageWidth = 8.5 ' Letter width
m_lv.PrintPageHeight = 11 ' Letter height
' PrintShouldPrintBackgrounds � include background graphics/colors
m_lv.PrintShouldPrintBackgrounds = True
' PrintShouldPrintSelectionOnly � print selected content only
m_lv.PrintShouldPrintSelectionOnly = False
' PrintShouldPrintHeaderAndFooter � enable header/footer
m_lv.PrintShouldPrintHeaderAndFooter = True
' PrintHeaderTitle � header template (&T=title, &U=URL, &D=date)
m_lv.PrintHeaderTitle = "&T"
' PrintFooterUri � footer template (&P=page, &N=total pages)
m_lv.PrintFooterUri = "Page &P of &N"
' PrintCopies � number of copies
m_lv.PrintCopies = 2
' PrintPagesPerSide � n-up printing
m_lv.PrintPagesPerSide = 1
' PrintPageRanges � specific pages to print
m_lv.PrintPageRanges = "1-3,5,7-9"
' HasPrintToPdf (R) � check runtime support
If m_lv.HasPrintToPdf Then m_lv.PrintToPdfWithSettings "output.pdf"
' HasCapturePreview (R) � check screenshot support
Debug.Print "CapturePreview: " & m_lv.HasCapturePreview
Runtime settings that control browser behavior, security, and UI features.
| Property | Type | R/W | Description |
|---|---|---|---|
| IsScriptEnabled | Boolean | R/W | JavaScript enabled |
| AreDefaultContextMenusEnabled | Boolean | R/W | Right-click menus enabled |
| AreDevToolsEnabled | Boolean | R/W | DevTools (F12) enabled |
| IsStatusBarEnabled | Boolean | R/W | Status bar enabled |
| ZoomFactor | Double | R/W | Zoom (1.0 = 100%) |
| UserAgent | String | R/W | Custom user agent |
| IsWebMessageEnabled | Boolean | R/W | Web messaging enabled |
| IsBuiltInErrorPageEnabled | Boolean | R/W | Built-in error pages |
| AreBrowserAcceleratorKeysEnabled | Boolean | R/W | Ctrl+F, F5, etc. |
| IsPasswordAutosaveEnabled | Boolean | R/W | Password autosave |
| IsGeneralAutofillEnabled | Boolean | R/W | General autofill |
| IsPinchZoomEnabled | Boolean | R/W | Pinch zoom |
| IsSwipeNavigationEnabled | Boolean | R/W | Swipe navigation |
| HiddenPdfToolbarItems | Long | R/W | PDF toolbar flags (see LV2_PDF_TOOLBAR_ITEMS enum) |
| IsReputationCheckingRequired | Boolean | R/W | SmartScreen reputation checking |
| NonClientRegionSupportEnabled | Boolean | R/W | Custom title bar support |
| DefaultScriptDialogsEnabled | Boolean | R/W | alert/confirm/prompt dialogs |
| IsZoomControlEnabled | Boolean | R/W | Ctrl+scroll zoom |
| IsDragDropEnabled | Boolean | W | Drag and drop |
| SmartResize | Boolean | R/W | Auto-fit on resize (default True) |
Per-Member Usage
' IsScriptEnabled � enable/disable JavaScript
m_lv.IsScriptEnabled = True
' AreDefaultContextMenusEnabled � right-click menus
m_lv.AreDefaultContextMenusEnabled = False ' disable right-click
' AreDevToolsEnabled � F12 DevTools
m_lv.AreDevToolsEnabled = False ' disable F12
' IsStatusBarEnabled � link preview on hover
m_lv.IsStatusBarEnabled = True
' ZoomFactor � zoom level (1.0 = 100%)
m_lv.ZoomFactor = 1.25 ' 125%
' UserAgent � custom user agent string
m_lv.UserAgent = "MyApp/1.0 (LiteView2)"
' IsWebMessageEnabled � chrome.webview.postMessage
m_lv.IsWebMessageEnabled = True
' IsBuiltInErrorPageEnabled � browser error pages
m_lv.IsBuiltInErrorPageEnabled = False ' show custom errors
' AreBrowserAcceleratorKeysEnabled � Ctrl+F, F5, etc.
m_lv.AreBrowserAcceleratorKeysEnabled = False ' disable browser shortcuts
' IsPasswordAutosaveEnabled � password save prompts
m_lv.IsPasswordAutosaveEnabled = False
' IsGeneralAutofillEnabled � form autofill
m_lv.IsGeneralAutofillEnabled = False
' IsPinchZoomEnabled � touch pinch zoom
m_lv.IsPinchZoomEnabled = True
' IsSwipeNavigationEnabled � swipe back/forward
m_lv.IsSwipeNavigationEnabled = False
' HiddenPdfToolbarItems � hide PDF toolbar buttons (flags)
m_lv.HiddenPdfToolbarItems = 0 ' show all
' IsReputationCheckingRequired � SmartScreen
m_lv.IsReputationCheckingRequired = True
' NonClientRegionSupportEnabled � custom title bar
m_lv.NonClientRegionSupportEnabled = False
' DefaultScriptDialogsEnabled � alert/confirm/prompt
m_lv.DefaultScriptDialogsEnabled = True
' IsZoomControlEnabled � Ctrl+scroll zoom
m_lv.IsZoomControlEnabled = True
' IsDragDropEnabled � drag and drop (write-only)
m_lv.IsDragDropEnabled = False
' SmartResize � auto-fit WebView on resize (default True)
m_lv.SmartResize = True
These properties must be set BEFORE WebView2 creation (before WebViewReady fires). Setting them after has no effect.
| Property | Type | R/W | Description |
|---|---|---|---|
| AdditionalBrowserArguments | String | R/W | e.g. "--disable-gpu" |
| EnableHardwareAcceleration | Boolean | R/W | GPU acceleration |
| BrowserExecutableFolder | String | R/W | Fixed-version browser folder |
| Language | String | R/W | BCP 47 language code |
| ProxyServer | String | R/W | Proxy address |
| ProxyBypassList | String | R/W | Bypass list |
| RequiredMinimumVersion | String | R/W | Min runtime version |
| AutoRecoverOnCrash | Boolean | R/W | Auto-recreate on crash |
| EventsUseHexadecimal | Boolean | R/W | VB6 Int64 workaround |
| JsonToArrayMaxSize | Long | R/W | Max JSON size for JsonToArray and JsonToRowArray (default 50 MB). Unlike other pre-init properties, this can be changed at any time. |
Per-Member Usage
' All pre-init properties must be set BEFORE WebViewReady fires.
' Typically set in Form_Load or Form_Open.
' AdditionalBrowserArguments � pass Chromium command-line flags
m_lv.AdditionalBrowserArguments = "--disable-gpu --disable-extensions"
' EnableHardwareAcceleration � GPU rendering
m_lv.EnableHardwareAcceleration = True
' BrowserExecutableFolder � use fixed-version WebView2 runtime
m_lv.BrowserExecutableFolder = "C:\WebView2Runtime\130.0.2849.80"
' Language � set BCP 47 language code
m_lv.Language = "fr-FR"
' ProxyServer / ProxyBypassList � proxy configuration
m_lv.ProxyServer = "http://proxy.corp.local:8080"
m_lv.ProxyBypassList = "*.local;intranet.corp.local"
' RequiredMinimumVersion � fail if runtime is too old
m_lv.RequiredMinimumVersion = "120.0.0.0"
' AutoRecoverOnCrash � auto-recreate WebView on crash
m_lv.AutoRecoverOnCrash = True
' EventsUseHexadecimal � VB6 workaround for Int64 event params
m_lv.EventsUseHexadecimal = True ' sends Long params as hex strings
' JsonToArrayMaxSize � max JSON parse size for JsonToArray
m_lv.JsonToArrayMaxSize = 104857600 ' 100 MB
Version information and diagnostic utilities.
| Member | Type / Parameters | Returns | Description |
|---|---|---|---|
| ControlVersion | String R | OCX version (e.g. "1.0.0.1") | |
| BrowserVersionString | String R | WebView2 runtime version | |
| UserDataFolder | String R | User data folder path | |
| GetDiagnostics | (method) | String | Diagnostic info JSON |
| GetDefaultOcxPath | (method) | String | Default OCX path for current Office app |
Per-Member Usage
' ControlVersion (R) � OCX version string
Debug.Print "OCX: " & m_lv.ControlVersion ' "1.0.0.1"
' BrowserVersionString (R) � WebView2 runtime version
Debug.Print "Runtime: " & m_lv.BrowserVersionString ' "130.0.2849.80"
' UserDataFolder (R) � browser data folder path
Debug.Print "Data: " & m_lv.UserDataFolder
' GetDiagnostics � full diagnostic info as JSON
Dim diag As String
diag = m_lv.GetDiagnostics ' JSON with version, paths, settings, etc.
' GetDefaultOcxPath � default OCX registration path for current Office app
Debug.Print "OCX path: " & m_lv.GetDefaultOcxPath
Expose COM objects to JavaScript for direct automation from the page.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| AddHostObjectToScript | name As String, object As Object | Expose COM object to JS | |
| RemoveHostObjectToScript | name As String | Remove host object | |
| RemoveHostObjectFromScript | name As String | Remove host object (alias) | |
| AreHostObjectsAllowed | Boolean R/W | Must be True for AddHostObjectToScript |
Per-Member Usage
' AreHostObjectsAllowed (R/W) � must be True for host objects to work
Debug.Print "Host objects: " & m_lv.AreHostObjectsAllowed
' AddHostObjectToScript � expose COM object to JS
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
dict.Add "greeting", "Hello from VBA"
m_lv.AddHostObjectToScript "vbaHelper", dict
' JS: let obj = await chrome.webview.hostObjects.vbaHelper
' RemoveHostObjectToScript � remove host object (original name)
m_lv.RemoveHostObjectToScript "vbaHelper"
' RemoveHostObjectFromScript � remove host object (alias, same effect)
m_lv.RemoveHostObjectFromScript "vbaHelper"
Route JS messages to a VBA macro in a standard module instead of using OCX events.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| SetWebMessageCallback | vbaApplication As Object, macroName As String | Register VBA macro for JS messages | |
| ClearWebMessageCallback | Clear callback |
Per-Member Usage
' SetWebMessageCallback � route JS messages to a VBA macro (standard module)
m_lv.SetWebMessageCallback Application, "OnWebMessage"
' In a standard module:
' Public Sub OnWebMessage(ByVal message As String)
' Debug.Print "Received: " & message
' End Sub
' ClearWebMessageCallback � stop routing to macro
m_lv.ClearWebMessageCallback
Manage browser cache, cookies, and browsing data.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| ClearCache | Clear browser cache | ||
| ClearCookies | Clear all cookies | ||
| ClearBrowsingData | dataKinds As Long | Clear data by kind flags (see LiteView2BrowsingDataKinds enum) | |
| GetCookies | url As String | String (JSON) | Get cookies for URL |
| SetCookie | name, value, domain, path As String | Set a cookie | |
| ClearProfileCookies | Clear profile cookies | ||
| ClearBrowsingDataInTimeRange | dataKinds As Long, startTime As Date, endTime As Date | Clear data in time range |
Per-Member Usage
' ClearCache � clear browser cache
m_lv.ClearCache
' ClearCookies � clear all cookies
m_lv.ClearCookies
' ClearBrowsingData � clear by kind flags (bitwise OR)
m_lv.ClearBrowsingData 1 + 2 + 4 ' see LiteView2BrowsingDataKinds enum
' GetCookies � get cookies for URL (returns JSON)
Dim cookies As String
cookies = m_lv.GetCookies("https://lv2.local/")
' SetCookie � set a cookie (name, value, domain, path)
m_lv.SetCookie "session_id", "abc123", "lv2.local", "/"
' ClearProfileCookies � clear profile-level cookies
m_lv.ClearProfileCookies
' ClearBrowsingDataInTimeRange � clear data within date range
m_lv.ClearBrowsingDataInTimeRange 1, DateAdd("d", -7, Now()), Now()
Configure HTTP authentication, SSL handling, and single sign-on.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| SetBasicAuthCredentials | uriPattern, username, password As String | Set HTTP Basic Auth | |
| ClearBasicAuthCredentials | Clear stored auth | ||
| IgnoreCertificateErrors | Boolean R/W | Ignore SSL errors | |
| AllowSingleSignOnUsingOSPrimaryAccount | Boolean R/W | SSO using OS account | |
| HasAuthenticationSupport | Boolean R | Enhanced auth available |
Per-Member Usage
' SetBasicAuthCredentials � auto-respond to HTTP Basic Auth challenges
m_lv.SetBasicAuthCredentials "*", "admin", "password123"
' uriPattern: "*" = all, "*.corp.local" = specific domain
' ClearBasicAuthCredentials � remove stored auth
m_lv.ClearBasicAuthCredentials
' IgnoreCertificateErrors (R/W) � skip SSL validation
m_lv.IgnoreCertificateErrors = True ' for self-signed certs
' AllowSingleSignOnUsingOSPrimaryAccount (R/W) � Windows SSO
m_lv.AllowSingleSignOnUsingOSPrimaryAccount = True
' HasAuthenticationSupport (R) � enhanced auth available
If m_lv.HasAuthenticationSupport Then
m_lv.SetBasicAuthCredentials "*.corp.local", "user", "pass"
End If
Intercept, filter, and block web requests. Create custom requests and responses.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| AddWebResourceRequestedFilter | uriPattern As String, resourceContext As Long | Add request filter | |
| RemoveWebResourceRequestedFilter | uriPattern As String, resourceContext As Long | Remove filter | |
| ClearAllWebResourceRequestedFilters | Remove all filters | ||
| GetWebResourceRequestedFilters | String (JSON) | Get active filters | |
| SetWebResourceBlocking | enabled As Boolean | Enable/disable blocking | |
| IsWebResourceBlockingEnabled | Boolean R | Is blocking on | |
| BlockedRequestCount | Long R | Blocked requests since reset | |
| ResetBlockedRequestCount | Reset counter | ||
| EnableWebResourceResponseTracking | enabled As Boolean | Enable response events | |
| CreateWebResourceRequest | method, uri, headers, body As String | Long | Create request handle |
| CreateWebResourceResponse | content As String, statusCode As Long, reasonPhrase, headers As String | Long | Create response handle |
Per-Member Usage
' AddWebResourceRequestedFilter � subscribe to requests matching pattern
m_lv.AddWebResourceRequestedFilter "*://ads.example.com/*", 0 ' 0=All
' RemoveWebResourceRequestedFilter � unsubscribe
m_lv.RemoveWebResourceRequestedFilter "*://ads.example.com/*", 0
' ClearAllWebResourceRequestedFilters � remove all filters
m_lv.ClearAllWebResourceRequestedFilters
' GetWebResourceRequestedFilters � list active filters (JSON)
Dim filters As String
filters = m_lv.GetWebResourceRequestedFilters
' SetWebResourceBlocking � enable/disable blocking mode
m_lv.SetWebResourceBlocking True
' IsWebResourceBlockingEnabled (R) � check if blocking is on
Debug.Print "Blocking: " & m_lv.IsWebResourceBlockingEnabled
' BlockedRequestCount (R) � count of blocked requests
Debug.Print "Blocked: " & m_lv.BlockedRequestCount
' ResetBlockedRequestCount � reset counter to 0
m_lv.ResetBlockedRequestCount
' EnableWebResourceResponseTracking � enable WebResourceResponseReceived events
m_lv.EnableWebResourceResponseTracking True
' CreateWebResourceRequest � create a custom HTTP request handle
Dim hReq As Long
hReq = m_lv.CreateWebResourceRequest("POST", "https://api.example.com", _
"Content-Type: application/json", "{""data"":1}")
' CreateWebResourceResponse � create a custom HTTP response handle
Dim hResp As Long
hResp = m_lv.CreateWebResourceResponse("<h1>Blocked</h1>", 403, _
"Forbidden", "Content-Type: text/html")
Control file downloads, download dialog position, and silent download mode.
| Member | Type / Parameters | R/W or Returns | Description |
|---|---|---|---|
| DefaultDownloadFolderPath | String | R/W | Download folder |
| AllowDownloads | Boolean | R/W | Allow downloads |
| IsDownloadDialogOpen | Boolean | R | Dialog state |
| OpenDownloadDialog | (method) | Open dialog | |
| CloseDownloadDialog | (method) | Close dialog | |
| PauseDownload | downloadId As Long | Pause download | |
| ResumeDownload | downloadId As Long | Resume download | |
| CancelDownload | downloadId As Long | Cancel download | |
| ShowSaveAsDialog | (method) | Show Save As | |
| HiddenDownloadUI | Boolean | R/W | Silent downloads |
| DefaultDownloadDialogCornerAlignment | LV2_DOWNLOAD_DIALOG_CORNER_ALIGNMENT | R/W | Dialog position |
| DefaultDownloadDialogMarginX | Long | R/W | Dialog margin X |
| DefaultDownloadDialogMarginY | Long | R/W | Dialog margin Y |
Per-Member Usage
' DefaultDownloadFolderPath (R/W) � set/get download folder
m_lv.DefaultDownloadFolderPath = "C:\Downloads"
Debug.Print m_lv.DefaultDownloadFolderPath
' AllowDownloads (R/W) � enable/disable downloads
m_lv.AllowDownloads = True
' IsDownloadDialogOpen (R) � check dialog state
Debug.Print "Dialog open: " & m_lv.IsDownloadDialogOpen
' OpenDownloadDialog / CloseDownloadDialog
m_lv.OpenDownloadDialog
m_lv.CloseDownloadDialog
' PauseDownload � pause by download ID
m_lv.PauseDownload m_lastDownloadId
' ResumeDownload � resume paused download
m_lv.ResumeDownload m_lastDownloadId
' CancelDownload � cancel download
m_lv.CancelDownload m_lastDownloadId
' ShowSaveAsDialog � prompt user for save location
m_lv.ShowSaveAsDialog
' HiddenDownloadUI (R/W) � silent downloads (no UI)
m_lv.HiddenDownloadUI = True
' DefaultDownloadDialogCornerAlignment (R/W) � dialog position
m_lv.DefaultDownloadDialogCornerAlignment = 0 ' see LV2_DOWNLOAD_DIALOG_CORNER_ALIGNMENT
' DefaultDownloadDialogMarginX / MarginY (R/W) � dialog offset
m_lv.DefaultDownloadDialogMarginX = 20
m_lv.DefaultDownloadDialogMarginY = 20
Programmatic find-in-page with match counting and navigation.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| StartFind | searchText As String, caseSensitive As Boolean, matchWholeWord As Boolean | Start finding | |
| FindNext | Next match | ||
| FindPrevious | Previous match | ||
| StopFind | cancel As Boolean | Stop finding | |
| FindMatchCount | Long R | Total matches | |
| FindActiveMatchIndex | Long R | Current match (1-based) | |
| IsFindActive | Boolean R | Session active | |
| SuppressFindUI | Boolean R/W | Hide default Find UI | |
| FindHighlightAllMatches | Boolean R/W | Highlight all |
Per-Member Usage
' StartFind � begin a find session (text, caseSensitive, matchWholeWord)
m_lv.StartFind "webview2", False, False
' FindNext � go to next match
m_lv.FindNext
' FindPrevious � go to previous match
m_lv.FindPrevious
' StopFind � end session (True=clear highlights, False=keep last highlight)
m_lv.StopFind True
' FindMatchCount (R) � total matches found
Debug.Print "Matches: " & m_lv.FindMatchCount
' FindActiveMatchIndex (R) � current match index (1-based)
Debug.Print "Current: " & m_lv.FindActiveMatchIndex
' IsFindActive (R) � True if a find session is running
If m_lv.IsFindActive Then m_lv.StopFind True
' SuppressFindUI (R/W) � hide the default browser Find bar
m_lv.SuppressFindUI = True ' use your own UI instead
' FindHighlightAllMatches (R/W) � highlight all matches at once
m_lv.FindHighlightAllMatches = True
Suspend, resume, and manage WebView2 memory and lifecycle.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| TrySuspend | Suspend WebView to reduce resources | ||
| Resume | Resume after suspend | ||
| IsSuspended | Boolean R | Check if suspended | |
| GetMemoryUsage | Long | Approximate memory in bytes | |
| ForceGarbageCollection | Force JS GC | ||
| Dispose | Release all WebView resources | ||
| CloseBrowserProcess | Force close browser | ||
| IsVisible | Boolean R/W | Visibility state | |
| MemoryUsageTargetLevel | Long R/W | 0=Normal, 1=Low | |
| MoveFocus | reason As Long | Move focus in/out of WebView | |
| NotifyParentWindowPositionChanged | Fix DPI/rendering after move |
Per-Member Usage
' TrySuspend � suspend WebView to reduce resource usage
m_lv.TrySuspend
' Resume � resume after suspend
m_lv.Resume
' IsSuspended (R) � check if suspended
If m_lv.IsSuspended Then m_lv.Resume
' GetMemoryUsage � approximate memory in bytes
Debug.Print "Memory: " & Format(m_lv.GetMemoryUsage / 1048576, "0.0") & " MB"
' ForceGarbageCollection � trigger JS garbage collection
m_lv.ForceGarbageCollection
' Dispose � release all WebView2 resources (cannot be undone)
m_lv.Dispose
' CloseBrowserProcess � force-close the browser subprocess
m_lv.CloseBrowserProcess
' IsVisible (R/W) � show/hide the WebView
m_lv.IsVisible = False ' hide browser while loading
m_lv.IsVisible = True ' show when ready
' MemoryUsageTargetLevel (R/W) � 0=Normal, 1=Low
m_lv.MemoryUsageTargetLevel = 1 ' reduce memory footprint
' MoveFocus � move focus in/out of WebView
m_lv.MoveFocus 0 ' 0=Next, 1=Previous, 2=Programmatic
' NotifyParentWindowPositionChanged � fix DPI/rendering after move
m_lv.NotifyParentWindowPositionChanged
Browser privacy controls and compatibility settings for enterprise and testing environments.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| EnableStealthMode | enabled As Boolean | Enable comprehensive privacy protection mode | |
| HideWebDriver | hide As Boolean | Remove automation indicators for browser compatibility | |
| SpoofWebGL | vendor As String, renderer As String | Set custom WebGL renderer strings for compatibility testing | |
| RandomizeCanvasFingerprint | enabled As Boolean | Protect against cross-site canvas fingerprint tracking | |
| SpoofScreenSize | width As Long, height As Long, colorDepth As Long | Set custom screen dimensions for responsive testing | |
| DisableWebRTC | disabled As Boolean | Prevent WebRTC IP address exposure for privacy | |
| EnableMouseNoise | enabled As Boolean | Natural mouse movement simulation for UI testing | |
| EnableTimingNoise | minMs As Long, maxMs As Long | Randomized timing for realistic interaction testing | |
| IsStealthEnabled | Boolean R | Check if privacy mode is active |
Per-Member Usage
' EnableStealthMode � comprehensive privacy protection
m_lv.EnableStealthMode True
' HideWebDriver � remove navigator.webdriver indicator
m_lv.HideWebDriver True
' SpoofWebGL � custom WebGL renderer strings
m_lv.SpoofWebGL "NVIDIA Corporation", "NVIDIA GeForce RTX 4090"
' RandomizeCanvasFingerprint � protect against canvas tracking
m_lv.RandomizeCanvasFingerprint True
' SpoofScreenSize � custom screen dimensions for responsive testing
m_lv.SpoofScreenSize 1920, 1080, 24 ' width, height, colorDepth
' DisableWebRTC � prevent IP address exposure
m_lv.DisableWebRTC True
' EnableMouseNoise � natural mouse movement simulation
m_lv.EnableMouseNoise True
' EnableTimingNoise � randomized timing for realistic interactions
m_lv.EnableTimingNoise 50, 200 ' minMs, maxMs
' IsStealthEnabled (R) � check if privacy mode is active
Debug.Print "Stealth: " & m_lv.IsStealthEnabled
Tools for handling CAPTCHA challenges in automated testing and QA workflows.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| SetCaptchaService | serviceName As String, apiKey As String | Configure CAPTCHA solving service for automated testing | |
| DetectCaptcha | String | Detect CAPTCHA presence on page (returns JSON) | |
| SolveCaptcha | timeoutMs As Long | Boolean | Resolve detected CAPTCHA challenge |
| SolveRecaptchaV2 | siteKey As String, pageUrl As String | String | Handle reCAPTCHA v2 challenge |
| SolveHCaptcha | siteKey As String, pageUrl As String | String | Handle hCaptcha challenge |
| SubmitCaptchaToken | token As String | Submit resolved token to page |
Per-Member Usage
' SetCaptchaService � configure solving service (e.g. 2captcha)
m_lv.SetCaptchaService "2captcha", "YOUR_API_KEY"
' DetectCaptcha � check if page has a CAPTCHA (returns JSON)
Dim info As String
info = m_lv.DetectCaptcha ' e.g. '{"type":"recaptcha_v2","siteKey":"..."}'
' SolveCaptcha � resolve detected CAPTCHA (timeout in ms)
Dim solved As Boolean
solved = m_lv.SolveCaptcha(30000)
' SolveRecaptchaV2 � handle reCAPTCHA v2 specifically
Dim token As String
token = m_lv.SolveRecaptchaV2("6Le-SITE-KEY", "https://example.com/login")
' SolveHCaptcha � handle hCaptcha specifically
token = m_lv.SolveHCaptcha("HCAPTCHA-SITE-KEY", "https://example.com/login")
' SubmitCaptchaToken � inject resolved token into page
m_lv.SubmitCaptchaToken token
High-level automation methods that simplify common patterns. WaitForElement polls every 50 ms using ElementExistsBySelector — the UI stays responsive (messages are pumped between checks). All methods accept CSS selectors.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| WaitForElement | cssSelector As String, timeoutMs As Long | Boolean | Wait for element matching CSS selector to appear in DOM. Returns True if found, False on timeout. Polls every 50 ms. |
| ClickElementBySelector | cssSelector As String | — | Click the first element matching CSS selector. |
| GetTextBySelector | cssSelector As String | String | Get textContent of first element matching CSS selector. |
WaitForElement checks immediately first — if the element already exists, it returns instantly. Otherwise it polls every 50 ms, pumping messages between checks so the UI stays responsive. If timeoutMs is 0 or omitted, the SynchronousTimeOut property value is used (default 30 s).
Usage — Login Automation Example
' Navigate and wait for login form to appear
m_lv.Navigate "https://example.com/login"
' Wait up to 10 seconds for the form element
If m_lv.WaitForElement("#loginForm", 10000) Then
' Fill fields (use existing SetElementValueById or selector methods)
m_lv.SetElementValueById "email", "user@example.com"
m_lv.SetElementValueById "password", "secret123"
' Click submit button by CSS selector
m_lv.ClickElementBySelector "#loginForm button[type='submit']"
' Wait for dashboard to render
If m_lv.WaitForElement(".dashboard-panel", 15000) Then
' Read welcome message
Dim welcome As String
welcome = m_lv.GetTextBySelector(".welcome-message")
Debug.Print "Logged in: " & welcome
End If
Else
Debug.Print "Login form did not appear within 10 seconds"
End If
Reg-Free (BrowserPool) Usage
' Same methods, with browserIndex as first parameter
If m_Pool.WaitForElement(m_Idx, "#dashboard", 10000) Then
Dim msg As String
msg = m_Pool.GetTextBySelector(m_Idx, ".status-text")
End If
Embed the WebView2 browser in external window handles (HWND) or Access Frames.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| EmbedInHwnd | hwndParent As LongLong, width As Long, height As Long | Embed in external HWND (64-bit VBA only � use EmbedInHwndByLong for 32-bit) | |
| EmbedInHwndByLong | hwndParent As Long, width As Long, height As Long | VB6/VFP compatibility | |
| ResizeEmbedded | width As Long, height As Long | Resize embedded browser | |
| MoveEmbedded | left As Long, top As Long | Reposition embedded browser | |
| CloseEmbedded | Destroy embedded browser | ||
| QuickInitInFrame | parentForm As Object, targetFrame As Object | Auto DPI/handle init in Frame | |
| PointsToPixels | points As Long, isHorizontal As Boolean | Long | DPI conversion |
Per-Member Usage
' EmbedInHwnd � embed WebView2 in an external window handle
m_lv.EmbedInHwnd hwndParent, 800, 600
' EmbedInHwndByLong � VB6/VFP compatibility version
m_lv.EmbedInHwndByLong hwndParent, 800, 600
' ResizeEmbedded � resize embedded browser
m_lv.ResizeEmbedded 1024, 768
' MoveEmbedded � reposition embedded browser
m_lv.MoveEmbedded 10, 50 ' left, top in pixels
' CloseEmbedded � destroy embedded browser instance
m_lv.CloseEmbedded
' QuickInitInFrame � auto DPI/handle init inside an Access Frame control
m_lv.QuickInitInFrame Me, Me.Frame1
' PointsToPixels � convert Access twips/points to screen pixels
Dim px As Long
px = m_lv.PointsToPixels(400, True) ' horizontal DPI conversion
Open, edit, and preview documents (Office, PDF, images, video) inside the WebView2 control.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| OpenDocument | filePath As String, viewMode As Long | Open any document. viewMode: 0=Auto, 1=ForceHTML, 2=ForcePDF | |
| OpenOfficeDocument | filePath As String | Open Office doc for editing | |
| CloseOfficeDocument | Close embedded Office doc | ||
| SaveOfficeDocument | Save | ||
| SaveOfficeDocumentAs | filePath As String | Save As | |
| IsOfficeDocumentOpen | Boolean R | Is doc open | |
| OfficeDocumentPath | String R | Current doc path | |
| OfficeDocumentType | String R | Word/Excel/PowerPoint/Unknown | |
| CurrentDocumentPath | String R | Current doc path (universal) | |
| CurrentDocumentType | String R | Image/PDF/Video/Audio/Text/Word/Excel/PowerPoint | |
| WordApplication | Object R | Word.Application for automation | |
| WordDocument | Object R | Active Word.Document | |
| ShowDocumentPreview | filePath As String, hwndTarget As LongPtr | Preview in separate window | |
| ShowDocumentPreviewInBrowserFrame | filePath As String | Preview in same Frame as WebView2 | |
| CloseDocumentPreview | Close preview | ||
| EmbeddedParentHwnd | LongPtr R | Frame window handle |
Per-Member Usage
' OpenDocument � open any file (viewMode: 0=Auto, 1=ForceHTML, 2=ForcePDF)
m_lv.OpenDocument "C:\Reports\invoice.pdf", 0
' OpenOfficeDocument � open Word/Excel/PowerPoint for editing
m_lv.OpenOfficeDocument "C:\Docs\template.docx"
' CloseOfficeDocument � close the embedded Office document
m_lv.CloseOfficeDocument
' SaveOfficeDocument � save changes
m_lv.SaveOfficeDocument
' SaveOfficeDocumentAs � save to new path
m_lv.SaveOfficeDocumentAs "C:\Docs\copy.docx"
' IsOfficeDocumentOpen (R) � check if doc is open
If m_lv.IsOfficeDocumentOpen Then m_lv.SaveOfficeDocument
' OfficeDocumentPath (R) � current document path
Debug.Print m_lv.OfficeDocumentPath
' OfficeDocumentType (R) � Word/Excel/PowerPoint/Unknown
Debug.Print m_lv.OfficeDocumentType
' CurrentDocumentPath (R) � universal (any doc type)
Debug.Print m_lv.CurrentDocumentPath
' CurrentDocumentType (R) � Image/PDF/Video/Audio/Text/Word/Excel/etc.
Debug.Print m_lv.CurrentDocumentType
' WordApplication (R) � get Word.Application for automation
Dim wdApp As Object: Set wdApp = m_lv.WordApplication
' WordDocument (R) � get active Word.Document
Dim wdDoc As Object: Set wdDoc = m_lv.WordDocument
' ShowDocumentPreview � preview in external window
m_lv.ShowDocumentPreview "C:\Reports\chart.png", hwndTarget
' ShowDocumentPreviewInBrowserFrame � preview in same frame
m_lv.ShowDocumentPreviewInBrowserFrame "C:\Reports\chart.png"
' CloseDocumentPreview � close preview
m_lv.CloseDocumentPreview
' EmbeddedParentHwnd (R) � frame window handle
Debug.Print "Frame HWND: " & m_lv.EmbeddedParentHwnd
Access Chrome DevTools Protocol (CDP) for advanced browser automation.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| OpenDevToolsWindow | Open F12 DevTools | ||
| CallDevToolsProtocolMethod | methodName As String, parametersAsJson As String | String | Call CDP method |
| AddDevToolsProtocolEventHandler | eventName As String | Subscribe to CDP event | |
| RemoveDevToolsProtocolEventHandler | eventName As String | Unsubscribe | |
| HasDevToolsProtocol | Boolean R | CDP available | |
| OpenTaskManagerWindow | Browser task manager |
Per-Member Usage
' OpenDevToolsWindow � open F12 DevTools
m_lv.OpenDevToolsWindow
' CallDevToolsProtocolMethod � call any CDP method
Dim result As String
result = m_lv.CallDevToolsProtocolMethod("Browser.getVersion", "{}")
result = m_lv.CallDevToolsProtocolMethod("Page.captureScreenshot", "{""format"":""png""}")
' AddDevToolsProtocolEventHandler � subscribe to CDP event
m_lv.AddDevToolsProtocolEventHandler "Page.loadEventFired"
' RemoveDevToolsProtocolEventHandler � unsubscribe
m_lv.RemoveDevToolsProtocolEventHandler "Page.loadEventFired"
' HasDevToolsProtocol (R) � check if CDP is available
If m_lv.HasDevToolsProtocol Then
result = m_lv.CallDevToolsProtocolMethod("Runtime.evaluate", _
"{""expression"":""1+1""}")
End If
' OpenTaskManagerWindow � open browser task manager
m_lv.OpenTaskManagerWindow
Browser profile preferences including color scheme, tracking prevention, and popup handling.
| Property | Type | R/W | Description |
|---|---|---|---|
| PreferredColorScheme | LV2_COLOR_SCHEME | R/W | Auto/Light/Dark |
| PreferredTrackingPreventionLevel | LV2_TRACKING_PREVENTION | R/W | Tracking prevention |
| ProfileIsPasswordAutosaveEnabled | Boolean | R/W | Profile password save |
| ProfileIsGeneralAutofillEnabled | Boolean | R/W | Profile autofill |
| GetBrowserExtensionList | (method) | String (JSON) | Extensions |
| PopupMode | LV2_POPUP_MODE | R/W | Popup handling |
| OpenPopupsInSameWindow | Boolean | R/W | Legacy popup control |
Per-Member Usage
' PreferredColorScheme (R/W) � 0=Auto, 1=Light, 2=Dark
m_lv.PreferredColorScheme = 2 ' force dark mode
' PreferredTrackingPreventionLevel (R/W) � 0=None, 1=Basic, 2=Balanced, 3=Strict
m_lv.PreferredTrackingPreventionLevel = 2
' ProfileIsPasswordAutosaveEnabled (R/W) � profile-level password save
m_lv.ProfileIsPasswordAutosaveEnabled = False
' ProfileIsGeneralAutofillEnabled (R/W) � profile-level autofill
m_lv.ProfileIsGeneralAutofillEnabled = False
' GetBrowserExtensionList � installed extensions (JSON array)
Dim ext As String
ext = m_lv.GetBrowserExtensionList
' PopupMode (R/W) � 0=Allow, 1=BlockAll, 2=SameWindow
m_lv.PopupMode = 1 ' block all popups
' OpenPopupsInSameWindow (R/W) � legacy popup control
m_lv.OpenPopupsInSameWindow = True ' load popups in same WebView
Query license status and activate product keys.
| Member | Type / Parameters | Returns | Description |
|---|---|---|---|
| LicenseStatus | String R | VALID, TRIAL, EXPIRED, UNLICENSED | |
| LicenseType | String R | TRIAL, PRO, ENTERPRISE, NONE | |
| TrialDaysRemaining | Long R | Days left in trial | |
| LicenseExpiry | Date R | Expiry date | |
| LicenseVersion | String R | Licensed version range | |
| LicenseState | LV2_LICENSE_STATE R | Enum state | |
| ActivateLicense | company As String, key As String | Activate with license key |
Licensing Example
Source: frmAdvancedFeatures_Code.txt
' Check license status
Debug.Print "Status: " & m_lv.LicenseStatus ' VALID, TRIAL, EXPIRED
Debug.Print "Type: " & m_lv.LicenseType ' TRIAL, PRO, ENTERPRISE
Debug.Print "Days: " & m_lv.TrialDaysRemaining
Debug.Print "State: " & m_lv.LicenseState ' LV2_LICENSE_STATE enum
' Activate with license key
m_lv.ActivateLicense "MyCompany", "XXXXX-XXXXX-XXXXX"
Debug VBA/JS communication with a live message traffic HUD.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| ToggleBridgeInspector | Toggle HUD showing live JS/VBA message traffic |
Bridge Inspector Example
Source: frmScriptBridge_Code.txt
' Toggle the live message traffic HUD overlay
m_lv.ToggleBridgeInspector
' A floating panel appears showing all JS/VBA messages in real time