I do not publish book reviews very often, but last year I had a chance to participate in publishing of Learning Windows 8 Game Development book as a technical reviewer, and would like to share my thoughts about the book.

My main advice will be related to the way of reading the book – you definitely will want to have a computer nearby to try ideas described in the book. It is organized in a form of tutorial driving you from the basics of Direct3D to modelling game world and publishing game at the Windows Store. It covers the following topics:

The only missing piece, from my perspective, is audio. It is difficult to imagine any modern game without music or sound effects, but the book does not include information about it.

In addition to pure practical information, some chapters and appendix are dedicated to the theory of 2D/3D graphics and game development. Chapters 3 and 4 are especially good in providing best practices on capturing user input and structuring games.

All code in the book is written in C++, but samples are properly annotated and explained, so basic knowledge of C++ should be enough for reading this book.

You can win free copy of book of Learning Windows 8 Game Development

I have teamed up with Packt Publishing to organize a giveaway of this book. Three lucky winners stand a chance to win 3 digital copies of the book.

How to enter

All you need to do is to tweet about this review with a link to the post and #Win8GameDev hashtag, for example:

This book will help me to learn Windows 8 Game Development: http://bit.ly/Win8GameDev via @amarukovich #Win8GameDev

The contest will close on Wednesday, Feb 22. Winners will be chosen randomly and will be contacted via Twitter to get an e-copy of the book.

Exception handling improvements for async void methods in Windows 8.1

Introduced in C# 5 async/await keywords significantly simplify asynchronous code and improve code readability and maintainability. However, when it comes to exception handling, it becomes a bit trickier.

Let’s consider the following example:


static void Main(string[] args)
{
    try
    {
        AsyncMethod();
    }
    catch
    {
        Console.WriteLine("Exception in Main");
    }

    Console.ReadLine();
}

private async static void AsyncMethod()
{
    throw new NotImplementedException();
}

When executed, instead of displaying “Exception in Main” message, this program crashes. Similar to this console application, all exceptions raised from async void methods crash Windows 8 apps too.

In console and desktop programs unhandled exceptions can be intercepted using AppDomain.UnhandledException event. Only intercepted, for example for logging - it doesn’t prevent crash of the program. In Windows 8 apps even interception is not possible because AppDomain is not part of .NET profile for Windows Store apps.

Windows 8.1 changes the way the async-related exceptions are handled. Now it is possible to catch exception raised from async void method by handling Application.UnhandledException event:


sealed partial class MyApp : Application
{
    public MyApp()
    {
        this.InitializeComponent();

        UnhandledException += Application_UnhandledException;

    }

    private void Application_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        e.Handled = true;
        // ...
    }
}

With UnhandledException event it is possible to not only log exception but also prevent process termination (e.Handled = true).

The following example demonstrate code that will behave differently in Windows 8 and Windows 8.1:


private async void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
    throw new NotImplementedException();
}

In Windows 8 it will raise exception and terminate process, without possibility to catch it using Application.UnhandledException event. In Windows 8.1 Application.UnhandledException event will be fired in case of such exception.

Windows 8 app development: secure user passwords by using Credential Locker

Passwords and authorization tokens are commonly used in mobile applications for user authorization and for connecting apps with third-party services like Twitter and Facebook. It is app’s responsibility to select secure storage for the credentials, encrypt the password and provide credentials management functionality so user can modify password or revoke granted access.

Windows 8 simplifies these tasks by introducing a Credential Locker. The Locker lets application to store and retrieve user’s credentials in a secure way: all password are encrypted and cannot be accessed by other applications.

Access to the Credential Locker is provided by WinRT PasswordVault class. This class allows adding, retrieving and removing credentials from the Locker. The following example demonstrates storing user’s password using PasswordVault.

PasswordVault

PasswordVault allows grouping of credentials by providing name of the resource for which the credentials are used. Later this name can be used for retrieving the credentials using PasswordVault.FindAllByResource and PasswordVault.Retrieve functions.

The following example demonstrates usage of Retrieve function for credentials verification.

PasswordVault.Retrieve

If the Locker does not contains credential data for the requested resource or name, an Exception will be thrown.

Control Panel’s Credential Manager allows users to control all stored credentials simplifying password management logic for applications.

Credential Manager

PasswordVault is a simple, secure approach for storing user’s passwords in Windows 8 applications. The Credential Locker not only stores credentials, but also roams them between user’s devices that helps to create transparent, continuous experience for app users that owns multiple Windows 8 devices.

Using Windows 8 WinRT APIs in .NET Desktop Applications

WinRT is a set of modern, object-oriented APIs introduced in Windows 8. WinRT is built on top of Win32 and COM and is designed to provide interoperability for the various languages using metadata. In addition to the previously available Windows and .NET APIs, now exposed in a cleaner, streamlined way, WinRT provides an access to all the new features of Windows 8.

Some WinRT APIs are closely coupled with the new Windows Store app model while others can safely be used for desktop application development. For Windows desktop applications, using the WinRT APIs enables simple ways to access GPS and NFC devices, the accelerometer, orientation, light, and other sensors.

Accessing WinRT APIs from desktop applications is a supported process and the documentation on how to do it is light. But you are in the right spot because that is what I am covering in a guest post at Canadian Developer Connection blog:

http://blogs.msdn.com/b/cdndevs/archive/2013/10/02/using-windows-8-winrt-apis-in-net-desktop-applications.aspx

What is new in Windows 8.1 for file access: SkyDrive integration

With the release of Windows 8.1, SkyDrive will become an integral part of the Windows. SkyDrive modern app is going to be bundled with the operating system and SkyDrive properties are exposed via PC settings so user, for example, can even purchase additional space from the Settings app.

SkyDrive - PC settings

Moreover, installation of the desktop SkyDrive client will not be required anymore – the client will be integrated with File Explorer from the beginning.

SkyDrive - File Explorer

Like SkyDrive client for Windows 7/8, SkyDrive for Windows 8.1 maps cloud storage to a folder on user’s drive. However, it implements a more sophisticated synchronization mechanism.

Previously, all files created or stored in the cloud were fully replicated to all connected devices. For example, when SkyDrive contained 10 GB of data in the cloud, the size of SkyDrive folder on PC was 10GB as well. The Windows 8.1 SkyDrive folder in the same situation will be much smaller because of use of placeholder files – a local representation of files stored in the cloud. The following picture demonstrate the size difference between an actual file (Size) and the placeholder (Size on disk):

SkyDrive - Placeholder

Placeholder files

Placeholder files appear as normal files that can be copied, renamed, deleted, etc. However, these files contain no data, just a minimum information about the original files, like thumbnails or picture dimensions.

SkyDrive - Placeholder properties

When user attempts to open a placeholder file, SkyDrive downloads the actual file and replaces the placeholder, transparently for the target application.

What will happen if user will try to reach some placeholder file when system is offline? Because the original file is not available, SkyDrive will display an error: “This file is available only when you are online”.

In many situations, such behaviour is undesirable and SkyDrive lets users to control files availability. The right click menu includes “Make available offline” item for placeholders and “Make available online-only” item for files.

SkyDrive - Online/Offline

“Make available offline” command instructs SkyDrive to download actual file and all associated metadata. “Make available online-only” replaces selected file with the placeholder. The following file is available offline:

SkyDrive - Placeholder all properties

Changes in WinRT

To accompany the new online/offline file states, WinRT for Windows 8.1 includes new interface – IstorageFilePropertiesWithAvailability. StorageFile implements this interface to expose IsAvailable property.

IsAvailable equals true when the target file is a local file, or file was downloaded and cached locally, or it can be downloaded. For example, it will be true for any non-SkyDrive files, for SkyDrive-based files available offline and for files available online-only when SkyDrive can be accessed. It will be false for online-only files when there is no access to SkyDrive servers.

Applications that provide file browsing functionality can use this property to visualize files availability. For example, apps can gray out unavailable files.

File pickers

In Windows 8.1 SkyDrive introduced as a first class location for storing documents, pictures and video. The following picture demonstrates differences between Windows 8 FileOpenPicker (where SkyDrive is just an app) and 8.1 FileOpenPicker with integrated SkyDrive:

SkyDrive - File Picker

When SkyDrive is selected as a default storage, it becomes a default location for FileOpenPicker and FileSavePicker. Developers can use SuggestedStartLocation property to override this behaviour and suggest other locations.

What is new in Windows 8.1 for file access: indexing and searching app content

The search experience was completely redesigned for Windows 8.1. From now on, the Windows Store apps are fully responsible for implementation of the in-app search functionality - Search Charm does not support Search Contract and does not trigger in-app search anymore.

The following screenshot demonstrates difference between Windows 8 and Windows 8.1 search results

Search - Windows 8 vs Windows 8.1

To facilitate this new design pattern, WinRT for Windows 8.1 includes a new search box UI control and a set of APIs for indexing and searching application data.

The new indexing functionality is based on the Windows Property System supported by WinRT since Windows 8 (see WinRT and Windows Property System). The Windows Store apps can use Windows Properties to annotate the data, add it to the index and use Advanced Query Syntax (AQS) to search it later.

There are two ways for indexing the data: by using Windows.Storage.Search APIs or by creating appcontent-ms files.

Using Windows.Storage.Search

The new IndexableContent class represents a unit of data for the indexing. It allows setting an ID to link the index with the actual data, defining data properties and supplying data for full-text indexing.

For example, email client can use IndexableContent for the individual emails:


IndexableContent content = new IndexableContent();
content.Id = "{90003c43-db8a-41ad-907b-567eab5dc468}";
content.Properties[Windows.Storage.SystemProperties.Keywords] = "draft";
content.Properties["System.Contact.EmailAddress"] = "contact@company.com"; 
content.Stream = ... // the email content as a stream

ContentIndexer class enables apps to generate per-app index for the content:


IndexableContent content = new IndexableContent();
…
await indexer.AddAsync(content);

ContentIndexer is also responsible for searching the indexed data:


var query = indexer.CreateQuery("keyword:draft", new[] { "System.Contact.EmailAddress"});
IReadOnlyList<IIndexableContent> drafts = await query.GetAsync();

First parameter for the CreateQuery is an AQS filter and the second parameter is a list of the properties to retrieve. These properties do not affect the query and application should not retrieve the properties it will not use.

This approach is useful when app already has some database and needs a way to simplify the search. The index should not be the main data storage as user can reset or delete it. ContentIndexer.Revision helps to keep the apps’ data storage and the index in sync.

appcontent-ms files

An alternative approach includes creation of the appcontent-ms files. Similar to IndexableContent objects, the appcontent-ms files include properties and indexable data. However, unlike the IndexableContent, appcontent-ms files can be used both for indexing and for storing the data.


<?xml version="1.0" encoding="utf-8"?>

<!-- The root node can have any name -->
<EmailAppData> 

  <!-- Well-known properties -->
  <Properties xmlns="http://schemas.microsoft.com/Search/2013/ApplicationContent">
    <Name>{90003c43-db8a-41ad-907b-567eab5dc468}</Name>
    <Keywords>
      <Keyword>draft</Keyword>
      <Keyword>work</Keyword>
    </Keywords>

    <!-- Other Windows Properties -->  
    <AdditionalProperties>
      <Property Key="System.Contact.EmailAddresses">
        <Value>user1@company.com</Value>
        <Value>user2@company.com</Value>
      </Property>
    </AdditionalProperties>
  </Properties>
  
  <!-- App specific nodes, can be indexed for full-text search -->  
  <MailBody sc:IndexableContent="true" 
            xmlns:sc="http://schemas.microsoft.com/Search/2013/ApplicationContent">E-mail text here</MailBody>
</EmailAppData>

These files can be created run-time or deployed as a part of the project. However, they should be placed in a very specific folder: to be indexed appcontent-ms files should be in an Indexed sub-folder of the Local or Roaming data folders.

The properly placed files are indexed and can be retrieved later using the file queries:


var queryOptions = new Windows.Storage.Search.QueryOptions();
queryOptions.IndexerOption = Windows.Storage.Search.IndexerOption.OnlyUseIndexer;
queryOptions.ApplicationSearchFilter = "keyword:draft";

StorageFolder indexedFolder = 
                await ApplicationData.Current.LocalFolder.CreateFolderAsync("Indexed",
                                 Windows.Storage.CreationCollisionOption.OpenIfExists);

var query = indexedFolder.CreateFileQueryWithOptions(queryOptions);
IReadOnlyList files = await query.GetFilesAsync();

// read data from the files…

The properties defined inside of appcontent-ms file treated by indexer as file’s properties and all AQS filters are fully supported.

Windows 8.1 Reading List uses appcontent-ms files for storing individual articles. Similarly, other Windows Store apps can use appcontent-ms for storing appropriate data and benefit from property indexing and full-text search.

References

  1. Using Advanced Query Syntax Programmatically
  2. Windows Property System Reference
  3. WinRT and Windows Property System
  4. Windows.Storage.Search namespace
  5. Indexer sample
What is new in Windows 8.1 for file access: managing user libraries

Libraries continue to play important role in Windows Store app development, even though they are hidden by default in Windows 8.1. Moreover, a new class called StorageLibrary is introduced in WinRT to help managing user libraries.

StorageLibrary provides methods and events to add and delete folders within the libraries, to monitor library changes. It supports Documents, Music, Pictures and Videos libraries. Custom libraries are not supported and apps have to declare corresponding capabilities to access standard libraries.

How to add new folder to Pictures library


// Get StorageLibrary object, throws exception when Pictures library capability isn't declared
StorageLibrary library = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
   
// Ask user to select folder to add
StorageFolder newFolder = await library.RequestAddFolderAsync();

RequestAddFolderAsync() shows a new specialized file picker where users can select folder to add to Pictures library:

Add folder picker

In this case, SkyDrive camera roll folder was selected:

Libraries

How to remove folder from Pictures library

StorageLibrary.RequestRemoveFolderAsync() let applications to remove folders from the libraries. Unlike RequestAddFolderAsync(), RequestRemoveFolderAsync() does not provide any UI. Developers have to implement folder selection logic by themselves, for example by using folder picker or StorageLibrary.Folders.

The following code demonstrates removing of the SkyDrive camera roll folder added in the previous example:


StorageLibrary library = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);

StorageFolder folder = library.Folders.FirstOrDefault(x => x.Name == "SkyDrive camera roll")

if (folder != null)
{
   bool deleted = await library.RequestRemoveFolderAsync(folder);
   // …
}

RequestRemoveFolderAsync method displays the following question:

Remove folder

and removes the folder if action is approved.

Removed folder

Monitoring libraries

Since the selected library can be modifies outside of app (by user or another app), StorageLibrary provides DefinitionChanged event to let applications to track changes in the list of folders.

In addition, StorageLibrary.SaveFolder provides the default save folder for the library.

Windows 8.1, where are my Libraries?

If you are an active user of Windows Explorer Libraries, you will be surprised by the default view of Windows 8.1 Explorer

Windows Explorer

The Libraries section is gone and all the standard folders (Documents, Music, Pictures, etc.) are displayed under This PC. Fortunately, Libraries were not removed from this release of Windows, they are just hidden by default.

To bring Libraries back, open Folder Options dialog (View tab->Options) and select “Show libraries” option – this option is new for Windows 8.1.

Folder Options

It will return back the Libraries section in the Explorer’s navigation pane.

Windows Explorer

Documents Library capability and Visual Studio 2013

Documents Library capability has been a source of confusion for app developers from the first days of Windows Store. This capability can be easily set through App Manifest editor to enable the app to access user’s Documents library through WinRT API. Although it perfectly works during development, enabled Documents Library capability means almost automatic failure of the Store certification process for the affected app, when the app is submitted using non-company account.

So, look what is missed in Visual Studio 2013 Preview App Manifest UI:

App Manifest

Documents Library capability is gone and all attempts to access this folder will generate exceptions:

Documents Library access

However, this capability is gone just from the UI, you still can open appxmanifest source and manually add the capability. The result will probably be the same as before – failure of certification for individual developers, so you better stay away from this trick. Microsoft strongly recommend against using Documents Library capability, suggesting Folder and File Pickers instead.

Displaying About, Settings and other Flyouts using Prism for Windows Store

1. Windows Store apps made easy with Prism and Prism project templates
2. Views, ViewModels and navigation
3. Configuring Prism using Unity or Ninject
4. Displaying About, Settings and other Flyouts

Windows Store apps use Flyouts for Login and Settings forms, About dialogs and for displaying other temporary information. While HTML5/JS developers experience the comfort of using native WinJS.UI.Flyout control, XAML developers have to use third-party controls.

Prism for Windows Store provides infrastructure for displaying and managing Flyout dialogs in a simple way.

Register Settings Charm commands

According to the Windows Store design guidance, it is recommended to use Settings Charm for providing access to apps’ setting and About dialog. Apps have to register commands by providing titles and command handlers (a function that will be invoked when command is clicked).

Create a new project using Prism Unity app template and open App.xaml.cs. App’s base class – MvvmAppBase – defines virtual method GetSettingsCharmActionItems and we are going to override it to register About and Settings commands.


sealed partial class App : MvvmAppBase
{
    ...
    
    protected override IList GetSettingsCharmActionItems()
    {
        return new List
                   {
                       new SettingsCharmActionItem("Settings", SettingsCommandHandler),
                       new SettingsCharmActionItem("About", AboutCommandHandler)
                   };
    }

    private void SettingsCommandHandler()
    {
        // TODO
    }

    private void AboutCommandHandler()
    {
        // TODO
    }
}

Registration is done and if you will start the app, you will see two new commands in Setting Charm.

Setting Charm

However, command handlers are still empty and before implementing them, we need to introduce visual elements to show.

Add About dialog

Use Add New Item dialog and add Flyout View with name AboutFlyout to Views folder. The created view is empty and you can modify it to present any information you need. For example, the following code makes it nicer and displays app’s title and version.


<prism:FlyoutView 
    x:Class="FlyoutDemoApp.Views.AboutFlyout"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="using:Microsoft.Practices.Prism.StoreApps"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    prism:ViewModelLocator.AutoWireViewModel="True"
    mc:Ignorable="d">

    <Border BorderBrush="{StaticResource FlyoutBorderBrush}"
            BorderThickness="1,0,0,0">
        <Grid Background="{StaticResource FlyoutBackground}">
            <Grid.RowDefinitions>
                <RowDefinition Height="80" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>

            <Grid Background="{StaticResource FlyoutHeaderBackground}">
                <StackPanel Orientation="Horizontal" Margin="40, 32, 0, 13">
                    <Button Command="{Binding GoBackCommand}"
                            Margin="0,3,0,0"
                            Style="{StaticResource FlyoutBackButtonStyle}" />
                    <TextBlock Margin="10,0,10,0"
                               Style="{StaticResource FlyoutHeaderText}"
                               Text="About" />
                </StackPanel>
            </Grid>

            <TextBlock Text="{Binding AppTitle}" Style="{StaticResource CaptionFlyoutTextStyle}" 
                       Grid.Row="1" Margin="40,40,10,10"/>
            <TextBlock Text="{Binding AppVersion}" Style="{StaticResource BasicFlyoutTextStyle}" 
                       Grid.Row="2" Margin="40,0,10,10"/>

        </Grid>

    </Border>
</prism:FlyoutView>

Once the Flyout is ready, we need to create corresponding View Model. Note the bindings in the code above: the target View Model needs to provide GoBackCommand command and properties to display title and version.

View Model

Use Flyout View Model template to create AboutFlyoutViewModel class in ViewModes folder. It will generate the View Model with predefined methods for the Flyout lifetime management.


public class AboutFlyoutViewModel : BindableBase, IFlyoutViewModel
{
    private Action _closeFlyout;
    private Action _goBack;

    public Action CloseFlyout
    {
        get { return _closeFlyout; }
        set { SetProperty(ref _closeFlyout, value); }
    }

    public Action GoBack
    {
        get { return _goBack; }
        set { SetProperty(ref _goBack, value); }
    }

    public void Open(object parameter, Action successAction)
    {
    }
}

The following code introduces fields required for the About Flyout.


public class AboutFlyoutViewModel : BindableBase, IFlyoutViewModel
{
    ...
    
    public ICommand GoBackCommand { get; private set; }

    public AboutFlyoutViewModel()
    {
        GoBackCommand = new DelegateCommand(() => GoBack());
    }

    public string AppTitle
    {
        get { return "Flyout Demo"; }
    }

    public string AppVersion
    {
        get
        {
            var version = Package.Current.Id.Version;
            return String.Format("Version {0}.{1}", version.Major, version.Minor);
        }
    }
}

The ViewModelLocator magic links View and View Model for us, all what we need to do is to show the Flyout.

Command handlers

Return to App class and change AboutCommandHandler to show About Flyout: FlyoutService uses the same convention as ViewModelLocator and NavigationService and automatically discover required type based on the provided Flyout ID.


private void AboutCommandHandler()
{
    FlyoutService.ShowFlyout("About");
}

Now we are done with coding – it is demo time

About Flyout

Described technique can be used to display Setting, Login, Privacy or any other types of Flyouts.

Next posts Previous posts