Von Bedeutung
C++/WinRT 開発用に Visual Studio をセットアップする方法 (C++/WinRT Visual Studio 拡張機能 (VSIX) と NuGet パッケージ (プロジェクト テンプレートとビルド サポートを提供) のインストールと使用など) については、Visual Studio での C++/WinRTのサポート
C++/WinRT の使用を高速化するために、このトピックでは、新しい Windows コンソール アプリケーション (C++/WinRT) プロジェクトに基づく簡単なコード例について説明します。 このトピックでは、 Windows デスクトップ アプリケーション プロジェクトに C++/WinRT サポートを追加する方法についても説明します。
注
最新バージョンの Visual Studio と Windows SDK を使用して開発することをお勧めしますが、Visual Studio 2017 (バージョン 15.8.0 以降) を使用し、Windows SDK バージョン 10.0.17134.0 (Windows 10 バージョン 1803) を対象としている場合、新しく作成された C++/WinRT プロジェクトがコンパイルに失敗する可能性があり、エラー "エラー C3861: 'from_abi': 識別子が見つかりません" や base.hから発生する他のエラーが生成されることがあります。 解決策は、新しい (より準拠した) バージョンの Windows SDK をターゲットにするか、プロジェクト プロパティ C/C++>言語>準拠モードを設定することです。 (/permissive- がプロジェクト プロパティに表示されない場合 、C/C++>言語>コマンド ライン [追加オプション]の下。 次に削除します)。
C++/WinRT クイック スタートガイド
新しい Windows コンソール アプリケーション (C++/WinRT) プロジェクトを 作成します。
pch.h
とmain.cpp
を次のように編集します。
// pch.h
#pragma once
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Web.Syndication.h>
#include <iostream>
// main.cpp
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Web::Syndication;
int main()
{
winrt::init_apartment();
Uri rssFeedUri{ L"https://blogs.windows.com/feed" };
SyndicationClient syndicationClient;
syndicationClient.SetRequestHeader(L"User-Agent", L"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
SyndicationFeed syndicationFeed = syndicationClient.RetrieveFeedAsync(rssFeedUri).get();
for (const SyndicationItem syndicationItem : syndicationFeed.Items())
{
winrt::hstring titleAsHstring = syndicationItem.Title().Text();
// A workaround to remove the trademark symbol from the title string, because it causes issues in this case.
std::wstring titleAsStdWstring{ titleAsHstring.c_str() };
titleAsStdWstring.erase(remove(titleAsStdWstring.begin(), titleAsStdWstring.end(), L'™'), titleAsStdWstring.end());
titleAsHstring = titleAsStdWstring;
std::wcout << titleAsHstring.c_str() << std::endl;
}
}
上記の短いコード例を 1 つずつ見て、各部分で何が起こっているかを説明しましょう。
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Web.Syndication.h>
既定のプロジェクト設定では、含まれるヘッダーは、フォルダー %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt
内の Windows SDK から取得されます。 Visual Studio では、そのパスが IncludePath マクロに含まれます 。 ただし、( cppwinrt.exe
ツールを使用して) プロジェクトがプロジェクトの $(GeneratedFilesDir) フォルダーに同じヘッダーを生成するため、Windows SDK には厳密な依存関係はありません。 他の場所に見つからない場合、またはプロジェクトの設定を変更した場合は、そのフォルダーから読み込まれます。
ヘッダーには、C++/WinRT に投影された Windows API が含まれています。 つまり、Windows の種類ごとに、C++/WinRT は C++に対応する同等の ( 投影型と呼ばれます) を定義します。 投影型の完全修飾名は Windows 型と同じですが、C++ winrt 名前空間に配置されます。 これらのインクルードをプリコンパイル済みヘッダーに配置すると、増分ビルド時間が短縮されます。
Von Bedeutung
Windows 名前空間の型を使用する場合は、前に示すように、対応する C++/WinRT Windows 名前空間ヘッダー ファイルを #include
する必要があります。
対応するヘッダーは、型の名前空間と同じ名前を持つヘッダーです。 たとえば、 Windows::Foundation::Collections::P ropertySet ランタイム クラスに C++/WinRT プロジェクションを使用するには、 winrt/Windows.Foundation.Collections.h
ヘッダーを含めます。
C++/WinRT プロジェクション ヘッダーには、関連する名前空間ヘッダー ファイルが自動的に含まれるのが一般的です。 たとえば、 winrt/Windows.Foundation.Collections.h
には winrt/Windows.Foundation.h
が含まれます。 ただし、時間の経過と同時に変化する実装の詳細であるため、この動作に依存しないでください。 必要なヘッダーを明示的に含める必要があります。
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Web::Syndication;
using namespace
ディレクティブは省略可能ですが、便利です。 このようなディレクティブに対して上に示したパターン ( winrt 名前空間内の何かの非修飾名参照を許可する) は、新しいプロジェクトを開始するときに適しており、そのプロジェクト内で使用している唯一の言語プロジェクションは C++/WinRT です。 次に、C++/WinRT コードを C++/CX や SDK アプリケーション バイナリ インターフェイス (ABI) コード
winrt::init_apartment();
winrt::init_apartment の呼び出しは、Windows ランタイムでスレッドを初期化します。既定では、マルチスレッド アパートメント内。 呼び出しによって COM も初期化されます。
Uri rssFeedUri{ L"https://blogs.windows.com/feed" };
SyndicationClient syndicationClient;
2 つのオブジェクトをスタック割り当てます。これらは、Windows ブログの URI とシンジケーション クライアントを表します。 単純なワイド文字列リテラルを使用して URI を構築します (文字列の操作方法の詳細については、 C++/WinRT での文字列処理 を参照してください)。
SyndicationFeed syndicationFeed = syndicationClient.RetrieveFeedAsync(rssFeedUri).get();
SyndicationClient::RetrieveFeedAsync は、非同期 Windows ランタイム関数の例です。 このコード例では、RetrieveFeedAsyncから非同期操作オブジェクトを受け取り、そのオブジェクトで get を呼び出すことで呼び出し元のスレッドをブロックし、結果(この場合はシンジケーションフィード)を待機します。 コンカレンシーの詳細と非ブロッキング手法については、「 C++/WinRT を使用したコンカレンシーと非同期操作」を参照してください。
for (const SyndicationItem syndicationItem : syndicationFeed.Items()) { ... }
SyndicationFeed.Items は、begin 関数と end 関数(およびそれらの定数、逆順、定数逆順のバリアント)から返されるイテレータによって定義される範囲です。 このため、範囲ベースの ステートメントまたは for
テンプレート関数を使用してアイテムを列挙できます。 このような Windows ランタイム コレクションを反復処理するときは常に、#include <winrt/Windows.Foundation.Collections.h>
する必要があります。
winrt::hstring titleAsHstring = syndicationItem.Title().Text();
// Omitted: there's a little bit of extra work here to remove the trademark symbol from the title text.
std::wcout << titleAsHstring.c_str() << std::endl;
winrt::hstring オブジェクトとしてフィードのタイトル テキストを取得します (C++/WinRT での文字列処理の詳細)。 その後、c++ 標準ライブラリ文字列で使用されるパターンを反映する c_str 関数を介して hstring が出力されます。
ご覧のように、C++/WinRT では、 syndicationItem.Title().Text()
などの最新のクラスに似た C++ 式が推奨されています。 これは、従来の COM プログラミングとは異なり、よりクリーンなプログラミング スタイルです。 COM を直接初期化する必要も、COM ポインターを操作する必要もありません。
HRESULT リターン コードを処理する必要もありません。 C++/WinRT は、エラー HRESULT を、自然でモダンなプログラミング スタイルの winrt::hresult-error などの例外に変換します。 エラー処理とコード例の詳細については、「 C++/WinRT でのエラー処理」を参照してください。
Windows デスクトップ アプリケーション プロジェクトを変更して C++/WinRT サポートを追加する
一部のデスクトップ プロジェクト (Visual Studio の WinUI 3 テンプレートなど) には、C++/WinRT サポートが組み込まれています。
ただし、このセクションでは、Windows デスクトップ アプリケーション プロジェクトに C++/WinRT サポートを追加する方法について説明します。 既存の Windows デスクトップ アプリケーション プロジェクトがない場合は、最初に作成することで、次の手順に従うことができます。 たとえば、Visual Studio を開き、 Visual C++>Windows Desktop>Windows デスクトップ アプリケーション プロジェクトを 作成します。
必要に応じて、 C++/WinRT Visual Studio 拡張機能 (VSIX) と NuGet パッケージをインストールできます。 詳細については、 Visual Studio での C++/WinRT のサポートに関するページを参照してください。
プロジェクトのプロパティを設定する
プロジェクト プロパティ [全般>Windows SDK バージョン] に移動し、[ すべての構成] と [ すべてのプラットフォーム] を選択します。 Windows SDK バージョンが 10.0.17134.0 (Windows 10 バージョン 1803) 以上に設定されていることを確認します。
新しいプロジェクトがコンパイルされない理由の影響を受けないことを確認します。
C++/WinRT では C++17 標準の機能が使用されるため、プロジェクト プロパティ C/C++>Language>C++ Language Standard を ISO C++17 Standard (/std:c++17) に設定します。
プリコンパイル済みヘッダー
既定のプロジェクト テンプレートでは、 framework.h
または stdafx.h
のいずれかの名前のプリコンパイル済みヘッダーが自動的に作成されます。 名前を pch.h
に変更します。
stdafx.cpp
ファイルがある場合は、その名前を pch.cpp
に変更します。 プリコンパイル済みヘッダー
すべての #include "framework.h"
(または #include "stdafx.h"
) を検索して #include "pch.h"
に置き換えます。
pch.h
には、winrt/base.h
を含めます。
// pch.h
...
#include <winrt/base.h>
リンク
C++/WinRT 言語プロジェクションは、 WindowsApp.lib アンブレラ ライブラリへのリンクを必要とする特定の Windows ランタイムフリー (メンバー以外) 関数とエントリ ポイントに依存します。 このセクションでは、リンカーを満たす 3 つの方法について説明します。
最初のオプションは、すべての C++/WinRT MSBuild プロパティとターゲットを Visual Studio プロジェクトに追加することです。 これを行うには、 Microsoft.Windows.CppWinRT NuGet パッケージ をプロジェクトにインストールします。 Visual Studio でプロジェクト
プロジェクト リンク設定を使用して、 WindowsApp.lib
を明示的にリンクすることもできます。 または、次のようにソース コード ( pch.h
など) で行うことができます。
#pragma comment(lib, "windowsapp")
C++/WinRT コードをコンパイルしてリンクし、プロジェクトに追加できるようになりました (たとえば、上記の A C++/WinRT クイック スタート セクションに示すようなコード)。
C++/WinRT の 3 つの主なシナリオ
C++/WinRT を使用して理解し、このドキュメントの残りの部分で作業すると、次のセクションで説明するように、主に 3 つのシナリオがあることに気付くでしょう。
Windows API と型の使用
つまり、を使用して
Windows API や型の定義
つまり、 API と型を生成
C++/WinRT を使用した API の作成は、API を実装する前に IDL を使用して API の形状を定義する必要があるため、それらを使用するよりも少し複雑です。 XAML コントロールでこれを行うためのウォークスルーがあります。C++/WinRT プロパティにバインドします。
XAML アプリケーション
このシナリオでは、XAML UI フレームワークでアプリケーションとコントロールを構築します。 XAML アプリケーションでの作業は、使用と作成の組み合わせに相当します。 ただし、XAML は現在 Windows の主要な UI フレームワークであり、Windows ランタイムに対するその影響はそれに比例するため、独自のカテゴリのシナリオに値します。
XAML はリフレクションを提供するプログラミング言語に最適です。 C++/WinRT では、XAML フレームワークと相互運用するために、少し余分な作業を行う必要がある場合があります。 これらのケースはすべてドキュメントで説明されています。 開始するのに適した場所は、XAML コントロール
C++/WinRT で記述されたサンプル アプリ
C++/WinRT サンプル アプリはどこにありますか? を参照してください。
重要な API
- SyndicationClient::RetrieveFeedAsync メソッド
- SyndicationFeed.Items プロパティ
- winrt::hstring 構造体
- winrt::hresult-error 構造体
関連トピック
- C++/CX
- C++/WinRT でのエラー処理
- C++/WinRT と C++/CX 間の相互運用
- C++/WinRT と ABI の間の相互運用
- C++/CX から C++/WinRT に移動する
- C++/WinRT での文字列処理