かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

ネイティブの C++ から UWP の API を呼ぶ (C++/WinRT を使って)

C++/WinRT っていうのが追加されてたんですね。知らなかったのですが。

docs.microsoft.com

これを使うと C++/CX とかみたいな魔改造言語じゃなくて C++ で UWP の開発が出来ますし、UWP の API を呼ぶのもお手軽です。

ちょっとやってみましょう。

環境設定

厳密にこれだけが必要という最小要件はちょっと確認できてないのですが私は以下の環境です。

  • Windows 10 October 2018 Update
  • Visual Studio 2017 15.8 (UWP アプリの開発と C++ 開発あたりのチェックが入っていて Windows 10 SDK 全部入り) + C++/WinRT 拡張

多分、C++ 開発機能と最新の Windows 10 SDK と UWP 開発があれば行けると思います。

やってみよう

以下のプロジェクトを作成します。

  • Windows アプリケーション パッケージングプロジェクト
  • MFC アプリケーション(デフォルトで作成)

Windows アプリケーションパッケージングプロジェクトの下にアプリケーションというノードがあるので、そこに MFC アプリを追加しましょう。

MFC アプリケーションの設定をします。プロパティの中の C/C++ -> Language -> C++ Language Standard の値を ISO C++ 17 Standard (/std:c++17) にします。同じページの Conformance modeNo にします。(上から二番目)

f:id:okazuki:20181016144145p:plain

書いてて気づいたのですが諸事情で英語にしてましたが…、気にせずいきましょう。

続いて Linker -> Input -> Additional Dependencieswindowsapp.lib を追加します。

あとは stdafx.h あたりによく使う以下のヘッダーを追加して

#include "winrt/base.h"
#include <winrt/Windows.Foundation.h>

そして、適当なところで UWP の API を呼ぶだけです。

// 上らへんで
#include <winrt/Windows.UI.Notifications.h>
#include <winrt/Windows.Data.Xml.Dom.h>
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::UI::Notifications;

// 処理の中身
auto notificationManager = ToastNotificationManager::GetDefault();
auto toastXml = ToastNotificationManager::GetTemplateContent(ToastTemplateType::ToastText01);
auto textNode = toastXml.GetElementsByTagName(L"text").Item(0);
textNode.AppendChild(toastXml.CreateTextNode(L"Hello from Native dll function!"));
auto toast = ToastNotification(toastXml);
toast.ExpirationTime(winrt::clock::now() + std::chrono::hours() * 2);
notificationManager.CreateToastNotifier().Show(toast);

Windows アプリケーションパッケージングプロジェクトをスタートアッププロジェクトにして実行するとトーストが出ると思います。 凄い!ちゃんと C++ だ!!