Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu konu başlığında, C++/WinRT API'lerinin nasıl kullanılıp kullanılmadığı, Windows parçası olup olmadıkları, üçüncü taraf bir bileşen satıcısı tarafından nasıl uygulandığı veya kendiniz tarafından nasıl uygulandığı gösterilmektedir.
Önemli
Bu konudaki kod örneklerinin kısa ve kolayca denemeniz için yeni bir Windows Konsol Uygulaması (C++/WinRT) projesi oluşturup kodu kopyalayarak bunları yeniden oluşturabilirsiniz. Ancak, bunun gibi paketlenmemiş bir uygulamadan rastgele özel (üçüncü taraf) Windows Çalışma Zamanı türleri kullanamazsınız. Bu şekilde yalnızca Windows türlerini kullanabilirsiniz.
Bir konsol uygulamasında özel (üçüncü taraf) Windows Çalışma Zamanı türlerini kullanabilmek için, uygulamaya kullanılan özel türlerin kayıtlarını çözümleyebilmesi amacıyla bir paket kimliği vermeniz gerekir. Daha fazla bilgi için bkz. Windows Uygulama Paketleme Projesi.
Alternatif olarak, C++ için Boş Uygulama, Paketlenmiş (Masaüstünde WinUI 3) veya Windows Çalışma Zamanı Bileşeni (C++/WinRT) proje şablonlarından yeni bir proje oluşturun. Bu uygulama türleri zaten bir paket kimliğine sahiptir.
API bir Windows ad alanı içindeyse
Bu, bir Windows Çalışma Zamanı API'sini kullanmanız gereken en yaygın durumdur. Meta veride tanımlanan bir Windows ad alanındaki her tür için C++/WinRT, C++ ile uyumlu bir eşdeğer tanımlar (buna yansıtılan tür denir). Yansıtılan tür, Windows türüyle aynı tam ada sahiptir, ancak C++ söz dizimi kullanılarak C++ winrt ad alanına yerleştirilir. Örneğin, Windows::Foundation::Uri, C++/WinRT'ye winrt::Windows::Foundation::Uri olarak yansıtılır.
İşte basit bir kod örneği. Aşağıdaki kod örneklerini doğrudan Windows Konsol Uygulaması (C++/WinRT) projesinin ana kaynak kod dosyasına kopyalayıp yapıştırmak istiyorsanız, önce Proje özelliklerinde Önceden Derlenmiş Üst Bilgileri Kullanma seçeneğini belirleyin.
// main.cpp
#include <winrt/Windows.Foundation.h>
using namespace winrt;
using namespace Windows::Foundation;
int main()
{
winrt::init_apartment();
Uri contosoUri{ L"http://www.contoso.com" };
Uri combinedUri = contosoUri.CombineUri(L"products");
}
Eklenen üst bilgi winrt/Windows.Foundation.h , klasörünün %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt\içinde bulunan SDK'nın bir parçasıdır. Bu klasördeki üst bilgiler, C++/WinRT'ye yansıtılan Windows ad alanı türünü içerir. Bu örnekte, winrt/Windows.Foundation.h, çalışma zamanı sınıfı Windows::Foundation::Uri için öngörülen tür olan winrt::Windows::Foundation::Uri öğesini içerir.
Tavsiye
bir Windows ad alanından tür kullanmak istediğinizde, bu ad alanına karşılık gelen C++/WinRT üst bilgisini ekleyin.
using namespace Yönergeler isteğe bağlıdır, ancak kullanışlıdır.
Yukarıdaki kod örneğinde, C++/WinRT'yi başlatdıktan sonra, bu örnekte genel olarak belgelenen oluşturucularından biri (Uri(Dize)) aracılığıyla yansıtılan türün winrt::Windows::Foundation::Uri değerini yığın olarak ayırıyoruz. Bunun için, en yaygın kullanım örneği, genellikle yapmanız gereken tek şey budur. C++/WinRT öngörülen tür değerini aldıktan sonra, tüm üyeleri aynı olduğundan, gerçek Windows Çalışma Zamanı türünün bir örneğiymiş gibi davranabilirsiniz.
Aslında, bu öngörülen değer bir proxy'dir; temelde yalnızca bir yedekleme nesnesine yönelik akıllı bir işaretçidir. Yansıtılan değerin oluşturucusu/oluşturucuları, arka plandaki Windows Çalışma Zamanı sınıfının (bu durumda Windows.Foundation.Uri) bir örneğini oluşturmak için RoActivateInstance çağrısı yapar ve bu nesnenin varsayılan arabirimini yeni yansıtılan değerin içinde depolar. Aşağıda gösterildiği gibi, yansıtılmış değerin üyelerine yaptığınız çağrılar aslında akıllı işaretçi aracılığıyla destekleyici nesneye yönlendirilir; durum değişikliklerinin gerçekleştiği yer de burasıdır.
contosoUri değeri kapsam dışına çıktığında yok edilir ve varsayılan arabirime olan referansını serbest bırakır. Bu başvuru, temel aldığı Windows Çalışma Zamanı Windows.Foundation.Uri nesnesine yapılan son başvuruysa, temel alınan nesne de yok edilir.
Tavsiye
Öngörülen tür, API'lerini kullanma amacıyla bir Windows Çalışma Zamanı türü üzerindeki sarmalayıcıdır. Örneğin, yansıtılan arabirim, Windows Çalışma Zamanı arabirimi üzerindeki bir sarmalayıcıdır.
C++/WinRT projeksiyon üst bilgileri
C++/WinRT kullanarak Windows ad alanı API’lerini kullanmak için %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt klasöründeki üst bilgi dosyalarını eklersiniz. Kullandığınız her ad alanına karşılık gelen üst bilgileri eklemeniz gerekir.
Örneğin, Windows::Security::Cryptography::Certificates ad alanı için eşdeğer C++/WinRT türü tanımları içinde winrt/Windows.Security.Cryptography.Certificates.hbulunur. Bu üst bilgi dosyasını dahil etmek, Windows::Security::Cryptography::Certificates ad alanındaki tüm türlere erişmenizi sağlar.
Bazen, bir ad alanı üst bilgisi ilgili ad alanı üst bilgilerinin bölümlerini içerir, ancak bu uygulama ayrıntılarına güvenmemeniz gerekir. Kullandığınız ad alanlarının üst bilgilerini açıkça ekleyin.
Örneğin, Certificate::GetCertificateBlob yöntemi bir Windows::Storage::Streams::IBuffer arabirimi döndürür.
Certificate::GetCertificateBlob yöntemini çağırmadan önce, döndürülen winrt/Windows.Storage.Streams.h alıp üzerinde çalışabildiğinizden emin olmak için ad alanı üst bilgi dosyasını eklemeniz gerekir.
Bu ad alanında türleri kullanmadan önce gerekli ad alanı üst bilgilerini eklemeyi unutmak, derleme hatalarının yaygın bir kaynağıdır.
Nesne, arabirim veya ABI aracılığıyla üyelere erişme
C++/WinRT projeksiyonuyla, Windows Çalışma Zamanı sınıfının çalışma zamanı gösterimi, temel alınan ABI arabirimlerinden farklı değildir. Ancak, size kolaylık sağlamak için sınıfları, geliştiricisinin amaçladığı şekilde kullanarak kod yazabilirsiniz. Örneğin, ToString yöntemini, bu yöntem sınıfın bir yöntemiymiş gibi Uri üzerinde çağırabilirsiniz (aslında bu, ayrı IStringable arabiriminin bir yöntemidir).
WINRT_ASSERT bir makro tanımıdır ve _ASSERTE genişletilir.
Uri contosoUri{ L"http://www.contoso.com" };
WINRT_ASSERT(contosoUri.ToString() == L"http://www.contoso.com/"); // QueryInterface is called at this point.
Bu kolaylık, uygun arabirim için bir sorgu aracılığıyla sağlanır. Ama her zaman kontrol senindir. IStringable arabirimini kendiniz alıp doğrudan kullanarak biraz performans için bu kolaylıklardan biraz vazgeçmeyi tercih edebilirsiniz. Aşağıdaki kod örneğinde, çalışma zamanında (tek seferlik sorgu aracılığıyla) gerçek bir IStringable arabirim işaretçisi elde edebilirsiniz. Bundan sonra, ToString çağrınız doğrudandır ve QueryInterface'e yapılacak başka bir çağrıyı önler.
...
IStringable stringable = contosoUri; // One-off QueryInterface.
WINRT_ASSERT(stringable.ToString() == L"http://www.contoso.com/");
Aynı arabirimde birkaç yöntem çağırabileceğinizi biliyorsanız bu tekniği seçebilirsiniz.
Bu arada, ABI düzeyinde üyelere erişmek istiyorsanız, bunu yapabilirsiniz. Aşağıdaki kod örneği bunun nasıl yapıldığını gösterir ve C++/WinRT ile ABI arasındaki Birlikte Çalışma bölümünde daha fazla ayrıntı ve kod örneği vardır.
#include <Windows.Foundation.h>
#include <unknwn.h>
#include <winrt/Windows.Foundation.h>
using namespace winrt::Windows::Foundation;
int main()
{
winrt::init_apartment();
Uri contosoUri{ L"http://www.contoso.com" };
int port{ contosoUri.Port() }; // Access the Port "property" accessor via C++/WinRT.
winrt::com_ptr<ABI::Windows::Foundation::IUriRuntimeClass> abiUri{
contosoUri.as<ABI::Windows::Foundation::IUriRuntimeClass>() };
HRESULT hr = abiUri->get_Port(&port); // Access the get_Port ABI function.
}
Gecikmeli başlatma
C++/WinRT'de, yansıtılan her tür özel bir C++/WinRT std::nullptr_t oluşturucuya sahiptir. Bunun dışında, varsayılan oluşturucu da dahil olmak üzere tüm öngörülen tür oluşturucular, bir yedekleme Windows Çalışma Zamanı nesnesinin oluşturulmasına neden olur ve size bunun için akıllı bir işaretçi verir. Bu nedenle, bu kural başlatılmamış yerel değişkenler, başlatılmamış genel değişkenler ve başlatılmamış üye değişkenleri gibi varsayılan oluşturucunun kullanıldığı her yerde geçerlidir.
Öte yandan, projeksiyonu yapılmış bir türde, bunun otomatik olarak arka plandaki bir Windows Çalışma Zamanı nesnesi oluşturmasına yol açmadan bir değişken oluşturmak istiyorsanız (böylece bu işi sonraya erteleyebilirsiniz), bunu yapabilirsiniz. Değişkeninizi veya alanınızı bu özel C++/WinRT std::nullptr_t oluşturucuyu (C++/WinRT projeksiyonunun her çalışma zamanı sınıfına eklediği) kullanarak bildirin. Bu özel oluşturucuyu aşağıdaki kod örneğinde m_gamerPicBuffer ile kullanırız.
#include <winrt/Windows.Storage.Streams.h>
using namespace winrt::Windows::Storage::Streams;
#define MAX_IMAGE_SIZE 1024
struct Sample
{
void DelayedInit()
{
// Allocate the actual buffer.
m_gamerPicBuffer = Buffer(MAX_IMAGE_SIZE);
}
private:
Buffer m_gamerPicBuffer{ nullptr };
};
int main()
{
winrt::init_apartment();
Sample s;
// ...
s.DelayedInit();
}
Yansıtılmış türde, std::nullptr_t oluşturucusu hariç tüm oluşturucular, destekleyen bir Windows Çalışma Zamanı nesnesinin oluşturulmasına neden olur. std::nullptr_t oluşturucu temelde bir no-op. Yansıtılan nesnenin sonraki bir zamanda başlatılmasını bekler. Bu nedenle, çalışma zamanı sınıfının varsayılan bir oluşturucuya sahip olup olmadığı fark etmese de, verimli gecikmeli başlatma için bu tekniği kullanabilirsiniz.
Bu önemli nokta, vektörler ve haritalar gibi varsayılan oluşturucuyu çağırdığınız diğer yerleri etkiler. C++ projesi için Paketlenmiş (Masaüstünde WinUI 3) adlı boş bir uygulamaya ihtiyacınız olan bu kod örneğini göz önünde bulundurun.
std::map<int, TextBlock> lookup;
lookup[2] = value;
Atama yeni bir TextBlock oluşturur ve hemen üzerine valueyazar. İşte çare.
std::map<int, TextBlock> lookup;
lookup.insert_or_assign(2, value);
Ayrıca bkz. Varsayılan oluşturucu koleksiyonları nasıl etkiler?
Yanlışlıkla gecikmeli başlatma yapmayın
Std::nullptr_t oluşturucuyu yanlışlıkla çağırmamanıza dikkat edin. Derleyicinin çakışma çözümlemesi, bunu fabrika oluşturucularına tercih eder. Örneğin, bu iki çalışma zamanı sınıf tanımını göz önünde bulundurun.
// GiftBox.idl
runtimeclass GiftBox
{
GiftBox();
}
// Gift.idl
runtimeclass Gift
{
Gift(GiftBox giftBox); // You can create a gift inside a box.
}
Diyelim ki kutu içinde olmayan bir Hediye oluşturmak istiyoruz (başlatılmamış bir GiftBox ile oluşturulan bir Hediye). İlk olarak, bunu yapmak için yanlış yola bakalım. Hediye Kutusu alan bir Hediye oluşturucu olduğunu biliyoruz. Ancak null bir GiftBox iletmeye kalkışırsak (aşağıda yaptığımız gibi, Gift oluşturucusunu uniform başlatma yoluyla çağırarak), istediğimiz sonucu elde edemeyiz.
// These are *not* what you intended. Doing it in one of these two ways
// actually *doesn't* create the intended backing Windows Runtime Gift object;
// only an empty smart pointer.
Gift gift{ nullptr };
auto gift{ Gift(nullptr) };
Burada aldığınız şey, başlatılmamış bir Gift. Başlatılmamış bir GiftBox ile Hediye alamazsınız. Bunu yapmak için doğru yöntem aşağıdadır.
// Doing it in one of these two ways creates an initialized
// Gift with an uninitialized GiftBox.
Gift gift{ GiftBox{ nullptr } };
auto gift{ Gift(GiftBox{ nullptr }) };
Yanlış örnekte, değişmez değerin nullptr geçirilmesi, gecikmeli başlatma oluşturucusunun lehine çözümleniyor. Fabrika oluşturucusunun lehine çözümlenebilmesi için parametrenin türü bir GiftBox olmalıdır. Doğru örnekte gösterildiği gibi, gecikmeli başlatılacak bir GiftBox'ı açıkça geçme seçeneğiniz yine de vardır.
Bu sonraki örnek de doğrudur, çünkü parametrenin türü GiftBox'tır, std::nullptr_t değil.
GiftBox giftBox{ nullptr };
Gift gift{ giftBox }; // Calls factory constructor.
Belirsizlik yalnızca bir nullptr literal'i iletildiğinde ortaya çıkar.
Yanlışlıkla kopyalayarak oluşturmayın.
Bu uyarı, yukarıdaki Başlatmayı yanlışlıkla geciktirmeyin bölümünde açıklanana benzer.
Gecikmeli başlatma oluşturucusuna ek olarak, C++/WinRT projeksiyonu da her çalışma zamanı sınıfına bir kopya oluşturucu ekler. Bu, oluşturmakta olan nesneyle aynı türü kabul eden tek parametreli bir oluşturucu. Ortaya çıkan akıllı işaretçi, oluşturucu parametresinin işaret ettiğiyle aynı temelindeki Windows Çalışma Zamanı nesnesine işaret eder. Sonuç, aynı yedekleme nesnesine işaret eden iki akıllı işaretçi nesnesidir.
Kod örneklerinde kullanacağımız çalışma zamanı sınıf tanımı aşağıda verilmiştir.
// GiftBox.idl
runtimeclass GiftBox
{
GiftBox(GiftBox biggerBox); // You can place a box inside a bigger box.
}
Daha büyük bir GiftBox içinde bir GiftBox oluşturmak istediğimizi düşünelim.
GiftBox bigBox{ ... };
// These are *not* what you intended. Doing it in one of these two ways
// copies bigBox's backing-object-pointer into smallBox.
// The result is that smallBox == bigBox.
GiftBox smallBox{ bigBox };
auto smallBox{ GiftBox(bigBox) };
Bunu yapmak için doğru yol, etkinleştirme fabrikasını açıkça çağırmaktır.
GiftBox bigBox{ ... };
// These two ways call the activation factory explicitly.
GiftBox smallBox{
winrt::get_activation_factory<GiftBox, IGiftBoxFactory>().CreateInstance(bigBox) };
auto smallBox{
winrt::get_activation_factory<GiftBox, IGiftBoxFactory>().CreateInstance(bigBox) };
API bir Windows Çalışma Zamanı bileşeninde uygulandıysa
Bu bölüm, bileşeni kendiniz yazmanız veya bir satıcıdan gelmeniz fark etmeksizin geçerlidir.
Note
C++/WinRT Visual Studio Uzantısını (VSIX) ve NuGet paketini (birlikte proje şablonu ve derleme desteği sağlayan) yükleme ve kullanma hakkında bilgi için bkz. C++/WinRT için Visual Studio desteği.
Uygulama projenizde, Windows Çalışma Zamanı bileşeninin Windows Çalışma Zamanı meta veri (.winmd) dosyasına ve derlemesine başvurun. Derleme sırasında cppwinrt.exe aracı, bileşenin API yüzeyini tam olarak açıklayan veya yansıtan standart bir C++ kitaplığı oluşturur. Başka bir deyişle, oluşturulan kitaplık bileşen için öngörülen türleri içerir.
Ardından, Windows ad alanı türlerinde olduğu gibi, bir başlık dosyası eklersiniz ve projeksiyon türünü oluşturucularından birini kullanarak oluşturursunuz. Uygulama projenizin başlangıç kodu çalışma zamanı sınıfını kaydeder ve yansıtılan türün oluşturucusu, başvuruda bulunılan bileşenden çalışma zamanı sınıfını etkinleştirmek için RoActivateInstance'ı çağırır.
#include <winrt/ThermometerWRC.h>
struct App : AppT<App>
{
ThermometerWRC::Thermometer thermometer;
...
};
Bir Windows Çalışma Zamanı bileşeninde uygulanan API'leri kullanmaya ilişkin daha fazla ayrıntı, kod ve adım adım açıklama için bkz. C++/WinRT ile Windows Çalışma Zamanı bileşenleri ve C++/WinRT'de olaylar yazma.
API, tüketen projede uygulanıyorsa
Bu bölümdeki kod örneği XAML denetimlerinden alınmıştır; C++/WinRT özelliğine bağlama. Daha fazla ayrıntı, kod örnekleri ve onu kullanan aynı projede uygulanan bir çalışma zamanı sınıfının nasıl kullanılacağına ilişkin adım adım açıklama için bu konuya bakın.
XAML kullanıcı arayüzünde kullanılan bir tür, XAML ile aynı projede yer alsa bile bir çalışma zamanı sınıfı olmalıdır. Bu senaryo için, çalışma zamanı sınıfının Windows Çalışma Zamanı meta verilerinden (.winmd) öngörülen bir tür oluşturursunuz. Yine bir başlık dosyası eklersiniz, ancak sonra çalışma zamanı sınıfı örneğini oluşturmak için kullanılan C++/WinRT sürüm 1.0 ya da sürüm 2.0 yöntemlerinden birini seçebilirsiniz. Sürüm 1.0 yöntemi winrt::make; sürüm 2.0 yöntemi tekdüzen yapı olarak bilinir. Sırayla her birine bakalım.
winrt::make kullanarak oluşturma
En azından bu desene aşina olmak iyi bir fikir olduğundan, varsayılan (C++/WinRT sürüm 1.0) yöntemiyle başlayalım. Öngörülen türü std::nullptr_t oluşturucu aracılığıyla oluşturursunuz. Bu oluşturucu herhangi bir başlatma yapmaz; bu nedenle sonraki adım olarak, gerekli oluşturucu bağımsız değişkenlerini geçirip winrt::make yardımcı işlevini kullanarak örneğe bir değer atamanız gerekir. Tüketen kodla aynı projede uygulanan bir çalışma zamanı sınıfının kaydedilmesi veya Windows Çalışma Zamanı/COM etkinleştirmesi yoluyla örneklenmesi gerekmez.
Ayrıntılı bir açıklama için bkz. XAML denetimleri; C++/WinRT özelliğine bağlama. Bu bölüm, söz konusu adım adım açıklamadan alıntıları gösterir.
// MainPage.idl
import "BookstoreViewModel.idl";
namespace Bookstore
{
runtimeclass MainPage : Microsoft.UI.Xaml.Controls.Page
{
BookstoreViewModel MainViewModel{ get; };
}
}
// MainPage.h
...
struct MainPage : MainPageT<MainPage>
{
...
private:
Bookstore::BookstoreViewModel m_mainViewModel{ nullptr };
};
...
// MainPage.cpp
...
#include "BookstoreViewModel.h"
MainPage::MainPage()
{
m_mainViewModel = winrt::make<Bookstore::implementation::BookstoreViewModel>();
...
}
Tek tip inşaat
C++/WinRT sürüm 2.0 ve üzeri ile, tekdüzen yapı olarak bilinen iyileştirilmiş bir yapı biçimi mevcuttur ( bkz. C++/WinRT 2.0'da Haberler ve değişiklikler).
Ayrıntılı bir adım adım açıklama için XAML denetimleri; bir C++/WinRT özelliğine bağlama konusuna bakın. Bu bölümde, söz konusu adım adım anlatımdan alınmış kesitler gösterilmektedir.
winrt::make yerine tekdüzen yapı kullanmak için bir etkinleştirme fabrikası gerekir. Oluşturmanın iyi bir yolu, IDL'nize bir oluşturucu eklemektir.
// MainPage.idl
import "BookstoreViewModel.idl";
namespace Bookstore
{
runtimeclass MainPage : Microsoft.UI.Xaml.Controls.Page
{
MainPage();
BookstoreViewModel MainViewModel{ get; };
}
}
Ardından, MainPage.h aşağıda gösterildiği gibi yalnızca bir adımda m_mainViewModel bildirin ve başlatın.
// MainPage.h
...
struct MainPage : MainPageT<MainPage>
{
...
private:
Bookstore::BookstoreViewModel m_mainViewModel;
...
};
}
...
Ardından, içindeki MainPage oluşturucusunda MainPage.cppkoduna m_mainViewModel = winrt::make<Bookstore::implementation::BookstoreViewModel>();gerek yoktur.
Tekdüzen oluşturma ve kod örnekleri hakkında daha fazla bilgi için bkz. Tekdüzen yapıyı kabul etme ve doğrudan uygulama erişimi.
Öngörülen türleri ve arabirimleri örnekleme ve döndürme
Aşağıda, tüketen projenizde yansıtılan türlerin ve arabirimlerin nasıl görünebileceğine ilişkin bir örnek verilmiştir. Yansıtılan bir türün (bu örnekteki gibi) araç tarafından oluşturulduğunu ve kendiniz yazabileceğiniz bir şey olmadığını unutmayın.
struct MyRuntimeClass : MyProject::IMyRuntimeClass, impl::require<MyRuntimeClass,
Windows::Foundation::IStringable, Windows::Foundation::IClosable>
MyRuntimeClass yansıtılan bir türdür; yansıtılan arabirimler IMyRuntimeClass, IStringable ve IClosable'dır. Bu konu başlığında, yansıtılan bir türün örneğini oluşturmak için kullanabileceğiniz farklı yollar gösterilmiştir. Örnek olarak MyRuntimeClass'ı kullanan bir anımsatıcı ve özet aşağıda verilmiştir.
// The runtime class is implemented in another compilation unit (it's either a Windows API,
// or it's implemented in a second- or third-party component).
MyProject::MyRuntimeClass myrc1;
// The runtime class is implemented in the same compilation unit.
MyProject::MyRuntimeClass myrc2{ nullptr };
myrc2 = winrt::make<MyProject::implementation::MyRuntimeClass>();
- Yansıtılan türdeki tüm arabirimlerin üyelerine erişebilirsiniz.
- Çağırana yansıtılan bir tür döndürebilirsiniz.
- Yansıtılan türler ve arabirimler winrt::Windows::Foundation::IUnknown'dan türetilir. Dolayısıyla, diğer yansıtılan arabirimleri sorgulamak için IUnknown::as yöntemini yansıtılan bir tür veya arabirim üzerinde çağırabilir; bu arabirimleri kullanabilir ya da bir çağırana geri döndürebilirsiniz. as member işlevi QueryInterface gibi çalışır.
void f(MyProject::MyRuntimeClass const& myrc)
{
myrc.ToString();
myrc.Close();
IClosable iclosable = myrc.as<IClosable>();
iclosable.Close();
}
Etkinleştirme fabrikaları
C++/WinRT nesnesi oluşturmanın kullanışlı ve doğrudan yolu aşağıdaki gibidir.
using namespace winrt::Windows::Globalization::NumberFormatting;
...
CurrencyFormatter currency{ L"USD" };
Ancak bazen etkinleştirme fabrikasını kendiniz oluşturmak ve ardından gerektiğinde bu fabrikadan nesneler oluşturmak isteyebilirsiniz. winrt::get_activation_factory işlev şablonunu kullanarak nasıl yapıldığını gösteren bazı örnekler aşağıda verilmiştir.
using namespace winrt::Windows::Globalization::NumberFormatting;
...
auto factory = winrt::get_activation_factory<CurrencyFormatter, ICurrencyFormatterFactory>();
CurrencyFormatter currency = factory.CreateCurrencyFormatterCode(L"USD");
using namespace winrt::Windows::Foundation;
...
auto factory = winrt::get_activation_factory<Uri, IUriRuntimeClassFactory>();
Uri uri = factory.CreateUri(L"http://www.contoso.com");
Yukarıdaki iki örnekteki sınıflar bir Windows ad alanından türlerdir. Bu sonraki örnekte ThermometerWRC::Thermometer, Windows Çalışma Zamanı bileşeninde uygulanan özel bir türdür.
auto factory = winrt::get_activation_factory<ThermometerWRC::Thermometer>();
ThermometerWRC::Thermometer thermometer = factory.ActivateInstance<ThermometerWRC::Thermometer>();
Üye/Tür belirsizlikleri
Bir üye fonksiyon bir türle aynı adı taşıyorsa bir belirsizlik ortaya çıkar. C++’ta üye işlevlerindeki nitelendirilmemiş ad araması kuralları, ad alanlarında arama yapmadan önce sınıfta arama yapılmasına yol açar. Değiştirme hatası bir hata değil (SFINAE) kuralı uygulanmaz (işlev şablonlarının aşırı yükleme çözümlemesi sırasında uygulanır). Bu nedenle, sınıfın içindeki ad anlamlı değilse derleyici daha iyi bir eşleşme aramaya devam etmez; yalnızca bir hata bildirir.
struct MyPage : Page
{
void DoWork()
{
// This doesn't compile. You get the error
// "'winrt::Windows::Foundation::IUnknown::as':
// no matching overloaded function found".
auto style{ Application::Current().Resources().
Lookup(L"MyStyle").as<Style>() };
}
}
Yukarıda derleyici, FrameworkElement.Style() ifadesini (C++/WinRT'de bir üye işlevi olan) IUnknown::as için şablon parametresi olarak geçirdiğinizi düşünüyor. Çözüm, adın StyleMicrosoft::UI::Xaml::Style türü olarak yorumlanması için zorlamaktır.
struct MyPage : Page
{
void DoWork()
{
// One option is to fully-qualify it.
auto style{ Application::Current().Resources().
Lookup(L"MyStyle").as<Microsoft::UI::Xaml::Style>() };
// Another is to force it to be interpreted as a struct name.
auto style{ Application::Current().Resources().
Lookup(L"MyStyle").as<struct Style>() };
// If you have "using namespace Windows::UI;", then this is sufficient.
auto style{ Application::Current().Resources().
Lookup(L"MyStyle").as<Xaml::Style>() };
// Or you can force it to be resolved in the global namespace (into which
// you imported the Microsoft::UI::Xaml namespace when you did
// "using namespace Microsoft::UI::Xaml;".
auto style = Application::Current().Resources().
Lookup(L"MyStyle").as<::Style>();
}
}
Nitelendirilmemiş ad aramasının, adın ardından :: gelmesi durumunda geçerli olan özel bir istisnası vardır; bu durumda işlevler, değişkenler ve enum değerleri yok sayılır. Bu, böyle şeyler yapmanıza olanak tanır.
struct MyPage : Page
{
void DoSomething()
{
Visibility(Visibility::Collapsed); // No ambiguity here (special exception).
}
}
Visibility() çağrısı, UIElement.Visibility üye işlevinin adına çözümlenir. Ancak Visibility::Collapsed parametresi, :: ile Visibility sözcüğünden sonra geldiğinden yöntem adı yok sayılır ve derleyici enum sınıfını bulur.
Önemli API'ler
- QueryInterface işlevi
- RoActivateInstance işlevi
- Windows::Foundation::Uri sınıfı
- winrt::get_activation_factory işlev şablonu
- winrt::make işlev şablonu
- winrt::Windows::Foundation::IUnknown yapısı
İlgili konular
Windows developer