Bagikan melalui


Mulai menggunakan C++/WinRT

Penting

Untuk informasi tentang menyiapkan Visual Studio untuk pengembangan C++/WinRT—termasuk menginstal dan menggunakan C++/WinRT Visual Studio Extension (VSIX) dan paket NuGet (yang bersama-sama menyediakan templat proyek dan dukungan build)—lihat Dukungan Visual Studio untuk C++/WinRT.

Untuk mempercepat Anda menggunakan C++/WinRT, topik ini membahas contoh kode sederhana berdasarkan proyek Aplikasi Konsol Windows (C++/WinRT) baru. Topik ini juga menunjukkan cara menambahkan dukungan C++/WinRT ke proyek aplikasi Windows Desktop.

Catatan

Meskipun kami menyarankan agar Anda mengembangkan dengan versi terbaru Visual Studio dan Windows SDK, jika Anda menggunakan Visual Studio 2017 (versi 15.8.0 atau yang lebih baru), dan menargetkan Windows SDK versi 10.0.17134.0 (Windows 10, versi 1803), maka proyek C++/WinRT yang baru dibuat mungkin gagal dikompilasi dengan kesalahan "kesalahan C3861: 'from_abi': pengidentifikasi tidak ditemukan", dan dengan kesalahan lain yang berasal dari base.h. Solusinya adalah menargetkan versi Windows SDK yang lebih baru (lebih sesuai), atau mengatur properti proyek C/C++>mode Kesuaian Bahasa>: Tidak (juga, jika /permisif- muncul di properti proyek C/C++>Language>Command Line di bawah Opsi Tambahan, lalu hapus).

Mulai cepat C++/WinRT

Buat proyek Aplikasi Konsol Windows (C++/WinRT) baru.

Edit pch.h dan main.cpp agar terlihat seperti ini.

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

Mari kita ambil contoh kode pendek di atas sepotong demi sepotong, dan jelaskan apa yang terjadi di setiap bagian.

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

Dengan pengaturan proyek default, header yang disertakan berasal dari Windows SDK, di dalam folder %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt. Visual Studio menyertakan jalur tersebut dalam makro IncludePath-nya. Tetapi tidak ada dependensi ketat pada Windows SDK, karena proyek Anda (melalui cppwinrt.exe alat) menghasilkan header yang sama ke folder $(GeneratedFilesDir) proyek Anda. Mereka akan dimuat dari folder tersebut jika tidak dapat ditemukan di tempat lain, atau jika Anda mengubah pengaturan proyek Anda.

Header berisi API Windows yang diproyeksikan ke dalam C++/WinRT. Dengan kata lain, untuk setiap jenis Windows, C++/WinRT mendefinisikan setara C++-friendly (disebut jenis yang diproyeksikan). Jenis yang diproyeksikan memiliki nama yang sepenuhnya memenuhi syarat yang sama dengan jenis Windows, tetapi ditempatkan di namespace C++ winrt . Menempatkan ini termasuk dalam header yang telah dikommpilasikan sebelumnya mengurangi waktu build inkremental.

Penting

Setiap kali Anda ingin menggunakan jenis dari namespace Layanan Windows, Anda harus #include memiliki file header namespace layanan Windows C++/WinRT yang sesuai, seperti yang ditunjukkan di atas. Header yang sesuai adalah header dengan nama yang sama dengan namespace tipe. Misalnya, untuk menggunakan proyeksi C++/WinRT untuk kelas runtime Windows::Foundation::Collections::P ropertySet , sertakan winrt/Windows.Foundation.Collections.h header.

Biasanya header proyeksi C++/WinRT secara otomatis menyertakan file header namespace terkait. Misalnya, winrt/Windows.Foundation.Collections.h termasuk winrt/Windows.Foundation.h. Tetapi Anda tidak boleh mengandalkan perilaku ini, karena ini adalah detail implementasi yang berubah dari waktu ke waktu. Anda harus secara eksplisit menyertakan header apa pun yang Anda butuhkan.

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

Direktif using namespace bersifat opsional, tetapi nyaman. Pola yang ditunjukkan di atas untuk arahan tersebut (memungkinkan pencarian nama yang tidak memenuhi syarat untuk apa pun di namespace winrt ) cocok untuk ketika Anda memulai proyek baru dan C++/WinRT adalah satu-satunya proyeksi bahasa yang Anda gunakan di dalam proyek tersebut. Jika, di sisi lain, Anda mencampur kode C++/WinRT dengan kode antarmuka biner aplikasi C++/CX dan/atau SDK (ABI) (Anda menggunakan porting, atau beroperasi dengan, satu atau kedua model tersebut), lalu lihat topik Interop antara C++/WinRT dan C++/CX, Pindah ke C++/WinRT dari C++/CX, dan Interop antara C++/WinRT dan ABI.

winrt::init_apartment();

Panggilan ke winrt::init_apartment menginisialisasi utas di Windows Runtime; secara default, di apartemen multithreaded. Panggilan juga menginisialisasi COM.

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

Stack-mengalokasikan dua objek: mereka mewakili uri blog Windows, dan klien sindikasi. Kami membuat uri dengan literal string lebar sederhana (lihat Penanganan string di C++/WinRT untuk cara lain Anda dapat bekerja dengan string).

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

SyndicationClient::RetrieveFeedAsync adalah contoh fungsi Windows Runtime asinkron. Contoh kode menerima objek operasi asinkron dari RetrieveFeedAsync, dan memanggil masuk ke objek tersebut untuk memblokir utas panggilan dan menunggu hasilnya (yang merupakan umpan sindikasi, dalam hal ini). Untuk informasi selengkapnya tentang konkurensi, dan untuk teknik non-pemblokiran, lihat Operasi konkurensi dan asinkron dengan C++/WinRT.

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

SyndicationFeed.Items adalah rentang, yang ditentukan oleh iterator yang dikembalikan dari fungsi awal dan akhir (atau konstanta, terbalik, dan konstanta-balik varian). Karena itu, Anda dapat menghitung Item dengan pernyataan berbasis for rentang, atau dengan fungsi templat std::for_each . Setiap kali Anda melakukan iterasi melalui koleksi Windows Runtime seperti ini, Anda harus #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;

Mendapatkan teks judul umpan, sebagai objek winrt::hstring (detail selengkapnya dalam penanganan String di C++/WinRT). Hstring kemudian dihasilkan, melalui fungsi c_str, yang mencerminkan pola yang digunakan dengan string Pustaka Standar C++.

Seperti yang Anda lihat, C++/WinRT mendorong ekspresi C++ modern, dan seperti kelas seperti syndicationItem.Title().Text(). Ini adalah gaya pemrograman yang berbeda, dan lebih bersih dari pemrograman COM tradisional. Anda tidak perlu langsung menginisialisasi COM, atau bekerja dengan penunjuk COM.

Anda juga tidak perlu menangani kode pengembalian HRESULT. C++/WinRT mengonversi kesalahan HRESULT menjadi pengecualian seperti winrt::hresult-error untuk gaya pemrograman alami dan modern. Untuk informasi selengkapnya tentang penanganan kesalahan, dan contoh kode, lihat Penanganan kesalahan dengan C++/WinRT.

Mengubah proyek aplikasi Windows Desktop untuk menambahkan dukungan C++/WinRT

Beberapa proyek desktop (misalnya, templat WinUI 3 di Visual Studio) memiliki dukungan C++/WinRT bawaan.

Tetapi bagian ini menunjukkan kepada Anda bagaimana Anda dapat menambahkan dukungan C++/WinRT ke proyek aplikasi Windows Desktop apa pun yang mungkin Anda miliki. Jika Anda tidak memiliki proyek aplikasi Windows Desktop yang sudah ada, maka Anda dapat mengikuti langkah-langkah ini dengan terlebih dahulu membuatnya. Misalnya, buka Visual Studio dan buat proyek Visual C++>Windows Desktop>Windows Desktop Application.

Anda dapat secara opsional menginstal C++/WinRT Visual Studio Extension (VSIX) dan paket NuGet. Untuk detailnya, lihat Dukungan Visual Studio untuk C++/WinRT.

Mengatur properti proyek

Buka properti proyek Versi Windows SDK Umum>, dan pilih Semua Konfigurasi dan Semua Platform. Pastikan bahwa Windows SDK Version diatur ke 10.0.17134.0 (Windows 10, versi 1803) atau lebih tinggi.

Konfirmasikan bahwa Anda tidak terpengaruh oleh Mengapa proyek baru saya tidak dikompilasi?.

Karena C++/WinRT menggunakan fitur dari standar C++17, atur properti proyek C/C++>Language>C++ Language Standard ke ISO C++17 Standard (/std:c++17).

Header yang telah dikommpilasikan sebelumnya

Templat proyek default membuat header yang telah dikommpilasikan sebelumnya untuk Anda, bernama framework.h, atau stdafx.h. Ganti nama itu menjadi pch.h. Jika Anda memiliki stdafx.cpp file, maka ganti namanya menjadi pch.cpp. Atur properti proyek C/C++>Header Precompiled Headers> Precompiled ke Create (/Yc), dan Precompiled Header File ke pch.h.

Temukan dan ganti semua #include "framework.h" (atau #include "stdafx.h") dengan #include "pch.h".

Dalam pch.h, sertakan winrt/base.h.

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

Menghubungkan

Proyeksi bahasa C++/WinRT bergantung pada fungsi Windows Runtime free (non-anggota) tertentu, dan titik masuk, yang memerlukan penautan ke pustaka payung WindowsApp.lib . Bagian ini menjelaskan tiga cara untuk memuaskan linker.

Opsi pertama adalah menambahkan ke proyek Visual Studio Anda semua properti dan target C++/WinRT MSBuild. Untuk melakukan ini, instal paket NuGet Microsoft.Windows.CppWinRT ke dalam proyek Anda. Buka proyek di Visual Studio, klik Kelola Proyek>Paket NuGet...>Telusuri, ketik, atau tempel Microsoft.Windows.CppWinRT di kotak pencarian, pilih item di hasil pencarian, lalu klik Instal untuk menginstal paket untuk proyek tersebut.

Anda juga dapat menggunakan pengaturan tautan proyek untuk menautkan WindowsApp.libsecara eksplisit . Atau, Anda dapat melakukannya dalam kode sumber (di pch.h, misalnya) seperti ini.

#pragma comment(lib, "windowsapp")

Anda sekarang dapat mengkompilasi dan menautkan, dan menambahkan kode C++/WinRT ke proyek Anda (misalnya, kode yang mirip dengan yang ditunjukkan di bagian mulai cepat A C++/WinRT, di atas).

Tiga skenario utama untuk C++/WinRT

Saat Anda menggunakan dan terbiasa dengan C++/WinRT, dan bekerja melalui sisa dokumentasi di sini, Anda mungkin akan melihat bahwa ada tiga skenario utama, seperti yang dijelaskan di bagian berikut.

Mengonsumsi API dan jenis Windows

Dengan kata lain, menggunakan, atau memanggil API. Misalnya, melakukan panggilan API untuk berkomunikasi menggunakan Bluetooth; untuk melakukan streaming dan menyajikan video; untuk berintegrasi dengan shell Windows; dan sebagainya. C++/WinRT sepenuhnya dan tanpa kompromi mendukung kategori skenario ini. Untuk informasi selengkapnya, lihat Menggunakan API dengan C++/WinRT.

Penulisan API dan jenis Windows

Dengan kata lain, memproduksi API dan jenis. Misalnya, memproduksi jenis API yang dijelaskan di bagian di atas; atau API grafis; API penyimpanan dan sistem file; API jaringan, dan sebagainya. Untuk informasi selengkapnya, lihat API Penulis dengan C++/WinRT.

Penulisan API dengan C++/WinRT sedikit lebih terlibat daripada mengonsumsinya, karena Anda harus menggunakan IDL untuk menentukan bentuk API sebelum Anda dapat mengimplementasikannya. Ada panduan untuk melakukannya dalam kontrol XAML; ikat ke properti C++/WinRT.

Aplikasi XAML

Skenario ini adalah tentang membangun aplikasi dan kontrol pada kerangka kerja UI XAML. Bekerja dalam aplikasi XAML berjumlah kombinasi mengkonsumsi dan menulis. Tetapi karena XAML adalah kerangka kerja UI yang dominan pada Windows saat ini, dan pengaruhnya atas Windows Runtime sebanding dengan itu, ia layak mendapatkan kategori skenarionya sendiri.

Ketahuilah bahwa XAML berfungsi paling baik dengan bahasa pemrograman yang menawarkan refleksi. Di C++/WinRT, Terkadang Anda harus melakukan sedikit pekerjaan ekstra untuk beroperasi dengan kerangka kerja XAML. Semua kasus tersebut tercakup dalam dokumentasi. Tempat yang baik untuk memulai adalah kontrol XAML; mengikat properti C++/WinRT dan kontrol kustom XAML (templat) dengan C++/WinRT.

Contoh aplikasi yang ditulis dalam C++/WinRT

Lihat Di mana saya dapat menemukan aplikasi sampel C++/WinRT?.

API penting