Share via


Eine Windows App SDK-Migration der Beispiel-App für den UWP-Foto-Editor (C++/WinRT)

Dieses Thema ist eine Fallstudie zur Verwendung der C++/WinRT UWP-Foto-Editor-Beispiel-App und der Migration zur Windows App SDK.

Wichtig

Überlegungen und Strategien für die Annäherung an den Migrationsprozess sowie das Einrichten Ihrer Entwicklungsumgebung für die Migration finden Sie unter Gesamtmigrationsstrategie.

Installieren von Tools für das Windows App SDK

Informationen zum Einrichten Ihres Entwicklungscomputers finden Sie unter Installieren von Tools für das Windows App SDK.

Wichtig

Sie finden Themen mit Versionshinweisen zusammen mit dem Thema Windows App SDK – Veröffentlichungskanäle. Es gibt Versionshinweise für jeden Kanal. Überprüfen Sie unbedingt alle Einschränkungen und bekannten Probleme in diesen Versionshinweisen, da diese sich auf die Ergebnisse der Folgenden zusammen mit dieser Fallstudie und/oder ausführung der migrierten App auswirken können.

Erstellen eines neuen Projekts

  • Erstellen Sie in Visual Studio ein neues C++/WinRT-Projekt aus der Projektvorlage Leere App, Verpackt (WinUI 3 in Desktop). Nennen Sie das Projekt PhotoEditor, deaktivieren Sie Projektmappe und Projekt im selben Verzeichnis platzieren. Sie können auf das neueste Release (keine Vorschau) des Clientbetriebssystems abzielen.

Hinweis

Wir beziehen uns auf die UWP-Version des Beispielprojekts (die, die Sie aus dem Repository geklont haben) als Quelllösung/- projekt. Wir beziehen uns auf die Windows App SDK Version als Ziellösung bzw. das Zielprojekt.

Die Reihenfolge, in der der Code migriert wird

MainPage ist ein wichtiger und markanter Teil der App. Wenn wir jedoch mit der Migration beginnen würden, würden wir bald feststellen, dass MainPage eine Abhängigkeit von der DetailPage-Ansicht aufweist. und dann, dass DetailPage eine Abhängigkeit vom Fotomodell aufweist. Für diese exemplarische Vorgehensweise wird also dieser Ansatz verwendet.

  • Wir beginnen mit dem Kopieren der Objektdateien.
  • Anschließend migrieren wir das Fotomodell .
  • Als Nächstes migrieren wir die App-Klasse (da dafür einige Member hinzugefügt werden müssen, von denen DetailPage und MainPage abhängen).
  • Anschließend beginnen wir mit der Migration der Ansichten, beginnend mit DetailPage .
  • Abschließend wird die MainPage-Ansicht migriert.

Wir kopieren die gesamten Quellcodedateien.

In dieser exemplarischen Vorgehensweise kopieren wir Quellcodedateien mithilfe von Explorer. Wenn Sie Dateiinhalte lieber kopieren möchten, finden Sie im Abschnitt Anhang: Kopieren des Inhalts der Dateien des Fotomodells am Ende dieses Themas ein Beispiel dafür, wie Sie dies für Photo tun können (und Sie könnten dann ein ähnliches Verfahren auf andere Typen im Projekt anwenden). Diese Option umfasst jedoch noch viel mehr Schritte.

Kopieren von Objektdateien

  1. Suchen Sie in Ihrem Klon des Quellprojekts in Explorer den Ordner Windows-appsample-photo-editor>PhotoEditor>Assets. In diesem Ordner befinden sich acht Medienobjektdateien. Wählen Sie diese acht Dateien aus, und kopieren Sie sie in die Zwischenablage.

  2. Suchen Sie nun auch in Explorer den entsprechenden Ordner im von Ihnen erstellten Zielprojekt. Der Pfad zu diesem Ordner lautet PhotoEditor>PhotoEditor>Assets. Fügen Sie die soeben kopierten Objektdateien in diesen Ordner ein, und akzeptieren Sie die Aufforderung, um die sieben Dateien zu ersetzen, die bereits im Ziel vorhanden sind.

  3. Erweitern Sie in Ihrem Zielprojekt in Visual Studio in Projektmappen-Explorer den Ordner Assets. Fügen Sie diesem Ordner die vorhandene bg1.png Medienobjektdatei hinzu, die Sie gerade eingefügt haben. Sie können mit dem Mauszeiger auf die Medienobjektdateien zeigen. Für jede wird eine Miniaturansicht angezeigt, die bestätigt, dass Sie die Ressourcendateien ordnungsgemäß ersetzt bzw. hinzugefügt haben.

Migrieren des Fotomodells

Photo ist eine Laufzeitklasse, die ein Foto darstellt. Es handelt sich um ein Modell (im Sinne von Modellen, Ansichten und Ansichtsmodellen).

Kopieren von Fotoquellcodedateien

  1. Suchen Sie in Ihrem Klon des Quellprojekts in Explorer den Ordner Windows-appsample-photo-editor>PhotoEditor. In diesem Ordner finden Sie die drei Quellcodedateien Photo.idl, Photo.hund Photo.cpp. Diese Dateien implementieren zusammen die Photo-Laufzeitklasse . Wählen Sie diese drei Dateien aus, und kopieren Sie sie in die Zwischenablage.

  2. Klicken Sie in Visual Studio mit der rechten Maustaste auf den Zielprojektknoten, und klicken Sie auf Ordner in Explorer öffnen. Dadurch wird der Zielprojektordner in Explorer geöffnet. Fügen Sie in diesen Ordner die drei Dateien ein, die Sie gerade kopiert haben.

  3. Stellen Sie in Projektmappen-Explorer mit ausgewähltem Zielprojektknoten sicher, dass Alle Dateien anzeigen aktiviert ist. Klicken Sie mit der rechten Maustaste auf die drei Dateien, die Sie gerade eingefügt haben, und klicken Sie auf In Projekt einschließen. Schalten Sie Alle Dateien anzeigen aus.

  4. Im Quellprojekt, in Projektmappen-Explorer und .cpp werden unter Photo.idl geschachtelt, Photo.h um anzugeben, dass sie (abhängig davon) generiert werden. Wenn Ihnen diese Anordnung gefällt, können Sie dasselbe im Zielprojekt tun, indem Sie manuell bearbeiten \PhotoEditor\PhotoEditor\PhotoEditor\PhotoEditor.vcxproj (Sie müssen zuerst alle in Visual Studio speichern ). Suchen Sie nach:

    <ClInclude Include="Photo.h" />
    

    Ersetzen Sie sie durch Folgendes:

    <ClInclude Include="Photo.h">
      <DependentUpon>Photo.idl</DependentUpon>
    </ClInclude>
    

    Wiederholen Sie dies für Photo.cpp, und speichern und schließen Sie die Projektdatei. Wenn Sie den Fokus wieder auf Visual Studio festlegen, klicken Sie auf Neu laden.

Migrieren des Quellcodes für Fotos

  1. Suchen Sie in Photo.idlnach dem Namespacenamen Windows.UI.Xaml (der Namespace für UWP-XAML), und ändern Sie diesen in Microsoft.UI.Xaml (der Namespace für WinUI XAML).

Hinweis

Das Thema Zuordnen von UWP-APIs zum Windows App SDK bietet eine Zuordnung von UWP-APIs zu ihren Windows App SDK Entsprechungen. Die oben vorgenommene Änderung ist ein Beispiel für eine Änderung des Namespacenamens, die während des Migrationsprozesses erforderlich ist.

  1. Fügen Photo.cppSie #include "Photo.g.cpp" in den vorhandenen include-Anweisungen direkt nach #include "Photo.h"hinzu. Dies ist einer der Unterschiede zwischen Ordner und Dateinamen (C++/WinRT), die zwischen UWP- und Windows App SDK-Projekten beachtet werden sollen.

  2. Stellen Sie im Inhalt des gesamten Quellcodes in den Dateien, die Sie gerade kopiert und eingefügt haben, den folgenden Such-/Ersetzungsvorgang (Groß-/Kleinschreibung und ganzes Wort) vor.

    • Windows::UI::Xaml =>Microsoft::UI::Xaml
  3. Kopieren Sie pch.h aus dem Quellprojekt die folgenden Includes, und fügen Sie sie in pch.h das Zielprojekt ein. Dies ist eine Teilmenge der Headerdateien, die im Quellprojekt enthalten sind. Dies sind nur die Header, die wir benötigen, um den bisher migrierten Code zu unterstützen.

    #include <winrt/Microsoft.UI.Xaml.Media.Imaging.h>
    #include <winrt/Windows.Storage.h>
    #include <winrt/Windows.Storage.FileProperties.h>
    #include <winrt/Windows.Storage.Streams.h>
    
  4. Vergewissern Sie sich nun, dass Sie die Ziellösung erstellen können (aber noch nicht ausgeführt werden).

Migrieren der App-Klasse

Es sind keine Änderungen an den Und App.xamldes Zielprojekts App.idl erforderlich. Aber wir müssen und App.xaml.cpp bearbeitenApp.xaml.h, um der App-Klasse einige neue Mitglieder hinzuzufügen. Wir tun dies auf eine Weise, die es uns ermöglicht, nach jedem Abschnitt zu erstellen (mit Ausnahme des letzten Abschnitts, der sich um App::OnLaunched handelt).

Verfügbarmachen des Standard Fensterobjekts

In diesem Schritt nehmen wir die Änderung vor, die unter Ändern von Windows.UI.Xaml.Window.Current in App.Window erläutert wird.

Im Zielprojekt speichert App das Standard Fensterobjekt in seinem privaten Datenmemberfenster. Später im Migrationsprozess (wenn wir die Verwendung von Window.Current im Quellprojekt migrieren), ist es praktisch, wenn dieser Fensterdatenmember statisch ist. und wird auch über eine Accessorfunktion zur Verfügung gestellt. Daher nehmen wir diese Änderungen als Nächstes vor.

  • Da wir das Fenster statisch machen, müssen wir es in App.xaml.cpp initialisieren und nicht über den Standardelementinitialisierer, den der Code derzeit verwendet. Im Folgenden sehen diese Änderungen in App.xaml.h und App.xaml.cppaus.

    // App.xaml.h
    ...
    struct App : AppT<App>
    {
         ...
         static winrt::Microsoft::UI::Xaml::Window Window(){ return window; };
    
    private:
         static winrt::Microsoft::UI::Xaml::Window window;
    };
    ...
    
    // App.xaml.cpp
    ...
    winrt::Microsoft::UI::Xaml::Window App::window{ nullptr };
    ...
    

App::OnNavigationFailed

Die Beispiel-App für den Foto-Editor verwendet Navigationslogik, um zwischen MainPage und DetailPage zu navigieren. Weitere Informationen zu Windows App SDK Apps, die Navigation benötigen (und solche, die dies nicht tun), finden Sie unter Muss ich die Seitennavigation implementieren?.

Daher sind die Mitglieder, die wir in den nächsten Abschnitten migrieren werden, alle vorhanden, um die Navigation innerhalb der App zu unterstützen.

  1. Beginnen wir mit der Migration des OnNavigationFailed-Ereignishandlers . Kopieren Sie die Deklaration und die Definition dieser Memberfunktion aus dem Quellprojekt, und fügen Sie sie in das Zielprojekt ein (in App.xaml.h und App.xaml.cpp).

  2. Ändern Windows::UI::Xaml Sie im Code, den Sie in App.xaml.heingefügt haben, in Microsoft::UI::Xaml.

App::CreateRootFrame

  1. Das Quellprojekt enthält eine Hilfsfunktion namens App::CreateRootFrame. Kopieren Sie die Deklaration und die Definition dieser Hilfsfunktion aus dem Quellprojekt, und fügen Sie sie in das Zielprojekt ein (in App.xaml.h und App.xaml.cpp).

  2. Ändern Windows::UI::Xaml Sie im Code, den Sie in App.xaml.heingefügt haben, in Microsoft::UI::Xaml.

  3. Ändern Sie im Code, den Sie in App.xaml.cppeingefügt haben, die beiden Vorkommen von Window::Current() in window (der Name des Datenmembers der Zuvor gesehenen App-Klasse ).

App::OnLaunched

Das Zielprojekt enthält bereits eine Implementierung des OnLaunched-Ereignishandlers . Der Parameter ist ein konstanter Verweis auf ein Microsoft::UI::Xaml::LaunchActivatedEventArgs, das für die Windows App SDK korrekt ist (im Gegensatz zum Quellprojekt, das Windows::ApplicationModel::Activation::LaunchActivatedEventArgs verwendet, was für UWP korrekt ist).

  • Wir müssen nur die beiden Definitionen (Quelle und Ziel) von OnLaunched zusammenführen, damit App::OnLaunchedApp.xaml.cpp im Zielprojekt wie die folgende Auflistung aussieht. Beachten Sie, dass (anstelle von Window::Current()) verwendet wird window , wie es bei der UWP-Version der Fall ist.

    void App::OnLaunched(LaunchActivatedEventArgs const&)
    {
         window = make<MainWindow>();
    
         Frame rootFrame = CreateRootFrame();
         if (!rootFrame.Content())
         {
             rootFrame.Navigate(xaml_typename<PhotoEditor::MainPage>());
         }
    
         window.Activate();
    }
    

Der obige Code gibt App eine Abhängigkeit von MainPage, sodass wir von diesem Punkt an erst erstellen können, wenn wir DetailPage und dann MainPage migriert haben. Wenn wir in der Lage sind, wieder zu erstellen, werden wir dies sagen.

Migrieren der DetailPage-Ansicht

DetailPage ist die Klasse, die die Foto-Editor-Seite darstellt, auf der Win2D-Effekte umgeschaltet, festgelegt und miteinander verkettet werden. Sie gelangen zur Foto-Editor-Seite, indem Sie auf MainPage eine Fotominiaturansicht auswählen. DetailPage ist eine Ansicht (im Sinne von Modellen, Ansichten und ViewModels).

Verweisen auf das Win2D-NuGet-Paket

Um Code in DetailPage zu unterstützen, ist das Quellprojekt von Microsoft.Graphics.Win2D abhängig. Daher benötigen wir auch eine Abhängigkeit von Win2D in unserem Zielprojekt.

  • Klicken Sie in der Zielprojektmappe in Visual Studio auf Tools>NuGet-Paket-Manager>NuGet-Pakete für Projektmappe verwalten...>Durchsuchen. Stellen Sie sicher, dass Vorabversion einschließen deaktiviert ist, und geben Sie Microsoft.Graphics.Win2D in das Suchfeld ein, oder fügen Sie es ein. Wählen Sie das richtige Element in den Suchergebnissen aus, überprüfen Sie das PhotoEditor-Projekt , und klicken Sie auf Installieren , um das Paket zu installieren.

Kopieren von DetailPage-Quellcodedateien

  1. Suchen Sie in Ihrem Klon des Quellprojekts in Explorer den Ordner Windows-appsample-photo-editor>PhotoEditor. In diesem Ordner finden Sie die vier Quellcodedateien DetailPage.idl, DetailPage.xaml, DetailPage.hund DetailPage.cpp. Diese Dateien implementieren zusammen die DetailPage-Ansicht . Wählen Sie diese vier Dateien aus, und kopieren Sie sie in die Zwischenablage.

  2. Klicken Sie in Visual Studio mit der rechten Maustaste auf den Zielprojektknoten, und klicken Sie auf Ordner in Explorer öffnen. Dadurch wird der Zielprojektordner in Explorer geöffnet. Fügen Sie in diesen Ordner die vier Dateien ein, die Sie gerade kopiert haben.

  3. Ändern Sie in Explorer die Namen von DetailPage.h und DetailPage.cpp in DetailPage.xaml.h bzwDetailPage.xaml.cpp. . Dies ist einer der Unterschiede zwischen Ordner und Dateinamen (C++/WinRT), die zwischen UWP- und Windows App SDK-Projekten beachtet werden sollen.

  4. Stellen Sie in Projektmappen-Explorer mit ausgewähltem Zielprojektknoten sicher, dass Alle Dateien anzeigen aktiviert ist. Klicken Sie mit der rechten Maustaste auf die vier Dateien, die Sie gerade eingefügt (und umbenannt haben), und klicken Sie dann auf In Projekt einschließen. Schalten Sie Alle Dateien anzeigen aus.

  5. Im Quellprojekt in Projektmappen-ExplorerDetailPage.idl ist unter DetailPage.xamlgeschachtelt. Wenn Ihnen diese Anordnung gefällt, können Sie dasselbe im Zielprojekt tun, indem Sie manuell bearbeiten \PhotoEditor\PhotoEditor\PhotoEditor\PhotoEditor.vcxproj (Sie müssen zuerst alle in Visual Studio speichern ). Suchen Sie nach:

    <Midl Include="DetailPage.idl" />
    

    Ersetzen Sie sie durch Folgendes:

    <Midl Include="DetailPage.idl">
      <DependentUpon>DetailPage.xaml</DependentUpon>
    </Midl>
    

Speichere und schließe die Projektdatei. Wenn Sie den Fokus wieder auf Visual Studio festlegen, klicken Sie auf Neu laden.

Migrieren des DetailPage-Quellcodes

  1. Suchen Sie in DetailPage.idlnach Windows.UI.Xaml, und ändern Sie dies in Microsoft.UI.Xaml.

  2. Ändern Sie in DetailPage.xaml.cpp den Eintrag #include "DetailPage.h" in #include "DetailPage.xaml.h".

  3. Fügen Sie direkt darunter hinzu #include "DetailPage.g.cpp".

  4. Fügen #include "App.xaml.h" Sie unmittelbar vor #include "Photo.h"für den Aufruf der statischen App::Window-Methode (die wir hinzufügen werden) zum Kompilieren noch in DetailPage.xaml.cpphinzu.

  5. Nehmen Sie die folgenden Such-/Ersetzungen (Groß-/Kleinschreibung und ganzes Wort) im Inhalt des Quellcodes in den Dateien vor, die Sie gerade kopiert und eingefügt haben.

    • In DetailPage.xaml.h und .xaml.cpp, Windows::UI::Composition =>Microsoft::UI::Composition
    • In DetailPage.xaml.h und .xaml.cpp, Windows::UI::Xaml =>Microsoft::UI::Xaml
    • In DetailPage.xaml.cpp, Window::Current() =>App::Window()
  6. Kopieren Sie pch.h aus dem Quellprojekt die folgenden Includes, und fügen Sie sie in pch.h das Zielprojekt ein.

    #include <winrt/Windows.Graphics.Effects.h>
    #include <winrt/Microsoft.Graphics.Canvas.Effects.h>
    #include <winrt/Microsoft.Graphics.Canvas.UI.Xaml.h>
    #include <winrt/Microsoft.UI.Composition.h>
    #include <winrt/Microsoft.UI.Xaml.Input.h>
    #include <winrt/Windows.Graphics.Imaging.h>
    #include <winrt/Windows.Storage.Pickers.h>
    
  7. Fügen Sie außerdem direkt pch.hnach #pragma onceoben von folgendes hinzu:

    // This is required because we are using std::min and std::max, otherwise 
    // we have a collision with min and max macros being defined elsewhere.
    #define NOMINMAX
    

Wir können noch nicht erstellen, aber wir können dies nach der Migration von MainPage (als Nächstes) durchführen.

Migrieren der MainPage-Ansicht

Die seite Standard der App stellt die Ansicht dar, die Beim Ausführen der App zuerst angezeigt wird. Dies ist die Seite, auf der die Fotos aus der Bildbibliothek geladen werden und eine gekachelte Miniaturansicht angezeigt wird.

Kopieren von MainPage-Quellcodedateien

  1. Ähnlich wie bei DetailPage kopieren Sie jetzt über MainPage.idl, MainPage.xaml, MainPage.hund MainPage.cpp.

  2. Benennen Sie die .h Dateien und .cpp in bzw.xaml.cpp. um.xaml.h.

  3. Schließen Sie alle vier Dateien wie zuvor in das Zielprojekt ein.

  4. Im Quellprojekt in Projektmappen-ExplorerMainPage.idl ist unter MainPage.xamlgeschachtelt. Wenn Ihnen diese Anordnung gefällt, können Sie dasselbe im Zielprojekt tun, indem Sie manuell bearbeiten \PhotoEditor\PhotoEditor\PhotoEditor\PhotoEditor.vcxproj. Suchen Sie nach:

    <Midl Include="MainPage.idl" />
    

    Und ersetzen Sie sie durch:

    <Midl Include="MainPage.idl">
      <DependentUpon>MainPage.xaml</DependentUpon>
    </Midl>
    

Migrieren des MainPage-Quellcodes

  1. Suchen Sie in MainPage.idlnach Windows.UI.Xaml, und ändern Sie beide Vorkommen in Microsoft.UI.Xaml.

  2. Ändern Sie in MainPage.xaml.cpp den Eintrag #include "MainPage.h" in #include "MainPage.xaml.h".

  3. Fügen Sie direkt darunter hinzu #include "MainPage.g.cpp".

  4. Fügen #include "App.xaml.h" Sie unmittelbar vor #include "Photo.h"für den Aufruf der statischen App::Window-Methode (die wir hinzufügen werden) zum Kompilieren noch in MainPage.xaml.cpphinzu.

Im nächsten Schritt nehmen wir die unter ContentDialog und Popup erläuterte Änderung vor.

  1. Fügen Sie also in MainPage.xaml.cppder MainPage::GetItemsAsync-Methode unmittelbar nach der Zeile ContentDialog unsupportedFilesDialog{};diese Codezeile hinzu.

    unsupportedFilesDialog.XamlRoot(this->Content().XamlRoot());
    
  2. Nehmen Sie die folgenden Such-/Ersetzungen (Groß-/Kleinschreibung und ganzes Wort) im Inhalt des Quellcodes in den Dateien vor, die Sie gerade kopiert und eingefügt haben.

    • In MainPage.xaml.h und .xaml.cpp, Windows::UI::Composition =>Microsoft::UI::Composition
    • In MainPage.xaml.h und .xaml.cpp, Windows::UI::Xaml =>Microsoft::UI::Xaml
    • In MainPage.xaml.cpp, Window::Current() =>App::Window()
  3. Kopieren Sie pch.h aus dem Quellprojekt die folgenden Includes, und fügen Sie sie in pch.h das Zielprojekt ein.

    #include <winrt/Microsoft.UI.Xaml.Hosting.h>
    #include <winrt/Microsoft.UI.Xaml.Media.Animation.h>
    #include <winrt/Windows.Storage.Search.h>
    

Vergewissern Sie sich, dass Sie die Ziellösung erstellen können (aber noch nicht ausgeführt werden).

Aktualisieren von MainWindow

  1. Löschen MainWindow.xamlSie in das StackPanel und den zugehörigen Inhalt, da wir keine Benutzeroberfläche in MainWindow benötigen. Dadurch bleibt nur das leere Window-Element erhalten.

  2. Löschen MainWindow.idlSie in den Platzhalter Int32 MyProperty;, wobei nur der Konstruktor übrig bleibt.

  3. Löschen Sie in MainWindow.xaml.h und MainWindow.xaml.cppdie Deklarationen und Definitionen des Platzhalters MyProperty und myButton_Click, wobei nur der Konstruktor beibehalten wird.

Migrationsänderungen, die für den Threadingmodellunterschied erforderlich sind

Die beiden Änderungen in diesem Abschnitt sind aufgrund eines Threadingmodells zwischen UWP und dem Windows App SDK erforderlich, wie unter ASTA zu STA-Threadingmodell beschrieben. Hier finden Sie eine kurze Beschreibung der Ursachen der Probleme und dann eine Möglichkeit, die einzelnen Probleme zu beheben.

MainPage

MainPage lädt Bilddateien aus dem Ordner Bilder , ruft StorageItemContentProperties.GetImagePropertiesAsync auf, um die Eigenschaften der Bilddatei abzurufen, erstellt ein Fotomodellobjekt für jede Bilddatei (speichert dieselben Eigenschaften in einem Datenmember), und fügt dieses Photo-Objekt einer Auflistung hinzu. Die Auflistung von Photo-Objekten ist an ein GridView-Objekt in der Benutzeroberfläche gebunden. Im Namen dieses GridView-Objekts verarbeitet MainPage das ContainerContentChanging-Ereignis , und für Phase 1 ruft dieser Handler in eine Coroutine auf, die StorageFile.GetThumbnailAsync aufruft. Dieser Aufruf von GetThumbnailAsync führt dazu, dass Nachrichten gepumpt werden (es wird nicht sofort zurückgegeben und die gesamte Arbeit asynchron ausgeführt), und dies führt zu erneuter Anfälligkeit. Das Ergebnis ist, dass die Items-Auflistung der GridView geändert wird, während das Layout stattfindet, was zu einem Absturz führt.

Wenn wir den Aufruf von StorageItemContentProperties::GetImagePropertiesAsync auskommentieren, erhalten wir den Absturz nicht. Die eigentliche Lösung besteht jedoch darin, den StorageFile.GetThumbnailAsync-Aufruf explizit asynchron zu machen, indem er direkt vor dem Aufruf von GetThumbnailAsync auf wil::resume_foreground wartet. Dies funktioniert, weil wil::resume_foreground den darauf folgenden Code als Aufgabe in der DispatcherQueue plant.

Der folgende Code muss geändert werden:

// MainPage.xaml.cpp
IAsyncAction MainPage::OnContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
    ...
    if (args.Phase() == 1)
    {
        ...
        try
        {
            co_await wil::resume_foreground(this->DispatcherQueue());
            auto thumbnail = co_await impleType->GetImageThumbnailAsync(this->DispatcherQueue());
            image.Source(thumbnail);
        }
        ...
    }
}

Photo

Die Photo::ImageTitle-Eigenschaft ist an die Benutzeroberfläche gebunden, sodass die Benutzeroberfläche die Accessorfunktion für diese Eigenschaft aufruft, wenn sie ihren Wert benötigt. Wenn wir jedoch versuchen, über diese Accessorfunktion im UI-Thread auf ImageProperties.Title zuzugreifen, erhalten wir eine Zugriffsverletzung.

Stattdessen können wir nur einmal über den Konstruktor von Photo auf diesen Titel zugreifen und ihn im m_imageName Datenmember speichern, wenn er nicht leer ist. Dann müssen wir in der Photo::ImageTitle-Accessorfunktion nur auf den m_imageName Datenmember zugreifen.

Der folgende Code muss geändert werden:

// Photo.h
...
Photo(Photo(Windows::Storage::FileProperties::ImageProperties const& props,
    ...
    ) : ...
{
	if (m_imageProperties.Title() != L"")
	{
		m_imageName = m_imageProperties.Title();
	}
}
...
hstring ImageTitle() const
{
	return m_imageName;
}
...

Dies sind die letzten Änderungen, die wir vornehmen müssen, um die Foto-Editor-Beispiel-App zu migrieren. Im Abschnitt Testen der migrierten App bestätigen wir, dass wir die Schritte ordnungsgemäß ausgeführt haben.

Bekannte Probleme

App-Typproblem (betrifft nur Vorschau 3)

Wenn Sie diese Fallstudie mit der Projektvorlage von VSIX für Windows App SDK Version 1.0 Preview 3 befolgt haben, müssen Sie eine kleine Korrektur an PhotoEditor.vcxprojvornehmen. Hierzu gehst du wie folgt vor.

Klicken Sie in Visual Studio in Projektmappen-Explorer mit der rechten Maustaste auf den Projektknoten, und klicken Sie auf Projekt entladen. Jetzt PhotoEditor.vcxproj ist für die Bearbeitung geöffnet. Fügen Sie als erstes untergeordnetes Element von Project ein PropertyGroup-Element wie folgt hinzu:

<Project ... >
    <PropertyGroup>
        <EnableWin32Codegen>true</EnableWin32Codegen>
    </PropertyGroup>
    <Import ... />
...

Speichern und schließen Sie PhotoEditor.vcxproj. Klicken Sie mit der rechten Maustaste auf den Projektknoten, und klicken Sie dann auf Projekt neu laden. Erstellen Sie nun das Projekt neu.

Testen der migrierten App

Erstellen Sie nun das Projekt, und führen Sie die App aus, um es zu testen. Wählen Sie ein Bild aus, legen Sie einen Zoomfaktor fest, wählen Sie Effekte aus, und konfigurieren Sie sie.

Anhang: Kopieren des Inhalts der Dateien des Fotomodells

Wie bereits erwähnt, haben Sie die Möglichkeit, Quellcodedateien selbst oder den Inhalt von Quellcodedateien zu kopieren. Wir haben bereits gezeigt, wie Quellcodedateien selbst kopiert werden. Daher enthält dieser Abschnitt ein Beispiel für das Kopieren von Dateiinhalten.

Suchen Sie im Quellprojekt in Visual Studio den Ordner PhotoEditor (Universelle Windows)>Modelle. Dieser Ordner enthält die Dateien Photo.idl, Photo.hund Photo.cpp, die zusammen die Photo-Laufzeitklasse implementieren.

Hinzufügen der IDL und Generieren von Stubs

Fügen Sie in Ihrem Zielprojekt in Visual Studio dem Projekt ein neues Midl File-Element (.idl) hinzu. Benennen Sie das neue Element Photo.idl. Löschen Sie den Standardinhalt von Photo.idl.

Kopieren Sie aus dem Quellprojekt in Visual Studio den Inhalt von Modellen>Photo.idl, und fügen Sie sie in die Photo.idl Datei ein, die Sie ihrem Zielprojekt gerade hinzugefügt haben. Suchen Sie im eingefügten Code nach Windows.UI.Xaml, und ändern Sie den Code in Microsoft.UI.Xaml.

Speichern Sie die Datei .

Wichtig

Wir sind dabei, einen Build Ihrer Ziellösung durchzuführen. Der Build wird zu diesem Zeitpunkt nicht bis zum Abschluss ausgeführt, aber er wird weit genug sein, um die erforderlichen Arbeiten für uns zu erledigen.

Erstellen Sie nun die Ziellösung. Obwohl es nicht abgeschlossen wird, ist das Erstellen jetzt erforderlich, da die Quellcodedateien (Stubs) generiert werden, die wir für die Implementierung des Fotomodells benötigen.

Klicken Sie in Visual Studio mit der rechten Maustaste auf den Zielprojektknoten, und klicken Sie auf Ordner in Explorer öffnen. Dadurch wird der Zielprojektordner in Explorer geöffnet. Navigieren Sie dort in den Generated Files\sources Ordner (sie befinden sich also in \PhotoEditor\PhotoEditor\PhotoEditor\Generated Files\sources). Kopieren Sie die Stubdateien Photo.h und .cpp, und fügen Sie sie in den Projektordner ein, der jetzt zwei Ordnerebenen in aufwärts \PhotoEditor\PhotoEditor\PhotoEditorist.

Stellen Sie in Projektmappen-Explorer mit ausgewähltem Zielprojektknoten sicher, dass Alle Dateien anzeigen aktiviert ist. Klicken Sie mit der rechten Maustaste auf die soeben eingefügten Stubdateien (Photo.h und .cpp), und klicken Sie auf In Projekt einschließen. Schalten Sie Alle Dateien anzeigen aus.

Am Anfang des Inhalts von Photo.h und .cppwird eine static_assert angezeigt, die Sie löschen müssen.

Vergewissern Sie sich, dass Sie erneut erstellen können (aber noch nicht ausführen).

Migrieren von Code in die Stubs

Kopieren Sie den Inhalt von Photo.h und .cpp aus dem Quellprojekt in das Zielprojekt.

Von hier aus sind die verbleibenden Schritte zum Migrieren des kopierten Codes identisch mit denen im Abschnitt Migrieren des Quellcodes für Fotos.