Menggunakan API hosting WinRT XAML di aplikasi desktop C++ (Win32)

Penting

Topik ini menggunakan atau menyebutkan jenis dari repositori GitHub CommunityToolkit/Microsoft.Toolkit.Win32 . Untuk informasi penting tentang dukungan Kepulauan XAML, silakan lihat Pemberitahuan Kepulauan XAML di repositori tersebut.

Mulai dari aplikasi desktop Windows 10, versi 1903, non-UWP (termasuk aplikasi desktop C++ (Win32), WPF, dan Formulir Windows) dapat menggunakan API hosting WinRT XAML untuk menghosting kontrol WinRT XAML di elemen UI apa pun yang terkait dengan handel jendela (HWND). API ini memungkinkan aplikasi desktop non-UWP untuk menggunakan fitur Windows UI terbaru yang hanya tersedia melalui kontrol WinRT XAML. Misalnya, aplikasi desktop non-UWP dapat menggunakan API ini untuk menghosting kontrol WinRT XAML yang menggunakan Sistem Fluent Design dan mendukung Windows Ink.

API hosting WinRT XAML menyediakan fondasi untuk serangkaian kontrol yang lebih luas yang kami sediakan untuk memungkinkan pengembang membawa UI Fasih ke aplikasi desktop non-UWP. Fitur ini disebut Kepulauan XAML. Untuk gambaran umum fitur ini, lihat Kontrol Host WinRT XAML di aplikasi desktop (Kepulauan XAML).

Catatan

Jika Anda memiliki umpan balik tentang Kepulauan XAML, buat masalah baru di repositori Microsoft.Toolkit.Win32 dan tinggalkan komentar Anda di sana.

Apakah API hosting WinRT XAML merupakan pilihan yang tepat untuk aplikasi desktop Anda?

API hosting WinRT XAML menyediakan infrastruktur tingkat rendah untuk menghosting kontrol WinRT XAML di aplikasi desktop. Beberapa jenis aplikasi desktop memiliki opsi untuk menggunakan API alternatif yang lebih nyaman untuk mencapai tujuan ini.

  • Jika Anda memiliki aplikasi desktop C++ dan ingin menghosting kontrol WinRT XAML di aplikasi, Anda harus menggunakan API hosting WinRT XAML. Tidak ada alternatif untuk jenis aplikasi ini.

  • Untuk aplikasi WPF dan Formulir Windows, kami sangat menyarankan Anda menggunakan kontrol .NET Pulau XAML di Windows Community Toolkit alih-alih menggunakan API hosting WinRT XAML secara langsung. Kontrol ini menggunakan API hosting WinRT XAML secara internal dan mengimplementasikan semua perilaku yang Anda perlukan untuk menangani diri Anda sendiri jika Anda menggunakan API hosting WinRT XAML secara langsung, termasuk navigasi keyboard dan perubahan tata letak.

Karena kami menyarankan agar hanya aplikasi desktop C++ yang menggunakan API hosting WinRT XAML, artikel ini terutama menyediakan instruksi dan contoh untuk aplikasi desktop C++. Namun, Anda dapat menggunakan API hosting WinRT XAML di WPF dan aplikasi Formulir Windows jika Anda memilih. Artikel ini menunjuk ke kode sumber yang relevan untuk kontrol host untuk WPF dan Formulir Windows di Toolkit Komunitas Windows sehingga Anda dapat melihat bagaimana API hosting WinRT XAML digunakan oleh kontrol tersebut.

Pelajari cara menggunakan XAML Hosting API

Untuk mengikuti instruksi langkah demi langkah dengan contoh kode untuk menggunakan XAML Hosting API di aplikasi desktop C++, lihat artikel berikut:

Sampel

Cara Anda menggunakan API hosting WinRT XAML dalam kode Anda tergantung pada jenis aplikasi Anda, desain aplikasi Anda, dan faktor lainnya. Untuk membantu mengilustrasikan cara menggunakan API ini dalam konteks aplikasi lengkap, artikel ini merujuk ke kode dari sampel berikut.

Desktop C++ (Win32)

Sampel berikut menunjukkan cara menggunakan API hosting WinRT XAML di aplikasi desktop C++:

  • Sampel Pulau XAML sederhana. Sampel ini menunjukkan implementasi dasar hosting kontrol WinRT XAML di aplikasi desktop C++ yang tidak dikemas.

  • Pulau XAML dengan sampel kontrol kustom. Sampel ini menunjukkan implementasi lengkap hosting kontrol WinRT XAML kustom dalam aplikasi desktop C++ paket, serta menangani perilaku lain seperti input keyboard dan navigasi fokus.

WPF dan Formulir Windows

Kontrol WindowsXamlHost di Windows Community Toolkit berfungsi sebagai sampel referensi untuk menggunakan API hosting WinRT XAML di WPF dan aplikasi Formulir Windows. Kode sumber tersedia di lokasi berikut:

Catatan

Kami sangat menyarankan Anda menggunakan kontrol .NET Pulau XAML di Windows Community Toolkit alih-alih menggunakan API hosting WinRT XAML langsung di WPF dan aplikasi Formulir Windows. Tautan sampel WPF dan Formulir Windows dalam artikel ini hanya untuk tujuan ilustrasi.

Arsitektur API

API hosting WinRT XAML mencakup jenis Windows Runtime utama dan antarmuka COM ini.

Jenis atau antarmuka Deskripsi
WindowsXamlManager Kelas ini mewakili kerangka kerja UWP XAML. Kelas ini menyediakan satu metode InitializeForCurrentThread statis yang menginisialisasi kerangka kerja XAML UWP pada utas saat ini di aplikasi desktop.
DesktopWindowXamlSource Kelas ini mewakili instans konten UWP XAML yang Anda hosting di aplikasi desktop Anda. Anggota terpenting dari kelas ini adalah properti Konten . Anda menetapkan properti ini ke Windows.UI.Xaml.UIElement yang ingin Anda host. Kelas ini juga memiliki anggota lain untuk merutekan navigasi fokus keyboard ke dalam dan keluar dari Kepulauan XAML.
IDesktopWindowXamlSourceNative Antarmuka COM ini menyediakan metode AttachToWindow , yang Anda gunakan untuk melampirkan Pulau XAML di aplikasi Anda ke elemen UI induk. Setiap objek DesktopWindowXamlSource mengimplementasikan antarmuka ini.
IDesktopWindowXamlSourceNative2 Antarmuka COM ini menyediakan metode PreTranslateMessage , yang memungkinkan kerangka kerja UWP XAML memproses pesan Windows tertentu dengan benar. Setiap objek DesktopWindowXamlSource mengimplementasikan antarmuka ini.

Diagram berikut mengilustrasikan hierarki objek di Pulau XAML yang dihosting di aplikasi desktop.

  • Pada tingkat dasar adalah elemen UI di aplikasi tempat Anda ingin menghosting Pulau XAML. Elemen UI ini harus memiliki handel jendela (HWND). Contoh elemen UI tempat Anda dapat menghosting Pulau XAML termasuk jendela untuk aplikasi desktop C++, System.Windows.Interop.HwndHost untuk aplikasi WPF, dan System.Windows.Forms.Control untuk aplikasi Formulir Windows.

  • Pada tingkat berikutnya adalah objek DesktopWindowXamlSource . Objek ini menyediakan infrastruktur untuk menghosting Pulau XAML. Kode Anda bertanggung jawab untuk membuat objek ini dan melampirkannya ke elemen UI induk.

  • Saat Anda membuat DesktopWindowXamlSource, objek ini secara otomatis membuat jendela anak asli untuk menghosting kontrol WinRT XAML Anda. Jendela anak asli ini sebagian besar diabstraksi jauh dari kode Anda, tetapi Anda dapat mengakses handelnya (HWND) jika perlu.

  • Terakhir, di tingkat atas adalah kontrol WinRT XAML yang ingin Anda host di aplikasi desktop Anda. Ini bisa menjadi objek UWP apa pun yang berasal dari Windows.UI.Xaml.UIElement, termasuk kontrol WinRT XAML yang disediakan oleh Windows SDK serta kontrol pengguna kustom.

DesktopWindowXamlSource architecture

Catatan

Saat Anda menghosting Kepulauan XAML di aplikasi desktop, Anda dapat memiliki beberapa pohon konten XAML yang berjalan pada utas yang sama secara bersamaan. Untuk mengakses elemen akar pohon konten XAML di Pulau XAML dan mendapatkan informasi terkait tentang konteks dihosting, gunakan kelas XamlRoot . API CoreWindow, ApplicationView, dan Window tidak akan memberikan informasi yang benar untuk Kepulauan XAML. Untuk informasi selengkapnya, lihat bagian ini.

Praktik Terbaik

Saat menggunakan API hosting WinRT XAML, ikuti praktik terbaik ini untuk setiap utas yang menghosting kontrol WinRT XAML:

  • Buat WindowsXamlManager khusus untuk utas.
  • Untuk setiap kontrol WinRT XAML yang ingin Anda host, buat DesktopWindowXamlSource.
  • Hancurkan setiap DesktopWindowXamlSource setelah tidak lagi diperlukan.
  • Sebelum keluar dari utas, hancurkan WindowsXamlManager khusus untuk utas. Perhatikan bahwa penghancuran WindowsXamlManager ini tidak sinkron, dan memerlukan pengurasan antrean pesan Windows sebelum keluar dari utas. Untuk contoh cara melakukannya, lihat sampel Kepulauan XAML.
  • Setelah menghancurkan WindowsXamlManager untuk utas tertentu, membuat WindowsXamlManager baru pada utas yang sama tidak didukung dan akan mengakibatkan perilaku yang tidak dapat diprediksi.

Pemecahan Masalah

Kesalahan saat menggunakan API hosting WinRT XAML di aplikasi UWP

Masalah Resolusi
Aplikasi Anda menerima COMException dengan pesan berikut: "Tidak dapat mengaktifkan DesktopWindowXamlSource. Jenis ini tidak dapat digunakan dalam aplikasi UWP." atau "Tidak dapat mengaktifkan WindowsXamlManager. Jenis ini tidak dapat digunakan dalam aplikasi UWP." Kesalahan ini menunjukkan Anda mencoba menggunakan API hosting WinRT XAML (khususnya, Anda mencoba membuat instans jenis DesktopWindowXamlSource atau WindowsXamlManager ) di aplikasi UWP. API hosting WinRT XAML hanya dimaksudkan untuk digunakan dalam aplikasi desktop non-UWP, seperti aplikasi desktop WPF, Formulir Windows, dan C++.

Kesalahan saat mencoba menggunakan jenis WindowsXamlManager atau DesktopWindowXamlSource

Masalah Resolusi
Aplikasi Anda menerima pengecualian dengan pesan berikut: "WindowsXamlManager dan DesktopWindowXamlSource didukung untuk aplikasi yang menargetkan Windows versi 10.0.18226.0 dan yang lebih baru. Silakan periksa manifes aplikasi atau manifes paket dan pastikan properti MaxTestedVersion diperbarui." Kesalahan ini menunjukkan bahwa aplikasi Anda mencoba menggunakan jenis WindowsXamlManager atau DesktopWindowXamlSource di API hosting WinRT XAML, tetapi OS tidak dapat menentukan apakah aplikasi dibuat untuk menargetkan Windows 10, versi 1903 atau yang lebih baru. API hosting WinRT XAML pertama kali diperkenalkan sebagai pratinjau di versi Windows 10 yang lebih lama, tetapi hanya didukung mulai dari Windows 10, versi 1903.

Untuk mengatasi masalah ini, buat paket MSIX untuk aplikasi dan jalankan dari paket, atau instal paket NuGet Microsoft.Toolkit.Win32.UI.SDK di proyek Anda.

Kesalahan melampirkan ke jendela pada utas yang berbeda

Masalah Resolusi
Aplikasi Anda menerima COMException dengan pesan berikut: "Metode AttachToWindow gagal karena HWND yang ditentukan dibuat pada utas yang berbeda." Kesalahan ini menunjukkan bahwa aplikasi Anda memanggil metode IDesktopWindowXamlSourceNative::AttachToWindow dan meneruskannya HWND jendela yang dibuat pada utas yang berbeda. Anda harus meneruskan metode ini HWND jendela yang dibuat pada utas yang sama dengan kode tempat Anda memanggil metode .

Kesalahan melampirkan ke jendela pada jendela tingkat atas yang berbeda

Masalah Resolusi
Aplikasi Anda menerima COMException dengan pesan berikut: "Metode AttachToWindow gagal karena HWND yang ditentukan turun dari jendela tingkat atas yang berbeda dari HWND yang sebelumnya diteruskan ke AttachToWindow pada utas yang sama." Kesalahan ini menunjukkan bahwa aplikasi Anda memanggil metode IDesktopWindowXamlSourceNative::AttachToWindow dan meneruskannya HWND jendela yang turun dari jendela tingkat atas yang berbeda dari jendela yang Anda tentukan dalam panggilan sebelumnya ke metode ini pada utas yang sama.

Setelah aplikasi Anda memanggil AttachToWindow pada utas tertentu, semua objek DesktopWindowXamlSource lainnya pada utas yang sama hanya dapat dilampirkan ke jendela yang merupakan turunan dari jendela tingkat atas yang sama yang diteruskan dalam panggilan pertama ke AttachToWindow. Ketika semua objek DesktopWindowXamlSource ditutup untuk utas tertentu, DesktopWindowXamlSource berikutnya kemudian bebas untuk dilampirkan ke jendela apa pun lagi.

Untuk mengatasi masalah ini, tutup semua objek DesktopWindowXamlSource yang terikat ke jendela tingkat atas lainnya pada utas ini, atau buat utas baru untuk DesktopWindowXamlSource ini.