Sunday, June 12, 2022

Template Studio for WinUI

For creation of new WPF, WinUI3 and UWP applications you can now use Template Studio - it is a new suite of Visual Studio 2022 extensions.

You can now install Template Studio extension and use Template Studio for creation of WPF, WinUI3 and UWP applications. First you select project type as one of the following: Blank, MenuBar (with menu added) and NavigationBar.

MVVM Toolkit is applied now in the application by the default, template creates Views/ViewModels (that's a great idea I believe to have MVVM by default):

Then you can initialize your content to Blank, WebView2, Settings, DataGrid, etc.

On the last step of the wizard, you can add theming and select between packaged/unpackaged app:

Saturday, June 11, 2022

Inno Setup 3rd party tools

There is a bunch of 3rd party tools which can simplify your Inno Setup installers development. They include Inno Script Studio, Visual & Installer and others. You can find their list here.

Recently we've got a chance to try some of these tools and found Graphical Installer really nice and easy to use. It can be useful if you create an installer for a game, for example or if your application has some unusual skin or graphics. Graphical Installer supports both Inno Setup and NSIS. It is not free but its price is really affordable (this is not an advertisement :) ).

With Graphical Installer you can select custom background, custom images for installer elements, custom colors for headers, texts, buttons, scrollbars, etc. This is possible through wizard or (advanced option) through code where you can add any number of scripts.

With all its advantages Graphical Installer has its own limitations. Mostly these limitations are due to Inno Setup itself. For example, you can't take Next/Cancel/Install button to arbitrary place of the window. There is a working area where you can do whatever you want (the middle of installer pages) and the edges are mostly restricted by background images changes.

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.