
Browser mit WebView2
« | 07 Jul 2024 | »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
CreateCoreWebView2EnvironmentWithOptions()
wird mit einem selbst implementiertenICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler
Pointer aufgerufen um eine Sitzung vorzubereiten.- Wir erhalten einen
ICoreWebView2Environment
Pointer über die Callback MethodeInvoke()
. - Nun können wir per
CreateWindowEx
ein beliebigesHWND
Fenster erzeugen, in welchem WebView laufen soll. - Über den Environment Pointer rufen wir
CreateCoreWebView2Controller()
mit auf dem neuenHWND
auf um über einenICoreWebView2CreateCoreWebView2ControllerCompletedHandler
Callback an eine neueICoreWebView2Controller
Instanz zu kommen. - Per
controller->get_CoreWebView2()
erhalten wir nun einICoreWebView2
Interface, mit dem wir den Web-Inhalt in unserem Fenster steuern können. - 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.