SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

UWPアプリ開発の最前線

簡単になったUWP Bridge
~Windows 10 1803の新機能「タイムライン」をWPFアプリに実装してみる

UWPアプリ開発の最前線 第6回


  • X ポスト
  • このエントリーをはてなブックマークに追加

プロトコルアクティベーションへの対応

 マニフェストに宣言したので、「タイムライン」からプロトコルアクティベーションでアプリを起動してもらえるようにはなりました。でも、ただ起動するだけです。「ユーザーアクティビティ」として登録した状態を復元しましょう。また、このままでは、「タイムライン」で「ユーザーアクティビティ」をクリックするたびに新しいプロセスが起動してしまいます。複数のプロセスが立ち上がらないようにもしてみましょう。

デスクトップブリッジでのプロトコルアクティベーション

 純粋なUWPアプリとは違って、「UWPアプリ化」したデスクトップアプリの場合は、プロトコルアクティベーションによって必ずアプリが起動されます。起動時、Main関数の最初の引数としてアクティベーションURIが渡されます。

 従って、Main関数の冒頭で引数をチェックして、第1引数がアクティベーションURIであれば、プロトコルアクティベーションで起動されたと判定すればよさそうです。今回は、引数のアクティベーションURIから状態を復元するための情報(=表示していたWebページのURL)を取り出してみて、その結果がnullでなければプロトコルアクティベーションだと判定することにします。

Main関数を追加する

 WPFのプロジェクトの既定では、Main関数はビルド時に自動生成されるようになっています。Main関数に独自の処理を追加するには、自動生成を止めてから、AppクラスにMain関数を追加します。

 まず、ソリューションエクスプローラーでWPFプロジェクトの「App.xaml」ファイルを選び、そのプロパティペインでビルドアクションを[ApplicationDefinition]から[Page]に変更します。これでMain関数の自動生成が止まります。

 次に、「App.xaml.cs」ファイルを開いて、Main関数を追加します(次のコード)。

Appクラスに追加したMain関数
[STAThread]
public static void Main(string[] args)
{
  App app = new App();
  app.InitializeComponent();
  app.Run();
}

 さらに、AppクラスからMainWindowを操作できるようにしておきましょう。自動生成されたコードではMainWindowのインスタンスを明示的に作っていないので、操作しにくいのです。「App.xaml」ファイルを開いて、先頭の「Application」タグ内から「StartupUri="MainWindow.xaml"」の部分を削除します。そうしたら、Main関数を次のコードのように変更します。

明示的にMainWindowインスタンスを生成するように変更
[STAThread]
public static void Main(string[] args)
{
  App app = new App();
  app.Startup += OnStartup;
  app.InitializeComponent();
  app.Run();

  return; // 以下はローカル関数のみ

  void OnStartup(object sender, StartupEventArgs e)
  {
    // 明示的にMainWindowインスタンスを生成して表示する
    MainWindow mainWindow = new MainWindow();
    mainWindow.Show();
  }
}

プロトコルアクティベーションで指定されたWebページを表示する

 先に、MainWindowクラスに、外部から指定したWebページを表示する機能を追加しておきましょう(次のコード)。

外部から指定したWebページを表示するメソッド(MainWindowクラス)
internal async void Navigate(string url)
{
  this.WebView1.Navigate(new Uri(url));
}

 さて、今回の場合、プロトコルアクティベーションで渡された引数から表示すべきWebページのURL文字列を取り出すコードは、次のようになります。プロトコルアクティベーションではないときはnullを返すようにしました。

引数から表示すべきWebページのURL文字列を取り出すメソッド
string GetProtocolActivationUrl(string args) // argsはMain関数の引数
{
  if (args.Length > 0 // 引数が存在し
      && args[0].StartsWith("uf05.bluewatersoft.jp-timelinetest:") //先頭がプロトコル名なら
      && Uri.TryCreate(args[0], UriKind.Absolute, out var uri)) //引数をUriクラスに変換し、
    return uri.Query.Substring(1); //そのUriのクエリ部分(先頭の'?'を除く)が表示すべきURL
  else
    return null;
}

 このGetProtocolActivationUrlメソッドをMain関数に組み込みます。そして、プロトコルアクティベーションのURLが得られたときには、MainWindowを表示したときに前述のNavigateメソッドを呼び出すようにします(次のコード、Appクラス内)。

プロトコルアクティベーションでWebページを表示できるようになったMain関数
[STAThread]
public static void Main(string[] args)
{
  // プロトコルアクティベーションで起動されたときの、表示すべきURL
  string protocolActivationUrl = GetProtocolActivationUrl();

  App app = new App();
  app.Startup += OnStartup;
  app.InitializeComponent();
  app.Run();

  return; // 以下はローカル関数のみ

  string GetProtocolActivationUrl() //ローカル関数にしたので、args引数の受け渡しは不要
  {
    if (args.Length > 0
        && args[0].StartsWith("uf05.bluewatersoft.jp-timelinetest:")
        && Uri.TryCreate(args[0], UriKind.Absolute, out var uri))
      return uri.Query.Substring(1);
    else
      return null;
  }

  void OnStartup(object sender, StartupEventArgs e)
  {
    // App.xamlから「StartupUri="MainWindow.xaml"」の部分を削除しておく

    MainWindow mainWindow = new MainWindow();
    mainWindow.Show();
    if (protocolActivationUrl != null)
      // プロトコルアクティベーションのときは、そのURLを表示する
      mainWindow.Navigate(protocolActivationUrl);
  }
}

 これで、「タイムライン」から起動されたときに、以前のWebページを表示するようになりました。

次のページ
まとめ

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
UWPアプリ開発の最前線連載記事一覧

もっと読む

この記事の著者

biac(ばいあっく)

HONDA R&Dで自動車の設計をやっていた機械屋さんが、技術の進化スピードに魅かれてプログラマーに。以来30年ほど、より良いコードをどうやったら作れるか、模索の人生。わんくま同盟の勉強会(名古屋)で、よく喋ってたりする。2014/10~2019/6 Microsoft MVP (Windows Devel...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/10810 2019/11/10 21:18

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング