Thursday, December 23, 2021

Receiving web messages and making screenshots for WebView2 inside WinUI 3 in Desktop project (Part 5)

In Part 4 we discussed injecting Javascript into a web page and printed WebView2 content with the help of Javascript. Now let's talk about receiving web messages from a page and also let's make screenshots of some web page.

Here is the code for receiving web message. Note that WebMessageReceived is raised when the IsWebMessageEnabled setting is set and the top-level document of the WebView runs window.chrome.webview.postMessage.

webView.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived;

private void CoreWebView2_WebMessageReceived(CoreWebView2 sender, CoreWebView2WebMessageReceivedEventArgs args)
{
    var message = args.WebMessageAsJson;

    // do whatever you need
}

Now let's add one more button for making screenshots. CapturePreviewAsync allows to capture of what WebView2 is displaying.
private async void makeScreenshotButton_Click(object sender, RoutedEventArgs e)
{
    using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
    {
        await webView.CoreWebView2.CapturePreviewAsync(CoreWebView2CapturePreviewImageFormat.Png, stream);
        stream.Seek(0);               
                
        // here you can add saving to a file or copying to clipboard
    }
}

Saturday, November 20, 2021

Microsoft releases Windows App Sdk 1.0

November 16, 2021 Microsoft has released Windows App SDK 1.0 - the first release of unified set of APIs which can be used on Windows 11 and and downlevel to Windows 10, version 1809.

Windows App SDK main features includes WinUI 3 (the new user interface framework for desktop apps development and probably the most important part of Windows App SDK), rendering text with DWriteCore, push notifications, new deployment model, app lifecycle, etc. Both packaged apps (creating MSIX installers) and unpackaged apps (creating EXE) are supported by 1.0 release.

The next release of Windows App SDK is planned for the Q2 2022 and should include multiple windows support.

WinUI 3 in 1.0 and 1.1 is only supported for use by full WinUI 3 apps. You'll be able to use WinUI 3 in WPF/WinForms/other apps in a future release via XAML Islands.

Saturday, June 26, 2021

Injecting Javascript and printing for WebView2 inside WinUI 3 in Desktop project (Part 4)

In Part 3 we discussed new windows, context menus and default dialogs customization. Now let's talk about injecting Javascript into a web page and try to print WebView2 content with the help of Javascript.

Let's add one more button to our sample called "Print" and an event handler for it:


private async void printButton_Click(object sender, RoutedEventArgs e)
{
    string js = "window.print();";
    await webView.CoreWebView2.ExecuteScriptAsync(js);
}

Here we are executing Javascript code passed with the help of string parameter. Note that there is only async version of ExecuteScriptAsync() function. We can pass any Javascript code we want, in this example we say to print the current web page.

From version 0.8 Project Reunion was renamed to Windows App SDK https://github.com/microsoft/WindowsAppSDK

In the next part we will discuss receiving web messages from a page and also making screenshots of a web page.

Wednesday, May 26, 2021

Using WebView2 inside WinUI 3 in Desktop project (Part 3)

In Part 2 we added Stop, Reload, Go Back, Go Forward and Inspect possibilities to our WebView 2 project. Now let's cover how to deal with context menu, default dialogs and new windows.

By default, we have got the following context menu for WebView 2 control:

If you want to hide this default context menu, the following piece of code will be helpful:


// add in MainWindow constructor for demo purposes
webView.CoreWebView2Initialized += WebView_CoreWebView2Initialized;

private void WebView_CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
{
	webView.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
}

In similar way, you can hide standard alert and prompt dialogs and customize them on your own:


private void WebView_CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
{
	webView.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled = false;
	webView.CoreWebView2.ScriptDialogOpening += CoreWebView2_ScriptDialogOpening;
}

private void CoreWebView2_ScriptDialogOpening(CoreWebView2 sender, CoreWebView2ScriptDialogOpeningEventArgs args)
{
	if (args.Kind == CoreWebView2ScriptDialogKind.Alert)
	{
		// this is an alert, would you like to display it?
	}

	// always press OK (not the best idea)
	args.Accept();
}

Now imagine, your web page requests to create a new window, for example with window.open() and you need to add some custom processing. This is how you can do it:


private void WebView_CoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
{
	webView.CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested;
}

private void CoreWebView2_NewWindowRequested(CoreWebView2 sender, CoreWebView2NewWindowRequestedEventArgs args)
{
	args.Handled = true;
	webView.Source = new Uri(args.Uri);
}

We set here Handled property to true, telling our WebView 2 that it is not necessary to create new window any more. And then, just for demo purposes we redirect current web page to received URL.

Next time in Part 4 we will discuss how to work with JavaScript and how to receive messages from web page in C# code.

Sunday, May 9, 2021

Using WebView2 inside WinUI 3 in Desktop project (Part 2)

In Part 1 we created WinUI 3 in Desktop sample project. Now we will add Stop, Reload, Go Back, Go Forward and Inspect possibilities.

To keep our sample simple, let's add just a bunch of buttons on the left side of the window:

Great, now let's just add button handlers, starting for Stop:

private void stopButton_Click(object sender, RoutedEventArgs e)
{
	webView.CoreWebView2.Stop();
}

Notice CoreWebView2 property, this underlying object exposes more properties and methods than WebView2 itself. So we will often need to use it. Before using it, you should check it is already initialized by calling EnsureCoreWebView2Async().

Now let's look how we can reload the web page:

private void reloadButton_Click(object sender, RoutedEventArgs e)
{
	webView.Reload();
}

If you press on a link, then you may need to return back to the previous page. This is how it can be done programmatically:

private void backButton_Click(object sender, RoutedEventArgs e)
{
	if (webView.CanGoBack)
	{
		webView.GoBack();
	}
}

After you've gone back, you may need to return forward:

private void forwardButton_Click(object sender, RoutedEventArgs e)
{
	if (webView.CanGoForward)
	{
		webView.GoForward();
	}
}

If you have some errors on your page or in your code, it may be very useful to open Dev Tools Chromium window:

private void inspectButton_Click(object sender, RoutedEventArgs e)
{
	webView.CoreWebView2.OpenDevToolsWindow();
}

This is how Inspect/Dev Tools window will look like:

In Part 3 we will discuss how you can remove context menu and default script dialogs from WebView2. Also we will talk about creating new windows.

Using WebView2 inside WinUI 3 in Desktop project (Part I)

Microsoft Edge WebView2 control allows you to use Chromium Engine in any type of apps (including WinForms, WPF, WinUI 3). In several articles we will describe how to use WebView2 control inside WinUI 3 in Desktop project which is the part of Microsoft Reunion.

To create this type of this project first you need to install Microsoft Reunion Extension:

Now we can create our WinUI 3 in Desktop project:

After creating the project make sure Application->Target Framework is set and also in case of Reunion version 0.5.6 you may need to add the following lines:

Now let's add WebView2 to MainWindow content.

Now we can navigate to whatever page we need in code using Source property and also we can add NavigationStarting and NavigationCompleted events.


using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.Web.WebView2.Core;
using System;

public MainWindow()
{
    this.InitializeComponent();

	webView.Source = new Uri("https://microsoft.com");

	webView.NavigationStarting += WebView_NavigationStarting;
	webView.NavigationCompleted += WebView_NavigationCompleted;
}

First, NavigationStarting will be triggered:

private void WebView_NavigationStarting(WebView2 sender, CoreWebView2NavigationStartingEventArgs args)
{
            
}

And then, NavigationCompleted will be triggered:

private void WebView_NavigationCompleted(WebView2 sender, CoreWebView2NavigationCompletedEventArgs args)
{
	bool success = args.IsSuccess;
}

By now our sample is very simple:

In Part 2 we will describe how to stop navigation, reload the page, go back, go forward and also inspect the page.