Building a browser shell

A short worked tutorial: turn a CefBrowser control into a working browser with an address bar, back / forward / reload buttons, zoom, and a few helpers (DevTools, PDF export).

The complete project ships as Sample 1b — Chromium Embedded Framework Examples in the New-Project dialog (form Example 1). This tutorial walks through its key pieces.

The form

Drop a CefBrowser control onto a Form and rename it WebView. Around it, add a TextBox named AddressBar plus six CommandButtons — btnBack, btnForward, btnRefresh, btnZoomIn, btnZoomOut, btnPDF, btnDevTools.

The bare-bones navigation surface — Navigate, GoBack, GoForward, Reload — is one-liners:

Private Sub btnBack_Click() Handles btnBack.Click
    WebView.GoBack()
End Sub

Private Sub btnForward_Click() Handles btnForward.Click
    WebView.GoForward()
End Sub

Private Sub btnRefresh_Click() Handles btnRefresh.Click
    WebView.Reload()
End Sub

To make the back / forward buttons follow the actual history state, sync them against CanGoBack and CanGoForward after every navigation:

Private Sub WebView_NavigationComplete( _
        ByVal IsSuccess As Boolean, ByVal WebErrorStatus As Long) _
        Handles WebView.NavigationComplete
    btnBack.Enabled = WebView.CanGoBack
    btnForward.Enabled = WebView.CanGoForward
End Sub

Note

IsSuccess and WebErrorStatus are part of the event signature but currently return placeholder values (True and 0) — use DocumentURL to confirm where the browser actually landed.

The address bar

Pressing Enter in the address bar triggers a navigation. The reverse direction — keeping the visible URL in sync with the page — is the SourceChanged event, which fires whenever DocumentURL changes (including same-document history.pushState updates):

Private Sub AddressBar_KeyDown(KeyCode As Integer, Shift As Integer) _
        Handles AddressBar.KeyDown
    If KeyCode = vbKeyReturn Then WebView.Navigate AddressBar.Text
End Sub

Private Sub WebView_SourceChanged(ByVal IsNewDocument As Boolean) _
        Handles WebView.SourceChanged
    AddressBar.Text = WebView.DocumentURL
End Sub

Navigate requires a full URI with scheme — http://, https://, file://, … Unlike WebView2, no automatic https:// prefix is added when the scheme is missing.

Zoom

ZoomFactor is a Double1.0 is 100%, 1.5 is 150%. The value reads as 0 until the browser has reached Ready, so arithmetic that multiplies the current value silently starts from zero unless you clamp first:

Private Sub btnZoomIn_Click() Handles btnZoomIn.Click
    If WebView.ZoomFactor = 0 Then WebView.ZoomFactor = 1
    On Error Resume Next
    WebView.ZoomFactor *= 1.1
End Sub

Private Sub btnZoomOut_Click() Handles btnZoomOut.Click
    If WebView.ZoomFactor = 0 Then WebView.ZoomFactor = 1
    On Error Resume Next
    WebView.ZoomFactor /= 1.1
End Sub

The On Error Resume Next catches the “control not ready” error that fires when the button is clicked before Ready has fired.

PDF export

PrintToPdf saves the current document to disk asynchronously — the result surfaces as PrintToPdfCompleted or PrintToPdfFailed:

Private Sub btnPDF_Click() Handles btnPDF.Click
    Dim outputPath As String = _
        Environ$("USERPROFILE") & "\Documents\page.pdf"
    WebView.PrintToPdf(outputPath)
End Sub

Private Sub WebView_PrintToPdfCompleted() Handles WebView.PrintToPdfCompleted
    MsgBox "PDF saved.", vbInformation
End Sub

The optional parameters that follow outputPathcefPrintOrientation, page size in microns, margins, header/footer toggles — let the host override Chromium’s defaults. See the PrintToPdf reference for the full signature.

DevTools

The Chromium DevTools window opens in its own top-level window:

Private Sub btnDevTools_Click() Handles btnDevTools.Click
    WebView.OpenDevToolsWindow()
End Sub

The CEF package does not currently expose WebView2’s OpenTaskManagerWindow equivalent — see the WebView2 parity section of the reference for the current gap list.

Form-title sync

To make the host window’s caption track the page’s <title>, listen for DocumentTitleChanged and read DocumentTitle:

Private Sub WebView_DocumentTitleChanged() Handles WebView.DocumentTitleChanged
    Me.Caption = WebView.DocumentTitle
End Sub

Where next