IBrowserPool — Reg-Free VBA WebView2 Multi-Browser Manager Reg-Free Mode — programmatic multi-browser pool; every method takes browserIndex As Long as the first parameter

Works in VBA (Excel, Access, Word, Outlook, PowerPoint, Visio, Project), VB6, VB.NET, C#, C++, Delphi, Python, PowerShell, AutoIt — and any COM host.

New here? Start with plain English

The Setup Module — paste once, forget it

When you add LiteView2 in no-admin mode, you paste one standard module into your VBA project. You do this once, the same way you'd paste a utility module full of string functions.

The module does three things when your database first opens:

  1. Tells Windows where to find the OCX file (it's next to your .accdb)
  2. Loads the OCX without registering it in the Windows registry
  3. Creates the browser engine and makes it available to all your forms

After you paste it, you never look at it again. Every form uses it with one line:

Dim pool As Object
Set pool = GetPool()   ' that's all — the browser engine is ready

Works without IT involvement
Most ActiveX controls need to be "registered" with Windows — which means running a program as Administrator, or asking IT. LiteView2 doesn't need this. Copy two files next to your .accdb file and it runs. When you copy your database to another PC, copy the OCX files too. No installation, no admin rights, no IT ticket — it just works.

Step-by-step Reg-Free Mode setup (5 minutes) →

Note

IBrowserPool mirrors most of ILiteView2Ctrl's functionality but adds browserIndex As Long as the first parameter to every method. This page documents only the pool-specific methods. For shared methods (Navigate, ExecuteScript, PushRecordset, etc.), see the ILiteView2Ctrl reference — just add browserIndex as the first argument.

Canonical lifecycle template — Reg-Free Mode

The lifecycle pattern below eliminates the friction every customer hits the first time they use the pool from a VBA 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)

  1. Add a Frame control named fraBrowser to the form.
  2. Open the modLV2Pool bootstrap module that ships with LiteView2. Inside GetPool(), edit the m_Pool.ActivateLicense "Your Company", "YOUR-LICENSE-KEY" line — replace the two string literals with your real company name and V1|... activation key (see the full module below). Every form then picks the licence up automatically via GetPool().
  3. Paste this into the form's code module:
Option Explicit
Private pool As Object
Private idx  As Long

Private Sub Form_Load()
    Set pool = GetPool()              ' GetPool activates the license once per process
    idx = pool.CreateInControl("about:blank", Me.fraBrowser)
    pool.SetReadyCallback idx, Me, "OnBrowserReady"
End Sub

Public Sub OnBrowserReady()
    pool.SetLocalContentRoot idx, CurrentProject.Path
    pool.Navigate idx, "https://lv2.example/index.html"
End Sub

Private Sub Form_Unload(Cancel As Integer)
    pool.DestroyBrowserSync idx, 2000
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 modLV2Pool.bas once, and every form inherits it via GetPool().

The full modLV2Pool bootstrap module

There is no second module in Reg-Free Mode. modLV2Pool is the bootstrap module that ships with LiteView2 and exports GetPool(). Use the module exactly as shown below — to activate your purchased license, edit the two string literals ("Your Company" and "YOUR-LICENSE-KEY") inside the single ActivateLicense line. Comment that one line out to keep the 30-day Trial Period.

Option Explicit

' ============================================================================
'  LiteView2 Reg-Free Pool bootstrap
'  No regsvr32 required. The matching LiteView2_x64.ocx / LiteView2_x86.ocx
'  must sit in the same folder as the .accdb / .xlsm.
' ============================================================================

#If Win64 Then
    Private Declare PtrSafe Function SetDllDirectory Lib "kernel32" _
        Alias "SetDllDirectoryW" (ByVal lpPathName As LongPtr) As Long
    Private Declare PtrSafe Function LiteView2_ActivateManifest _
        Lib "LiteView2_x64.ocx" (ByVal path As LongPtr) As Long
    Private Declare PtrSafe Function LiteView2_CreateBrowserPool _
        Lib "LiteView2_x64.ocx" () As Object
#Else
    Private Declare PtrSafe Function SetDllDirectory Lib "kernel32" _
        Alias "SetDllDirectoryW" (ByVal lpPathName As LongPtr) As Long
    Private Declare PtrSafe Function LiteView2_ActivateManifest _
        Lib "LiteView2_x86.ocx" (ByVal path As LongPtr) As Long
    Private Declare PtrSafe Function LiteView2_CreateBrowserPool _
        Lib "LiteView2_x86.ocx" () As Object
#End If

Private m_Pool As Object
Private m_Initialized As Boolean

Public Function GetPool() As Object
    If Not m_Initialized Then
        Dim p As String: p = CurrentProject.Path
        SetDllDirectory StrPtr(p)
        #If Win64 Then
            LiteView2_ActivateManifest StrPtr(p & "\LiteView2_x64.ocx")
        #Else
            LiteView2_ActivateManifest StrPtr(p & "\LiteView2_x86.ocx")
        #End If
        Set m_Pool = LiteView2_CreateBrowserPool()

        ' Edit the two strings below: your registered company name and your
        ' V1|... activation key from the purchase email. Comment this line
        ' out to keep the 30-day Trial Period.
        m_Pool.ActivateLicense "Your Company", "YOUR-LICENSE-KEY"

        m_Initialized = True
    End If
    Set GetPool = m_Pool
End Function

Activation is process-wide and happens automatically the first time any form calls GetPool(). Forms never need to call ActivateLicense themselves.

Per-form code — full canonical template

' ============================================================================
'  Reg-Free Mode — canonical lifecycle template (per form)
' ============================================================================
'  Form prerequisites:
'    - A Frame control named  fraBrowser
'    - modLV2Pool (bootstrap module shipped with LiteView2; the
'      ActivateLicense line inside GetPool() holds your activation key)
'      with your activation key edited into ActivateLicense. GetPool() then
'      activates the license automatically on its first call in the process.
'
'  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

Private pool As Object
Private idx  As Long

Private Sub Form_Load()
    On Error GoTo ErrH
    If Me.CurrentView = 0 Then Exit Sub   ' Skip in design view

    ' GetPool() handles license activation once per process -- see modLV2Pool.bas.
    Set pool = GetPool()

    idx = pool.CreateInControl("about:blank", Me.fraBrowser)
    pool.SetReadyCallback idx, Me, "OnBrowserReady"

    Exit Sub
ErrH:
    MsgBox "Form_Load: " & Err.Number & " " & Err.Description, vbCritical
End Sub

' Public — invoked by the pool by name when the browser is ready.
Public Sub OnBrowserReady()
    On Error GoTo ErrH

    pool.SetLocalContentRoot idx, CurrentProject.Path
    pool.SetAreHostObjectsAllowed idx, True
    pool.AddHostObjectToScript idx, "vba", Me
    pool.Navigate idx, "https://lv2.example/index.html"

    Exit Sub
ErrH:
    MsgBox "OnBrowserReady: " & Err.Number & " " & Err.Description, vbCritical
End Sub

' Called by the page via window.chrome.webview.hostObjects.sync.vba.OnReady()
Public Sub OnReady()
End Sub

Private Sub Form_Unload(Cancel As Integer)
    On Error Resume Next
    If Not pool Is Nothing And idx <> 0 Then
        pool.Stop idx                       ' halt any in-flight navigation
        pool.ClearReadyCallback idx         ' detach callback so it can't fire after teardown
        pool.DestroyBrowserSync idx, 2000   ' synchronous teardown (max 2 s wait) -- REQUIRED
        idx = 0
    End If
    Set pool = Nothing                      ' release the pool reference
End Sub

Lifecycle rules

  1. The activation key lives in modLV2Pool.bas, not in per-form code. GetPool() activates the license automatically on the first call in the process. Forms simply call Set pool = GetPool() and inherit the licensed state.
  2. Everything else waits for OnBrowserReady. SetLocalContentRoot, host-object registration, and the first Navigate belong in OnBrowserReady. Calling them in Form_Load after CreateInControl races with async init.
  3. Host objects must be added before the navigation that uses them. Order: SetLocalContentRootSetAreHostObjectsAllowedAddHostObjectToScriptNavigate.
  4. Buttons need a MouseDown mirror when focus may be inside the browser. Keep Click for keyboard activation; add MouseDown for the first physical click.
  5. Form_Unload teardown is required. Call ClearReadyCallback, DestroyBrowserSync idx, 2000, then Set pool = Nothing. Without DestroyBrowserSync, the browser process keeps Access alive after the form closes.

Activation key placement

  • ✅ The activation key lives inside the single ActivateLicense line in GetPool() in modLV2Pool.bas. Forms just call Set pool = GetPool() — 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 ActivateLicense AFTER the first Navigate. The watermark may already have rendered.
  • ❌ Never call ActivateLicense inside OnBrowserReady. 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 ActivateLicense call activates every browser the pool creates afterwards in the same Access (or Office) session.
  • The pool shares the activated license across every CreateInControl call automatically — you do not register the license per browser-index.
  • Activation does not persist across Access restarts. Each fresh process must call ActivateLicense once — that's what GetPool() handles for you on the first form that calls it.

That is why the recommended pattern stores the key in modLV2Pool.bas: the activation key appears in exactly one place, the bootstrap module. Whichever form opens first calls GetPool() which triggers activation; every later form's GetPool() call is a cheap no-op (the singleton is already initialised). You change the key once, in one file, and every form picks it up automatically.

Never do this in Form_Load

' ❌ WRONG — the browser isn't ready right after CreateInControl.
' These calls race with async init or hit an unmapped lv2.example.
Private Sub Form_Load()
    Set pool = GetPool()
    idx = pool.CreateInControl("about:blank", Me.fraBrowser)
    pool.SetLocalContentRoot idx, CurrentProject.Path     ' ❌ wait for OnBrowserReady
    pool.AddHostObjectToScript idx, "vba", Me            ' ❌ wait for OnBrowserReady
    pool.Navigate idx, "https://lv2.example/index.html"   ' ❌ wait for OnBrowserReady
End Sub
' ✅ CORRECT — Form_Load does setup; OnBrowserReady does the rest.
' GetPool() activates the license internally (key lives in modLV2Pool.bas).
Private Sub Form_Load()
    Set pool = GetPool()
    idx = pool.CreateInControl("about:blank", Me.fraBrowser)
    pool.SetReadyCallback idx, Me, "OnBrowserReady"
End Sub

Public Sub OnBrowserReady()
    pool.SetLocalContentRoot idx, CurrentProject.Path
    pool.SetAreHostObjectsAllowed idx, True
    pool.AddHostObjectToScript idx, "vba", Me
    pool.Navigate idx, "https://lv2.example/index.html"
End Sub

Lifecycle timeline

TIME EVENT                            WHAT YOUR CODE DOES HERE
──── ───────────────────────────────── ──────────────────────────────────────────
 t0  Form_Load                        Set pool = GetPool()    (modLV2Pool activates
                                                               the license internally)
                                      idx = pool.CreateInControl("about:blank", fra)
                                      pool.SetReadyCallback idx, Me, "OnBrowserReady"
 ↓
     (WebView2 starts up — async)     (you do nothing)
 ↓
 t1  Public Sub OnBrowserReady        pool.SetLocalContentRoot idx, CurrentProject.Path
                                      pool.SetAreHostObjectsAllowed idx, True
                                      pool.AddHostObjectToScript idx, "vba", Me
                                      pool.Navigate idx, "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_Unload                      pool.Stop idx
                                      pool.ClearReadyCallback idx
                                      pool.DestroyBrowserSync idx, 2000
                                      Set pool = Nothing

Exit lifecycle — closing the form safely

The loading sequence has a clear order; the unloading sequence does too. Following it cleanly prevents three real problems:

  1. A navigation in flight at the moment the form closes can fire NavigationCompleted against a half-destroyed browser.
  2. An async ready callback that hasn't fired yet can trigger after VBA references are gone.
  3. Reg-Free Mode only — the WebView2 host process (msedgewebview2.exe) keeps Access alive after the form closes if it isn't explicitly torn down.
Private Sub Form_Unload(Cancel As Integer)
    On Error Resume Next
    If Not pool Is Nothing And idx <> 0 Then
        pool.Stop idx                       ' halt any in-flight navigation
        pool.ClearReadyCallback idx         ' detach callback so it can't fire after teardown
        pool.DestroyBrowserSync idx, 2000   ' synchronous teardown (max 2 s wait) -- REQUIRED
        idx = 0
    End If
    Set pool = Nothing                      ' release the pool reference
End Sub

What each line does:

  • pool.Stop idx — halts a navigation that might still be loading when the user closes the form. Without it, the page can fire NavigationCompleted while the browser is being destroyed.
  • pool.ClearReadyCallback idx — removes the OnBrowserReady callback so it cannot fire on a form that's already unloading. Without this, an async ready callback can call back into VBA after the form's references are gone (Type mismatch / Object required).
  • pool.DestroyBrowserSync idx, 2000the critical one for Reg-Free Mode. Tears down the browser instance synchronously, waiting up to 2 seconds for in-process cleanup to complete. Without this call, the WebView2 host process keeps running and Access cannot exit cleanly — Task Manager will show a lingering msedgewebview2.exe and MSACCESS.EXE until the OS finally kills them.
  • idx = 0 — sentinel so a stray callback hitting this form sees an invalid handle and exits cleanly.
  • Set pool = Nothing — releases your VBA reference to the pool singleton.
  • On Error Resume Next — if the form is closing because of an earlier error, we still want the teardown attempt to complete; a second error during shutdown produces a half-stuck form customers struggle to dismiss.

SetLocalContentRoot path mapping

pool.SetLocalContentRoot idx, folder maps a folder on disk to the https://lv2.example/ virtual host. The mapping is one-to-one per browser: the folder you pass becomes the URL root.

Disk path you passURL rootExample file on diskURL to navigate to
C:\Apps\MyDB\https://lv2.example/C:\Apps\MyDB\index.htmlhttps://lv2.example/index.html
C:\Apps\MyDB\https://lv2.example/C:\Apps\MyDB\pages\admin.htmlhttps://lv2.example/pages/admin.html
CurrentProject.Pathhttps://lv2.example/the form's folderhttps://lv2.example/<any-file>

Common path-mapping mistakes:

  • Wrong root level. You map C:\Apps\ but your HTML lives in C:\Apps\MyDB\index.html. The URL must then be https://lv2.example/MyDB/index.html, not /index.html.
  • Subfolder confusion. You pass CurrentProject.Path & "\html" and then navigate to https://lv2.example/html/index.html. The \html part already became the new root.
  • Backslash in URL. Use forward slashes only: https://lv2.example/index.html.
  • Missing target file. The mapping is correct but index.html doesn't actually exist in the mapped folder. WebView2 shows its own "page can't be reached" error.

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 third argument of pool.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 pool.AddHostObjectToScript idx, "vba", Me call (in OnBrowserReady) 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 the embedded browser, Access uses the FIRST click on any external 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 with any embedded ActiveX control (legacy WebBrowser, Microsoft DatePicker, TreeView all have it), not a LiteView2 bug.

Mirror Click into MouseDownMouseDown 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.

Copy-Paste Checklist

Before reporting a problem, verify each of these:

  • modLV2Pool.bas is imported into the VBA project, with your real company name and V1|... activation key edited into the m_Pool.ActivateLicense line inside GetPool()
  • ☐ The form's Form_Load calls Set pool = GetPool() (this is what triggers activation)
  • index.html (or whatever filename the code navigates to) physically exists in the folder you pass to SetLocalContentRoot
  • SetLocalContentRoot is called BEFORE the first Navigate
  • AddHostObjectToScript is called BEFORE the Navigate that loads the page that uses the host object
  • ☐ The form has an OnBrowserReady handler registered via SetReadyCallback — that handler is where the setup calls live, not Form_Load
  • ☐ Every Public Sub the page calls via hostObjects.sync.vba.<name>() exists in the form's code module (including OnReady if your page calls it)
  • ☐ Any button reachable while focus is inside the WebView2 has BOTH a Click handler AND a MouseDown mirror that runs the same action
  • Form_Unload calls pool.ClearReadyCallback idx and pool.DestroyBrowserSync idx, 2000

Troubleshooting

SymptomMost likely causeFix
Watermark renders despite a valid keyEither the m_Pool.ActivateLicense line in GetPool() still has the placeholder "YOUR-LICENSE-KEY", or that line is commented out, or GetPool() isn't being called from Form_Load.Open modLV2Pool.bas — confirm the ActivateLicense line inside GetPool() holds your real company name and your V1|... activation key, and that the line is not commented out.
Local files don't load — "Can't reach this page" or 404SetLocalContentRoot not called, called with the wrong folder, or the URL points outside the mapped folderMap CurrentProject.Path; verify index.html exists in that folder; the URL must use forward slashes.
Local files exist but still won't loadNavigate executed before SetLocalContentRootCall SetLocalContentRoot BEFORE the first Navigate inside OnBrowserReady.
window.chrome.webview.hostObjects.sync.vba is undefined in JSAddHostObjectToScript was called AFTER Navigate. Host objects only bind on the NEXT navigation.Inside OnBrowserReady the order must be: SetLocalContentRootSetAreHostObjectsAllowedAddHostObjectToScriptNavigate.
First click on a form button does nothing; second click worksAccess 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.
WebView2 process lingers in Task Manager; Access hangs on exitDestroyBrowserSync not called in Form_Unload. The browser process keeps Access alive.Add pool.ClearReadyCallback idx, pool.DestroyBrowserSync idx, 2000, then Set pool = Nothing to Form_Unload.

Getting Started — Reg-Free Setup

Before you can use IBrowserPool, add this standard module to your project. It declares the Win32 API calls needed to load the OCX without COM registration, then exposes a GetPool() singleton you can call from any form.

Place the OCX in the same folder as your .accdb or .xlsm.

modLV2Pool.bas — add once per project

Option Explicit

' --- Win32 + OCX declarations (64-bit / 32-bit) ---
#If Win64 Then
    Private Declare PtrSafe Function SetDllDirectory Lib "kernel32" _
        Alias "SetDllDirectoryW" (ByVal lpPathName As LongPtr) As Long
    Private Declare PtrSafe Function LiteView2_ActivateManifest _
        Lib "LiteView2_x64.ocx" (ByVal path As LongPtr) As Long
    Private Declare PtrSafe Function LiteView2_CreateBrowserPool _
        Lib "LiteView2_x64.ocx" () As Object
#Else
    Private Declare PtrSafe Function SetDllDirectory Lib "kernel32" _
        Alias "SetDllDirectoryW" (ByVal lpPathName As LongPtr) As Long
    Private Declare PtrSafe Function LiteView2_ActivateManifest _
        Lib "LiteView2_x86.ocx" (ByVal path As LongPtr) As Long
    Private Declare PtrSafe Function LiteView2_CreateBrowserPool _
        Lib "LiteView2_x86.ocx" () As Object
#End If

Private m_Pool As Object

Public Function GetPool() As Object
    If m_Pool Is Nothing Then
        Dim p As String
        p = CurrentProject.Path          ' Access  (Excel: ThisWorkbook.Path)
        SetDllDirectory StrPtr(p)        ' Tell Windows where the OCX lives
        #If Win64 Then
            LiteView2_ActivateManifest StrPtr(p & "\LiteView2_x64.ocx")
        #Else
            LiteView2_ActivateManifest StrPtr(p & "\LiteView2_x86.ocx")
        #End If
        Set m_Pool = LiteView2_CreateBrowserPool()
        m_Pool.ActivateLicense "Your Company", "YOUR-LICENSE-KEY"  ' omit this line during 30-day trial
    End If
    Set GetPool = m_Pool
End Function

Usage from any form

Private pool As Object
Private idx  As Long

Private Sub Form_Load()
    Set pool = GetPool()
    idx = pool.CreateInControl("about:blank", Me.Frame1)
    pool.SetReadyCallback idx, Me, "OnBrowserReady"
End Sub

' LiteView2 calls this on the UI thread when the browser is ready
Public Sub OnBrowserReady()
    pool.SetLocalContentRoot idx, CurrentProject.Path & "\html"
    pool.Navigate idx, "https://lv2.local/dashboard.html"
End Sub

Private Sub Form_Unload(Cancel As Integer)
    On Error Resume Next
    If Not pool Is Nothing And idx <> 0 Then
        pool.ClearReadyCallback idx
        pool.DestroyBrowserSync idx, 2000
        idx = 0
    End If
End Sub
What is lv2.local?

SetLocalContentRoot maps a folder on disk to the virtual hostname https://lv2.local/. Files in that folder are then accessible via URLs like https://lv2.local/dashboard.html. This avoids file:// URLs (which have security restrictions) and gives your local HTML files a proper HTTPS origin. See ILiteView2Ctrl › Local Content Mapping for details.

Licensing

ActivateLicense is called once per process, before creating any browser instances. The recommended place is inside GetPool(), right after LiteView2_CreateBrowserPool():

m_Pool.ActivateLicense "Your Company", "YOUR-LICENSE-KEY"
Trial & Activation

A 30-day trial starts automatically � all features are fully functional with no limitations. After trial expiry, the control displays a watermark and API methods return E_ACCESSDENIED. Add the ActivateLicense line with your purchased key to activate immediately. No license files, no registry entries � just one line of VBA code.

Reg-Free (IBrowserPool)

' Inside GetPool(), right after LiteView2_CreateBrowserPool()
m_Pool.ActivateLicense "My Company", "LICENSE-KEY-HERE"

Registered (Design-Time Control)

' In your Form_Load or WebViewReady event
m_lv.ActivateLicense "My Company", "LICENSE-KEY-HERE"

License Status Properties

' Works on both pool and control objects
Debug.Print "Status: " & obj.LicenseStatus
Debug.Print "Type: "   & obj.LicenseType
Debug.Print "State: "  & obj.LicenseState       ' 0=Valid, 1=Trial, 2=Expired, 3=Invalid
Debug.Print "Days: "   & obj.TrialDaysRemaining

Key Difference

Every ILiteView2Ctrl method gains a browserIndex As Long first parameter on IBrowserPool:

' ILiteView2Ctrl (design-time OCX — single browser)
m_lv.Navigate "https://example.com"
m_lv.PushRecordset rs, "onData"

' IBrowserPool (multi-browser pool — add browserIndex)
pool.Navigate browserIndex, "https://example.com"
pool.PushRecordset browserIndex, rs, "onData"
Create & Destroy 6 methods

Create and destroy browser instances in the pool. Each Create call returns a unique index (1, 2, 3...) or 0 on failure.

MemberParametersReturnsDescription
CreatehwndParent As Long, url As String, x As Long, y As Long, width As Long, height As LongLongCreate browser, returns index (1,2,3...) or 0 on failure
DestroybrowserIndex As LongDestroy browser (fire and forget)
DestroySyncbrowserIndex As LongDestroy synchronously (no timeout)
DestroyBrowserSyncbrowserIndex As Long, timeoutMs As LongDestroy synchronously with a timeout — blocks until destroyed or timeout expires. Recommended for Form_Unload.
CreateWithProfilehwndParent As Long, url As String, x As Long, y As Long, w As Long, h As Long, profileName As StringLongCreate with named profile
CreateWithProfileInPrivatehwndParent As Long, url As String, x As Long, y As Long, w As Long, h As Long, profileName As StringLongCreate with InPrivate profile

Create & Destroy Example

Source: frmLifecycleCore_Code.txt

' Create a browser in the pool
Dim idx As Long
idx = pool.Create(Me.hwnd, "about:blank", 0, 0, 800, 600)
If idx = 0 Then
    MsgBox "Failed to create browser"
    Exit Sub
End If

' Map local folder to https://lv2.local/ (call once per browser)
pool.SetLocalContentRoot idx, CurrentProject.Path & "\html"

' Navigate to a local HTML file
pool.Navigate idx, "https://lv2.local/dashboard.html"

' Cleanup
pool.Destroy idx
Parking 3 methods

Park browsers to hide them while preserving state for later reuse, or destroy all parked browsers at once.

MemberParametersReturnsDescription
ParkbrowserIndex As LongHide browser (park) — preserves state for reuse
DestroyAllParkedLongDestroy all parked browsers, returns count destroyed
GetParkedBrowserCountLongCount of currently parked browsers

Parking Example

' Park a browser to free resources but keep state
pool.Park browserIndex
Debug.Print "Parked browsers: " & pool.GetParkedBrowserCount

' Later: destroy all parked browsers
Dim freed As Long
freed = pool.DestroyAllParked
Debug.Print "Freed " & freed & " browsers"
Embedding 4 methods

Embed browsers into VBA Frame controls or reparent them to different windows.

MemberParametersReturnsDescription
EmbedInControlbrowserIndex As Long, control As ObjectEmbed browser in VBA Frame control
CreateInControlurl As String, control As ObjectLongCreate + embed in one call, returns index
CreateInControlWithProfileurl As String, control As Object, profileName As StringLongCreate + embed with named profile
ReparentbrowserIndex As Long, hwndNewParent As Long, x As Long, y As Long, w As Long, h As LongMove browser to new parent window

Embedding Example

Source: src\frmBrowser.cls

' Map local folder first (required for lv2.local URLs)
pool.SetLocalContentRoot idx, CurrentProject.Path & "\html"

' Create and embed in an Access Frame control in one call
Dim idx As Long
idx = pool.CreateInControl("https://lv2.local/app.html", Me.fraWebView)
If idx > 0 Then
    m_browserIndex = idx
End If
Profiles 5 methods

Manage browser profiles, InPrivate mode, and browsing data per browser instance.

MemberParametersReturnsDescription
GetProfileNamebrowserIndex As LongStringGet profile name for browser
IsInPrivateModebrowserIndex As LongBooleanCheck if browser is InPrivate
GetProfilePathbrowserIndex As LongStringOn-disk profile folder path
ClearProfileBrowsingDatabrowserIndex As Long, dataKinds As LongClear browsing data by kind flags
ClearProfileBrowsingDataAllbrowserIndex As LongClear all browsing data for profile
Management 7 methods

Manage browser lifecycle, visibility, sizing, and suspension state.

MemberParametersReturnsDescription
IsValidIndexbrowserIndex As LongBooleanCheck if browser index is still valid
GetBrowserCountLongCount of active browsers in pool
ResizebrowserIndex As Long, x As Long, y As Long, width As Long, height As LongResize browser
SetVisiblebrowserIndex As Long, visible As BooleanSet browser visibility
TrySuspendbrowserIndex As LongSuspend browser to save resources
ResumeBrowserbrowserIndex As LongResume suspended browser
IsSuspendedbrowserIndex As LongBooleanCheck if browser is suspended
Runtime Detection 3 methods
Note

These methods do NOT take a browserIndex parameter — they query the system.

MemberParametersReturnsDescription
IsWebView2RuntimeInstalledBooleanCheck if WebView2 runtime is installed
GetWebView2RuntimeVersionStringGet installed runtime version string
GetWebView2RuntimePathStringGet runtime installation path

Runtime Detection Example

' Check runtime before creating browsers
If Not pool.IsWebView2RuntimeInstalled Then
    MsgBox "WebView2 runtime not found. Please install it."
    Exit Sub
End If
Debug.Print "Runtime version: " & pool.GetWebView2RuntimeVersion
Ready Callback 2 methods

Register a VBA method to be called when a browser is fully initialised. LiteView2 fires the callback on the UI thread via deferred PostMessage — no timer polling required.

Why this replaces timer polling

Previously, Reg-Free Mode required a Form_Timer loop to call IsReady() every 100 ms. SetReadyCallback is event-driven: LiteView2 calls your named VBA method exactly once, as soon as the browser is ready — even if the environment is reused from a previous session.

MemberParametersReturnsDescription
SetReadyCallbackbrowserIndex As Long, callbackObject As Object, methodName As StringRegister a VBA object method to be called when the browser is ready. Works from any COM host (VBA, VB6, Delphi, C#). Fires exactly once; call ClearReadyCallback to reset.
ClearReadyCallbackbrowserIndex As LongUnregister the ready callback and reset the fired flag. Always call this in Form_Unload before DestroyBrowserSync.

Ready Callback Example

Private pool As Object
Private idx  As Long

Private Sub Form_Load()
    Set pool = GetPool()
    idx = pool.CreateInControl("about:blank", Me.fraBrowser)
    pool.SetReadyCallback idx, Me, "OnBrowserReady"
End Sub

Public Sub OnBrowserReady()
    pool.SetLocalContentRoot idx, CurrentProject.Path
    pool.SetAreHostObjectsAllowed idx, True
    Set m_callbacks = New clsCallbacks
    pool.AddHostObjectToScript idx, "vba", m_callbacks
    pool.Navigate idx, "https://lv2.local/myForm.html"
End Sub

Private Sub Form_Unload(Cancel As Integer)
    On Error Resume Next
    If Not pool Is Nothing And idx <> 0 Then
        pool.ClearReadyCallback idx          ' always before DestroyBrowserSync
        pool.DestroyBrowserSync idx, 2000
        idx = 0
    End If
End Sub
Dispatch IDs

SetReadyCallback is dispatch ID 439; ClearReadyCallback is dispatch ID 444. The callback uses IDispatch::GetIDsOfNames + Invoke — it resolves your method name at call time, so any public Sub on any COM-visible object works as the target.

VBA Auto-Dispatch & Callbacks 6 methods

Allow JavaScript in the browser to call VBA macros directly, without manual WebMessageReceived routing.

MemberParametersReturnsDescription
EnableAutoDispatchbrowserIndex As Long, enabled As BooleanEnable or disable auto-dispatch of HTML/JS calls to VBA macros
IsAutoDispatchEnabledbrowserIndex As LongBooleanCheck whether auto-dispatch is currently enabled for this browser
SetAllowedVBAMacrosbrowserIndex As Long, macroList As StringSet comma-separated whitelist of VBA macro names that JS is allowed to call
ClearAllowedVBAMacrosbrowserIndex As LongClear the VBA macro whitelist (blocks all auto-dispatch calls)
RegisterVbaCallbackbrowserIndex As Long, jsName As String, callbackObject As Object, methodName As StringRegister a VBA object method as a callable function from JavaScript. jsName is the name JS uses to call it.
UnregisterVbaCallbackbrowserIndex As LongUnregister all VBA callbacks for this browser
Audio Control 3 methods

Query and control audio playback state for a browser instance.

MemberParametersReturnsDescription
GetIsDocumentPlayingAudiobrowserIndex As LongBooleanCheck if the document is currently playing audio
GetIsMutedbrowserIndex As LongBooleanGet the current mute state of the browser
SetIsMutedbrowserIndex As Long, muted As BooleanMute or unmute the browser audio
Pool-Only Utilities 5 methods

Additional methods available only on IBrowserPool (not on ILiteView2Ctrl).

MemberParametersReturnsDescription
GetUserAgentbrowserIndex As LongStringGet the current User-Agent string for this browser
SetDefaultBackgroundColorbrowserIndex As Long, argbColor As LongSet the default background color as ARGB (e.g. &HFF000000 for opaque black)
ShowSaveAsDialogbrowserIndex As LongShow the browser's native Save As dialog
GetLastErrorbrowserIndex As LongStringGet the last error message for this browser instance
GetLastErrorCodebrowserIndex As LongLongGet the last error code (HRESULT) for this browser instance

Shared Methods Reference

All other ILiteView2Ctrl methods are available on IBrowserPool with browserIndex as the first parameter. See the ILiteView2Ctrl reference for full documentation.

CategoryMethodsReference
NavigationNavigate, GoBack, GoForward, etc.ILiteView2Ctrl › Navigation
Script ExecutionExecuteScript, ExecuteScriptWithArgs, etc.ILiteView2Ctrl › Script Execution
Data BridgePostWebMessageAsJson, PushRecordset, CallJsFunction, SetJsVariable, etc.ILiteView2Ctrl › Data Bridge
JSON HelpersBuildJson, JsonGetValue, JsonIsValid, etc.ILiteView2Ctrl › JSON Helpers
JSON MutationJsonCreateObject, JsonSetValue, JsonMerge, JsonToRowArray, JsonUnwrapString, JsonCompact, etc.ILiteView2Ctrl › JSON Mutation
Automation APIWaitForElement, ClickElementBySelector, GetTextBySelectorILiteView2Ctrl › Automation API
DOM ManipulationGetElementValueById, SetInnerHtmlById, etc.ILiteView2Ctrl › DOM Manipulation
Printing & PDFPrintToPdf, CaptureScreenshot, etc.ILiteView2Ctrl › Printing & PDF
SettingsIsScriptEnabled, UserAgent, etc.ILiteView2Ctrl › Settings
Cookies & StorageGetCookies, SetCookie, etc.ILiteView2Ctrl › Cookies & Storage
Stealth ModeEnableStealthMode, SpoofWebGL, etc.ILiteView2Ctrl › Stealth Mode
Document HostingOpenDocument, OpenOfficeDocument, etc.ILiteView2Ctrl › Document Hosting
Find in PageStartFind, FindNext, StopFind, etc.ILiteView2Ctrl › Find in Page
LifecycleTrySuspend, Resume, Dispose, etc.ILiteView2Ctrl › Lifecycle
CAPTCHADetectCaptcha, SolveCaptcha, etc.ILiteView2Ctrl › CAPTCHA
DownloadsAllowDownloads, PauseDownload, etc.ILiteView2Ctrl › Downloads
Web ResourcesAddWebResourceRequestedFilter, etc.ILiteView2Ctrl › Web Resources
Auth & ProxySetBasicAuthCredentials, etc.ILiteView2Ctrl › Auth & Proxy
Host ObjectsAddHostObjectToScript, etc.ILiteView2Ctrl › Host Objects
DevToolsCallDevToolsProtocolMethod, etc.ILiteView2Ctrl › DevTools
EmbeddingEmbedInHwnd, QuickInitInFrame, etc.ILiteView2Ctrl › Embedding
LicensingActivateLicense, LicenseState, etc.ILiteView2Ctrl › Licensing
Explore More:
Core API | Events | JSON | Browser Pool | Enumerations