C++/WinRT kullanmaya başlama

Önemli

C++/WinRT geliştirmesi için C++/WinRT Visual Studio Uzantısını (VSIX) ve NuGet paketini (birlikte proje şablonu ve derleme desteği sağlayan) yükleme ve kullanma dahil olmak üzere Visual Studio ayarlama hakkında bilgi için bkz. C++/WinRT için Visual Studio desteği.

C++/WinRT'yi kullanmaya başlamanızı sağlamak için bu konu başlığında yeni bir Windows Konsol Uygulaması (C++/WinRT) projesine dayalı basit bir kod örneği açıklanmaktadır. Bu konu başlığında, Windows Desktop uygulama projesine C++/WinRT desteğinin nasıl ekleneceği de gösterilir.

Note

Visual Studio 2017 (sürüm 15.8.0 veya üzeri) kullanıyor ve Windows SDK sürüm 10.0.17134.0'ı (Windows 10) hedefliyorsanız, Visual Studio ve Windows SDK'nın en son sürümleriyle geliştirmenizi öneririz, sürüm 1803), ardından yeni oluşturulan bir C++/WinRT projesi "hata C3861: 'from_abi': tanımlayıcı bulunamadı" hatasıyla ve base.h dosyasından kaynaklanan diğer hatalarla derlenemiyor olabilir. Çözüm, Windows SDK'sının daha sonraki (daha uyumlu) bir sürümünü hedeflemek veya C/C++>Dil>Uyumluluğu modunu ayarlamaktır: Hayır (ayrıca, proje özelliği C/C++>>Ek Seçenekler'in altında /permissive- görünüyorsa, bunu silin).

C++/WinRT için hızlı başlangıç

Yeni bir Windows Konsol Uygulaması (C++/WinRT) projesi oluşturun.

pch.h ve main.cpp öğelerini aşağıdaki gibi görünecek şekilde düzenleyin.

// 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;
    }
}

Şimdi yukarıdaki kısa kod örneğini parça parça ele alalım ve her bölümde neler olduğunu açıklayalım.

#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Web.Syndication.h>

Varsayılan proje ayarlarıyla, eklenen üst bilgiler klasörünün %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrtiçindeki Windows SDK'sından gelir. Visual Studio bu yolu IncludePath makrosunda içerir. Ancak, projeniz (araç aracılığıylacppwinrt.exe) projenizin $(GeneratedFilesDir) klasörüne aynı üst bilgileri oluşturduğundan, Windows SDK'sına kesin bir bağımlılık yoktur. Başka bir yerde bulunamazsa veya proje ayarlarınızı değiştirirseniz bu klasörden yüklenirler.

Üst bilgiler C++/WinRT'ye yansıtılan Windows API'leri içerir. Başka bir deyişle, C++/WinRT her Windows türü için C++ için daha kullanışlı bir eşdeğer tanımlar (buna yansıtılmış tür denir). Yansıtılan tür, Windows türüyle aynı tam nitelikli ada sahiptir, ancak C++ winrt ad alanına yerleştirilir. Bu #include bildirimlerini önceden derlenmiş başlığınıza eklemek, artımlı derleme sürelerini azaltır.

Önemli

Windows ad alanlarından bir tür kullanmak istediğinizde, yukarıda gösterildiği gibi ilgili C++/WinRT Windows ad alanı üst bilgi dosyasını #include eklemeniz gerekir. Karşılık gelen başlık dosyası, türün ad alanıyla aynı adı taşıyandır. Örneğin, Windows::Foundation::Collections::PropertySet çalışma zamanı sınıfı için C++/WinRT projeksiyonunu kullanmak üzere winrt/Windows.Foundation.Collections.h başlık dosyasını ekleyin.

C++/WinRT projeksiyon üst bilgisinin ilgili ad alanı üst bilgi dosyalarını otomatik olarak içermesi yaygın bir durumdur. Örneğin, winrt/Windows.Foundation.Collections.h içerir winrt/Windows.Foundation.h. Ancak zaman içinde değişen bir uygulama ayrıntısı olduğundan bu davranışa güvenmemelisiniz. İhtiyacınız olan tüm üst bilgileri açıkça eklemeniz gerekir.

using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Web::Syndication;

using namespace Yönergeler isteğe bağlıdır, ancak kullanışlıdır. Bu tür yönergeler için yukarıda gösterilen desen ( winrt ad alanında herhangi bir şey için nitelenmemiş ad aramasına izin verme) yeni bir projeye başlarken uygundur ve C++/WinRT bu projenin içinde kullandığınız tek dil projeksiyonudur. Öte yandan, eğer, C++/WinRT kodunu C++/CX ve/veya SDK uygulama ikili arabirimi (ABI) koduyla (bu modellerden birini veya ikisini birden taşırken veya bunlarla birlikte çalışırken) karıştırırsınız, ardından C++/WinRT ile C++/CX arasında birlikte çalışma, C++/CX'tenC++/WinRT'ye gitme ve C++/WinRT ile ABI arasında birlikte çalışma konularına bakın.

winrt::init_apartment();

winrt::init_apartment çağrısı, iş parçacığını Windows Çalışma Zamanı ortamında başlatır; varsayılan olarak çok iş parçacıklı bir apartmanda. Çağrı ayrıca COM'u başlatır.

Uri rssFeedUri{ L"https://blogs.windows.com/feed" };
SyndicationClient syndicationClient;

Yığında iki nesne ayırın: biri Windows blogunun URI’sini, diğeri ise bir haber akışı istemcisini temsil eder. Uri'yi basit bir geniş dize değişmez değeriyle oluştururuz (dizelerle çalışabileceğiniz diğer yollar için bkz. C++/WinRT'de dize işleme ).

SyndicationFeed syndicationFeed = syndicationClient.RetrieveFeedAsync(rssFeedUri).get();

SyndicationClient::RetrieveFeedAsync, zaman uyumsuz bir Windows Çalışma Zamanı işlevi örneğidir. Kod örneği, RetrieveFeedAsync yönteminden bir eşzamansız işlem nesnesi alır ve çağıran iş parçacığını engelleyip sonucu (bu örnekte bir haber akışı) beklemek için bu nesne üzerinde get çağrısını yapar. Eşzamanlılık ve engelleyici olmayan teknikler hakkında daha fazla bilgi için bkz. C++/WinRT ile eşzamanlılık ve zaman uyumsuz işlemler.

for (const SyndicationItem syndicationItem : syndicationFeed.Items()) { ... }

SyndicationFeed.Items , başlangıç ve bitiş işlevlerinden (veya bunların sabit, ters ve sabit ters değişkenlerinden) döndürülen yineleyiciler tarafından tanımlanan bir aralıktır. Bu nedenle, Öğeleri aralık tabanlı for bir deyimle veya std::for_each şablon işleviyle numaralandırabilirsiniz. Bunun gibi bir Windows Çalışma Zamanı koleksiyonu üzerinde her yineleme yaptığınızda, #include <winrt/Windows.Foundation.Collections.h> kullanmanız gerekir.

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;

Akışın başlık metnini winrt::hstring nesnesi olarak alır ( C++/WinRT'de Dize işleme konusunda daha fazla ayrıntı). Daha sonra hstring, C++ Standart Kitaplık dizeleriyle kullanılan deseni yansıtan c_str işlevi aracılığıyla çıkışlanır.

Gördüğünüz gibi, C++/WinRT gibi syndicationItem.Title().Text()modern ve sınıf benzeri C++ ifadelerini teşvik eder. Bu, geleneksel COM programlamasından farklı ve daha temiz bir programlama stilidir. COM'ı doğrudan başlatmanız veya COM işaretçileriyle çalışmanız gerekmez.

HRESULT dönüş kodlarını da işlemeniz gerekmez. C++/WinRT, hata HRESULT'lerini doğal ve modern bir programlama stili için winrt::hresult-error gibi özel durumlara dönüştürür. Hata işleme ve kod örnekleri hakkında daha fazla bilgi için bkz. C++/WinRT ile hata işleme.

C++/WinRT desteği eklemek için Windows Desktop uygulama projesini değiştirme

Bazı masaüstü projeleri (örneğin, Visual Studio'deki WinUI 3 şablonları) yerleşik C++/WinRT desteğine sahiptir.

Ancak bu bölümde, sahip olabileceğiniz herhangi bir Windows Desktop uygulaması projesine nasıl C++/WinRT desteği ekleyebileceğiniz gösterilir. Mevcut bir Windows Desktop uygulama projeniz yoksa, önce bir tane oluşturarak bu adımları izleyebilirsiniz. Örneğin, Visual Studio açın ve bir Visual C++>Windows Desktop>Windows Masaüstü Uygulaması projesi oluşturun.

İsteğe bağlı olarak C++/WinRT Visual Studio Uzantısını (VSIX) ve NuGet paketini yükleyebilirsiniz. Ayrıntılar için bkz. Visual Studio’nun C++/WinRT desteği.

Proje özelliklerini ayarlama

Genel>Windows SDK Sürümü proje özelliğine gidin ve Tüm Yapılandırmalar ve Tüm Platformlar'ı seçin. Windows SDK Sürümünün 10.0.17134.0 (Windows 10, sürüm 1803) veya üzeri olarak ayarlandığından emin olun.

Yeni projem neden derlenmiyor? sorununun sizi etkilemediğini doğrulayın.

C++/WinRT C++17 standardının özelliklerini kullandığından, C/C++>Language> Standardı proje özelliğini ISO C++17 Standart (/std:c++17) olarak ayarlayın.

Önceden derlenmiş başlık

Varsayılan proje şablonu, sizin için adı framework.h veya stdafx.h olan önceden derlenmiş bir üst bilgi dosyası oluşturur. Bunu olarak pch.hyeniden adlandırın. Dosyanız stdafx.cpp varsa, bunu olarak pch.cppyeniden adlandırın. Proje özelliğinde C/C++>Önceden Derlenmiş Başlıklar>Önceden Derlenmiş Başlık değerini Oluştur (/Yc) ve Önceden Derlenmiş Başlık Dosyası değerini pch.h olarak ayarlayın.

#include "framework.h" (veya #include "stdafx.h") tümünü bulun ve #include "pch.h" ile değiştirin.

pch.h içine winrt/base.h ekleyin.

// pch.h
...
#include <winrt/base.h>

Bağlantı Kurma

C++/WinRT dil projeksiyonu, WindowsApp.lib şemsiye kitaplığına bağlanmayı gerektiren belirli Windows Çalışma Zamanı ücretsiz (üye olmayan) işlevlere ve giriş noktalarına bağlıdır. Bu bölümde bağlayıcıyı karşılamanın üç yolu açıklanmaktadır.

İlk seçenek, Visual Studio projenize tüm C++/WinRT MSBuild özelliklerini ve hedeflerini eklemektir. Bunu yapmak için Microsoft.Windows.CppWinRT NuGet paketini projenize yükleyin. Projeyi Visual Studio’da açın, Project>NuGet Paketlerini Yönet...>Gözat seçeneğine tıklayın, arama kutusuna Microsoft.Windows.CppWinRT yazın veya yapıştırın, arama sonuçlarında öğeyi seçin ve ardından paketi o proje için yüklemek üzere Yükle düğmesine tıklayın.

Açıkça bağlamak için WindowsApp.libproje bağlantı ayarlarını da kullanabilirsiniz. Alternatif olarak, bunu bunun gibi kaynak kodunda (örneğin, içinde pch.h) yapabilirsiniz.

#pragma comment(lib, "windowsapp")

Artık projenize C++/WinRT kodu derleyip bağlayabilir ve ekleyebilirsiniz (örneğin, yukarıdaki A C++/WinRT hızlı başlangıç bölümünde gösterilene benzer bir kod).

C++/WinRT için üç ana senaryo

C++/WinRT'yi kullanıp kullanmaya başladıysanız ve buradaki belgelerin geri kalanını incelediğinizde, büyük olasılıkla aşağıdaki bölümlerde açıklandığı gibi üç ana senaryo olduğunu fark edeceksiniz.

Windows API'lerinden ve türlerinden yararlanma

Başka bir deyişle, API’leri kullanmak veya çağırmak. Örneğin, Bluetooth kullanarak iletişim kurmak için API çağrıları yapmak; video akışı sağlamak ve sunmak; Windows kabuğuyla tümleştirmek; vb. C++/WinRT bu senaryo kategorisini tamamen ve tavizsiz bir şekilde destekler. Daha fazla bilgi için bkz . C++/WinRT ile API'leri kullanma.

Windows API'leri ve türleri oluşturma

Başka bir deyişle, API'ler ve türler üretmek. Örneğin, yukarıdaki bölümde açıklanan API türlerinin üretilmesi; veya grafik API'leri; depolama ve dosya sistemi API'leri; ağ API'leri vb. Daha fazla bilgi için bkz. C++/WinRT ile API yazma.

API'yi uygulamadan önce API'nin şeklini tanımlamak için IDL kullanmanız gerektiğinden, API'leri C++/WinRT ile yazmak, api'leri kullanmaktan biraz daha önemlidir. XAML denetimlerinde bunu yapmanın bir kılavuzu vardır ; C++/WinRT özelliğine bağlama.

XAML uygulamaları

Bu senaryo, XAML UI çerçevesi üzerinde uygulama ve denetim oluşturma hakkındadır. Bir XAML uygulamasında çalışmak, kullanma ve oluşturmanın bir birleşimidir. Ancak XAML bugün Windows üzerinde baskın ui çerçevesi olduğundan ve Windows Çalışma Zamanı üzerindeki etkisi bununla orantılı olduğundan, kendi senaryo kategorisini hak ediyor.

XAML'nin yansıma sunan programlama dilleriyle en iyi şekilde çalıştığını unutmayın. C++/WinRT'de bazen XAML çerçevesiyle birlikte çalışmak için biraz ek iş yapmanız gerekir. Bu durumların tümü belgelerde ele alınmıştır. Başlamak için iyi yerler şunlardır: XAML denetimleri; bir C++/WinRT özelliğine bağlama ve C++/WinRT ile XAML özel (şablonlu) denetimleri.

C++/WinRT ile yazılmış örnek uygulamalar

Bkz. C++/WinRT örnek uygulamalarını nerede bulabilirim?.

Önemli API'ler