MFCでもWinRTその2.　MFCアプリからWinRT APIの利用（ダイアログからOCRの利用）

# 1. 今回やること
・MessageDialogを表示できるようになったので、その他のWinRT APIの使い方をやります。
・コントロールを表示させないのでダイアログベースのMFCアプリからWinRTのOCR機能を利用するアプリケーションを作成します。
・OCRについて詳しいことは以前やった[こちら](https://qiita.com/lilac0011/items/a8b5d8f0786553884651)を参照してください。
・MSの[C++/WinRT の使用を開始する](https://docs.microsoft.com/ja-jp/windows/uwp/cpp-and-winrt-apis/get-started)を前回の[その1](https://qiita.com/lilac0011/items/3c4b1322435092f32c40)に追加して、その他のAPIも使えるようにしていきます。（OCR機能だけならヘッダをインクルードするだけでも利用可能なのですが、それは内緒にしておいてください）。

・以下のことをさらに追加して行きます
　①WindowsApp.libのリンクと必要なヘッダのインクルード
　②winrt::init_apartmentによるWinRTの初期化
　③コードの追加


# 2. プロジェクトの作成
・前回と同じようにMFCアプリのダイアログベースでプロジェクトを作成します。名前は「MFCWinRTOCR」で。
・C++言語標準を「ISO C++17」へ変更し、コマンドラインへ「/await」を追加します。
・pch.hで「TRY」と「GetCurrentTime」を#undefします。ここまでは前回と同じですね。


# 3. WindowsApp.libのリンクと必要なヘッダのインクルード
・pch.hへ#pragma comment(lib, "windowsapp")を追加してwindowsapp.libへのリンクを追加します。
・さらに必要なヘッダを#includeします。どんなヘッダが必要かは[前回](https://qiita.com/lilac0011/items/3c4b1322435092f32c40)と[OCRを利用したとき](https://qiita.com/lilac0011/items/a8b5d8f0786553884651)を参照してください。
・というわけでpch.hは以下のようになります。

```CPP:pch.h（変更後）

#ifndef PCH_H
#define PCH_H

// プリコンパイルするヘッダーをここに追加します
#include "framework.h"

#undef GetCurrentTime
#undef TRY

#pragma comment(lib, "windowsapp")

#include <winrt/base.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.UI.Popups.h>

#include <hstring.h>

#include <winrt/Windows.Storage.Pickers.h>
#include <winrt/Windows.Graphics.Imaging.h>
#include <winrt/Windows.Media.Ocr.h>
#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.Storage.h>

#endif //PCH_H

```

# 4. ②winrt::init_apartmentによるWinRTの初期化
・MFCWinRTOCR.cppを開いて、InitInstance()へwinrt::init_apartment(winrt::apartment_type::single_threaded);を追加します。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/1664424e-c110-3281-1712-2937b82e4f93.png)
・ここまで来たらあとはコードを追加するだけです。

# 5. コードの追加
・Buttonを一個追加して、イベントハンドラも追加します。
・前回と同じように、IAsyncAction型のButton1Async()を作成し、イベントハンドラから呼び出すようにします。
・ファイルピッカーでファイルを選択して、ファイルを開いて、OCR機能を使用して、ダイアログへ保存する、と言う感じにしてみたのでMFCWinRTOCR.Dlg.cppは以下のように変更しています。

```CPP:MFCWinRTOCR.Dlg.cpp（変更後）

//前略
void CMFCWinRTOCRDlg::OnBnClickedButton1()
{
	Button1Async();
}

winrt::Windows::Foundation::IAsyncAction CMFCWinRTOCRDlg::Button1Async()
{

	//ファイルピッカーでファイルを選んで
	auto picker = winrt::Windows::Storage::Pickers::FileOpenPicker();
	picker.as<IInitializeWithWindow>()->Initialize(this->m_hWnd);
	picker.FileTypeFilter().Append(L".jpg");
	picker.FileTypeFilter().Append(L".png");
	auto picfile = co_await picker.PickSingleFileAsync();

	//ファイルを開いて
	auto picstream = co_await picfile.OpenAsync(winrt::Windows::Storage::FileAccessMode::Read);
	auto picdecoder = co_await winrt::Windows::Graphics::Imaging::BitmapDecoder::CreateAsync(picstream);
	auto showpic = co_await picdecoder.GetSoftwareBitmapAsync(winrt::Windows::Graphics::Imaging::BitmapPixelFormat::Bgra8, winrt::Windows::Graphics::Imaging::BitmapAlphaMode::Premultiplied);

	//OCR機能を使用する。
	winrt::Windows::Media::Ocr::OcrEngine ocr = nullptr;
	ocr = winrt::Windows::Media::Ocr::OcrEngine::TryCreateFromUserProfileLanguages();
	auto result = co_await ocr.RecognizeAsync(showpic);

	//結果の表示
	winrt::hstring restext = result.Text();
	auto msgdlg = winrt::Windows::UI::Popups::MessageDialog(L"Result");
	msgdlg.as<IInitializeWithWindow>()->Initialize(this->m_hWnd);
	msgdlg.Content(restext);
	auto dlgres = co_await msgdlg.ShowAsync();
}
```

・こんな画像を読み込んで、こんな結果でした。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/c15f5777-00db-008a-613d-07c7283fa836.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131051/fddf2b4a-db51-1750-5980-678880d77aea.png)

[github](https://github.com/yoshiyoshi-git/MFCWinRTOCR)はこちら

さて、これでWinRTの機能をMFCアプリから使用できるようになりました。
今回はOCR機能だけですが、その他の機能も利用可能なはずです。
しかし、コントロールの表示ができていない・・・

というわけで、[次こそは本当にボタンを表示](https://qiita.com/lilac0011/items/f05c81ba5a6a4076b5be)させます。


[目次](https://qiita.com/lilac0011/items/f53f7401ea7da31e3a0b)へ