Categories
Windows 10

WebAuthenticationBroker and GitHub

WebAuthenticationBroker is a component of Windows 10 which facilitates Oauth authentication with services from a client app. It handles the presentation and navigation of the authentication pages and returns control to your app along with a returned token or an error code. It’s a UWP API and integrates neatly with modern apps, however what may not be obvious is that it doesn’t use the Edge browser like a WebView control but instead uses the legacy Internet Explorer browser.

This is a problem because it’s old and a bit creaky and some sites don’t work with it, or actively refuse to – one of these is GitHub. If you try to authenticate with GitHub using it you’ll see a big ugly banner asking you to use a modern browser and you’ll be stuck. Hopefully this will change and the API will move to Edge (or even Chromium powered Edge which is on the horizon). However in the mean time you’ll need to roll your own solution. There are lots of ways you could do this by using the WebView control in your app and handling navigation events but I thought I’d try and recreate the same API so that I had a solution I could swap in without major changes. The result of this work is called, and excuse me it was very late when I thought of it, Authful. The full code is online in GitHub here. I haven’t released it as a NuGet library and won’t unless there is sufficient interest as I thought people might just prefer the code so that they can customise the look and feel for their own apps. There is a sample project to show how to call the API (hint: It’s the same as the UWP class). It doesn’t support the advanced options but it should work with most mainstream OAuth-based APIs.

https://github.com/inthehand/Authful

Categories
Windows 10

Calendar Import is Back

I was almost at the point of retiring the app since Mail & Calendar has supported iCalendar (.ics) files for a while now. Then I came across a scenario where the app is still required. vCalendar files (.vcs) are very similar but use version 1.0 of the vCalendar spec whereas iCalendar is version 2.0. Mail & Calendar still can’t open this format at the time of writing.

I’ve updated the UWP app for Creators Update and later and it now just registers for .vcs files (all .ics files will be handled by the Calendar app and this avoid the OS popping up a choose app dialog unnecessarily). Doing the update also made me check that it could work on Surface Hub and HoloLens (although it just uses the standard 2D Calendar UI). If you get .vcs files via email attachments or online this is a really simple (and free) app to import them into the Windows Calendar.

Download from the store for all Windows 10 devices:-

https://www.microsoft.com/store/productId/9WZDNCRDZZZF

 

Categories
Desktop Code Windows 10

Using specific versions of UWP from Win32

From a Win32 .NET library (One that targets desktop apps whether Console, WinForms or WPF) you can add two references and take advantage of (most) UWP APIs.

The first is a .NET library which handles interop with the UWP / WinRT APIs:-

C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETCorev4.5System.Runtime.WindowsRuntime.dll

The second is the metadata for the UWP APIs themselves:-

C:Program Files (x86)Windows Kits10UnionMetadataWindows.winmd

This describes the v1.0 versions of the API Contracts. These are expanded with each Windows 10 version and so you may find you want to target newer APIs and they are not available here. In a UWP project you can easily toggle the minimum target version of Windows 10 and this defines the API surface available to you. No such option exists for this kind of interop so instead you can switch the Windows.winmd reference for an alternative version. These are installed into subfolders of the above folder with the build number of each installed SDK. The latest released version for the April 2018 update is in 10.0.17134.0. As with UWP development you need to choose your API level carefully as it will affect which machines you can deploy to. For a library developer you need to ensure you document the minimum version you support to avoid any surprises.

Categories
Windows 10

Adventures in Desktop App Conversion

The Desktop App Converter (or Project Centennial) is a way of packaging up traditional desktop applications in appx format for the Windows 10 store. You would commonly use it for modernising an existing app. This allows you to take advantage of store distribution and incrementally add modern functionality to it.

My requirement was a little different. I needed a way of adding functionality to a UWP app which is not currently possible via UWP. The functionality in question was the ability to show a progress bar on the desktop taskbar entry. If you don’t know what I mean by this it is what you get with many desktop installers or other apps which make large downloads to keep you informed of progress while you do something else. There are two ways of approaching this – you can include a desktop “full-trust” component inside the same app package as a UWP app allowing you to mix and match and submit to the store as a single entity but this requires the developer to get full trust certification each time you repeat the process. The other approach is to build a standalone desktop bridge app to call the Win32 APIs necessary to control the taskbar and have other UWP apps call into this via an API. This way once the enabling app has gone through certification subsequent UWP apps can make use of it without any special permissions. Underneath there is a simple Uri scheme to request taskbar changes and so the caller won’t throw an error if the “Taskbar Progress” app isn’t installed.

 

taskbar test (2)
Taskbar Progress in a UWP app

 

The API to call this is already part of Pontoon as the InTheHand.UI.ViewManagement. StatusBarProgressIndicator. This mirrors the API in UWP which is only available on phone devices. We wrap the functionality for you so there is a common API across mobile and desktop flavours of Windows as well as Android and iOS (although iOS is limited to a indeterminate spinner).

I have a very basic sample app which I’m just waiting to convert from private to public in the store and will update this post with a link when published.

Get Taskbar Progress from the Windows Store

Pontoon on GitHub

Categories
Windows 10 Xamarin

GitHub Latest

While I prepare to refresh my main machine with Windows 10 Creator’s Update and the latest Visual Studio and Xamarin updates I thought I’d throw together a summary of open-source progress since I last blogged:-

Since the announcement of CodePlex’s upcoming retirement I’ve been moving projects across to GitHub. 32feet and my Compact Framework archive are now moved, there is just some tweaking to be done on the Wiki content for the former. I’m planning a blog post on the process I’ve used.

I’ve reworked the existing documentation site which was hosting the Pontoon documentation and it now also contains InTheHand.Forms and 32feet documentation. The Compact Framework stuff may follow but it depends on getting the dependencies setup just right for the help file builder.

Pontoon has had a number of enhancements. I’ve been refactoring the code to better handle the number of different platforms which are supported. This has also allowed me to identify gaps and fill some of them. Android now has InTheHand.Devices.Radios support for Bluetooth and the ability to launch any StorageFile with Launcher.LaunchFileAsync. macOS now has full support for local and roaming settings as-per iOS.

Categories
Bluetooth Windows 10

Talking to Printers

Recently I’ve been working with a selection of Bluetooth printers. During this work I’ve noticed an odd thing about the UWP Bluetooth APIs. It’s all about the Class of Device. These are a set of defined device types and are categorised into major and minor classes. For example a Printer has a Major class of Imaging and a Minor class of Printer. In the raw form the class of device is a bitmask and the bits reserved for the major class define the behaviour of the rest of the bits. The UWP API exposes a BluetoothClassOfDevice class and this has two properties – MajorClass and MinorClass and each uses an Enumeration. The interesting thing with this approach is that the MinorClass values overlap but have different meanings depending on the major class. There are already multiple fields with the same value – ComputerDesktop, PhoneCellular and PeripheralJoystick for example. For whatever reason all of the Imaging minor classes are missing – they all pre-date the original WinRT codebase so really should have been included.

I created a gist to pull together my helper method and enum to make identifying printers a little easier. I created an extension method to return the correct minor class when you identify a device with a major class of imaging:-

using System;
using Windows.Devices.Bluetooth;
namespace InTheHand.Devices.Bluetooth
{
/// <summary>
/// Defines missing values in the <see cref="BluetoothMinorClass"/> enumeration for devices with a <see cref="BluetoothClassOfDevice.MajorClass"/> of Imaging.
/// </summary>
[Flags]
public enum BluetoothImagingMinorClass
{
Uncategorized = 0,
Display = 4,
Camera = 8,
Scanner = 16,
Printer = 32,
}
/// <summary>
/// Provides an extension method to get the Imaging minor class.
/// </summary>
public static class BluetoothClassOfDeviceExtensions
{
/// <summary>
/// Returns the Minor Class of Device for an Imaging device.
/// </summary>
/// <param name="classOfDevice"></param>
/// <returns></returns>
public static BluetoothImagingMinorClass GetImagingMinorClass(this BluetoothClassOfDevice classOfDevice)
{
return (BluetoothImagingMinorClass)((int)classOfDevice.MinorClass);
}
}
}

Categories
Windows 10

All New Clipboarder

My free Clipboarder app for Windows Phone has now (finally) been re-written as a universal Windows 10 app. It’s currently available across all Windows 10 platforms (except Xbox but that seems fairly logical!). The app provides a share target allowing you to share data from modern apps to the clipboard to be pasted into any app (old or new, doesn’t matter as long as it has text input). A new feature made possible by using UWP is roaming content across devices. You can share something to your clipboard on your phone and then use it from the Clipboarder app on your desktop PC. The app still supports the clipboard Uri scheme in case you’ve been using it for clipboard access in Windows Phone 8.1 (appx) apps.

Download from the store (Free):-

https://www.microsoft.com/store/apps/9wzdncrdkj7j

 

Categories
Code Surface Windows 10

Building an Etch-a-Sketch with Surface Dial

Microsoft have demonstrated how the Surface Dial can be used in conjunction with Pen input for drawing, but what about drawing with the Dial itself?

For those of us with warm memories of the Etch-a-Sketch I thought it would be fun to replicate the experience with the Surface Dial. Now of course there is a big caveat – you only have a single Dial to use at a time. This can be worked around by using the Click functionality of the Dial – Tapping the top of the dial switches between horizontal and vertical drawing.

The code to achieve this is very simple, and I’ve pasted it in a Gist here:-

<Page
x:Class="DialASketch.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:DialASketch"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.TopAppBar>
<CommandBar>
<CommandBar.PrimaryCommands>
<AppBarButton Icon="Clear" Label="Clear" Click="ClearButton_Click"/>
</CommandBar.PrimaryCommands>
</CommandBar>
</Page.TopAppBar>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<InkCanvas x:Name="SketchCanvas" />
<Canvas>
<Ellipse x:Name="Pointer" Width="4" Height="4" Fill="Black"/>
</Canvas>
</Grid>
</Page>

view raw
MainPage.xaml
hosted with ❤ by GitHub

using System;
using System.Collections.Generic;
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Input;
using Windows.UI.Input.Inking;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace DialASketch
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
private RadialController Controller;
private RadialControllerMenuItem MenuItem;
private bool isHorizontal = true;
InkStrokeBuilder b = new InkStrokeBuilder();
private Point lastPoint;
public MainPage()
{
this.InitializeComponent();
SketchCanvas.SizeChanged += SketchCanvas_SizeChanged;
Controller = RadialController.CreateForCurrentView();
Controller.RotationResolutionInDegrees = 2;
Controller.RotationChanged += Controller_RotationChanged;
Controller.ButtonClicked += Controller_ButtonClicked;
MenuItem = RadialControllerMenuItem.CreateFromKnownIcon("DialASketch", RadialControllerMenuKnownIcon.PenType);
Controller.Menu.Items.Add(MenuItem);
}
private void SketchCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (e.NewSize.Width > 0)
{
if (lastPoint.X == 0f)
{
lastPoint = new Windows.Foundation.Point { X = SketchCanvas.ActualWidth / 2, Y = SketchCanvas.ActualHeight / 2 };
Canvas.SetLeft(Pointer, lastPoint.X 2);
Canvas.SetTop(Pointer, lastPoint.Y 2);
}
}
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
Controller?.Menu.Items.Clear();
base.OnNavigatedFrom(e);
}
private void Controller_ButtonClicked(RadialController sender, RadialControllerButtonClickedEventArgs args)
{
// switch direction (since we only have one dial)
isHorizontal = !isHorizontal;
}
private void Controller_RotationChanged(RadialController sender, RadialControllerRotationChangedEventArgs args)
{
var delta = args.RotationDeltaInDegrees * 4;
Point newPoint = new Windows.Foundation.Point { X = isHorizontal ? Math.Min(Math.Max(lastPoint.X + delta, 0), SketchCanvas.ActualWidth) : lastPoint.X, Y = !isHorizontal ? Math.Min(Math.Max(lastPoint.Y delta, 0), SketchCanvas.ActualHeight) : lastPoint.Y };
Canvas.SetLeft(Pointer, newPoint.X 2);
Canvas.SetTop(Pointer, newPoint.Y 2);
var stroke = b.CreateStroke(new List<Point> { lastPoint, newPoint });
lastPoint = newPoint;
stroke.DrawingAttributes.Color = Colors.Black;
stroke.DrawingAttributes.PenTip = PenTipShape.Circle;
SketchCanvas.InkPresenter.StrokeContainer.AddStroke(stroke);
}
private void ClearButton_Click(object sender, RoutedEventArgs e)
{
SketchCanvas.InkPresenter.StrokeContainer.Clear();
lastPoint = new Windows.Foundation.Point { X = SketchCanvas.ActualWidth / 2, Y = SketchCanvas.ActualHeight / 2 };
Canvas.SetLeft(Pointer, lastPoint.X 2);
Canvas.SetTop(Pointer, lastPoint.Y 2);
}
}
}

view raw
MainPage.xaml.cs
hosted with ❤ by GitHub

You could extend this to support keyboard input too as at the moment the app will do nothing if you don’t have a Dial setup on the PC. The output is created using the InkCanvas control along with a small Ellipse to show the current location:-

Dial-A-Sketch

Categories
Windows 10 Windows Phone

Interactive Toasts and Windows Phone 8.1

Windows 10 brings a whole range of new APIs and functionality for building apps. However in the phone space it’s important to be mindful that there are a lot more Windows Phone 8.1 devices in use than Windows 10. Many (but not all) will get an update to Windows 10. A lot of clients are keen on supporting 8.1 to cover the largest group (as an 8.1 app will just run on 10). Of course your users on Windows 10 may miss out on cool features in this way unless you are prepared to maintain both 8.1 and 10 versions of your app. There are a number of areas of the Charming Apps libraries which support “lighting-up” of functionality. That means exposing Windows 10 APIs to Windows 8.x projects. In some cases this is a remapping of existing functionality from an old-style API to one which is source compatible with UWP. In other cases there is functionality which is just not there on 8.x but you can make it available when your app is run on a Windows 10 device.

In order to support this a bit of Reflection is required but we’ve hidden that messy stuff for you – you just call the same APIs and get graceful failure or the “light-up” experience when running on Windows 10. For many of these APIs the Charming Apps library provides iOS and Android implementations while exposing the same UWP API surface. There are a number of possible ways of detecting whether the device at runtime is running Windows 10. One of these is to use:-

if (InTheHand.Foundation.Metadata.ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 1))

Another is to check:-

InTheHand.Environment.OSVersion.Version

(caveat – On 8.x we can return only Major.Minor.0.0 versions)

One of the new features in Windows 10 is the interactive toast notification. There is no API change to set these locally – it just requires a different XML template. So once you’ve checked your OS version you can switch between a traditional dumb toast or an interactive one such as:-

string xml = "<toast launch="yourstring"><visual><binding template="ToastGeneric" ><text>Big text</text><text>smaller text</text></binding></visual>"
                    + "<actions><input id="time" type="selection" defaultInput="2"><selection id="1" content="Breakfast"/><selection id="2" content="Lunch"/><selection id="3" content="Dinner"/></input>"
         	    + "<action activationType="foreground" content="Primary Action" arguments="primary"/><action activationType="foreground" content="Secondary Action" arguments="secondary"/></actions>"
                    + "</toast>";

Notice that I’ve specified foreground activation. In a UWP project you’d also have the option of background activation where a background task is launched to carry out an action. In the case of foreground activation the system calls your app’s OnActivated method. However this is where it gets a bit more fun. The ActivationKind is not specified in Windows Phone 8.1, nor is the ToastNotificationActivatedEventArgs which is passed through. However the value of ActivationKind.ToastNotification is documented as 1010. The event args contains two items of interest, the Argument – the action which was selected and UserInput which is a string keyed dictionary of input id and selection id or input id and text entered in the case of a text field. I’ve added the following code in my OnActivated method to build up a string containing these values which can be passed to the applications main page using rootFrame.Navigate:-

	    string navigationParameter = null;

            switch (args.Kind)
            {
                case (ActivationKind)1010: //ToastNotification:
                    StringBuilder sb = new StringBuilder();
                    sb.Append(args.GetType().GetRuntimeProperty("Argument").GetValue(args).ToString());
                    IDictionary<string,object> selections = (IDictionary<string,object>)args.GetType().GetRuntimeProperty("UserInput").GetValue(args);
                    if (selections.Count > 0)
                    {
                        sb.Append("?");
                        foreach (KeyValuePair<string, object> pair in selections)
                        {
                            sb.Append(pair.Key + "=" + pair.Value.ToString() + "&");
                        }

                        //remove trailing &
                        sb.Length -= 1;
                    }
                    navigationParameter = sb.ToString();

                    break;
            }
This is just another way of adding value to the user while still maintaining a Windows Phone 8.1 codebase. If you later update your app to Windows 10 it’s very easy to do without much alteration to your code. You don’t even have to go as far as adding interaction to your toasts but you could use this technique of detecting the OS version and simply use the new toast templates.
There are other areas of the Charming Apps libraries which “light-up” when running on Windows 10. For example there is a UWP style Clipboard API which just works on Windows 10 whereas the separate Clipboarder app is required for Windows Phone 8.1 (not Silverlight).

 

Categories
Bluetooth Windows 10

Bluetooth Development made easier in Windows 10

With Windows (and Phone) 8.1 there were two different device capabilities which needed to be set to use either RfComm or Bluetooth LE from your app. You had to specify a target device (or All) and target service name(s). With Windows 10 there is a simpler option. You still have to edit the appxmanifest code as it is not visible in the manifest designer but you can set simply:-

<Capabilities>
    ...
    <DeviceCapability Name="bluetooth" />
</Capabilities>

This gives you access to all Bluetooth functionality from your app. This is a much simpler approach and less prone to errors. Most of the documentation doesn’t mention this new value except for this page:-
What’s different in Windows 10 Insider Preview
“new valid values are “bluetooth”, “wiFiControl”, “radios”, and “optical”.”
These are not mentioned on the “App capability declarations” page so it’s not clear which specific APIs the other intriguing values relate to…