次の方法で共有


C++/WinRT を始める

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.hmain.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) コード と組み合わせる場合 (これらのモデルのいずれかまたは両方から移植または相互運用する場合)、以下のトピックを参照してください: C++/WinRT と C++/CX間の相互運用 、C++/CXから C++/WinRT への移行 、および C++/WinRT と 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 StandardISO C++17 Standard (/std:c++17) に設定します。

プリコンパイル済みヘッダー

既定のプロジェクト テンプレートでは、 framework.hまたは stdafx.hのいずれかの名前のプリコンパイル済みヘッダーが自動的に作成されます。 名前を pch.h に変更します。 stdafx.cpp ファイルがある場合は、その名前を pch.cpp に変更します。 プリコンパイル済みヘッダープリコンパイル済みヘッダー C/C++ プロジェクト プロパティを Create (/Yc)に設定し、プリコンパイル済みヘッダー ファイル を pch.hします。

すべての #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 でプロジェクト 開き、[プロジェクト][NuGet パッケージの管理]をクリックします。[参照]をし、検索ボックス Microsoft.Windows.CppWinRT を入力または貼り付け、検索結果の項目を選択して、[ のインストール] をクリックして、そのプロジェクトのパッケージをインストール します。

プロジェクト リンク設定を使用して、 WindowsApp.libを明示的にリンクすることもできます。 または、次のようにソース コード ( pch.hなど) で行うことができます。

#pragma comment(lib, "windowsapp")

C++/WinRT コードをコンパイルしてリンクし、プロジェクトに追加できるようになりました (たとえば、上記の A C++/WinRT クイック スタート セクションに示すようなコード)。

C++/WinRT の 3 つの主なシナリオ

C++/WinRT を使用して理解し、このドキュメントの残りの部分で作業すると、次のセクションで説明するように、主に 3 つのシナリオがあることに気付くでしょう。

Windows API と型の使用

つまり、を使用して するか、 API を呼び出して するかです。 たとえば、Bluetoothを使用して通信するための API 呼び出しを行います。ビデオをストリーミングして表示する。Windows シェルと統合する場合。などなど。 C++/WinRT は、このカテゴリのシナリオを完全かつ妥協なくサポートします。 詳細については、「C++/WinRT での API の使用」を参照してください。

Windows API や型の定義

つまり、 API と型を生成 。 たとえば、上記のセクションで説明した API の種類を生成します。またはグラフィックス API。ストレージおよびファイル システム API。ネットワーク API など。 詳細については、「C++/WinRTを使用した 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 を使用した XAML カスタム(テンプレート化)コントロール です。

C++/WinRT で記述されたサンプル アプリ

C++/WinRT サンプル アプリはどこにありますか? を参照してください。

重要な API