Uma migração do SDK do Aplicativo Windows do aplicativo de exemplo Photo Editor da UWP (C++/WinRT)

Este tópico é um estudo de caso sobre como usar o aplicativo de exemplo editor de fotos UWP do C++/WinRT e migrá-lo para o SDK do Aplicativo Windows.

Importante

Para obter considerações e estratégias para abordar o processo de migração e como configurar seu ambiente de desenvolvimento para migração, consulte Estratégia geral de migração.

Instalar ferramentas para o SDK do Aplicativo Windows

Para configurar o ambiente de desenvolvimento, confira Instalar ferramentas para o SDK do Aplicativo Windows.

Importante

Você encontrará tópicos de notas de versão com o tópico Canais de versão do SDK do Aplicativo Windows. Há notas de versão para cada canal. Certifique-se de marcar quaisquer limitações e problemas conhecidos nessas notas sobre a versão, pois elas podem afetar os resultados de acompanhar este estudo de caso e/ou executar o aplicativo migrado.

Criar um novo projeto

  • No Visual Studio, crie um novo projeto C++/WinRT do modelo de projeto Aplicativo em Branco, Empacotado (WinUI 3 na Área de Trabalho). Nomeie o projeto como PhotoEditor, desmarque Colocar solução e projeto no mesmo diretório. Você pode ter como alvo a versão mais recente (não a versão prévia) do sistema operacional cliente.

Observação

Vamos nos referir à versão UWP do projeto de exemplo (aquela que você clonou de seu repositório) como a solução/projeto de origem . Vamos nos referir à versão SDK do Aplicativo Windows como a solução/projeto de destino.

A ordem na qual migraremos o código

MainPage é uma parte importante e proeminente do aplicativo. Mas se começarmos migrando isso, logo perceberíamos que MainPage tem uma dependência no modo de exibição DetailPage ; e, em seguida, que DetailPage tem uma dependência no modelo foto . Portanto, para este passo a passo, vamos adotar essa abordagem.

  • Começaremos copiando os arquivos de ativo.
  • Em seguida, migraremos o modelo foto .
  • Em seguida, migraremos a classe App (porque isso precisa de alguns membros adicionando a ela que DetailPage e MainPage dependerão).
  • Em seguida, começaremos a migrar os modos de exibição, começando com DetailPage primeiro.
  • E terminaremos migrando o modo de exibição MainPage .

Copiaremos arquivos de código-fonte inteiros

Neste passo a passo, copiaremos arquivos de código-fonte usando Explorador de Arquivos. Se você preferir copiar o conteúdo do arquivo em vez disso, consulte a seção Apêndice: copiando o conteúdo dos arquivos do modelo de foto no final deste tópico para obter um exemplo de como você poderia fazer isso para Foto (e, em seguida, você pode aplicar um procedimento semelhante a outros tipos no projeto). No entanto, essa opção envolve muito mais etapas.

Copiar arquivos de ativo

  1. No clone do projeto de origem, em Explorador de Arquivos, localize a pasta Windows-appsample-photo-editor>PhotoEditor>Assets. Você encontrará oito arquivos de ativos nessa pasta. Selecione esses oito arquivos e copie-os para a área de transferência.

  2. Também no Explorador de Arquivos, agora localize a pasta correspondente no projeto de destino que você criou. O caminho para essa pasta é PhotoEditor>PhotoEditor>Assets. Cole nessa pasta os arquivos de ativo que você acabou de copiar e aceite o prompt para substituir os sete arquivos que já existem no destino.

  3. No projeto de destino no Visual Studio, em Gerenciador de Soluções, expanda a pasta Ativos. Adicione a essa pasta o arquivo de ativo existente bg1.png que você acabou de colar. Você pode passar o ponteiro do mouse sobre os arquivos de ativo. Uma visualização em miniatura será exibida para cada um, confirmando que você substituiu/adicionou os arquivos de ativos corretamente.

Migrar o modelo de Foto

Photo é uma classe de runtime que representa uma foto. É um modelo (no sentido de modelos, exibições e viewmodels).

Copiar arquivos de código-fonte da foto

  1. No clone do projeto de origem, em Explorador de Arquivos, localize a pasta Windows-appsample-photo-editor>PhotoEditor. Nessa pasta, você encontrará os três arquivos Photo.idlde código-fonte , Photo.he Photo.cpp; esses arquivos juntos implementam a classe de runtime Photo . Selecione esses três arquivos e copie-os para a área de transferência.

  2. No Visual Studio, clique com o botão direito do mouse no nó do projeto de destino e clique em Abrir Pasta no Explorador de Arquivos. Isso abre a pasta do projeto de destino no Explorador de Arquivos. Cole nessa pasta os três arquivos que você acabou de copiar.

  3. De volta ao Gerenciador de Soluções, com o nó de projeto de destino selecionado, verifique se Mostrar Todos os Arquivos está ativado. Clique com o botão direito do mouse nos três arquivos que você acabou de colar e clique em Incluir no Projeto. Desative Mostrar Todos os Arquivos .

  4. No projeto de origem, em Gerenciador de Soluções, Photo.h e .cpp são aninhados Photo.idl em para indicar que eles são gerados a partir dele (dependente dele). Se você gostar dessa organização, poderá fazer a mesma coisa no projeto de destino editando \PhotoEditor\PhotoEditor\PhotoEditor\PhotoEditor.vcxproj manualmente (primeiro você precisará salvar tudo no Visual Studio). Encontre o seguinte:

    <ClInclude Include="Photo.h" />
    

    E substitua-o por isso:

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

    Repita isso para Photo.cppe salve e feche o arquivo de projeto. Ao definir o foco de volta para o Visual Studio, clique em Recarregar.

Migrar o código-fonte da foto

  1. No Photo.idl, pesquise o nome Windows.UI.Xaml do namespace (que é o namespace para UWP XAML) e altere-o para Microsoft.UI.Xaml (que é o namespace para WinUI XAML).

Observação

O tópico Mapeando APIs UWP para o SDK do Aplicativo Windows fornece um mapeamento de APIs UWP para seus equivalentes de SDK do Aplicativo Windows. A alteração que fizemos acima é um exemplo de uma alteração de nome de namespace necessária durante o processo de migração.

  1. Em Photo.cpp, adicione #include "Photo.g.cpp" às diretivas de inclusão existentes, imediatamente após #include "Photo.h". Essa é uma das diferenças de nome de arquivo e pasta (C++/WinRT) a serem consideradas entre projetos UWP e SDK do Aplicativo Windows.

  2. Faça a seguinte localização/substituição (caso de correspondência e palavra inteira) no conteúdo de todo o código-fonte nos arquivos que você acabou de copiar e colar.

    • Windows::UI::Xaml =>Microsoft::UI::Xaml
  3. No projeto de origem, copie os seguintes inclusões e cole-os pch.h no projeto de pch.h destino. Este é um subconjunto dos arquivos de cabeçalho incluídos no projeto de origem; esses são apenas os cabeçalhos que precisamos para dar suporte ao código que migramos até agora.

    #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. Agora confirme se você pode criar a solução de destino (mas ainda não executou).

Migrar a classe App

Nenhuma alteração é necessária para o projeto de App.idl destino e App.xaml. Mas precisamos editar App.xaml.h e o Aplicativo.xaml.cpp para adicionar alguns novos membros à classe App . Faremos isso de uma maneira que nos permita compilar após cada seção (com exceção da última seção, que é sobre App::OnLaunched).

Disponibilizando o objeto de janela main

Nesta etapa, faremos a alteração explicada em Alterar Windows.UI.Xaml.Window.Current para App.Window.

No projeto de destino, App armazena o objeto de janela main em sua janela de membro de dados privados. Posteriormente no processo de migração (quando migrarmos o uso do projeto de origem de Window.Current), será conveniente se esse membro de dados da janela for estático; e também é disponibilizado por meio de uma função de acessador. Então, faremos essas alterações em seguida.

  • Como estamos tornando a janela estática, precisaremos inicializá-la em App.xaml.cpp vez de por meio do inicializador de membro padrão que o código está usando no momento. Estas são as aparências dessas alterações em App.xaml.h e App.xaml.cpp.

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

O aplicativo de exemplo editor de fotos usa a lógica de navegação para navegar entre MainPage e DetailPage. Para obter mais informações sobre SDK do Aplicativo Windows aplicativos que precisam de navegação (e aqueles que não precisam), consulte Preciso implementar a navegação de página?.

Portanto, os membros que migraremos nas próximas seções existirão para dar suporte à navegação no aplicativo.

  1. Vamos começar migrando o manipulador de eventos OnNavigationFailed . Copie a declaração e a definição dessa função membro do projeto de origem e cole-a no projeto de destino (em App.xaml.h e App.xaml.cpp).

  2. No código colado em App.xaml.h, altere Windows::UI::Xaml para Microsoft::UI::Xaml.

App::CreateRootFrame

  1. O projeto de origem contém uma função auxiliar chamada App::CreateRootFrame. Copie a declaração e a definição dessa função auxiliar do projeto de origem e cole-a no projeto de destino (em App.xaml.h e App.xaml.cpp).

  2. No código colado em App.xaml.h, altere Windows::UI::Xaml para Microsoft::UI::Xaml.

  3. No código que você postou em App.xaml.cpp, altere as duas ocorrências de Window::Current() para window (que é o nome do membro de dados da classe App que vimos anteriormente).

App::OnLaunched

O projeto de destino já contém uma implementação do manipulador de eventos OnLaunched . Seu parâmetro é uma referência constante a um Microsoft::UI::Xaml::LaunchActivatedEventArgs, que está correto para o SDK do Aplicativo Windows (contraste com o projeto de origem, que usa Windows::ApplicationModel::Activation::LaunchActivatedEventArgs, que está correto para UWP).

  • Só precisamos mesclar as duas definições (origem e destino) de OnLaunched para que App::OnLaunched no App.xaml.cpp projeto de destino se pareça com a listagem abaixo. Observe que ele usa window (em vez de Window::Current(), como a versão UWP usa).

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

O código acima fornece ao Aplicativo uma dependência no MainPage, portanto, não poderemos compilar a partir deste ponto até migrarmos DetailPage e, em seguida, MainPage. Quando formos capazes de construir novamente, vamos dizer isso.

Migrar a exibição DetailPage

DetailPage é a classe que representa a página do editor de fotos, em que os efeitos win2D são alternados, definidos e encadeados juntos. Você chega à página do editor de fotos selecionando uma miniatura de foto em MainPage. DetailPage é uma exibição (no sentido de modelos, exibições e viewmodels).

Referenciar o pacote NuGet Win2D

Para dar suporte ao código em DetailPage, o projeto de origem tem uma dependência em Microsoft.Graphics.Win2D. Portanto, também precisaremos de uma dependência do Win2D em nosso projeto de destino.

  • Na solução de destino no Visual Studio, clique em FerramentasGerenciador de Pacotes>> NuGetGerenciar Pacotes NuGet para solução...>Navegue. Verifique se Incluir pré-lançamento está desmarcado e digite ou cole Microsoft.Graphics.Win2D na caixa de pesquisa. Selecione o item correto nos resultados da pesquisa, marcar o projeto PhotoEditor e clique em Instalar para instalar o pacote.

Copiar arquivos de código-fonte detailPage

  1. No clone do projeto de origem, em Explorador de Arquivos, localize a pasta Windows-appsample-photo-editor>PhotoEditor. Nessa pasta, você encontrará os quatro arquivos DetailPage.idlde código-fonte , DetailPage.xaml, DetailPage.he DetailPage.cpp; esses arquivos juntos implementam a exibição DetailPage . Selecione esses quatro arquivos e copie-os para a área de transferência.

  2. No Visual Studio, clique com o botão direito do mouse no nó do projeto de destino e clique em Abrir Pasta no Explorador de Arquivos. Isso abre a pasta de projeto de destino em Explorador de Arquivos. Cole nessa pasta os quatro arquivos que você acabou de copiar.

  3. Ainda em Explorador de Arquivos, altere os nomes de DetailPage.h e DetailPage.cpp para DetailPage.xaml.h e DetailPage.xaml.cpp, respectivamente. Essa é uma das diferenças de nome de pasta e arquivo (C++/WinRT) para estar ciente entre projetos UWP e SDK do Aplicativo Windows.

  4. De volta ao Gerenciador de Soluções, com o nó de projeto de destino selecionado, verifique se Mostrar Todos os Arquivos está ativado. Clique com o botão direito do mouse nos quatro arquivos que você acabou de colar (e renomeou) e clique em Incluir no Projeto. Desativar Mostrar Todos os Arquivos .

  5. No projeto de origem, em Gerenciador de Soluções, DetailPage.idl está aninhado DetailPage.xamlem . Se você gostar dessa organização, poderá fazer a mesma coisa no projeto de destino editando \PhotoEditor\PhotoEditor\PhotoEditor\PhotoEditor.vcxproj manualmente (primeiro você precisará salvar tudo no Visual Studio). Encontre o seguinte:

    <Midl Include="DetailPage.idl" />
    

    E substitua-o por isso:

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

Salve e feche o arquivo de projeto. Quando você definir o foco de volta para o Visual Studio, clique em Recarregar.

Migrar o código-fonte DetailPage

  1. No DetailPage.idl, pesquise por Windows.UI.Xamle altere-o para Microsoft.UI.Xaml.

  2. Em DetailPage.xaml.cpp, altere #include "DetailPage.h" para #include "DetailPage.xaml.h".

  3. Imediatamente abaixo disso, adicione #include "DetailPage.g.cpp".

  4. Para a chamada para o método App::Window estático (que estamos prestes a adicionar) para compilar, ainda em DetailPage.xaml.cpp, adicione #include "App.xaml.h" imediatamente antes #include "Photo.h"de .

  5. Faça as seguintes localizações/substituições (caso de correspondência e palavra inteira) no conteúdo do código-fonte nos arquivos que você acabou de copiar e colar.

    • In DetailPage.xaml.h e .xaml.cpp, Windows::UI::Composition =>Microsoft::UI::Composition
    • In DetailPage.xaml.h e .xaml.cpp, Windows::UI::Xaml =>Microsoft::UI::Xaml
    • Em DetailPage.xaml.cpp, Window::Current() =>App::Window()
  6. No projeto de origem, copie os seguintes inclusões e cole-os pch.h no projeto de pch.h destino.

    #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. Além disso, na parte superior de pch.h, imediatamente após #pragma once, adicione este:

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

Ainda não podemos compilar, mas poderemos depois de migrar o MainPage (que é o próximo).

Migrar a exibição MainPage

A página main do aplicativo representa a exibição que você vê primeiro ao executar o aplicativo. É a página que carrega as fotos da Biblioteca de Imagens e exibe uma exibição em miniatura em blocos.

Copiar arquivos de código-fonte mainpage

  1. Semelhante ao que você fez com DetailPage, agora copie sobre MainPage.idl, MainPage.xaml, MainPage.he MainPage.cpp.

  2. Renomeie os .h arquivos e .cpp para .xaml.h e .xaml.cpp, respectivamente.

  3. Inclua todos os quatro arquivos no projeto de destino como antes.

  4. No projeto de origem, em Gerenciador de Soluções, MainPage.idl está aninhado MainPage.xamlem . Se você gostar dessa organização, poderá fazer a mesma coisa no projeto de destino editando \PhotoEditor\PhotoEditor\PhotoEditor\PhotoEditor.vcxprojmanualmente . Encontre o seguinte:

    <Midl Include="MainPage.idl" />
    

    E substitua-a por:

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

Migrar o código-fonte mainpage

  1. No MainPage.idl, pesquise e Windows.UI.Xamlaltere ambas as ocorrências para Microsoft.UI.Xaml.

  2. Em MainPage.xaml.cpp, altere #include "MainPage.h" para #include "MainPage.xaml.h".

  3. Imediatamente abaixo disso, adicione #include "MainPage.g.cpp".

  4. Para a chamada para o método App::Window estático (que estamos prestes a adicionar) para compilar, ainda em MainPage.xaml.cpp, adicione #include "App.xaml.h" imediatamente antes #include "Photo.h"de .

Para a próxima etapa, faremos a alteração explicada em ContentDialog e Popup.

  1. Portanto, ainda no MainPage.xaml.cpp, no método MainPage::GetItemsAsync , imediatamente após a linha ContentDialog unsupportedFilesDialog{};, adicione essa linha de código.

    unsupportedFilesDialog.XamlRoot(this->Content().XamlRoot());
    
  2. Faça as seguintes localizações/substituições (caso de correspondência e palavra inteira) no conteúdo do código-fonte nos arquivos que você acabou de copiar e colar.

    • In MainPage.xaml.h e .xaml.cpp, Windows::UI::Composition =>Microsoft::UI::Composition
    • In MainPage.xaml.h e .xaml.cpp, Windows::UI::Xaml =>Microsoft::UI::Xaml
    • Em MainPage.xaml.cpp, Window::Current() =>App::Window()
  3. No projeto de origem, copie os seguintes inclusões e cole-os pch.h no projeto de pch.h destino.

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

Confirme se você pode criar a solução de destino (mas ainda não foi executada).

Atualizar MainWindow

  1. No MainWindow.xaml, exclua o StackPanel e seu conteúdo, pois não precisamos de nenhuma interface do usuário no MainWindow. Isso deixa apenas o elemento Window vazio.

  2. No MainWindow.idl, exclua o espaço reservado Int32 MyProperty;, deixando apenas o construtor.

  3. Em MainWindow.xaml.h e MainWindow.xaml.cpp, exclua as declarações e definições do espaço reservado MyProperty e myButton_Click, deixando apenas o construtor.

Alterações de migração necessárias para a diferença do modelo de threading

As duas alterações nesta seção são necessárias devido a uma diferença de modelo de threading entre a UWP e a SDK do Aplicativo Windows, conforme descrito no modelo de threading ASTA to STA. Aqui estão breves descrições das causas dos problemas e, em seguida, uma maneira de resolve cada um.

MainPage

MainPage carrega arquivos de imagem de sua pasta Imagens , chama StorageItemContentProperties.GetImagePropertiesAsync para obter as propriedades do arquivo de imagem, cria um objeto modelo De foto para cada arquivo de imagem (salvando essas mesmas propriedades em um membro de dados) e adiciona esse objeto Photo a uma coleção. A coleção de objetos Photo está associada a dados a um GridView na interface do usuário. Em nome desse GridView, o MainPage manipula o evento ContainerContentChanging e, para a fase 1, esse manipulador chama uma corrotina que chama StorageFile.GetThumbnailAsync. Essa chamada para GetThumbnailAsync faz com que as mensagens sejam bombeadas (elas não retornam imediatamente e fazem todo o seu trabalho assíncrono) e isso causa reentrância. O resultado é que o GridView tem sua coleção Items alterada enquanto o layout está ocorrendo e isso causa uma falha.

Se comentarmos a chamada para StorageItemContentProperties::GetImagePropertiesAsync, não obteremos a falha. Mas a correção real é fazer com que a chamada StorageFile.GetThumbnailAsync seja explicitamente assíncrona aguardando cooperativamente wil::resume_foreground imediatamente antes de chamar GetThumbnailAsync. Isso funciona porque wil::resume_foreground agenda o código que o segue para ser uma tarefa no DispatcherQueue.

Aqui está o código a ser alterado:

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

A propriedade Photo::ImageTitle é associada a dados à interface do usuário, portanto, a interface do usuário chama a função de acessador para essa propriedade sempre que precisar de seu valor. Mas quando tentamos acessar ImageProperties.Title dessa função de acessador no thread da interface do usuário, obtemos uma violação de acesso.

Em vez disso, podemos apenas acessar esse Título uma vez, no construtor de Foto, e armazená-lo no membro de dados m_imageName se ele não estiver vazio. Em seguida, na função acessador Photo::ImageTitle , precisamos apenas acessar o membro de dados m_imageName .

Aqui está o código a ser alterado:

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

Essas são as últimas das alterações que precisamos fazer para migrar o aplicativo de exemplo editor de fotos. Na seção Testar o aplicativo migrado , confirmaremos que seguimos corretamente as etapas.

Problemas conhecidos

Problema de tipo de aplicativo (afeta apenas a versão prévia 3)

Se você acompanhou este estudo de caso usando o modelo de projeto do VSIX para SDK do Aplicativo Windows versão 1.0 Versão Prévia 3, precisará fazer uma pequena correção para PhotoEditor.vcxproj. Veja a seguir como fazer isso.

No Visual Studio, em Gerenciador de Soluções, clique com o botão direito do mouse no nó do projeto e clique em Descarregar Projeto. Agora PhotoEditor.vcxproj está aberto para edição. Como o primeiro filho do Project, adicione um elemento PropertyGroup como este:

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

Salve e feche PhotoEditor.vcxproj. Clique com o botão direito do mouse no nó do projeto e clique em Recarregar Projeto. Agora recompile o projeto.

Testar o aplicativo migrado

Agora, crie o projeto e execute o aplicativo para testá-lo. Selecione uma imagem, defina um nível de zoom, escolha efeitos e configure-os.

Apêndice: copiar o conteúdo dos arquivos do modelo de foto

Como discutimos anteriormente, você tem a opção de copiar os próprios arquivos de código-fonte ou o conteúdo dos arquivos de código-fonte. Já mostramos como copiar os próprios arquivos de código-fonte. Portanto, esta seção fornece um exemplo de cópia de conteúdo de arquivo.

No projeto de origem no Visual Studio, localize a pasta PhotoEditor (Universal windows)>Models. Essa pasta contém os arquivos Photo.idl, Photo.he Photo.cpp, que juntos implementam a classe de runtime De fotos .

Adicionar a IDL e gerar stubs

Em seu projeto de destino no Visual Studio, adicione um novo item midl file (.idl) ao projeto. Dê ao novo item o nome Photo.idl. Exclua o conteúdo padrão de Photo.idl.

No projeto de origem no Visual Studio, copie o conteúdo de Modelos>Photo.idl e cole-os no Photo.idl arquivo que você acabou de adicionar ao projeto de destino. No código colado, pesquise e Windows.UI.Xamlaltere-o para Microsoft.UI.Xaml.

Salve o arquivo.

Importante

Estamos prestes a executar um build de sua solução de destino. O build não será executado até a conclusão neste momento, mas ele será longe o suficiente para fazer o trabalho necessário para nós.

Agora, crie a solução de destino. Mesmo que não seja concluído, a criação é necessária agora porque gerará os arquivos de código-fonte (stubs) que precisamos para começar a implementar o modelo de Foto .

No Visual Studio, clique com o botão direito do mouse no nó do projeto de destino e clique em Abrir Pasta no Explorador de Arquivos. Isso abre a pasta de projeto de destino em Explorador de Arquivos. Lá, navegue até a Generated Files\sources pasta (para que você esteja em \PhotoEditor\PhotoEditor\PhotoEditor\Generated Files\sources). Copie os arquivos Photo.h stub e .cppe cole-os na pasta do projeto, que agora está acima de dois níveis de pasta em \PhotoEditor\PhotoEditor\PhotoEditor.

De volta ao Gerenciador de Soluções, com o nó de projeto de destino selecionado, verifique se Mostrar Todos os Arquivos está ativado. Clique com o botão direito do mouse nos arquivos stub que você acabou de colar (Photo.h e .cpp) e clique em Incluir no Projeto. Desativar Mostrar Todos os Arquivos .

Você verá um static_assert na parte superior do conteúdo de Photo.h e .cpp, que você precisará excluir.

Confirme se você pode compilar novamente (mas ainda não foi executado).

Migrar código para os stubs

Copie o conteúdo de Photo.h e .cpp do projeto de origem para o projeto de destino.

A partir daqui, as etapas restantes para migrar o código copiado são as mesmas fornecidas na seção Migrar código-fonte da foto.