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.


Comments are closed