連載
» 2013年12月05日 14時13分 公開

WinRT/Metro TIPS:Windows 8.1の新機能、セカンダリ・タイル作成時の代替ロゴを使うには?[Windows 8.1ストア・アプリ開発]

Windows 8.1ストア・アプリでは「ピン留め」するタイルの初期サイズや図柄の選択肢をエンド・ユーザーに提示できる。その開発方法を解説する。

[山本康彦(http://www.bluewatersoft.jp/),BluewaterSoft]
WinRT/Metro TIPS
業務アプリInsider/Insider.NET

powered by Insider.NET

「WinRT/Metro TIPS」のインデックス

連載目次

 Windowsストア・アプリでセカンダリ・タイルをスタート画面に「ピン留め」するにはエンド・ユーザーの許可が必要だ。そのときに、タイルの初期サイズや図柄の選択肢(=代替ロゴ)をエンド・ユーザーに提示したいと思ったことはないだろうか? Windows 8.1(以降、Win 8.1)用のWindowsストア・アプリ(以降、Win 8.1アプリ)では、それが可能になった。本稿では、セカンダリ・タイルを作成する際に、代替ロゴをエンド・ユーザーに提示する方法を解説する。本稿のサンプルは「Windows Store app samples:MetroTips #59(Windows 8.1版)」からダウンロードできる。

事前準備

 Win 8.1アプリを開発するには、Win 8.1とVisual Studio 2013(以降、VS 2013)が必要である。本稿ではOracle VM VirtualBox上で64bit版Windows 8.1 Pro Preview(日本語版)*1とVisual Studio Express 2013 Preview for Windows(日本語版)を使用してプログラミングしている。これらを準備する方法や注意事項は、「WinRT/Metro TIPS: Win8用のソース・コードをWin8.1用に変換するには?[Win 8.1]」の記事をご参照いただきたい。また、本稿のソース・コードは、64bit版Windows 8.1 Pro(日本語版の製品版)とVisual Studio Express 2013 for Windows(日本語版の製品版)*2でも動作を確認している。

*1Win 8.1Preview版の使用期限は来月(2014年1月)の半ばまでとなっている。

*2マイクロソフト公式ダウンロード・センターの「Microsoft Visual Studio Express 2013 for Windows」から無償で入手できる。


初期サイズの選択肢

 Windows 8(以降、Win 8)用のWindowsストア・アプリでセカンダリ・タイルを作成する方法は、本連載でも以前に紹介した(「WinRT/Metro TIPS:セカンダリ・タイルを活用するには?[Win 8]」参照)。Win 8では、セカンダリ・タイルの作成許可をエンド・ユーザーに求めるフライアウトは次の画像のようなものだった。

セカンダリ・タイルの作成許可をユーザーに求めるフライアウト(Win 8) セカンダリ・タイルの作成許可をユーザーに求めるフライアウト(Win 8)
この画像は以前の記事に掲載したものだ。アプリからはワイド・タイル(310×150ピクセル)と中タイル(150×150ピクセル)の2種類のタイルをセットしているのに、エンド・ユーザーは初期サイズを選べず、スタート画面にはワイド・タイルがピン留めされた。中タイルを望むエンド・ユーザーは、スタート画面でタイルのサイズをあらためて変更する必要があった。

 Win 8では、アプリ側で2種類(ワイド・サイズと中サイズ)のタイルをセットした場合、作成されるセカンダリ・タイルは必ずワイド・サイズになってしまう。エンド・ユーザーが中サイズを望む場合は、後からスタート画面でリサイズする必要があった。

 Win 8.1ではこれが改良されており、セカンダリ・タイルの作成許可をエンド・ユーザーに求めるフライアウトで初期サイズを選択できるようになっている。上のフライアウトを表示するアプリをそのままWin 8.1で実行すると、表示されるフライアウトは次の画像のようになる。

セカンダリ・タイルの作成許可をユーザーに求めるフライアウト(Win 8.1)
セカンダリ・タイルの作成許可をユーザーに求めるフライアウト(Win 8.1)
セカンダリ・タイルの作成許可をユーザーに求めるフライアウト(Win 8.1) セカンダリ・タイルの作成許可をユーザーに求めるフライアウト(Win 8.1)
先ほどの画像のアプリをWin 8.1で実行した場合、エンド・ユーザーはこのように3種類の初期サイズ(順に小(70×70ピクセル)/中/ワイド・タイル)から選択できる。なお、このアプリでは小タイルをセットしていないのだが、中タイルの画像が自動的に縮小されて使われている。

 このように、Win 8.1では、セカンダリ・タイルの初期サイズをエンド・ユーザーが選択できるようになっている。アプリでは何も対応する必要はない。なお、スタート画面にピン留めした後で、エンド・ユーザーがタイルのサイズを変更できるのは同じだ。

タイルの図柄の選択肢を出すには?

 Win 8.1のセカンダリ・タイルは、初期サイズだけでなく複数のタイルの図柄をエンド・ユーザーに提示して選択してもらうことも可能だ。セカンダリ・タイルの図柄は既定のものに加えて追加の図柄(=代替ロゴ)が最大3種類(合わせて4種類)まで。初期サイズは4種類(小/中/ワイド/大(310×310ピクセル))なので、最大で16通りの選択肢が提示できることになる。以下、それを実装してみよう。

画像を用意する

 まずはタイルに使う画像を用意してもらいたい。プライマリ・タイルの分も含めて5種類×4サイズで20通りの画像があるとよいのだが、それは大変だ。透過画像として作り、セカンダリ・タイルに設定するときに背景色を変えるようにすれば、1種類×4サイズだけでも構わない。筆者は次の画像のように、大サイズのみ5種類(ほかのサイズは1種類だけ)用意した。

今回用意したタイル画像(エクスプローラで表示) 今回用意したタイル画像(エクスプローラで表示)
大タイルは、プライマリ・タイル用(上段右端の透過画像)とセカンダリ・タイル用(下段の4種類)の、合わせて5種類を用意した。小/中/ワイドは1種類ずつだが、透過画像にして背景色を別途指定できるようにした。なお、タイルに使用する画像ファイルのサイズは200KBytesまでに制限されているので注意してほしい。
下段のタイルの背景には、MSDNの「Windowsアプリ・アート・ギャラリー」で提供されている写真を使わせてもらった。

 画像ファイルの拡張子は、この画像にあるように「.scale-100.png」や「.scale-100.jpg」などとしてほしい。ファイル名の中の「.scale-100」という表記の意味は、「WinRT/Metro TIPS:解像度が変わっても画像をシャープに表示するには?[Win 8]」を参照のこと。VS 2013では、画像ファイルのこの表記法が必須となっている。

 画像が用意できたら、VS 2013でプロジェクトを作成し、マニフェスト・ファイルでプライマリ・タイルに画像を設定してほしい(次の画像)。筆者は、上の画像にある4つの透過画像を使って、背景色を青色(#00a2e8)に設定した。なお、プライマリ・タイルに複数サイズのタイルを設定していなくても、セカンダリ・タイルには複数のサイズが使用できる。

プライマリ・タイルの画像をマニフェストで設定する(VS 2013 Preview版) プライマリ・タイルの画像をマニフェストで設定する(VS 2013 Preview版)
ここでファイル名を入れる場合は、ファイル名中の「.scale-100」は入力しない。

セカンダリ・タイルを1種類だけ提示するには?

 SecondaryTileクラス(Windows.UI.StartScreen名前空間)のオブジェクトを作り、ユーザーにピン留めの許可を求めるリクエストを発行すればよい(次のコード)。ただし、パラメータの設定方法がWin 8.1で新しくなっている。以前の記事に掲載したコードと比較してほしい。

private async System.Threading.Tasks.Task<bool> CreateSecondaryTileAsync(Rect buttonArea)
{
  string tileId = ……省略……;

  var secondaryTile = new Windows.UI.StartScreen.SecondaryTile()
    {
      TileId = tileId, // 【必須】タイルを識別するID。削除時にも使う
      // ShortName ←Win 8.1では使わない
      DisplayName = tileId, // 【必須】アプリの名前
      Arguments = tileId, // 起動時に渡される引数
      // TileOptions ←Win 8.1では使わない
      // Logo ←Win 8.1では使わない
      // WideLogo ←Win 8.1では使わない
      // BackgroundColor ←Win 8.1では使わない
      // ForegroundText ←Win 8.1では使わない

      RoamingEnabled = false// [Win 8.1で新設] 既定でtrue(=ローミングされる)
    };

  // 基本タイルの設定(背景色は緑)[VisualElementsはWin 8.1で新設]
  secondaryTile.VisualElements.BackgroundColor = Windows.UI.Colors.DarkGreen; // 背景色を緑色に
  secondaryTile.VisualElements.ForegroundText = Windows.UI.StartScreen.ForegroundText.Light; // 表示するアプリ名の色

  secondaryTile.VisualElements.ShowNameOnSquare150x150Logo = true; // 中タイルにアプリ名を表示する
  secondaryTile.VisualElements.ShowNameOnWide310x150Logo = true; // ワイド・タイルにアプリ名を表示する
  secondaryTile.VisualElements.ShowNameOnSquare310x310Logo = true; // 大タイルにアプリ名を表示する

  secondaryTile.VisualElements.Square70x70Logo = new Uri("ms-appx:///Assets/70x70.png"); // 小タイルの画像を指定
  secondaryTile.VisualElements.Square150x150Logo = new Uri("ms-appx:///Assets/150x150.png");  // 【必須】中タイルの画像を指定
  secondaryTile.VisualElements.Wide310x150Logo = new Uri("ms-appx:///Assets/310x150.png"); // ワイド・タイルの画像を指定
  secondaryTile.VisualElements.Square310x310Logo = new Uri("ms-appx:///Assets/310x310A.png"); // 大タイルの画像を指定

  // エンド・ユーザーにピン留めの許可を求めるリクエストを発行する
  return await secondaryTile.RequestCreateForSelectionAsync(
                  buttonArea, Windows.UI.Popups.Placement.Below
                );
}

Private Async Function CreateSecondaryTileAsync(buttonArea As Rect) As System.Threading.Tasks.Task(Of Boolean)
  Dim tileId As String = ……省略……

  Dim secondaryTile = New Windows.UI.StartScreen.SecondaryTile()
  With secondaryTile
    .TileId = tileId  ' 【必須】タイルを識別するID。削除時にも使う
    ' ShortName ←Win 8.1では使わない
    .DisplayName = tileId ' 【必須】アプリの名前
    .Arguments = tileId ' 起動時に渡される引数
    ' .TileOptions ←Win 8.1では使わない
    ' .Logo ←Win 8.1では使わない
    ' .WideLogo ←Win 8.1では使わない
    ' .BackgroundColor ←Win 8.1では使わない
    ' .ForegroundText ←Win 8.1では使わない

    .RoamingEnabled = False  ' [Win 8.1で新設] 既定でtrue(=ローミングされる)
  End With

  ' 基本タイルの設定(背景色は緑)[VisualElementsはWin 8.1で新設]
  secondaryTile.VisualElements.BackgroundColor = Windows.UI.Colors.DarkGreen ' 背景色を緑色に
  secondaryTile.VisualElements.ForegroundText = Windows.UI.StartScreen.ForegroundText.Light ' 表示するアプリ名の色

  secondaryTile.VisualElements.ShowNameOnSquare150x150Logo = True ' 中タイルにアプリ名を表示する
  secondaryTile.VisualElements.ShowNameOnWide310x150Logo = True ' ワイド・タイルにアプリ名を表示する
  secondaryTile.VisualElements.ShowNameOnSquare310x310Logo = True ' 大タイルにアプリ名を表示する

  secondaryTile.VisualElements.Square70x70Logo = New Uri("ms-appx:///Assets/70x70.png") ' 小タイルの画像を指定
  secondaryTile.VisualElements.Square150x150Logo = New Uri("ms-appx:///Assets/150x150.png"' 【必須】中タイルの画像を指定
  secondaryTile.VisualElements.Wide310x150Logo = New Uri("ms-appx:///Assets/310x150.png") ' ワイド・タイルの画像を指定
  secondaryTile.VisualElements.Square310x310Logo = New Uri("ms-appx:///Assets/310x310A.png") ' 大タイルの画像を指定

  ' エンド・ユーザーにピン留めの許可を求めるリクエストを発行する
  Return Await secondaryTile.RequestCreateForSelectionAsync(
                  buttonArea, Windows.UI.Popups.Placement.Below
                )
End Function

セカンダリ・タイルを作成するメソッド(上:C#、下:VB)
以前の記事に掲載したコードを改修した。SecondaryTileオブジェクトのいくつかのプロパティは、使用しなくなった(使用すると警告が出る)。代わりに、VisualElementsプロパティが新設され、最初のセカンダリ・タイルの設定はそこで行うようになった。

 このメソッドを呼び出すと、Win 8と同様に1種類だけ(ただし初期サイズは4通り)のセカンダリ・タイルがエンド・ユーザーに提示される。

2種類目以降のセカンダリ・タイルを提示するには?

 SecondaryTileオブジェクトのVisualElementsRequestedイベント・ハンドラの中で追加のタイル(=代替ロゴ)を設定すればよい(最大3種類まで)。VisualElementsRequestedイベントはセカンダリ・タイルの作成を確認するフライアウトを表示するメソッド(上で呼び出しているRequestCreateForSelectionAsyncメソッドやRequestCreateAsyncメソッド)が呼び出されると発生する。

 そのためには、まず先ほどのコードに、イベント・ハンドラを結び付けるコードを追加する(次のコード)。

private async System.Threading.Tasks.Task<bool> CreateSecondaryTileAsync(Rect buttonArea)
{
  ……省略……;
  secondaryTile.VisualElements.Square310x310Logo = new Uri("ms-appx:///Assets/310x310A.png"); // 大タイルの画像を指定

  // 代替ロゴをセットするためのイベント・ハンドラ[Win 8.1で新設]
  secondaryTile.VisualElementsRequested += SecondaryTile_VisualElementsRequested;

  // エンド・ユーザーにピン留めの許可を求めるリクエストを発行する
  return await secondaryTile.RequestCreateForSelectionAsync(
                  buttonArea, Windows.UI.Popups.Placement.Below
                );
}

Private Async Function CreateSecondaryTileAsync(buttonArea As Rect) As System.Threading.Tasks.Task(Of Boolean)
  ……省略……;
  secondaryTile.VisualElements.Square310x310Logo = New Uri("ms-appx:///Assets/310x310A.png") ' 大タイルの画像を指定

  ' 代替ロゴをセットするためのイベント・ハンドラ[Win 8.1で新設]
  AddHandler secondaryTile.VisualElementsRequested, AddressOf SecondaryTile_VisualElementsRequested

  ' エンド・ユーザーにピン留めの許可を求めるリクエストを発行する
  Return Await secondaryTile.RequestCreateForSelectionAsync(
                  buttonArea, Windows.UI.Popups.Placement.Below
                )
End Function

セカンダリ・タイルを作成するメソッドの中でVisualElementsRequestedイベント・ハンドラを追加する(上:C#、下:VB)
先ほどのメソッドに、太字の部分を追加する。

 次に、VisualElementsRequestedイベント・ハンドラを作成し、そこで次のコードのようにして代替ロゴ(=2種類目以降のタイル)を設定する。

private void SecondaryTile_VisualElementsRequested(
               Windows.UI.StartScreen.SecondaryTile secondaryTile,
               Windows.UI.StartScreen.VisualElementsRequestedEventArgs args)
{
  var elements = args.Request.AlternateVisualElements;

  // 代替ロゴ1
  elements[0].BackgroundColor = Windows.UI.Colors.DarkRed; // 背景色を赤色に
  elements[0].ForegroundText = Windows.UI.StartScreen.ForegroundText.Light;

  elements[0].ShowNameOnSquare150x150Logo = true;
  elements[0].ShowNameOnWide310x150Logo = true;
  elements[0].ShowNameOnSquare310x310Logo = true;

  elements[0].Square70x70Logo = new Uri("ms-appx:///Assets/70x70.png");
  elements[0].Square150x150Logo = new Uri("ms-appx:///Assets/150x150.png");
  elements[0].Wide310x150Logo = new Uri("ms-appx:///Assets/310x150.png");
  elements[0].Square310x310Logo = new Uri("ms-appx:///Assets/310x310B.png"); // 赤い画像

  // 代替ロゴ2
  elements[1].BackgroundColor = Windows.UI.Colors.Indigo; // 背景色を紫色に
  elements[1].ForegroundText = Windows.UI.StartScreen.ForegroundText.Light;

  elements[1].ShowNameOnSquare150x150Logo = true;
  elements[1].ShowNameOnWide310x150Logo = true;
  elements[1].ShowNameOnSquare310x310Logo = true;

  elements[1].Square70x70Logo = new Uri("ms-appx:///Assets/70x70.png");
  elements[1].Square150x150Logo = new Uri("ms-appx:///Assets/150x150.png");
  elements[1].Wide310x150Logo = new Uri("ms-appx:///Assets/310x150.png");
  elements[1].Square310x310Logo = new Uri("ms-appx:///Assets/310x310C.png"); // 紫色の画像

  // 代替ロゴ3
  elements[2].BackgroundColor = Windows.UI.Colors.Goldenrod; // 背景色を黄色に
  elements[2].ForegroundText = Windows.UI.StartScreen.ForegroundText.Light;

  elements[2].ShowNameOnSquare150x150Logo = true;
  elements[2].ShowNameOnWide310x150Logo = true;
  elements[2].ShowNameOnSquare310x310Logo = true;

  elements[2].Square70x70Logo = new Uri("ms-appx:///Assets/70x70.png");
  elements[2].Square150x150Logo = new Uri("ms-appx:///Assets/150x150.png");
  elements[2].Wide310x150Logo = new Uri("ms-appx:///Assets/310x150.png");
  elements[2].Square310x310Logo = new Uri("ms-appx:///Assets/310x310D.png"); // 黄色い画像
}

Private Sub SecondaryTile_VisualElementsRequested( _
              secondaryTile As Windows.UI.StartScreen.SecondaryTile, _
              args As Windows.UI.StartScreen.VisualElementsRequestedEventArgs)
  Dim elements = args.Request.AlternateVisualElements

  ' 代替ロゴ1
  elements(0).BackgroundColor = Windows.UI.Colors.DarkRed ' 背景色を赤色に
  elements(0).ForegroundText = Windows.UI.StartScreen.ForegroundText.Light

  elements(0).ShowNameOnSquare150x150Logo = True
  elements(0).ShowNameOnWide310x150Logo = True
  elements(0).ShowNameOnSquare310x310Logo = True

  elements(0).Square70x70Logo = New Uri("ms-appx:///Assets/70x70.png")
  elements(0).Square150x150Logo = New Uri("ms-appx:///Assets/150x150.png")
  elements(0).Wide310x150Logo = New Uri("ms-appx:///Assets/310x150.png")
  elements(0).Square310x310Logo = New Uri("ms-appx:///Assets/310x310B.png") ' 赤い画像

  ' 代替ロゴ2
  elements(1).BackgroundColor = Windows.UI.Colors.Indigo ' 背景色を紫色に
  elements(1).ForegroundText = Windows.UI.StartScreen.ForegroundText.Light

  elements(1).ShowNameOnSquare150x150Logo = True
  elements(1).ShowNameOnWide310x150Logo = True
  elements(1).ShowNameOnSquare310x310Logo = True

  elements(1).Square70x70Logo = New Uri("ms-appx:///Assets/70x70.png")
  elements(1).Square150x150Logo = New Uri("ms-appx:///Assets/150x150.png")
  elements(1).Wide310x150Logo = New Uri("ms-appx:///Assets/310x150.png")
  elements(1).Square310x310Logo = New Uri("ms-appx:///Assets/310x310C.png") ' 紫色の画像

  ' 代替ロゴ3
  elements(2).BackgroundColor = Windows.UI.Colors.Goldenrod ' 背景色を黄色に
  elements(2).ForegroundText = Windows.UI.StartScreen.ForegroundText.Light

  elements(2).ShowNameOnSquare150x150Logo = True
  elements(2).ShowNameOnWide310x150Logo = True
  elements(2).ShowNameOnSquare310x310Logo = True

  elements(2).Square70x70Logo = New Uri("ms-appx:///Assets/70x70.png")
  elements(2).Square150x150Logo = New Uri("ms-appx:///Assets/150x150.png")
  elements(2).Wide310x150Logo = New Uri("ms-appx:///Assets/310x150.png")
  elements(2).Square310x310Logo = New Uri("ms-appx:///Assets/310x310D.png") ' 黄色い画像
End Sub

代替ロゴを設定するメソッド(上:C#、下:VB)
それぞれで設定すべき内容は、前掲した1つ目のコードのVisualElementsプロパティへの設定と同じなので、迷うことはないだろう。ここでは、それぞれで背景色と大タイルの画像を変えている。

実行結果

 画面に適当にボタンを配置し、そのTappedイベントで前述のCreateSecondaryTileAsyncメソッドを呼び出す(次のコード)。

private async void PinButton_Tapped(object sender, TappedRoutedEventArgs e)
{
  await CreateSecondaryTileAsync(GetElementRect(this.PinButton));
}

public static Rect GetElementRect(FrameworkElement element)
{
  GeneralTransform buttonTransform = element.TransformToVisual(null);
  Point point = buttonTransform.TransformPoint(new Point());
  return new Rect(point, new Size(element.ActualWidth, element.ActualHeight));
}

Private Async Sub PinButton_Tapped(sender As Object, e As TappedRoutedEventArgs)
  Await CreateSecondaryTileAsync(GetElementRect(Me.PinButton))
End Sub

Public Shared Function GetElementRect(element As FrameworkElement) As Rect
  Dim buttonTransform As GeneralTransform = element.TransformToVisual(Nothing)
  Dim point As Point = buttonTransform.TransformPoint(New Point())
  Return New Rect(point, New Size(element.ActualWidth, element.ActualHeight))
End Function

セカンダリ・タイルを作成するメソッドを呼び出すコード(上:C#、下:VB)
画面に「PinButton」という名前のAppBarButtonコントロールを配置し、そのTappedイベントにこのPinButton_Tappedメソッドを割り当てた。なお、2つ目のメソッド(=GetElementRectメソッド)は、タップされたボタンの場所を算出するためのもの。

 これで実行してボタンをタップしてみると、次の画像のようなフライアウトが現れる。提示されたタイルの左右をタップすることで選択肢を切り替える。全部で16通りあるが、ここでは4つだけ紹介する。

表示されたフライアウト
表示されたフライアウト
表示されたフライアウト
表示されたフライアウト 表示されたフライアウト
作成するセカンダリ・タイルの選択肢の例。提示されたタイルの左右をタップして選択肢を切り替える。

 次の画像は、16通りのセカンダリ・タイルを全て作成したスタート画面だ。なお、エンド・ユーザーはスタート画面でセカンダリ・タイルのサイズを変えられるが、ほかの代替ロゴに切り替えることはできない。

16通りのセカンダリ・タイルを全て作成したスタート画面 16通りのセカンダリ・タイルを全て作成したスタート画面
プライマリ・タイル(青色のワイド・タイル)とセカンダリ・タイル(4色×4サイズ=16通り)が並んでいる。

補足

 自アプリで作成したセカンダリ・タイルがスタート画面にまだ存在していることを確認するには、SecondaryTileクラスのExistsメソッドを使う。また、自アプリで作成したセカンダリ・タイルを列挙するために、SecondaryTileクラスにFindAllAsyncメソッドなどいくつかのメソッドが用意されている。

 セカンダリ・タイルを削除する方法は、Win 8のときと同じである。以前の記事を参照してほしい。

 セカンダリ・タイルから起動された場合、AppクラスのOnLaunchedメソッドに渡されるLaunchActivatedEventArgs型の引数「args」のプロパティにセカンダリ・タイルの情報が入っていることは以前の記事で述べた。付け加えておくと、すでにアプリが実行中であってもセカンダリ・タイルがタップされるとOnLaunchedメソッドが実行されるので、実行中に別の画面へ遷移さられる。

まとめ

 Win 8.1では、セカンダリ・タイルをスタート画面にピン留めするときに、エンド・ユーザーがタイルの初期サイズを選択できるようになっている。また、アプリから代替ロゴを設定すると、エンド・ユーザーはタイルの図柄も選択できる(最大4種類)。なお、セカンダリ・タイルを生成するときのパラメータの与え方が、Win 8.1で新しくなっている。Win 8のときのコードのままでもビルドは可能だが、新しい記述方法は代替ロゴを設定する場合と同じなので、新しい書き方にした方がよいだろう。

 Win 8.1で新しくなったタイルの機能については、次のドキュメントも参照してほしい。

「WinRT/Metro TIPS」のインデックス

WinRT/Metro TIPS

Copyright© 1999-2017 Digital Advantage Corp. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。