Compartilhar via


Migrando o código existente no exemplo de otimizador de viagens do Mapas Bing

Este documento destaca algumas diretrizes importantes que seguimos quando migramos da versão ActiveX do Bing Maps Trip Optimizer para um aplicativo Windows Store. Este documento não fornece uma explicação completa de como migrar o código existente para o Tempo de Execução do Windows. Ele realça a experiência e os aspectos importantes que tivemos que ter em mente.

Dica

O código de exemplo que corresponde a este documento é encontrado em Bing Maps trip optimizer sample (aplicativo Windows Store) e em Bing Maps Trip Optimizer (aplicativo Web ActiveX).

Neste artigo

  • Pontos-chave da migração JavaScript

  • Pontos-chave da migração C++

  • Pontos-chave da migração de interoperabilidade

Pontos-chave da migração JavaScript

A versão ActiveX do Bing Maps Trip Optimizer usa um arquivo de código, o OptimizerControl.htm, para interface do usuário. Como descrito nesta documentação, quando migramos para usar o Tempo de Execução do Windows, tivemos que fazer contextos separados para os componentes que interagem com a Web e os que interagem com o Tempo de Execução do Windows. Tivemos que gravar código adicional para permitir que os contextos se comunicassem. O documento Features and restrictions by context explica mais sobre as diferenças entre os contextos local e da Web.

Pudemos usar a maior parte do código da versão original na versão de aplicativo Windows Store. A principal diferença é que, como o aplicativo Windows Store não faz mais referência a um controle ActiveX, substituímos o elemento object por uma variável global que representa o componente C++. Esse mecanismo é explicado em detalhes em Interoperação entre JavaScript e C++ no exemplo de otimizador de viagem do Mapas Bing.

Métodos de janela, como alert, prompt e open, não funcionam em aplicativos JavaScript Windows Store. A versão ActiveX do controle usa alert para informar o usuário de um problema, por exemplo, quando mais de 25 locais foram inseridos. A versão Windows Store do aplicativo usa a classe Windows.UI.Popups.MessageDialog para exibir mensagens ao usuário.

// Show message dialog.            
new Windows.UI.Popups.MessageDialog(data.message).showAsync().then();

Como não há nenhuma ação a executar após a exibição da caixa de diálogo de mensagem, a instrução then está vazia. Para obter mais informações sobre como trabalhar com operações assíncronas em JavaScript, consulte Asynchronous programming.

Para obter mais informações sobre algumas diferenças de como usar recursos HTML existentes em um aplicativo Windows Store JavaScript, consulte HTML, CSS, and JavaScript features and differences.

A versão ActiveX do aplicativo usa o controle AJAX do Bing Maps, versão 6,3, para exibir o mapa na interface do usuário. A versão do aplicativo Windows Store usa o Controle AJAX do Bing Maps, versão 7.0. A atualização da versão 6.3 para a 7.0 não era um requisito; você pode usar a versão 6.3 em um aplicativo Windows Store. Escolhemos a versão 7.0 nesta implementação porque ela inclui aprimoramentos de desempenho e suporte aperfeiçoado para o contato, e queríamos demonstrar a maneira mais recente de se obter informações do Bing Maps.

[Superior]

Pontos-chave da migração C++

Quando você usa C++/CX para criar componentes Windows Store, o compilador e o Tempo de Execução do Windows tratam a infraestrutura necessária para a interoperação com outros componentes e linguagens. Quando migramos a versão ActiveX do controle para um componente Windows Store, conseguimos remover o código de infraestrutura necessário para implementar uma interface COM personalizada. Por exemplo, um componente do Tempo de Execução do Windows não requer arquivos IDL que definam as interfaces e os eventos fornecidos por um componente. Além disso, quando possível, mantivemos os detalhes de implementação que usam código nativo puro. O uso de C++/CX e do Tempo de Execução do Windows é necessário somente quando o controle interage com outros objetos e componentes do Tempo de Execução do Windows.

Considere essas diretrizes quando migrar seus controles ActiveX para controles que usem o Tempo de Execução do Windows.

Dica

Muitas dessas diretrizes envolvem trabalhar com a sintaxe C++/CX. Para obter mais informações sobre essa sintaxe, consulte Referência de linguagem do Visual C++ (C + + / CX).

  • Use o modelo de Biblioteca de classe WinRT para criar o projeto no Visual Studio.

  • Adicione os métodos e propriedades de interface pública do controle ActiveX à sua classe Tempo de Execução do Windows. Converta o parâmetro e os tipos de retorno para usar tipos compatíveis com o Tempo de Execução do Windows. Por exemplo, TripOptimizerImpl.idl define a interface IOptimizerControl para o controle ActiveX.

    interface IOptimizerControl : IDispatch{
       [id(1)] HRESULT OptimizeTripAsync([in] VARIANT* waypoints, [in] BSTR travelMode, 
          [in] BSTR optmz, [in] BSTR bingMapsKey,
          [in] DOUBLE alpha, [in] DOUBLE beta, [in] DOUBLE rho, [in] ULONG iterations,
          [in] VARIANT_BOOL parallel);
       [id(2)] HRESULT CancelAsync();
    };
    

    Para o componente Windows Store, esta é a declaração do método TripOptimizer::OptimizeTripAsync no componente Tempo de Execução do Windows. Usamos o tipo de retorno real, Windows::Foundation::Collections::IMap<K, V>, em vez de HRESULT. Também usamos o tipo apropriado do Tempo de Execução do Windows para cada parâmetro.

    Dica

    Pudemos remover o método CancelAsync nesta implementação porque a funcionalidade de cancelamento é fornecida pelo método ::Cancel De Windows::Foundation::IAsyncOperationWithProgress<TResult, TProgress>.

    // Optimizes a trip as an asynchronous process.
    Windows::Foundation::IAsyncOperationWithProgress<
        Windows::Foundation::Collections::IMap<
            Platform::String^, 
            Windows::Foundation::Collections::IVector<Platform::String^>^>^, 
        Platform::String^>^ OptimizeTripAsync(
            Windows::Foundation::Collections::IVector<Platform::String^>^ waypoints, 
            Platform::String^ travelMode, 
            Platform::String^ optimize,
            Platform::String^ bingMapsKey, 
            double alpha, double beta, double rho,
            unsigned int iterations, bool parallel);
    

    O método TripOptimizer::OptimizeTripAsync é explicado em mais detalhes na seção Criando classes TripOptimizer e TripOptimizerImpl.

  • Adicione os eventos públicos do controle ActiveX à sua classe Tempo de Execução do Windows. Como com métodos e propriedades, converta o parâmetro e os tipos de retorno para usar tipos compatíveis com o Tempo de Execução do Windows.

    Nesta implementação, pudemos remover todos os eventos que foram definidos na versão ActiveX porque essas ações são processadas por outros meios. Por exemplo, não é mais necessário definir um evento de conclusão porque retornamos o resultado diretamente como parte do objeto IAsyncOperationWithProgress<TResult, TProgress> que é retornado por TripOptimizer::OptimizeRouteAsync. As chamadas de retorno de erro e andamento também são processadas pelo objeto IAsyncOperationWithProgress<TResult, TProgress>. Para obter mais informações sobre como parte de JavaScript do aplicativo consome a operação assíncrona, consulte Interoperação entre JavaScript e C++ no exemplo de otimizador de viagem do Mapas Bing.

  • Escolha o padrão C++ adequado e os tipos do Tempo de Execução do Windows ao definir membros de dados para a sua classe Tempo de Execução do Windows.

    Por exemplo, a classe COptimizerControl usa tipos COM como _bstr_t para armazenar valores de cadeia de caracteres.

    Na versão Windows Store do aplicativo, usamos std::wstring, o tipo de cadeia de caracteres C++, para manter os valores da cadeia de caracteres. Por exemplo, no método TripOptimizerImpl::OptimizeTripAsync, convertemos os parâmetros Windows::Foundation::Collections::IVector<T> e Platform::String em std::vector e em std::wstring porque essas variáveis não são passadas novamente para um componente Tempo de Execução do Windows.

    // Copy inputs to a OptimizeTripParams structure.
    auto params = make_shared<OptimizeTripParams>();
    for (auto waypoint : waypoints)
    {
        params->Waypoints.push_back(waypoint->Data());
    }
    params->TravelMode = wstring(travelMode->Data());
    params->Optimize = wstring(optimize->Data());
    params->BingMapsKey = UriEncode(bingMapsKey->Data());
    params->Alpha = alpha;
    params->Beta = beta;
    params->Rho = rho;
    params->Iterations = iterations;
    params->Parallel = parallel;
    

    Quando você usa essa convenção, é possível distinguir com mais clareza quais variáveis são usadas com o Tempo de Execução do Windows. Os tipos de cadeia de caracteres e coleção Tempo de Execução do Windows (como Windows::Foundation::Collections::IMap<K, V> e Windows::Foundation::Collections::IVector<T>) são úteis quando você se comunica regularmente entre o Tempo de Execução do Windows e seu código, pois reduz o número de conversões de tipo de cadeia de caracteres que o aplicativo deve fazer. Caso contrário, considere usar os tipos de coleção C++ padrão como std::map e std::vector.

    Os detalhes da implementação do controle são descritos em mais detalhes na seção Fluxo de trabalho de componente.

  • Use as interfaces Windows::Foundation::IAsyncAction, Windows::Foundation::IAsyncActionWithProgress<TProgress>, Windows::Foundation::IAsyncOperation<TResult> ou Windows::Foundation::IAsyncOperationWithProgress<TResult, TProgress> para ajudar a definir métodos assíncronos. A função concurrency::create_async é a maneira recomendada de criar esses objetos de um aplicativo ou componente C++ Windows Store.

  • Use o máximo de códigos existentes possível. Pudemos migrar detalhes de implementação, como o algoritmo de otimização com colônia de formigas, com pouca ou nenhuma alteração de código. No entanto, como os aplicativos Windows Store podem usar um subconjunto da API do Win32 e COM, tivemos de usar mecanismos alternativos para algumas partes do componente. Por exemplo, a versão ActiveX do controle usa IXMLHTTPRequest para se comunicar com servidores HTTP. No componente C++, usamos IXMLHTTPRequest2, que é a maneira recomendada de se comunicar com servidores HTTP em um aplicativo Windows Store. Para processar a resposta XML do Bing Maps, o controle ActiveX usa XmlLite. No componente Windows Store, usamos a classe Tempo de Execução do Windows XmlDocument por ser fácil de usar e porque queríamos demonstrar como você pode atualizar o código COM existente para usar os tipos Tempo de Execução do Windows. No entanto, se você tiver um código Win32 ou COM disponível em um aplicativo Windows Store, poderá continuar a usá-lo.

    Para obter mais informações sobre como usar Win32 e COM em um aplicativo Windows Store, consulte Win32 and COM for Windows Store apps.

    Importante

    Se você usar Win32 e COM em seu aplicativo Windows Store, ele pode ser executado em seu ambiente de desenvolvimento, mas pode não ser aprovado para distribuição na Windows Store. Portanto, é recomendável que você execute o verificador do aplicativo com frequência para garantir que seu aplicativo passe na verificação. Para obter mais informações, consulte Preparing your app for the Windows Store e How to: Install, validate, and upload your package.

  • Projetos Visual C++ agora usam pch.h e pch.cpp para armazenar informações de cabeçalho pré-compilado. Migre as instruções #include relevantes de stdafx.h para pch.h.

[Superior]

Pontos-chave da migração de interoperabilidade

Na versão do aplicativo Windows Store do Bing Maps Trip Optimizer, pudemos usar a maior parte do código JavaScript da versão ActiveX. A principal diferença é como o código HTML e JavaScript fazem referência ao componente C++.

A versão ActiveX usa a marca HTML object para referenciar o componente C++.

<object id="OptimizerControl" name="OptimizerControl" classid="CLSID:10FFAAB9-0E73-4C4D-8118-6225C7F2E692"></object>

Da mesma forma, a versão ActiveX usa o valor id, “OptimizerControl”, para chamar os métodos COptimizerControl.

A versão do aplicativo Windows Store do Bing Maps Trip Optimizer define uma referência de projeto e usa uma variável global em vez de usar a marca object. O sistema do projeto executa as etapas que são necessárias para que o aplicativo JavaScript localize e carregue o componente C++. O artigo Criando componentes de tempo de execução do Windows em C++ explica mais detalhadamente como configurar referências de projeto.

A versão ActiveX usa a sintaxe :: para processar eventos.

// Event handler for progress notifications from the control.
function document.OptimizerControl::ProgressCallback(message) {
   // Set message.
   ProgressMessageText.innerHTML = message;
}

A versão do aplicativo Windows Store usa o processamento assíncrono e promete reagir às respostas do componente C++. Esse processo é explicado na seção Recebendo dados do componente C++.

[Superior]