かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

UWPで子 Window をサブディスプレイ(プロジェクターなど)に表示する方法(ただしフルスクリーンでな!)

UWP で子ウィンドウ作れるんですが、場所の制御方法がイマイチ自由度が無いですね…。 変な位置に隠れてウィンドウ出して、こそこそ動き回るタイプのアプリを作らせないためでしょうか?

今回は、メインのウィンドウから子ウィンドウを出して、そいつをサブディスプレイに全画面表示する方法を試してみました。 これをやるとプロジェクターに対してコンテンツを表示するみたいな教室とかで使えそうなアプリが簡単に作れそうです。

使うクラスは ProjectionManager クラスです。コードはこんな感じ。

using System;
using Windows.ApplicationModel.Core;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace App5
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private ApplicationView _subWindowApplicationView;

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            if (_subWindowApplicationView == null)
            {
                // まだ子 Window が無かったら作る
                await CoreApplication.CreateNewView().Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                {
                    _subWindowApplicationView = ApplicationView.GetForCurrentView();
                    Window.Current.Content = new Page
                    {
                        Content = new TextBlock
                        {
                            FontSize = 36,
                            Text = "Dummy",
                            HorizontalAlignment = HorizontalAlignment.Center,
                            VerticalAlignment = VerticalAlignment.Center,
                        },
                    };
                    Window.Current.Activate();
                });
            }

            // サブディスプレイに全画面表示させる
            await ProjectionManager.StartProjectingAsync(_subWindowApplicationView.Id, ApplicationView.GetForCurrentView().Id);
        }
    }
}

全画面表示は、ユーザーの操作により解除することが出来ます。これは恐らくキャンセルできないと思います。 その場合は、再度 ProjectionManager.StartProjectingAsync を呼んであげればサブディスプレイに持っていけます。

StartProjectingAsync メソッドには DeviceInformation を最後に受け取るオーバーロードがあります。 これを使うと任意のディスプレイに全画面表示できます。

因みに、ディスプレイの DeviceInformation の取得は以下の方法で出来ます。

var deviceInformations = await DeviceInformation.FindAllAsync(DisplayMonitor.GetDeviceSelector());

ドロップダウンとかに上記で取得した情報とかを表示して選ばれた奴に対して StartProjectingAsync 呼べば良さそうですね。