Aracılığıyla paylaş


C++/WinRT kullanmaya başlama

Önemli

C++/WinRT visual studio uzantısı (VSIX) ve NuGet paketini (birlikte proje şablonu ve derleme desteği sağlar) yükleme ve kullanma dahil olmak üzere C++/WinRT geliştirmesi için Visual Studio'yu ayarlama hakkında bilgi için bkz. C++/WinRTiç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 konuda ayrıcabir Windows Masaüstü uygulama projesine C++/WinRT desteği ekleme gösterilmektedir.

Uyarı

Visual Studio ve Windows SDK'nın en son sürümleriyle geliştirmenizi öneririz. Visual Studio 2017 (sürüm 15.8.0 veya üzeri) kullanıyorsanız ve Windows SDK sürüm 10.0.17134.0'ı (Windows 10, sürüm 1803) hedeflediyseniz, yeni oluşturulan bir C++/WinRT projesi "hata C3861: 'from_abi' hatasıyla derlenemiyor: tanımlayıcı bulunamadı" ve base.h dosyasından kaynaklanan diğer hatalarla birlikte. Çözüm, Windows SDK'nın ilerideki (daha uyumlu) bir sürümünü hedeflemek veya proje özelliği C/C++>Dil>Uyumluluk modu: Hayır olarak ayarlamaktır. Ayrıca, proje özelliği C/C++>> bölümünde Ek Seçenekleraltında /permissive- görünüyorsa, bunu silin.

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

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

pch.h ve main.cpp öğesini bu şekilde 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ığıyla cppwinrt.exe ) projenizin $(GeneratedFilesDir) klasörüne aynı üst bilgileri oluşturduğundan Windows SDK'sına katı bir bağımlılık yoktur. Başka bir yerde bulunamazsa veya proje ayarlarınızı değiştirirseniz bu klasörden yüklenirler.

Başlık dosyaları, C++/WinRT içine yansıtılmış Windows API'lerini içerir. Başka bir deyişle, her Windows türü için C++/WinRT bir C++dostu eşdeğeri tanımlar (öngörülen türolarak adlandırılır). Yansıtılan tür, Windows türüyle aynı tam nitelikli isme sahiptir, ancak C++ winrt ad alanına yerleştirilir. Bu ek dosyaları önceden derlenmiş üst bilgiye dahil etmek, artımlı derleme sürelerini azaltır.

Önemli

Bir Windows ad alanından tür kullanmak istediğinizde, yukarıda gösterildiği gibi ilgili C++/WinRT Windows ad alanı üst bilgi dosyasını #include gerekir. Türün ad alanıyla aynı isme sahip 'ye karşılık gelen üst bilgisi budur. Örneğin, Windows::Foundation::Collections::PropertySet çalışma zamanı sınıfı için C++/WinRT projeksiyonunu kullanmak için başlık dosyasını winrt/Windows.Foundation.Collections.h 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önergeleri 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 C++/WinRT kodunu C++/CX ve/veya SDK uygulama ikili arabirimi (ABI) koduyla karıştırıyorsanız (veya bu modellerden biriyle veya her ikisiyle birlikte çalışabilir), ardından C++/WinRT ile C++/CXarasında birlikte çalışma konularına bakın C++/CX'den C++/WinRT'ye Taşı'yı seçin. ve C++/WinRT ile ABIarasında Birlikte Çalışma .

winrt::init_apartment();

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

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

Şu iki nesneyi yığıt üzerinde ayırın: Bunlar, Windows blogunun URI'sini ve bir dağıtım istemcisini temsil ediyorlar. URI'yi basit bir geniş karakter dize değişmezi ile oluştururuz (dizelerle çalışmanın daha fazla yolu için bkz. C++/WinRT 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'den zaman uyumsuz bir işlem nesnesi alır ve bu nesne üzerinde get fonksiyonunu çağırarak, çağırılan iş parçacığını durdurur ve sonucu bekler (bu durumda bir dağıtım akışıdır). Eşzamanlılık hakkında 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, begin ve end işlevlerinden (veya bunların sabit, ters ve sabit ters varyantlarından) 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 yineleme yaptığınız her durumda #include <winrt/Windows.Foundation.Collections.h>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++ Standard Kütüphanesi dizeleriyle kullanılan deseni yansıtan c_str işlevi aracılığıyla çıkarılı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 Masaüstü uygulama projesini değiştirme

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

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

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

Proje özelliklerini ayarlama

GenelWindows SDK Sürümiçin proje özelliğine gidin ve Tüm Yapılandırmalar'ı ve Tüm Platformlar'i 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.

etkilenmediğinizden emin olun Yeni projem neden derlenmiyor?.

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 framework.hveya stdafx.hadlı önceden derlenmiş başlık dosyası oluşturur. Bunu olarak pch.hyeniden adlandırın. Dosyanız stdafx.cpp varsa, bunu olarak pch.cppyeniden adlandırın. C/C++ proje özelliğini>Önceden Derlenmiş Üst Bilgiler>Önceden Derlenmiş Üst BilgiOluşturma (/Yc)olarak ayarlayın ve Önceden Derlenmiş Üst Bilgi Dosyasıpch.holarak ayarlayın.

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

pch.h içinde 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şlevlerine 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'a 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 bu proje için yüklemek üzere Yükle'e 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'lerini ve türlerini kullanma

Başka bir deyişle,kullanarak veya , API'lerini çağırmak. Örneğin, Bluetooth kullanarak iletişim kurmak için API çağrıları yapma; video sunmak ve akış yapmak için; Windows kabuğuyla tümleştirmek için; ve benzerleri. C++/WinRT bu senaryo kategorisini tamamen ve tavizsiz bir şekilde destekler. Daha fazla bilgi için C++/WinRT ile API'leri kullanmabölümüne bakın.

Windows API'leri ve türleri yazma

Başka bir deyişle, API'leri ve türlerini üretiyor. Ö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 Yazma API'leri.

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 nasıl yapacağınıza dair bir kılavuz bulunmaktadır; C++/WinRT özelliğine bağlanma işlemi.

XAML uygulamaları

Bu senaryo, XAML UI çerçevesi üzerinde uygulama ve denetim oluşturma hakkındadır. Bir XAML uygulamasında çalışmak, kullanım ve oluşturmanın bir birleşimine denk düşer. 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. XAML denetimleri iyi başlangıç yerleridir; C++/WinRT özellik bağlama ve C++/WinRTile XAML özel (şablonlu) denetimleri .

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

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

Önemli API'ler