ILiteView2Ctrl — VBA WebView2 Methods Reference 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()
' This runs INSIDE the page's call: the page waits until it returns. Calls that
' wait for the browser (ExecuteScript, GetCookies, CallScriptSync, ...) fail here
' at once with &H80040203. Note that the page is ready, or push data with
' ExecuteScriptAsync, and return. Post-load work that needs ExecuteScript belongs
' in LiteView2Ctrl1_NavigationCompleted, which runs after WebView2's callback.
Public Sub OnReady()
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. Two calls belong inForm_Load, afterEnsureLicensed:EnableLvFacadeandAddScriptToExecuteOnDocumentCreated. Before the browser exists they are queued and applied before the first page. InsideWebViewReadythey fail at once with&H80040203. - 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 Note "page ready" / push data with ExecuteScriptAsync.
Runs inside the page's call: calls that wait for
the browser fail here (&H80040203)
↓
t4 LiteView2Ctrl1_NavigationCompleted
Post-load work that needs ExecuteScript and other
synchronous calls runs here
↓
(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.example/ 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.example/
m_lv.SetLocalContentRoot CurrentProject.Path & "\demos"
m_lv.Navigate "https://lv2.example/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 | HRESULT of the last failure that records one: WebView2 creation failures, an ExecuteScript / ExecuteScriptWithResult timeout (&H800705B4), or a call refused inside an event or host-object call (&H80040203). It is not reset by later successful calls, and many other failures don't set it. Handle Err at the call site and read LastErrorCode / LastError right after a failing call; don't poll it. |
| 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.example/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
Dim html As String
On Error Resume Next
html = m_lv.ExecuteScript("document.body.innerHTML")
If Err.Number <> 0 Then
Debug.Print "Error &H" & Hex(Err.Number) & ": " & Err.Description ' e.g. &H80040203
' m_lv.LastErrorCode / m_lv.LastError hold the same code and text now
End If
On Error GoTo 0
' 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.
Which calls wait. Some methods wait for the browser's answer before they return:
ExecuteScriptand everything built on it:ExecuteScriptWithArgs, the DOM helpers such asGetElementValueById,GetPageHtml,GetPageTextandGetTextBySelectorExecuteScriptWithResult,WaitForElement,GetCookies,GetBrowserExtensionList,ClearBrowsingDataInTimeRange,CallDevToolsProtocolMethod,DetectCaptcha,SolveCaptchaNavigateSync,NavigateToStringSync,NavigateWithWebResourceRequestSyncCallScriptSync,GetScriptProperty,SetScriptProperty, andBindScriptObjectwithLV2_BIND_VALIDATE- once the browser exists:
AddScriptToExecuteOnDocumentCreatedandEnableLvFacade
Where they work. In ordinary code (a button, a timer), and inside these events, which LiteView2 raises after WebView2's own callback has returned:
NavigationCompleted,NavigationCompletedHexSourceChanged,ContentLoading,ContentLoadingHex,DOMContentLoadedDocumentTitleChanged,HistoryChangedWebMessageReceived,DevToolsProtocolEventReceived
Where they fail. Everywhere else they do not wait. They fail at once with error &H80040203 (-2147220989), start nothing, and the error text says what to use instead. That applies:
- inside
WebViewReady,CreateWebViewCompleted,NavigationStartingand every other event not listed above; - inside a VBA method the page is calling through a host object (
chrome.webview.hostObjects.<name>or.sync.<name>) orRegisterVbaCallback.
WaitForElement returns False there instead of raising. The rule is per thread: inside one control's event, the other LiteView2 controls on the form refuse as well.
What to use in those places. Calls that do not wait: Navigate, NavigateToString, ExecuteScriptAsync, PostWebMessageAsJson / PostWebMessageAsString, CallScript, PushRecordset, FireJsEvent, CallJsFunction, SetJsVariable, AddHostObjectToScript, property assignments, and the JSON helpers. To get a value back, do one of these:
- return it from the host-object method;
- let the page answer with
chrome.webview.postMessage(...)and read the answer inWebMessageReceived; - make the call after the handler has returned: a form Timer in Access,
Application.OnTimein Excel or Word, a Timer control in VB6.
Reg-Free (BrowserPool). The pool raises no events. Its ready callback (SetReadyCallback) and message macro (SetWebMessageCallback) run from the message loop, where synchronous pool calls work. The exception is when your own code is pumping messages (MsgBox, DoEvents) inside an event or host-object method at that moment. Inside a VBA method the page is calling, a synchronous pool call fails with &H80004005; pool.GetLastErrorCode(idx) returns &H80040203 and pool.GetLastError(idx) gives the reason.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| ExecuteScript | script As String | String | Execute JS and return its result (JSON). Waits up to SynchronousTimeOut. Inside inline events and host-object calls it fails at once with &H80040203 (see the box above). |
| 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. Waits at most SynchronousTimeOut (0 means 30000). A timeout raises no error. Instead it returns succeeded = False, puts "ExecuteScriptWithResult got no result from the page within … ms (SynchronousTimeOut)…" in exceptionMessage, and sets LastErrorCode = &H800705B4. So succeeded = False does not always mean the script threw. Inside inline events and host-object methods it raises &H80040203 (it does not return succeeded = False) and runs nothing. |
| AddScriptToExecuteOnDocumentCreated | script As String | String (scriptId) | Inject JS that runs on every page load. Call it in Form_Load, where it is queued and also covers the first page (a queued call returns an empty scriptId), or later from ordinary code (it waits up to 5 s and returns the id). Inside WebViewReady and other inline events it fails at once with &H80040203. See the note below. |
| RemoveScriptToExecuteOnDocumentCreated | id As String | Remove injected script |
AddScriptToExecuteOnDocumentCreated — Registered. Register document scripts before the browser exists, in Form_Load / UserForm_Initialize. There the call is queued, and the script is registered before WebViewReady fires and before the first Navigate, so it also runs on the first page. A queued call returns an empty scriptId, so there is no id to pass to RemoveScriptToExecuteOnDocumentCreated.
Once the browser exists, the call waits (up to 5 s) for WebView2 to confirm and returns the id. That works from ordinary code and from notification events, and affects later navigations only. Inside WebViewReady, other inline events and host-object methods it fails at once with &H80040203 and registers nothing.
Reg-Free. Call pool.AddScriptToExecuteOnDocumentCreated idx, script inside OnBrowserReady, before pool.Navigate. The ready callback runs from the message loop, so the call completes there.
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
' Here: from ordinary code once the browser exists (waits up to 5 s, returns the id).
' In Form_Load the call is queued and returns an empty scriptId (nothing to remove).
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 the window.lv global JS facade into every page. Call it in Form_Load / UserForm_Initialize: there it is queued and in place before the first page. Or call it later from ordinary code. Inside WebViewReady and other inline events it fails at once with &H80040203. | |
| IsLvFacadeEnabled | Boolean | Whether window.lv facade is active |
Facade Example
' Enable the window.lv facade in Form_Load. The browser does not exist yet, so the
' call is queued and the facade is in place before the first page loads.
Private Sub Form_Load()
Set m_lv = Me.LiteView2Ctrl1.Object
EnsureLicensed m_lv
m_lv.EnableLvFacade True
End Sub
Private Sub LiteView2Ctrl1_WebViewReady()
' Not here: inside WebViewReady, EnableLvFacade fails at once with &H80040203.
m_lv.SetLocalContentRoot CurrentProject.Path
m_lv.Navigate "https://lv2.example/my_page.html"
End Sub
' IsLvFacadeEnabled is True as soon as EnableLvFacade True has succeeded
' (also while the call is still queued).
If m_lv.IsLvFacadeEnabled Then Debug.Print "window.lv is injected into every page"
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 nestedData As String
nestedData = "{""data"":[null,{""v"":1},null,{""v"":2}]}"
Debug.Print m_lv.JsonCompact(nestedData, "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.1.0") | |
| 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.1.0"
' 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, Optional ByVal source 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. Known issue in 1.0.1.0: returns without an error but clears nothing. Use ClearBrowsingData (all time) or ClearCookies instead. |
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.example/")
' SetCookie — set a cookie (name, value, domain, path)
m_lv.SetCookie "session_id", "abc123", "lv2.example", "/"
' ClearProfileCookies — clear profile-level cookies
m_lv.ClearProfileCookies
' ClearBrowsingDataInTimeRange — known issue in 1.0.1.0: returns without an error
' but clears nothing. Use ClearBrowsingData (all time) or ClearCookies instead:
m_lv.ClearBrowsingData 1 ' kind 1 = file systems, all time
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
Preview documents (Office, PDF, images, video) inside the control. Office editing & automation were removed — the methods here are preview-only. For PDF, images, and HTML: SetLocalContentRoot then Navigate "https://lv2.example/<file>". For Office documents: ShowDocumentPreview / ShowDocumentPreviewInBrowserFrame.
| Member | Parameters | Returns | Description |
|---|---|---|---|
| OpenDocument | filePath As String, viewMode As Long | Open a document (Office/text/CSV). For PDF/images/HTML use Navigate "https://lv2.example/…". viewMode: 0=Auto | |
| OpenOfficeDocument | filePath As String | Removed — use ShowDocumentPreview | |
| CloseOfficeDocument | Removed | ||
| SaveOfficeDocument | Removed (editing not supported) | ||
| SaveOfficeDocumentAs | filePath As String | Removed (editing not supported) | |
| IsOfficeDocumentOpen | Boolean R | Removed — always False | |
| OfficeDocumentPath | String R | Removed — use CurrentDocumentPath | |
| OfficeDocumentType | String R | Removed — use CurrentDocumentType | |
| CurrentDocumentPath | String R | Current doc path (universal) | |
| CurrentDocumentType | String R | Image/PDF/Video/Audio/Text/Word/Excel/PowerPoint | |
| WordApplication | Object R | Removed (automation not supported) | |
| WordDocument | Object R | Removed (automation not supported) | |
| ShowDocumentPreview | filePath As String, hwndTarget As LongPtr | Office docs — preview in a target window (hwndTarget) | |
| ShowDocumentPreviewInBrowserFrame | filePath As String | Recommended for Office docs — preview in the control's own frame | |
| 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\report.docx", 0 ' Office/text/CSV. For PDF/images: SetLocalContentRoot + Navigate "https://lv2.example/file.pdf"
' 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. Waits for the browser's answer (fixed 30 s). Works from ordinary code and inside DevToolsProtocolEventReceived, which is how you answer a CDP event. Inside WebViewReady, other inline events and host-object methods it fails at once with &H80040203 and sends nothing. Reg-Free: a refused call raises &H80004005; GetLastErrorCode(idx) returns &H80040203. |
| 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
' (waits up to 30 s; inside WebViewReady and other inline events it fails at once, &H80040203)
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