See Part 1 for creating views.

Creating a new view doesn’t actually make it visible—the view’s HTML, CSS, and JavaScript and C#/XAML are all loaded and running, but nothing will have appeared on the screen.

For that you need to use one of two APIs: the ProjectionManager (this part) or the ApplicationViewSwitcher (Part 3 of this post series), both of which are in Windows.UI.ViewManagement.

The ProjectionManager is meant for full-screen scenarios and work with a single secondary view. Its projectionDisplayAvailable property [and I’m going to give the member names in JavaScript casing, so C# readers please translate!], first off, tells you whether projection is possible and, along with the projectiondisplayavailablechanged event, is what you use to enable a projection feature in an app.

To make the view visible you pass its viewId to startProjectingAsync along with the ID of the primary view (the one from ApplicationView.getForCurrentView().id). Later on, call stopProjectingAsync to close the view and swapDisplaysForViewsAsync to do what it implies.

For a simple [JavaScript] example, refer to the SimpleViewProjection example in the companion content for Chapter 8 of my second edition. On startup it gets the primary view and the ProjectionManager (js/default.js):

var view = vm.ApplicationView.getForCurrentView();
var projMan = vm.ProjectionManager;

The Start button in the example is itself enabled or disabled according to the ProjectionManager:

btnStart.addEventListener(“click”, startProjection);

projMan.onprojectiondisplayavailablechanged = function () {
    checkEnableProjection();
​}

function checkEnableProjection() {
    btnStart.disabled = !projMan.projectionDisplayAvailable;
}

When you click Start, the app creates the view and starts projecting, using the id’s of both views:

viewProjection = MSApp.createNewView(“ms-appx:///projection/projection.html”);
projMan.startProjectingAsync(viewProjection.viewId, view.id).done(
function
() {
   
// enable/disable buttons

});

​Other buttons will call stopProjectingAsync and swapDisplaysForViewAsync, and other code handles selectively enabling the UI as needed. There’s also a button to do a postMessage to the projection with the current time.

function sendMessage() {
   
var date = new
Date();
   
var timeString = date.getHours() + “:” + date.getMinutes() + “:”
+ date.getSeconds()
        +
“:”
+ date.getMilliseconds();
   
var
msgObj = { text: timeString };
    viewProjection.postMessage(JSON.stringify(msgObj),
        document.location.protocol +
“//”
+ document.location.host);
}

The projection page is in projection/projection.html with associated .css and .js files. Within its activated handler it retrieves the opener view and listens for the consolidated event (js/projection.js):

var opener = MSApp.getViewOpener();

var thisView = Windows.UI.ViewManagement.ApplicationView.getForCurrentView();
thisView.onconsolidated =
function
() {
    sendCloseMessage();
}

where sendCloseMessage is a function that just does a postMessage with a “close” indicator so the main app can reset its UI. The same thing happens when you click the Close button in the projection, after which it calls window.close.

For another demonstration–which includes C# and C++ variants–refer to the Projection sample in the SDK. It basically does the same thing as the simple example above, adding a little more to set view properties like the title. I didn’t show any code from the sample, however, because it buries the basic API calls like createNewView and getViewOpener deep inside helper classes called ProjectionView.ViewManager (for the primary view) and ProjectionView.ViewLifeTimeControl (for the secondary view) [in the C# version there’s a SecondaryViewsHelper.ViewLifetimeControl class for the same purpose]. These classes s a little too complicated to use as an introduction to the API!

This same mini-framework is also used in the SDK’s Multiple Views sample, which demonstrates the methods of the ApplicationViewSwitcher class, that will be our subject for Part 3.


[The following is taken from Chapter 8 of ​Programming Windows Store Apps in HTML, CSS, and JavaScript, Second Edition/Second Preview​, available at http://aka.ms/BrockschmidtBook2. I’ve added a few notes that I hope will be useful to C# developers, though not working in C# much I can’t give as much detail.]

Many years ago, when I was very actively giving presentations at many developer conferences, I so much wished that Microsoft PowerPoint could present my slides on the main display for the audience while I got a view on my display that showed the next slide as well as my notes. You might be laughing because PowerPoint has had this feature for quite some time (I wasn’t the only one who made the request!). The point, though, is that there are certainly app scenarios where a single app wants to manage multiple independent views, possibly and oftentimes on separate monitors, and the user has the ability to rearrange and resize those views, which includes dragging them between monitors. Any one view, though, is limited to a single display (that is, a view cannot span displays).

Projection scenarios like PowerPoint are clearly one of the primary uses for multiple views; a game might also use a second view for various controls and output windows so they don’t interfere with the main display. A different kind of use is where an app has several independent (or loosely coupled) functions that can operate independently and can benefit from being placed side by side with views from other apps (multitasking at its best!). A customer-management system for a mobile sales rep might have one view for appointments and contacts, another for data entry forms, and a third for managing presentations and media. Although these functions could be part of the same layout within a single app view, they don’t need to be. Having them as separate views—which means they operate on different threads and can only share data via the file system—allows the user to place them in relation to other apps such as a web browser (for customer research) and an email app.

The caveat with multiple views is that they run on separate threads and therefore each have their own script context. Views can only communicate with each other through postMessage calls in JavaScript (as are used to communicate between the local and web contexts), or Dispatcher.BeginInvoke in C#. Views can, however, exchange data via appdata settings and/or files, which they share in common.​

In JavaScript, a view is created through the MSApp.createNewView API, provided by the app host and not WinRTs specific to apps written in HTML and JavaScript. The one argument you give to this method is a string with the ms-appx URI of an in-package HTML page to use for the new view (only ms-appx URIs are allowed, meaning the view runs in the local context). That HTML file can, of course, reference whatever own stylesheets and script (including WinJS) that it needs. All of this will be loaded as part of the createNewView call, even though the view is not yet visible. The usual DOM events like DOMContentLoaded will be raised in the process, and you can use the WinJS.Application events as always (provided that you call app.start() to drain the queue).

The MSAppView object that createNewView returns will have a unique viewId property to identify it, along with postMessage and close methods. The latter is what the app clearly uses to close the view. Within the secondary view, it will receive message through the window.onmessage event, as usual. The new view can also call window.close to close itself, and the user can also close the view with touch/mouse gestures or Alt+F4. As for sending data back to the app, the view calls MSApp.getViewOpener to obtain the MSAppView object for the app’s primary view—its postMessage method will raise a window.onmessage event in the primary view. These relationships are shown below:
View communication

A primary view creates a secondary view through MSApp.createNewView. The secondary view retrieves a reference to the primary view through MSApp.getViewOpener. The result in both cases is an MSAppView object whose postMessage call sends a message to the other view.

The C# analog to MSApp.createNewView is CoreApplication.CreateNewView. This produces a new CoreWindow object, and if you send that to Windows.UI.ViewManagement.ApplicationView.GetApplicationViewIdForWindow, you get the unique viewId. The view can close itself with ​Window.Current.Close()​, and it can access the primary view through App.Current.MainDispatcher (and App.Current.MainViewId).

Let me note up front that if a secondary view closes itself, the app won’t receive any kind of event. Typically, then, the secondary view will inform the app that it’s closing. This is also where the secondary view should subscribe to the ApplicationView.onconsolidated event to detect when the user closes it directly, and post a message to the app. We’ll see examples in later posts.


I finally found an answer to a sticky problem in my book’s Here My Am! app. The problem is that sometimes, on first launch, the Windows.Devices.Geolocation.Geolocator.getGeopositionAsync call fails even when I tap “Allow” in the consent dialog.

That is, in my startup sequence I have this code:

WinJS.Application.onactivated = function (…) {
var locator = new Windows.Devices.Geolocation.Geolocator();
locator.getGeopositionAsync().done(function (geocoord) { … };
}

The problem is that if the Geolocator object goes out of scope while the consent dialog is up, it will cancel the pending getGeopositionAsync operation, sending the error “Canceled” to the error handler just as if I tapped “Block” (though it all works on subseqeuent runs).

The simple solution is to just create the Geolocator outside of the event handler scope. That way the object sticks around and works just fine.

From what I can tell, this isn’t a universal behavior for WinRT objects; for example, in the same app I create a Windows.Media.Capture.CameraCaptureUI object, call captureFileAsync, and let the object go out of scope. This too has a consent prompt, but doesn’t cancel the capture operation.

In any case, it’s a good thing to be aware of–if you see odd behavior like this, try keeping the object in scope.


Apart from how you can protect your app code (in this previous post), there are two other key resources on best practices for writing secure apps. These are the practices for writing apps that are in themselves hardened against hacking through the apps UI itself (as opposed to hacks on the file system and OS):

Developing secure apps (in the documentation, for JavaScript apps): covers whether to trust the data your receiving, use of local/web contexts, script filtering, use of postMessage, use of HTTPS, cross-domain requests, and the sandbox attribute.

Similar and additional tips can be found in Security best practices for building Windows Store apps on the developer blog. This covers app capabilities, using pickers, authenticating users, and validating files and protocols.

 


It’s sometimes unclear to developers that appdata–what’s stored in %localappdata%packages<your package> in folders like LocalState, RoamingState, and TempState–is not dependent on the version of the app that’s using it. By design, app data is maintained across app updates. That is, the act of installing an app update has no effect whatsoever on app data, except when an app has a background task registered for the ServicingComplete trigger and that background task makes changes.

The version of the app and the version of the app data are two separate things: you can have many revs of the app using the same app data structures, so there’s nothing you need to do when upgrading/updating the app. It’s only when you want to change the app data that you then need to version the app data specifically. Here’s what to do:

  1. Even in your first app version, you should be calling Windows.Storage.ApplicationData.SetVersionAsync to assign a version number to your app data as a whole. This becomes important for how the roaming cloud service manages and maintains copies of the app data when a user hasn’t updated every app on every device.
  2. When you’re going to change the appdata version, the second parameter to SetVersionAsync is a function that will be called to migrate from one version to another. This is the trigger to go through an older version of app data (as it might be on disk) and refresh/update the structures. Windows will assume the migration is complete when you return from this. (See scenario 9 of the Application data sample.)
  3. You can call SetVersionAsync in a ServicingComplete background task, but be mindful of the CPU quotas on background tasks if you have a lot of work to do.
  4. You can always maintain per-file or per-settings versioning on your own, without ever changing the overall version number. The danger of this with roaming state, however, is that Windows will assume that all files are the same version, and because the last writer wins, it’s possible that an earlier version of the app on one of the user’s devices will overwrite a newer version of a file on some other device. I think it’s best to avoid adding another layer of complexity to this scene.

In short, apart from a background task, the callback you provide to SetVersionAsync is where you make any updates/changes to app data, and this would typically happen when you launch an app update that knows it’s going to use a new version of state. Before that time, the app data will be the same as before the app was updated.

 

BONUS: a related question to all this is what happens if an app is suspended and terminated, and then updated? Does that terminated state carry through to the next launch? Well, in Windows 8 the previousExecutionState flag gets reset when an update happens; in Windows 8.1, however, it’s preserved, so it is possible for a freshly updated app to be asked to reload session state from a previous version. If this is a problem for your app, either change the state version for the update, or simply check for a flag in your sessionState to determine whether it came from your updated app or a previous version. The latter is a more lightweight solution and won’t affect roaming state versions in the cloud. It’s one good place where even having a distinct version mark in your sessionState can be helpful, as sessionState is never roamed anyway.

 


To determine whether a device supports orientation changes–that is landscape, portrait, landscape-flipped, and portrait-flipped orientations–the simplest way is to just check whether an orientation sensor exists.

Call Windows.Devices.Sensors.SimpleOrientationSensor.getDefault() and if the return value is non-null, there is an orientation sensor.

For details on the APIs, see getDefault, the SimpleOrientationSensor sample, and Quickstart: Determining device orientation.


Typically, when a user rotates an accelerometer-equipped device, Windows will rotate the display to the nearest quadrant (landscape, portrait, landscape-flipped, and portrait-flipped) and apps will receive a resize event in which they can adjust their layout.

Some apps, however, prefer to keep their layout as-is, regardless of device rotation. A full screen video player, for example, wants to remain in landscape irrespective of the device orientation, allowing you to watch videos while laying sideways on a couch with a tablet propped up on a chair!

Locking the orientation can be done in two places. First, you can specify the orientations the app supports in the app manifest under Supported Rotations on the Application UI tab:

sidebar (preferred orientations)

By default, all these options are unchecked which means the app will be resized (and thus redrawn) when the device orientation changes (and checking all of them means the same thing). When you check a subset of the options, the following effects apply:

  • If the device is not in a supported rotation when the app is launched, the app is launched in the nearest supported rotation. For example, if you check Portrait and Landscape-flipped (I have no idea why you’d choose that combination!), and the device is in Landscape mode, the app will launch into Portrait.
  • When the app is in the foreground, rotating the device to a non-supported orientation has no effect on the app.
  • When the user switches away from the app, the device orientation is restored unless the new foreground app also has preferences. Of course, it’s likely that the user will have rotated the device to match the app’s preference, in which case that’s the new device orientation.
  • When the user switches back to the app, it will switch to the nearest supported rotation.
  • In all cases, when the app’s preference is in effect, system edge gestures work relative to that orientation, that is, the left and right edges relative to the app’s orientation.

You can achieve the same effects at runtime—changing preferences dynamically and overriding the manifest—by setting the autoRotationPreferences property of the Windows.Graphics.Display.DisplayInformation object (this is the one you use in Windows 8.1; in Windows 8, use the DisplayProperties object instead). The preference values come from the DisplayOrientations enumeration, and can be combined with the bitwise OR (|) operator. For example, here are the bits of code (JavaScript) to set a Portrait preference and the combination of Portrait and Landscape-flipped (Windows 8.1):

var wgd = Windows.Graphics.Display;
wgd.DisplayInformation.autoRotationPreferences = wgd.DisplayOrientations.portrait;
wgd.DisplayInformation.autoRotationPreferences = wgd.DisplayOrientations.portrait | wgd.DisplayOrientations.landscapeFlipped;

Note that orientation preferences set in the manifest and through the autoRotationPreferences property do not work with non-accelerometer hardware, such as desktop monitors and also the Visual Studio simulator. The rotations that the simulator performs happen in a different way than those induced by a real accelerometer. To really test these preferences, in other words, you’ll need a real device equipped with that sensor.

To play around with these settings, refer to the Device auto rotation preferences sample. Its different scenarios set one of the orientation preferences so you can see the effect when the device is rotated; scenario 1 for its part clears all preferences and restores the usual behavior for apps. You can also change rotation settings in the manifest to see their effects, but those are again overridden as soon as you change the preferences through any of the scenarios.


UPDATE: showing code that actually works.

As a prelude to a series I’m hoping to do on file queries and file information, I just wanted to share a little snippet for making a file read-only. Although you can retrieve the current status through the StorageFile.Attributes property, it just returns an enumeration rather than a property set you can manipulate.

Changing attributes instead has to go through the StorageFile.properties property, which is a StorageItemContentProperties object. Its savePropertiesAsync method is the one you want. For this you need to create a Windows.Foundation.Collections.PropertySet object (see this previous post), populate it with the properties you need, then call savePropertiesAsync.

The specific property you need to set is “System.FileAttributes” with the value FILE_ATTRIBUTE_READONLY, which is just 1 as described for the Win32 SetFileAttributes function. The code looks like this, where I’m just working with a test.jpg in the pictures library to demonstrate:

JavaScript (you can add a completed handler if you need to take other action after savePropertiesAsync):

var key = "System.FileAttributes";
var FILE_ATTRIBUTES_READONLY = 1;
var file;
var pix = Windows.Storage.KnownFolders.picturesLibrary;
pix.getFileAsync("test.jpg").then(function (fileTemp) {
    file = fileTemp;
    return file.properties.retrievePropertiesAsync([key]);
}).done(function (props) {                
    if (props) {                    
        props[key] |= FILE_ATTRIBUTES_READONLY;
    } else {
        props = new Windows.Foundation.Collections.PropertySet();
        props.insert(key, FILE_ATTRIBUTES_READONLY);                    
    }

    file.properties.savePropertiesAsync(props);
});

 

C#:

String key = "System.FileAttributes";
UInt32 FILE_ATTRIBUTES_READONLY = 1;
var pix = Windows.Storage.KnownFolders.PicturesLibrary;

var file = await pix.GetFileAsync("test.jpg");                                
String [] retrieveList = new String [] { key };

var props = await file.Properties.RetrievePropertiesAsync(retrieveList);

if (props != null) {
    var temp = (UInt32)props[key] | FILE_ATTRIBUTES_READONLY;
    props[key] = temp;
} else {
    props = new Windows.Foundation.Collections.PropertySet();                
    props.Add(key, FILE_ATTRIBUTES_READONLY);                    
}

await file.Properties.SavePropertiesAsync(props);

My associate David Roussett has been running a blog for some time on HTML5, Windows 8, and Gaming. The particular series I wanted to point to is Using WinJS & WinRT to build a fun HTML5 Camera Application in which he covers some core scenarios of media capture and then gets to details of applying effects, using web workers, and using WinRT components to get to GPU shader capabilities.


Figuring out which set of language resources to use in an app at runtime can be a tricky thing for the OS to do at runtime, especially if the app has multiple resource files for the same base language.

Fortunately, there’s a topic in the documentation that came out close to GA of Windows 8 last year that explains all this: Language matching. Totally recommended if you’re creating a multilingual app.