C++/WinRTでUWPその1　まずはHello World


#1.VS2019のインストール～ビルドできるようになるまで

##1-1.インストール

VS2019をインストールしていなければ、[MSのダウンロードページ](https://visualstudio.microsoft.com/ja/downloads/)から「コミュニティ」の「無料ダウンロード」から無料のwebダウンローダーをダウンロードしてください。規約にはしたがってね。
![0-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/9ac2a962-b923-67dd-55ee-2cba7dd59719.png)
<br>

「C++」とか「.NET」とかついているのにチェックをいれれば必要なものはインストールされるはず！
![0-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/d6da1ab8-8412-c326-93e4-e83685ffa22b.png)
<br>

私もよく忘れるのですが、「個別のコンポーネント」の「WIndows 10 SDK (...)」はチェック入れておいた方が良いかも。他のPCで作成してバージョン××が無いとかよく叱られます。
![0-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/a7a7fe9b-84fa-8f0f-4817-0e61a59869ed.png)

ここまで終わったら、インストールが終わるまでしばらく待ちましょう。
<br>

##1-2.C++/WinRTの追加

インストール後に「拡張機能」－「拡張機能の管理」からwinrtで検索して「C++/WinRT」を入れてください。これで「新しいプロジェクトの作成」等にC++/WinRTが追加され、ビルドまで可能になります。
![0-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/e217b391-6365-56d4-942b-961ce6aeeb3d.png)
<br>
<br>

#2.Hello World
##2-1.プロジェクトの追加
「Blank App(C++/WinRT)」を選んでください。UWPはこちらになります。
![1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/ef1d533e-259d-24b8-40e3-fef25a371c39.png)
<br>

##2-2.ボタンとテキストブロックの追加
・ソリューションエクスプローラーの「MainPage.xaml」をダブルクリックして表示し、「ツールボックス」の「Button」を2回ドラッグアンドドロップして2個のボタンを追加。「TextBlock」も一つ追加してください。
・MFCなどでアプリをつくる時はこの時点でボタンの位置はドラッグする位置で自由に決められるのですが、UWPではそれはできません（幅や高さ等はいじれますけどね）。
・位置を変更するにはxamlを編集する必要があります。これは次回の投稿で。
![1-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/7717019c-744d-346c-f510-f5c884dbd9f0.png)

さて、この時点で画面真ん中下のxamlの編集画面にて以下のコードが追加されています。

```MainPage.xaml:title
        <Button x:Name="button" Content="Button" Click="button_Click"/>
        <Button x:Name="button1" Content="Button" Click="button1_Click"/>
        <TextBlock x:Name="textBlock" Text="TextBlock" TextWrapping="Wrap"/>
```
・x:Name=""で囲われた名前を使用してそのボタンや、テキストブロックにアクセスします。
・MainPage.cppではbuttonで追加した左のボタン、同様にtextBlockで追加したテキストブロックにアクセルできます。
・次回はこれをドラッグアンドドロップではなく書いて追加します。
<br>

##2-3.ハンドラの追加
・ボタンを追加したので、MFCでいうイベントハンドラ（クリックしたよ）を追加します。
・追加したボタンを選択して、画面左上の「プロパティー」の稲妻っぽいアイコンをクリック（下のアイコン）。
　　　![1-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/bd5fc621-77e7-48cd-ddbe-389f8931caeb.png)

・「Click」のエディットボックスでダブルクリックすれば、buttonのクリックしたときのイベントハンドラMainPage.cppに追加されます。
・buttonとbutton1の両方にプロパティを追加してください。
![1-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/64b45352-f00b-8969-4e9c-0cc2ee41dca5.png)

##2-4.イベントハンドラの記述
・最初は以下のコードです。

```MainPage.cpp:title
#include "pch.h"
#include "MainPage.h"
#include "MainPage.g.cpp"


using namespace winrt;
using namespace Windows::UI::Xaml;

namespace winrt::hello_world::implementation
{
    MainPage::MainPage()
    {
        InitializeComponent();
    }

    int32_t MainPage::MyProperty()
    {
        throw hresult_not_implemented();
    }

    void MainPage::MyProperty(int32_t /* value */)
    {
        throw hresult_not_implemented();
    }

    void MainPage::ClickHandler(IInspectable const&, RoutedEventArgs const&)
    {
        myButton().Content(box_value(L"Clicked"));
    }
}


void winrt::hello_world::implementation::MainPage::button_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
}


void winrt::hello_world::implementation::MainPage::button1_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
}

```

<br>

・今回はダイアログとテキストブロックでHello Worldを表示します。
・ダイアログ用のヘッダをインクルードして、winrt::hello_world::implementation::MainPage::button_Clickへそれぞれをクリックしたときの動作を記述します。

```MainPage.cpp:title
#include "pch.h"
#include "MainPage.h"
#include "MainPage.g.cpp"

//追加
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.UI.Popups.h>

using namespace winrt;
using namespace Windows::UI::Xaml;
namespace winrt::hello_world::implementation
{
    MainPage::MainPage()
    {
        InitializeComponent();
    }

    int32_t MainPage::MyProperty()
    {
        throw hresult_not_implemented();
    }

    void MainPage::MyProperty(int32_t /* value */)
    {
        throw hresult_not_implemented();
    }

    void MainPage::ClickHandler(IInspectable const&, RoutedEventArgs const&)
    {
        myButton().Content(box_value(L"Clicked"));
    }
}


void winrt::hello_world::implementation::MainPage::button_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    //追加
    winrt::Windows::UI::Xaml::Controls::ContentDialog dialog;
    dialog.Title(box_value(L"hello"));
    dialog.Content(box_value(L"Hello World"));
    dialog.CloseButtonText(L"OK");
    dialog.PrimaryButtonText(L"OKOK");
    dialog.ShowAsync();

    Windows::UI::Popups::MessageDialog msg{ L"Hello World",L"Hello World" };
    msg.ShowAsync();
}


void winrt::hello_world::implementation::MainPage::button1_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e)
{
    //追加
    textBlock().Text(L"Hello World");

}

```
<br>
#3リビルド
・追加して、リビルド→デバックの開始でデバッグが始まるはず。
・私の環境だけかもしれませんが、C++/WinRTでどこかを書き換えた場合、「ビルド」で変更箇所のみビルドしても（App.hやApp.cppを大幅に書き換えるために？）エラーが発生したりするので、「リビルド」を選んですべてコンパイル/リンクをするようにしています。そのためビルド時間が長くてorz
・ここまでなら、MFCとそうはかわりませんね。

###3-1. 表示しているダイアログについて
ダイアログは「MessageDialog」と「ContentDialog」の2種類表示させています。MessageDialogはMessageBoxと似た方でContentDialogは新しめの方です。それぞれShowAsync()と非同期で表示させています。MFCのMessageBoxやAfxMessageBoxを表示させたときのように、そこで処理が停止しないのでダイアログが二個出てきます。同期非同期についてはそこまで勉強したらやります・・・

###3-1-1. MessageDialogについて
・MessageDialogは[「MessageDialog Class」](https://docs.microsoft.com/en-us/uwp/api/windows.ui.popups.messagedialog?view=winrt-19041)を見るとボタンを色々追加できそうですが、今回は追加無しで。

###3-1-2. ContentDialogについて
・ContentDialogはCloseButtonText()とPrimaryButtonText()を追加しました。CloseBottonText()の追加を忘れると閉じられなくなるので気をつけてください。[「ContentDialog Class」](https://docs.microsoft.com/ja-jp/uwp/api/windows.ui.xaml.controls.contentdialog?view=winrt-19041)をみるとC++/WinRTを指定していてもC#のサンプルばかりのページが表示されます。MSのC++/WinRTへのやる気が非常に良く伝わってきますね。
・SecondaryButtonText()までの3個までのボタンなら簡単に追加できそうです。tertiaryが無かったので多分。

###3-2. TextBlockについて
・StaticTextと同じようなものですね。StaticTextの場合はSetWindowTextで内容を変更できましたが、こちらではText()を使用します。

<br>
githubで公開したのでそれも。
[「yoshiyoshi-git/hello_world」](https://github.com/yoshiyoshi-git/hello_world)


#4参考にさせていただいたサイト
以下を参考にさせていただきました。ありがとうございます。
[C++/WinRTの始め方](https://qiita.com/yottui/items/390bf7582fa1abb42766)
[C++/WinRT](https://docs.microsoft.com/ja-jp/windows/uwp/cpp-and-winrt-apis/)


<br><br>
さて、次は[「Xamlの編集」](https://qiita.com/lilac0011/items/108b4c078a8806955a7b)をやります。

[もくじへ](https://qiita.com/lilac0011/items/f53f7401ea7da31e3a0b)