Développer une application WinJS 2.0 (Windows 8.1) multi-écrans avec WiDi

Afin de nous familiariser avec les mécanismes des applications multi-écrans, nous allons détailler tout ce qu'il nous faut pour développer une application permettant d'afficher et de contrôler un navigateur web sur un écran secondaire ou un projecteur. Bien que l'implémentation et les détails techniques contenus dans cet article soient propres à WinJS, sachez que des API similaires sont disponibles pour le développement en C# et que les concepts ne changent pas. Le dernier paragraphe de cet article donne des pistes pour l'implémentation de cette application en C#.

Si vous ne savez pas ce qu'est le WiDi, vous pouvez lire l'article "Tout sur le WiDi". Pour faire fonctionner l'application décrite par cet article, vous devez posséder une machine sous Windows 8.1 compatible WiDi, une télévision compatible (soit nativement soit au moyen d'un boîtier) WiDi et être capable de les connecter en mode extension d'affichage.
 

Description de l'application

Toute application Windows comporte une vue principale, notre application disposera en plus d'une vue secondaire qui sera affichée sur un second écran. La vue principale accueille une page WinJS standard dont le code Javascript contient tout le code gérant le multi-écrans et dont le code HTML contient les contrôles destinés à l'utilisateur.

Cette application a un fonctionnement très simple :
  1. En cas d'absence d'écran secondaire, elle invite l'utilisateur à en connecter un
  2. En cas de présence d'un écran secondaire, elle propose à l'utilisateur d'en prendre le contrôle. Le cas échéant, elle "projette" une seconde page sur l'écran secondaire invitant l'utilisateur à entrer une URL dans la zone de texte que la vue principale affiche
  3. Lorsque l'utilisateur entre une URL dans la zone de texte et d'un appui sur le bouton associé, la vue principale transmet l'ordre et l'URL à la vue secondaire qui s'occupe d'afficher la page web correspondante en plein écran
  4. Une connexion ou une déconnexion de l'écran secondaire par l'utilisateur cause une réaction adéquate sur les contrôles de la vue principale
Tout ceci est réalisable grâce aux nouvelles API de gestions des vues de WinJS 2.0 présentes dans le namespace "Windows.UI.ViewManagement" que nous allons voir en détails.
 

1. Vérification de la présence d'un écran secondaire

La première chose dans la vue principale est effectivement de choisir entre l'invitation à connecter un écran secondaire et le contrôle permettant de prendre le contrôle de cet écran. Ce choix se fait en fonction de la valeur du booléen suivant :
Windows.UI.ViewManagement.ProjectionManager.projectionDisplayAvailable
S'il vaut true, un écran secondaire est disponible, dans le cas contraire, aucune connexion de ce type n'est détectée.
 

2. Prise de contrôle d'un écran secondaire

Le mot désignant l'affichage d'une vue secondaire sur un écran supplémentaire est "projection", la méthode utilisée pour lancer cette projection est Windows.UI.ViewManagement.Projection Manager.startProjectingAsync(<idDeLaVueSecondaire>, <idDeLaVuePrincipale>), comme toutes les fonctions asynchrones, la fonction renvoie une promise permettant ainsi d'exécuter du code à la fin de l'opération.
Bien entendu, fournir l'id de la vue secondaire implique d'abord la création de cette dernière. Créer une vue passe par l'appel de la fonction MSApp.createNewView(<uriDeLaPage>), cette fonction renvoie la vue ainsi créée après avoir initialisé la page à afficher et ce même si elle n'est pour le moment affichée nulle part.
Le code suivant permet d'afficher notre seconde vue :
var view = MSApp.createNewView("ms-appx:///pages/browserPage.html");
Windows.UI.ViewManagement.ProjectionManager.startProjectingAsync(view.viewId, Windows.UI.ViewManagement.ApplicationView.getForCurrentView().id).done(function () {
   // Code exécuté à la fin de l'opération
   document.querySelector('.webControls').style.display = 'block';
});
L'arrêt de la projection se fait quasiment de la même façon, la méthode stopProjectingAsync() dans le même namespace prend en effet les mêmes paramètres et s'utilise de la même façon.
 

3. Communication entre les vues

Pour que notre application fonctionne, la vue secondaire doit pouvoir recevoir les ordres de la vue principale, pour ce faire, nous devons passer par la messagerie web HTML5 qui permet à deux contextes (objets window ou Web Workers) de communiquer par messages. L'objet créé par la méthode MSApp.createNewView() possède une fonction postMessage() permettant d'envoyer un objet de n'importe quel type autre qu'une fonction à la page affichée dans la vue secondaire. Invoquer cette méthode sur la vue secondaire déclenchera l'évènement window.onmessage de la page secondaire en lui passant l'objet contenu dans le message par les arguments d'évènement.

En pratique, on a donc dans la vue principale le code suivant :
view.postMessage('url_' + urlToReach, '*');
Qui déclenchera l'évènement auquel s'est abonné la vue secondaire par le code suivant :
window.onmessage = function (evt) {
   var msg = evt.data;
   // Exploiter le message

		};
Les pages affichées par la vue secondaire ne sont pas dans le contexte principale : les points d'arrêt du code Javascript fonctionnent mais les messages envoyés à la console ne s'affichent pas dans la console de VS et il est impossible d'utiliser le DOM Explorer pour débugger le code HTML ou les styles CSS.
 
La vue secondaire est une vue indépendante : l'utilisateur peut choisir de la fermer (via Alt + F4 quand le focus est dessus ou via un glisser de la souris de haut en bas) et la vue principale n'en saura rien ! Il est donc nécessaire de s'abonner à l'évènement consolidated de l'ApplicationView pour détecter cette fermeture et envoyer un message à la vue principale pour l'informer de la fermeture. Solliciter la vue principale depuis la vue secondaire se fait par le biais de la méthode MSApp.getViewOpener() qui renvoie un objet sur lequel on peut utiliser la fonction postMessage().
 
L'objet ProjectionManager offre aussi la possibilité d'intervertir les deux vues via la méthode swapDisplaysForViewAsync(), pour plus de détails à ce propos, téléchargez le sample "Projection" sur MSDN.
 

4. Abonnement au changement d'état de la connexion à l'écran secondaire

Demander à l'utilisateur de connecter un écran secondaire lorsqu'il n'y en a pas est bien, ainsi, l'utilisateur peut réagir en établissant une connexion depuis le "Charm" des paramètres. Néanmoins, l'application restant affichée, il est nécessaire que son comportement prenne en compte la connexion lors de son établissement. Pour se faire, il est possible de s'abonner à l'évènement projectiondisplayavailablechanged du ProjectionManager au moyen du code suivant :
Windows.UI.ViewManagement.ProjectionManager.addEventListener('projectiondisplayavailablechanged', function () {
   checkProjectionState();
});
Cet évènement est déclenché à chaque connexion ou déconnexion d'un écran secondaire, notre application réagit alors en adaptant la disposition de la page principale.
 

Conclusion

WinJS 2.0 contient tout ce qu'il faut pour développer des applications multi-écrans, que l'écran soit connecté en WiDi, en Miracast ou via un câble HDMI. Ces API sont assez simples à utiliser, vous trouverez en bas de cet article la solution de notre application de navigateur web multi-écrans qui, si elle ne recevra pas de récompense en matière de design, a le mérite d'implémenter tout ce que vous pouvez souhaiter utiliser pour la création de vos applications WinJS multi-écrans.
 

Pour les développeurs C#

A priori (je n'ai pas testé), l'équivalent de MSApp.createNewView() est CoreApplication.CreateNewView(), cette méthode renvoie un objet de type CoreWindow dont on peut obtenir le "ViewId" en appelant Windows.UI.ViewManagement.ApplicationView.GetApplicationViewIdForWindow() en passant la CoreWindow en paramètre. Le ViewId de la vue principale est accessible par App.Current.MainViewId et la vue secondaire peut communiquer avec la vue principale grâce à l'objet App.Current.MainDispatcher. Le reste doit fonctionner de la même façon en passant par les mêmes API, le sample "Projection" peut vous aiguiller dans l'implémentation.
 

Sources

Multiple Views for Windows 8.1 Apps (Kraig Brockschmidt) : http://kraigbrockschmidt.com/blog/?p=1153
AdjuntoTamaño
Descargar MultiscreenBrowser.zip49.95 KB
Etiquetas:
Para obtener más información sobre las optimizaciones del compilador, consulte el aviso sobre la optimización.