C++/WinRTでUWPその6　図形の描画（Win2Dを使用して）

#1. 今回やること
・Win2Dを使用して、図形を描画します。やることは以下の4点です。
①NugetでWin2Dをインストールする。
②追加のインクルードディレクトリにWin2Dのインクルードフォルダを追加
③MainPage.hでMicrosoft.Graphics.Canvas.UI.Xaml.hのインクルード
④描画処理の記述

・基本は[Win2D documentation](https://microsoft.github.io/Win2D/html/Introduction.htm)の内容です。


#2. 新しいプロジェクトの作成
・今回も新しいプロジェクトの作成→Blank App(C++/WinRT)から新しいプロジェクトを作成しましょう。名前は「win2d_1」です。
・作成したら、MainPage.xamlから余計なmyButtonを削除しましょう。MainPage.hとMainPage.cppからもイベントハンドラーを削除するのをお忘れ無く。
・今回はどうせ使わないMainPage.idlのMyPropertyも削除です。これもMainPage.hとMainPage.cppからも削除して下さい。
・削除した後はそれぞれ以下のようになります。雛型ですね。

```xml:MainPage.xaml（変更後）
<Page
    x:Class="win2d_1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:win2d_1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

</Page>
```

```xml:MainPage.idl（変更後）
namespace win2d_1
{
    [default_interface]
    runtimeclass MainPage : Windows.UI.Xaml.Controls.Page
    {
        MainPage();
    }
}
```

```C++:MainPage.h（変更後）
#pragma once

#include "MainPage.g.h"

namespace winrt::win2d_1::implementation
{
    struct MainPage : MainPageT<MainPage>
    {
        MainPage();
    };
}

namespace winrt::win2d_1::factory_implementation
{
    struct MainPage : MainPageT<MainPage, implementation::MainPage>
    {
    };
}
```

```C++:MainPage.cpp（変更後）
#include "pch.h"
#include "MainPage.h"
#include "MainPage.g.cpp"

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

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

```

##2-1. Win2Dのインストール
・ツール→NuGetパッケージマネージャー→ソリューションのNuGetパッケージ管理を選び、「Win2D」を検索して「Win2D.uwp」をインストールします（選択して、チェックして、インストールをクリックするだけ）。
![5-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/d1d82a58-37de-d127-3def-ec5a37d47029.png)
![5-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/2617a71e-f381-565a-77ea-2460e59e05d6.png)

・念のため、ここで一度リビルドします。
・「プロジェクトのフォルダ\Generated Files\winrt」に必要なヘッダーができるのでこれをインクルードします。
・今回は「F:\prg-2」フォルダに「win2d_1」プロジェクトを作成したので、「F:\prg-2\win2d_1\win2d_1\Generated Files\winrt」フォルダに「Microsoft.Graphics.Canvas.UI.Xaml.h」ができます。これをMainPage.hでインクルードすればWin2DがC++/WinRTでも使用できます。
![5-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/c22ab1dd-cf79-59da-1a5e-a1bdc6b5eaad.png)


##2-2. Microsoft.Graphics.Canvas.UI.Xaml.hのインクルード
・まずはインクルードディレクトリの追加から。この辺はMFC等と変わりません。プロジェクト→win2d_1のプロパティー→C/C++→全般→追加のインクルードディレクトリに追加するだけです。相対アドレスでインクルードしてもいけますけどね。
![5-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/5f8c2b27-95d7-6ae4-9d62-f0c80c41eebe.png)
・そこまで終了したら、MainPage.hでMicrosoft.Graphics.Canvas.UI.Xaml.hをインクルードします。pch.hでインクルードしたくなりますが、やるとエラーの嵐になるのでやめた方が良いですよ。


##2-3. MainPage.xamlの変更
・xmlnsのところにxmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"を追加してcanvasを追加します。
・その後、<canvas:CanvasControl Draw="CanvasControl_Draw" ClearColor="Aqua"></canvas:CanvasControl>をグリッドで囲んで追加して下さい。Draw=でイベントハンドラの追加になるのでダブルクリックしてイベントハンドラを追加して下さい。ClearColor="Aqua"は個人的に水色が好きなので趣味で水色背景にしているだけです・・・
![5-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/b1fad846-95f9-0ef8-6ff7-8a45bd3800e9.png)


```xml:MainPage.xaml（変更後）
<Page
    x:Class="win2d_1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:win2d_1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
    mc:Ignorable="d">
    
    <Grid>
        <canvas:CanvasControl Draw="CanvasControl_Draw" ClearColor="Aqua"></canvas:CanvasControl>
    </Grid>

</Page>
```

##2-4. MainPage.h
先ほどMicrosoft.Graphics.Canvas.UI.Xaml.hをインクルードしたので、イベントハンドラの宣言が追加されているだけです。

```C++:MainPage.h（変更後?）
#pragma once

#include "MainPage.g.h"
#include <Microsoft.Graphics.Canvas.UI.Xaml.h>

namespace winrt::win2d_1::implementation
{
    struct MainPage : MainPageT<MainPage>
    {
        MainPage();
        void CanvasControl_Draw(winrt::Microsoft::Graphics::Canvas::UI::Xaml::CanvasControl const& sender, winrt::Microsoft::Graphics::Canvas::UI::Xaml::CanvasDrawEventArgs const& args);
    };
}

namespace winrt::win2d_1::factory_implementation
{
    struct MainPage : MainPageT<MainPage, implementation::MainPage>
    {
    };
}
```

##2-5. MainPage.cpp
・CanvasControl_Drawに描画したい処理を記述します。MFCのOnDraw()と同じように書けます。ここに書けばサイズを変更しても、最小化しても大丈夫です。今回は丸と角丸四角の中にHello,Worldと書いてみました。

```C++:MainPage.cpp（変更後）
#include "pch.h"
#include "MainPage.h"
#include "MainPage.g.cpp"

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

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

void winrt::win2d_1::implementation::MainPage::CanvasControl_Draw(winrt::Microsoft::Graphics::Canvas::UI::Xaml::CanvasControl const& sender, winrt::Microsoft::Graphics::Canvas::UI::Xaml::CanvasDrawEventArgs const& args)
{
    args.DrawingSession().DrawText(L"Hello, world!", 250, 280, winrt::Windows::UI::Colors::Black());
    args.DrawingSession().DrawCircle(300, 300, 200, winrt::Windows::UI::Colors::BlueViolet(), 5);
    args.DrawingSession().FillRoundedRectangle(600, 50, 300, 200, 20, 20, winrt::Windows::UI::Colors::MediumSeaGreen());
    args.DrawingSession().DrawText(L"Hello, world!", 700, 125, winrt::Windows::UI::Colors::Aqua());
}
```

実行すると、こんな感じです。
![5-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/a0955f7b-59e0-9db6-d07b-5aba1cd85fe0.png)


・その他の描画関数等は[ここを参照](https://microsoft.github.io/Win2D/html/T_Microsoft_Graphics_Canvas_CanvasDrawingSession.htm)して下さい。
・Win2Dでは画像の表示やアルファブレンド、各種エフェクト等色々できるのでやりたい人は頑張って実装して下さい。

・[github](https://github.com/yoshiyoshi-git/win2d_1)にも置いときます。

・次は[非同期/async](https://qiita.com/lilac0011/items/54da15cc506b59e893d8)かな？現在色々試しているところなので、のんびりお待ちください。

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