かずきのBlog@hatena

日本マイクロソフトに勤めています。このブログは個人ブログなので、ここに書いている内容は個人的な意見で会社の公式見解ではない点にご注意ください。好きなものは XAML と C# 。苦手なものは型の無い言語です。

ネイティブの 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++ だ!!