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 implementiertenICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerPointer aufgerufen um eine Sitzung vorzubereiten.- Wir erhalten einen
ICoreWebView2EnvironmentPointer über die Callback MethodeInvoke(). - Nun können wir per
CreateWindowExein beliebigesHWNDFenster erzeugen, in welchem WebView laufen soll. - Über den Environment Pointer rufen wir
CreateCoreWebView2Controller()mit auf dem neuenHWNDauf um über einenICoreWebView2CreateCoreWebView2ControllerCompletedHandlerCallback an eine neueICoreWebView2ControllerInstanz zu kommen. - Per
controller->get_CoreWebView2()erhalten wir nun einICoreWebView2Interface, 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:
NavigationStartingContentLoadingSourceChangedHistoryChangedFrameNavigationStargingFrameNavigationCompletedScriptDialogOpeningPermissionRequestedWebMessageReceivedNewWindowRequestedDocumentTitleChangedContainsFullScreenElementChangedWindowCloseRequested
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.
