Browser mit WebView2

Seitdem der Internet Explorer verschwunden und “Edge” die Herrschaft übernommen hat, ist auch die alte SHDocVwCtl.WebBrowser ActiveX Webbrowser-Komponente zum Einbinden in eigene Programme abgekündigt.

An deren Stelle tritt WebView bzw. WebView2, womit man sich einen Chromium-Browser selbst bauen kann.


Microsoft hat Edge (zum Glück) mit einer ähnlichen COM-ActiveX Schnittstelle ausgestattet, wie damals den alten Internet Explorer. Somit kann jede Win32-Anwendung auch ein Fenster erzeugen und darin die Edge-WebView2-Komponente eine HTML Seite rendern lassen.
Genau das wird heute immer wichtiger, wo Content nicht mehr in nativen Controls als Text, Labels und Buttons dargestellt wird, sondern nur noch als HTML Code.

Hat man erst ein WebView2-Interface in seinen Händen, kann man es URLs ansurfen oder direkt HTML Code rendern lassen.
Allerdings muss man dafür zwischen einem “echten Fenster” und dem Interface ein paar Daten austauschen können. z.B.:

  • Größenänderungen des Fensters dem WebView2-Interface bekannt geben lassen
  • Events aus der Webseite “von außen” bestätigen lassen
    • z.B.: eine neue URL soll geladen werden
    • ein neues Fenster soll geöffnet werden

Implementierung

Alles beginnt mit einer .dll, die wir mitliefern müssen und sich um die Kommunikation mit der Edge/WebView2 Installation kümmert.
Sie heißt WebView2Loader.dll und stellt Funktionen wie CreateCoreWebView2EnvironmentWithOptions() bereit. Danach läuft alles über COM-Interfaces, die eine Funktion meist asynchron anstarten und wir müssen ein Callback-Interface gleich mitübergeben, welches über die Fertigstellung eines Ergebnisses wieder in den eigenen Code zurückspringen kann.

Ein WebView2 Fenster anlegen

  1. CreateCoreWebView2EnvironmentWithOptions() wird mit einem selbst implementierten ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler Pointer aufgerufen um eine Sitzung vorzubereiten.
  2. Wir erhalten einen ICoreWebView2Environment Pointer über die Callback Methode Invoke().
  3. Nun können wir per CreateWindowEx ein beliebiges HWND Fenster erzeugen, in welchem WebView laufen soll.
  4. Über den Environment Pointer rufen wir CreateCoreWebView2Controller() mit auf dem neuen HWND auf um über einen ICoreWebView2CreateCoreWebView2ControllerCompletedHandler Callback an eine neue ICoreWebView2Controller Instanz zu kommen.
  5. Per controller->get_CoreWebView2() erhalten wir nun ein ICoreWebView2 Interface, mit dem wir den Web-Inhalt in unserem Fenster steuern können.
  6. Nun können wir beliebig viele Event-Handler als Callback-COM Objekte registrieren. Hier ein paar Beispiele:
    • NavigationStarting
    • ContentLoading
    • SourceChanged
    • HistoryChanged
    • FrameNavigationStarging
    • FrameNavigationCompleted
    • ScriptDialogOpening
    • PermissionRequested
    • WebMessageReceived
    • NewWindowRequested
    • DocumentTitleChanged
    • ContainsFullScreenElementChanged
    • WindowCloseRequested

Wenn man auf diese Events reagiert, kann man ihr Verhalten beeinflussen, ihre Bearbeitung verhindern oder überhaupt erst ermöglichen. Das hängt von der Art der Anwendung ab.

Das WebView2 Fenster ist somit fertig erzeugt.
Über das ICoreWebView2Controller Interface kann man mit Methoden wie put_IsVisible() den Browser sichtbar oder unsichtbar machen oder die Größe des Fensters per put_Bounds() explizit anpassen.

Das ICoreWebView2 Interface lässt uns mit Navigate() eine URL ansurfen oder per NavigateToString gleich HTML Code als String rendern. Zusätzlich helfen Methoden wie GoBack() GoForward() oder Stop() das typische Verhalten eines Webbrowsers auszuführen.

Fazit

Auch wenn die Interfaces etwas anders benannt sind und mehr asynchrone Ausführung mit Callbacks erfordern, so ist die Funktionsweise zum alten IE Code doch recht ähnlich.

Das Öffnen von neuen Fenstern ist am kompliziertesten, weil man hier aus einem Callback heraus wieder im Hintergrund ein neues natives Fenster erzeugen muss, bevor man eine weitere WebView2 Instanz+Controller damit verknüpfen kann.

Ich habe eine Demo-Implementierung in den Win32-UI Teil übernommen und diese wird immer automatisch aktiv, wenn mein Demo-WebBrowser zusammen mit einer WebView2Loader.dll gestartet wird und WebView2 im System vorhanden ist. Falls nicht fällt der Code auf das alte SHDocVwCtl.WebBrowser Interface zurück, das auch im aktuellen Windows 11 trotz fehlendem Internet Explorer immer noch die altes IE-Engine im eignen Prozess ausführt.

📧 📋 🐘 | 🔗 🔔
 

Meine Dokus über:
 
Weitere externe Links zu:
Alle extern verlinkten Webseiten stehen nicht in Zusammenhang mit opengate.at.
Für deren Inhalt wird keine Haftung übernommen.



Wenn sich eine triviale Erkenntnis mit Dummheit in der Interpretation paart, dann gibt es in der Regel Kollateralschäden in der Anwendung.
frei zitiert nach A. Van der Bellen
... also dann paaren wir mal eine komplexe Erkenntnis mit Klugheit in der Interpretation!