| title | Quick Start |
|---|---|
| parent | WebView2 Package |
| nav_order | 3 |
This guide will help you quickly get started with the twinBASIC WebView2 control.
WebView2 requires Microsoft Edge WebView2 Runtime (Evergreen) to be installed.
Download URLs:
- Official download: https://developer.microsoft.com/microsoft-edge/webview2/
- Evergreen Runtime: https://go.microsoft.com/fwlink/p/?LinkId=2124703
Note: If you are using Windows 7, please download the WebView2 Runtime that supports Windows 7 from: https://gitcode.com/woeoio/tbman/releases/Webview2Runtime
Check if already installed:
You can verify whether WebView2 Runtime is installed by checking the default installation directory and registry.
Private Function IsWebView2Installed() As Boolean
Dim wsh As Object
Dim regValue As String
Dim installPath As String
Dim tempPath As String
Dim found As Boolean
found = False
Set wsh = CreateObject("WScript.Shell")
' ===== Method 1: Improved Registry Check =====
On Error Resume Next ' Only used for registry reads
' Check 64-bit system (WOW6432Node)
regValue = ""
regValue = wsh.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}\pv")
If Len(regValue) > 0 Then
found = True
GoTo CleanUp
End If
' Check 32-bit system (without WOW6432Node)
regValue = ""
regValue = wsh.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}\pv")
If Len(regValue) > 0 Then
found = True
GoTo CleanUp
End If
' Check user-level installation
regValue = ""
regValue = wsh.RegRead("HKEY_CURRENT_USER\SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}\pv")
If Len(regValue) > 0 Then
found = True
GoTo CleanUp
End If
On Error GoTo 0 ' Restore normal error handling
' ===== Method 2: Improved File System Check =====
' Check 64-bit program directory
installPath = Environ("ProgramFiles(x86)") & "\Microsoft\EdgeWebView\Application\"
If Dir(installPath, vbDirectory) <> "" Then
' Check if directory contains actual DLL files
tempPath = Dir(installPath & "*.dll")
If tempPath <> "" Then
found = True
GoTo CleanUp
End If
End If
' Check user directory
installPath = Environ("LOCALAPPDATA") & "\Microsoft\EdgeWebView\Application\"
If Dir(installPath, vbDirectory) <> "" Then
' Check if directory contains actual DLL files
tempPath = Dir(installPath & "*.dll")
If tempPath <> "" Then
found = True
End If
End If
CleanUp:
IsWebView2Installed = found
Set wsh = Nothing
End Function
' Return WebView2 version number (if installed), otherwise return empty string
Private Function GetWebView2Version() As String
Dim wsh As Object
Dim regKeys(1 To 3) As String
Dim i As Integer
regKeys(1) = "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}\pv"
regKeys(2) = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}\pv"
regKeys(3) = "HKEY_CURRENT_USER\SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}\pv"
Set wsh = CreateObject("WScript.Shell")
On Error Resume Next
For i = 1 To 3
GetWebView2Version = wsh.RegRead(regKeys(i))
If Len(GetWebView2Version) > 0 Then
Exit For
End If
Next i
On Error GoTo 0
Set wsh = Nothing
End FunctionReference the WebView2 package in your twinBASIC project:
- Open Project Settings
- Select "Packages/References"
- Add
WebView2Package
' Form1.frm
Option Explicit
Private WithEvents WebView21 As WebView2
Private Sub Form_Load()
' Create WebView2 control
Set WebView21 = Controls.Add("WebView2.WebView2", "WebView21")
' Set position and size
With WebView21
.Visible = True
.Move 0, 0, ScaleWidth, ScaleHeight
.DocumentURL = "https://www.twinbasic.com"
End With
End Sub
Private Sub WebView21_Ready()
Debug.Print "WebView2 is ready"
End Sub
Private Sub Form_Resize()
If WebView21 Is Nothing Then Exit Sub
WebView21.Move 0, 0, ScaleWidth, ScaleHeight
End SubIf you've added the WebView2 control to the form designer:
Private Sub Form_Load()
' Note: All WebView21 member operations must be done after WebView21_Ready()
End Sub
Private Sub WebView21_Ready()
' Set initial URL
WebView21.DocumentURL = "https://www.example.com"
End Sub
Private Sub WebView21_NavigationComplete(ByVal IsSuccess As Boolean, ByVal WebErrorStatus As Long)
If IsSuccess Then
Debug.Print "Page loaded successfully"
Debug.Print "Title: " & WebView21.DocumentTitle
Else
Debug.Print "Page loading failed, error code: " & WebErrorStatus
End If
End SubPrivate WithEvents cmdBack As CommandButton
Private WithEvents cmdForward As CommandButton
Private WithEvents cmdRefresh As CommandButton
Private WithEvents txtUrl As TextBox
Private WithEvents cmdGo As CommandButton
Private Sub Form_Load()
' Create navigation buttons
Set cmdBack = Controls.Add("VB.CommandButton", "cmdBack")
cmdBack.Caption = "Back"
cmdBack.Move 10, 10, 60, 30
Set cmdForward = Controls.Add("VB.CommandButton", "cmdForward")
cmdForward.Caption = "Forward"
cmdForward.Move 80, 10, 60, 30
Set cmdRefresh = Controls.Add("VB.CommandButton", "cmdRefresh")
cmdRefresh.Caption = "Refresh"
cmdRefresh.Move 150, 10, 60, 30
' Create URL input box
Set txtUrl = Controls.Add("VB.TextBox", "txtUrl")
txtUrl.Move 220, 10, 300, 30
txtUrl.Text = "https://www.twinbasic.com"
' Create Go button
Set cmdGo = Controls.Add("VB.CommandButton", "cmdGo")
cmdGo.Caption = "Go"
cmdGo.Move 530, 10, 60, 30
' Create WebView2 control
Set WebView21 = Controls.Add("WebView2.WebView2", "WebView21")
With WebView21
.Visible = True
.Move 0, 50, ScaleWidth, ScaleHeight - 50
End With
End Sub
Private Sub cmdGo_Click()
If Len(txtUrl.Text) > 0 Then
WebView21.Navigate txtUrl.Text
End If
End Sub
Private Sub cmdBack_Click()
If WebView21.CanGoBack Then
WebView21.GoBack
End If
End Sub
Private Sub cmdForward_Click()
If WebView21.CanGoForward Then
WebView21.GoForward
End If
End Sub
Private Sub cmdRefresh_Click()
WebView21.Reload
End Sub
Private Sub WebView21_SourceChanged(ByVal IsNewDocument As Boolean)
txtUrl.Text = WebView21.DocumentURL
End SubPrivate Sub WebView21_DOMContentLoaded()
' Modify page background color
WebView21.ExecuteScript "document.body.style.backgroundColor = '#f0f0f0'"
' Get page title
Dim title As Variant
title = WebView21.JsProp("document.title")
Debug.Print "Page title: " & title
End SubPrivate Sub WebView21_DOMContentLoaded()
' Call page function
Dim result As Variant
result = WebView21.JsRun("getWindowWidth")
Debug.Print "Window width: " & result
End SubPrivate Sub WebView21_Ready()
' Async JavaScript invocation
Dim token As LongLong
token = WebView21.JsRunAsync("fetchUserData", "user123")
Debug.Print "Async invocation Token: " & token
End Sub
Private Sub WebView21_JsAsyncResult(ByVal Result As Variant, Token As LongLong, ErrString As String)
Debug.Print "Async result Token: " & Token
If Len(ErrString) > 0 Then
Debug.Print "Error: " & ErrString
Else
Debug.Print "Result: " & Result
End If
End Sub' Twinbasic side
Private Sub btnSendMessage_Click()
WebView21.PostWebMessage "Hello from Twinbasic!"
WebView21.PostWebMessage Array("data1", "data2", 123)
End Sub// JavaScript side (in web page)
window.chrome.webview.addEventListener("message", function (e) {
console.log("Received message:", e.data);
// Process message
if (typeof e.data === "string") {
alert(e.data);
} else if (Array.isArray(e.data)) {
console.log("Array:", e.data);
}
});// JavaScript side
window.chrome.webview.postMessage({
type: "button_click",
buttonId: "submit",
timestamp: Date.now(),
});' Twinbasic side
Private Sub WebView21_JsMessage(ByVal Message As Variant)
Debug.Print "Received JS message: " & Message
' Process JSON object
If TypeName(Message) = "Object" Then
Debug.Print "Type: " & Message("type")
Debug.Print "Button ID: " & Message("buttonId")
End If
End Sub' Twinbasic class module - tbObjectInst.twin
Public Function GetUserName() As String
GetUserName = "John Doe"
End Function
Public Sub ShowMessage(ByVal msg As String)
MsgBox msg, vbInformation, "From Twinbasic"
End Sub
Public Function Calculate(ByVal a As Double, ByVal b As Double) As Double
Calculate = a + b
End Function' Main form
Private WithEvents WebView21 As WebView2
Private vbObj As tbObjectInst
Private Sub WebView21_Ready()
' Create object
Set vbObj = New tbObjectInst
' Expose to JavaScript (direct invocation, can return value)
WebView21.AddObject "tbObjectInst", vbObj, False
' Expose to JavaScript (deferred invocation, returns value asynchronously via Promise)
WebView21.AddObject "vbHandler", vbObj, True
End Sub// JavaScript side
// Call Twinbasic method (needs return value, direct invocation)
var userName = window.chrome.webview.hostObjects.tbObjectInst.GetUserName();
console.log(userName); // Output: John Doe
var result = window.chrome.webview.hostObjects.tbObjectInst.Calculate(10, 20);
console.log(result); // Output: 30
// Call Twinbasic method (deferred invocation, returns value asynchronously via Promise)
window.chrome.webview.hostObjects.vbHandler
.ShowMessage("Test message")
.then(function (returnValue) {
console.log("Twinbasic return value:", returnValue);
})
.catch(function (error) {
console.error("Invocation error:", error);
});
// Use async/await syntax
async function callVBHandler() {
try {
const result = await window.chrome.webview.hostObjects.vbHandler.Calculate(
5,
3,
);
console.log("Calculation result:", result);
} catch (error) {
console.error(error);
}
}Private Sub WebView21_PermissionRequested(ByVal IsUserInitiated As Boolean, _
ByRef State As wv2PermissionState, ByVal Uri As String, _
ByVal PermissionKind As wv2PermissionKind)
Select Case PermissionKind
Case wv2ClipboardRead
' Allow clipboard read
State = wv2StateAllow
Debug.Print "Allowed clipboard access: " & Uri
Case wv2Geolocation
' Ask user if they allow geolocation
If MsgBox("Web page requests access to location, allow?", vbYesNo + vbQuestion) = vbYes Then
State = wv2StateAllow
Debug.Print "Allowed location access: " & Uri
Else
State = wv2StateDeny
Debug.Print "Denied location access: " & Uri
End If
Case wv2Camera, wv2Microphone
' Deny camera and microphone
State = wv2StateDeny
Debug.Print "Denied " & PermissionKind & ": " & Uri
Case Else
' Other permissions use default behavior
State = wv2StateDefault
End Select
End SubPrivate Sub Form_Load()
' Note: All WebView21 member operations must be done after WebView21_Ready()
End Sub
Private Sub WebView21_Ready()
' Create HTML content
Dim html As String
html = "<!DOCTYPE html>" & vbCrLf
html = html & "<html>" & vbCrLf
html = html & "<head>" & vbCrLf
html = html & " <meta charset='UTF-8'>" & vbCrLf
html = html & " <title>Local HTML</title>" & vbCrLf
html = html & " <style>" & vbCrLf
html = html & " body { font-family: Arial, sans-serif; padding: 20px; }" & vbCrLf
html = html & " h1 { color: #333; }" & vbCrLf
html = html & " </style>" & vbCrLf
html = html & "</head>" & vbCrLf
html = html & "<body>" & vbCrLf
html = html & " <h1>Welcome to WebView2</h1>" & vbCrLf
html = html & " <p>This is a local HTML page</p>" & vbCrLf
html = html & " <button onclick='sendMessage()'>Send Message to VB</button>" & vbCrLf
html = html & " <script>" & vbCrLf
html = html & " function sendMessage() {" & vbCrLf
html = html & " window.chrome.webview.postMessage('Hello from HTML!');" & vbCrLf
html = html & " }" & vbCrLf
html = html & " </script>" & vbCrLf
html = html & "</body>" & vbCrLf
html = html & "</html>"
' Load HTML
WebView21.NavigateToString html
End SubPrivate Sub Form_Load()
' Note: All WebView21 member operations must be done after WebView21_Ready()
End Sub
Private Sub WebView21_Ready()
' Method 1: Use file path
WebView21.Navigate "file:///C:/Projects/MyApp/index.html"
' Method 2: Use virtual host mapping
WebView21.SetVirtualHostNameToFolderMapping "app.local", "C:\Projects\MyApp", wv2ResourceAllow
WebView21.Navigate "https://app.local/index.html"
End Sub| Feature | file:// protocol | Virtual host mapping |
|---|---|---|
| Protocol | file:// | https:// |
| Domain | File path | Custom domain name |
| Security | More restrictions | Less restrictions (follows HTTPS rules) |
| Compatibility | Some frameworks don't support | Widely supported |
Many modern frontend frameworks and libraries, for security reasons, prohibit or restrict running under the file:// protocol, including:
- React, Vue, Angular and other frameworks' features
- Service Worker (must be under HTTPS or localhost)
- Web Workers (some restrictions)
- IndexedDB (disabled under file:// in some browsers)
- Fetch API cross-origin requests
Virtual host mapping uses https:// protocol, completely avoiding these restrictions.
- No real server needed: No need to install nginx, Apache, etc.
- No port occupation: Maps directly to local folder
- Custom domain: Can set memorable domain names (like
app.local,dev.local) - Follows HTTPS rules: Enjoy security features of modern web standards
' file:// method may have issues
WebView21.Navigate "file:///C:/Projects/MyApp/index.html"
' Relative path resource loading may be restricted
' <script src="./app.js"></script> may fail
' Virtual host mapping method
WebView21.SetVirtualHostNameToFolderMapping "app.local", "C:\Projects\MyApp", wv2ResourceAllow
WebView21.Navigate "https://app.local/index.html"
' All resources loaded via https://app.local/, consistent with real serverThe second parameter of virtual host mapping can set resource access permissions:
' wv2ResourceAllow - Allow all access
' wv2ResourceDeny - Deny access
' wv2ResourceDenyCors - Deny CORS requestsPrivate Sub Form_Load()
' Note: All WebView21 member operations must be done after WebView21_Ready()
End Sub
Private Sub WebView21_Ready()
' Vue/React projects use virtual host mapping
WebView21.SetVirtualHostNameToFolderMapping "myapp.dev", "C:\MyVueApp\dist", wv2ResourceAllow
WebView21.Navigate "https://myapp.dev/index.html"
End SubPrivate Sub Form_Load()
' Note: All WebView21 member operations must be done after WebView21_Ready()
End Sub
Private Sub WebView21_Ready()
' Run multiple applications simultaneously
WebView21.SetVirtualHostNameToFolderMapping "admin.local", "C:\Apps\admin", wv2ResourceAllow
WebView21.SetVirtualHostNameToFolderMapping "api.local", "C:\Apps\api-docs", wv2ResourceAllow
' Switch to load different applications
WebView21.Navigate "https://admin.local/index.html"
End Sub// Using file://, fetch requests may be blocked
fetch("data.json"); // May fail under file://
// Using virtual host mapping, works like on a real server
fetch("/data.json"); // Works normally, uses https://app.local/data.jsonVirtual host mapping maps a local folder to a custom HTTPS domain name, making the browser think it's accessing a real web server.
- For simple static HTML, use
file:// - For modern frontend apps, SPAs, or scenarios needing Service Worker, etc., strongly recommend using virtual host mapping
- When publishing to production, just replace with real HTTPS server addresses
Private Sub btnSaveToPdf_Click()
Dim savePath As String
savePath = "C:\Temp\output.pdf"
' Check if feature is supported
If WebView21.SupportsPdfFeatures Then
' Print to PDF
WebView21.PrintToPdf savePath, _
Orientation:=wv2PrintPortrait, _
ShouldPrintBackgrounds:=True, _
MarginTop:=20, _
MarginBottom:=20, _
MarginLeft:=20, _
MarginRight:=20
Debug.Print "PDF printing..."
Else
MsgBox "Current WebView2 version does not support PDF features", vbExclamation
End If
End Sub
Private Sub WebView21_PrintToPdfCompleted()
MsgBox "PDF printing complete!", vbInformation
End Sub
Private Sub WebView21_PrintToPdfFailed()
MsgBox "PDF printing failed!", vbExclamation
End SubPrivate Sub cmdOpenDevTools_Click()
' Open developer tools
WebView21.OpenDevToolsWindow
End Sub
Private Sub cmdInspectPage_Click()
' Call DevTools protocol method
If WebView21.AreDevToolsEnabled Then
WebView21.CallDevToolsProtocolMethod "Runtime.enable", "{}", "enableRuntime"
End If
End Sub
Private Sub WebView21_DevToolsProtocolResponse(ByVal CustomEventId As Variant, ByVal JsonResponse As String)
Debug.Print "DevTools response [" & CustomEventId & "]: " & JsonResponse
End Sub' Make sure to set Visible and position
Private Sub Form_Load()
Set WebView21 = Controls.Add("WebView2.WebView2", "WebView21")
With WebView21
.Visible = True
.Move 0, 0, ScaleWidth, ScaleHeight
End With
End SubPrivate Sub WebView21_Error(ByVal code As Long, ByVal msg As String)
Debug.Print "Error code: " & code
Debug.Print "Error message: " & msg
' Check if WebView2 Runtime is installed
If code = -1 Then
MsgBox "WebView2 Runtime is not installed" & vbCrLf & vbCrLf & msg, vbCritical
End If
End SubPrivate Sub Form_Load()
' Note: All WebView21 member operations must be done after WebView21_Ready()
End Sub
Private Sub WebView21_Ready()
' Set JavaScript call timeout (seconds)
WebView21.JsCallTimeOutSeconds = 30
End SubPrivate Sub Form_Load()
' Note: All WebView21 member operations must be done after WebView21_Ready()
End Sub
Private Sub WebView21_Ready()
' Use deferred event mode to avoid re-entrancy problems
WebView21.UseDeferredEvents = True
End Sub- Read WebView2 Control to learn all properties, methods, and events
- Read Environment Options to configure WebView2 environment
- Read Enumeration Types to learn all enumeration values
- Read Deferred Callback to understand how to handle re-entrancy problems