UWP開発したこともC言語系触ったことないけど3時間で作れるようになってしまった世界。

#はじめに
windows10にいつの間にかある**切り取り＆スケッチ**
皆さんは使ったことはありますか？
（win7とかだとSnipping toolしかありませんでしたが）
このツール、画面の切り取りしかだめだと思っていたら、
実はファイルも開けるんですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498105/7a32bf53-7976-9c37-cb1e-4322f3264f4a.png)
個人的にはペイント3Dとかだと消しゴムツールで画像を消してしまうので、
使いにくいと思ってたのですが、なんとこいつは、
ストローク消しゴム付きでしかも読み込んだ画像は消さないという、
まさに求めている機能が全部入っているのです。
さてこのアプリ一つ、致命的問題がありまして、
**画像をアプリケーションのアイコンにD&Dしても反応しないんです。**
意味がわからないと思うんですが、なんか画像をD&Dしても開きません。
普段使っているペイントソフトは大半開いてくれるのですが、こいつは駄目です。
しかしどうしてもD&DしたいのでBATファイルを作ってみるも、
そもそもEXEファイルを選択してもアクセスは拒否され、
URI（ms-screensketch:）を使ってもそもそも画像パスを入れても使えません。

そしてたどり着いた先は.....
https://docs.microsoft.com/ja-jp/windows/uwp/launch-resume/launch-screen-snipping
もう意味がわかりません。
**sharedAccessToken**って何？
なんで起動のためにC#がいるの？？
となりました。

そしてsharedAccessTokenを調べていくうちにあることに気づきました。
**これUWPからしか使えないんじゃね**
（多分そんなことはないと思いますがこのときの私はこれしかわかりませんでした。）

結果UWPを作る羽目になりました。
ても作り方は知りません。
何ならC#すら使えません。
やばいですが、できる範囲でがんばります。
#開発環境
OS：windows10
いつもの奴。今回の主役
VS studio　2019
初めて使う。パソコンもらったときに入ってた。
Clip studio
アイコン作成用。話には出てこない。
#準備運動
VSCodeはよく使ってますが、VS　studioは初起動です。
起動するとなんか出てきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498105/4ea41936-59bc-382c-cd99-86b64f38cfad.png)
今回は新しいプロジェクトの作成から、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498105/09492fa6-ff1a-f263-63d8-d094e6861124.png)
黄色いやつを選びます。
（あれ、よく見たらVBでもつくれたんかーい。VBAはやってたから感覚同じだったかもしれない）
その後セットアップを順調に進み、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498105/b212dad1-9a8b-2ba9-3a0f-1a417e8b9620.png)
こんなのが出ます。
#いざ開発
そしたらMainPage.xamlをクリックしデザインを押すとなんか白いスクリーンが出てきます。
そこにツールボックスからボタンとかを設置して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498105/e82d4b8c-1d51-d4e7-7f1b-b4b53202fc1d.png)
ボタンをダブルクリックすると

```c#
private async void Button_Click(object sender, RoutedEventArgs e)
```

と出てきたのでこの中にクリック時のプログラムを書いていきました。

今回はファイル選択を作るために、
https://docs.microsoft.com/ja-jp/windows/uwp/files/quickstart-using-file-and-folder-pickers
を参考にこんな感じに書きました

```c#

            var picker = new Windows.Storage.Pickers.FileOpenPicker();
            picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
            picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Desktop;
            picker.FileTypeFilter.Add(".jpg");
            picker.FileTypeFilter.Add(".jpeg");
            picker.FileTypeFilter.Add(".png");

            var files = await picker.PickMultipleFilesAsync();
            if (files.Count > 0)
            {
                foreach (Windows.Storage.StorageFile file in files)
                {
                    // Application now has read/write access to the picked file
                    this.textBlock.Text = "Picked photo: " + file.Name;
                    String sharingToken = Windows.ApplicationModel.DataTransfer.SharedStorageAccessManager.AddFile(file);
                    Uri driveTo = new Uri("ms-screensketch:edit?isTemporary=false&sharedAccessToken=" + sharingToken);
                    var launch = await Windows.System.Launcher.LaunchUriAsync(driveTo);
                }
            }
            else {
                this.textBlock.Text = "Operation cancelled.";
            }

```

このコードの真ん中ぐらいにあるのが今回の主役で、
どうやら`Windows.Storage.StorageFile`は`filepicker`で取得できるのと同じようなのでそのまま、
sharedAccessTokenを取得するコードである、

```c#
String sharingToken = SharedStorageAccessManager.AddFile(file);
```

が使えました。あとはURIを生成して、

```c#
var launch = await Windows.System.Launcher.LaunchUriAsync(driveTo);
```

で実行させるだけです。

これで機能的には出来上がったのですが、
D&Dもしたいので
https://docs.microsoft.com/ja-jp/windows/uwp/design/input/drag-and-drop
を参考に、MainPage.xaml.csに

```c#
        private void Grid_DragOver(object sender, DragEventArgs e)
        {
            e.AcceptedOperation = DataPackageOperation.Copy;
        }
        private async void Grid_Drop(object sender, DragEventArgs e)
        {
            if (e.DataView.Contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.StorageItems))
            {
                var items = await e.DataView.GetStorageItemsAsync();
                foreach (Windows.Storage.StorageFile file in items)
                {
                    String sharingToken = Windows.ApplicationModel.DataTransfer.SharedStorageAccessManager.AddFile(file);
                    Uri driveTo = new Uri("ms-screensketch:edit?isTemporary=false&sharedAccessToken=" + sharingToken);
                    var launch = await Windows.System.Launcher.LaunchUriAsync(driveTo);
                }
            }
        }
```
を書き足しました。
ただ書き足す場所がわからなかったのでとりあえず
`    public sealed partial class MainPage : Page`
に書き足しておきました。

あとはAssetsフォルダ内の画像をロゴマークに塗り替えて、ビルドすれば完成です。
ビルド時の注意としては、
証明書を用意しておかないとインストールできないので自己証明書でもいいので作っておきます。
あとはアプリ名（Universal Windows）を右クリックし、
公開＞アプリパッケージの作成を押して、指示に従ってビルドするだけです。
お疲れさまでした。

#まとめ
なんか難しそうなイメージがあったWindowsアプリの作成も意外と簡単にできて驚きました。
ただ一つ心残りがあるとすれば、初回起動時にWindowサイズが指定したのと違うってことぐらいですかね。
これを機にAndroidアプリも作ってみたいと思いました。
（まあ多分こんな感じで唐突に必要になるかもだけど。）