Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Important
Para informações sobre como configurar o Visual Studio para desenvolvimento em C++/WinRT — incluindo a instalação e utilização da Extensão Visual Studio (VSIX) em C++/WinRT e do pacote NuGet (que juntos fornecem suporte para modelos de projeto e compilação) — consulte suporte ao Visual Studio para C++/WinRT.
Para o pôr a par do uso do C++/WinRT, este tópico percorre um exemplo simples de código baseado num novo projeto de aplicação Windows Console (C++/WinRT). Este tópico também mostra como adicionar suporte a C++/WinRT a um projeto de aplicação Windows Desktop.
Note
Embora recomendemos que desenvolva com as versões mais recentes do Visual Studio e do Windows SDK, se estiver a usar o Visual Studio 2017 (versão 15.8.0 ou posterior) e a direcionar o Windows SDK versão 10.0.17134.0 (Windows 10, versão 1803), então um projeto C++/WinRT recém-criado pode falhar em compilar com o erro "erro C3861: 'from_abi': identificador não encontrado", e com outros erros originados em base.h. A solução consiste em utilizar uma versão posterior (mais compatível com a norma) do SDK do Windows, ou em definir a propriedade do projeto C/C++>Idioma>Modo de conformidade: Não (além disso, se /permissive- aparecer na propriedade do projeto C/C++>Idioma>Linha de Comandos, em Opções Adicionais, elimine-o).
Guia de introdução rápida ao C++/WinRT
Crie um novo projeto de Aplicação de Consola Windows (C++/WinRT).
Edita pch.h e main.cpp para ficar assim.
// 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;
}
}
Vamos pegar no pequeno exemplo de código acima, peça a peça, e explicar o que se passa em cada parte.
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Web.Syndication.h>
Com as definições padrão do projeto, os cabeçalhos incluídos vêm do SDK do Windows, dentro da pasta %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt. O Visual Studio inclui esse caminho no seu macro IncludePath. Mas não há uma dependência estrita do SDK do Windows, porque o teu projeto (através da cppwinrt.exe ferramenta) gera esses mesmos cabeçalhos na pasta $(GeneratedFilesDir) do projeto. Eles serão carregados a partir dessa pasta se não forem encontrados noutro lado, ou se mudares as definições do teu projeto.
Os cabeçalhos contêm APIs do Windows projetadas em C++/WinRT. Por outras palavras, para cada tipo de Windows, C++/WinRT define um equivalente compatível com C++ (chamado tipo projetado). Um tipo projetado tem o mesmo nome completamente qualificado que o tipo do Windows, mas está no espaço de nomes C++ winrt. Colocar estas incluções no cabeçalho pré-compilado reduz os tempos incrementais de construção.
Important
Sempre que quiser utilizar um tipo de um espaço de nomes do Windows, deve #include o ficheiro de cabeçalho C++/WinRT correspondente a esse espaço de nomes do Windows, como mostrado acima. O cabeçalho correspondente é aquele com o mesmo nome do espaço de nomes do tipo. Por exemplo, para usar a projeção C++/WinRT para a classe de tempo de execução Windows::Foundation::Collections::PropertySet, inclua o cabeçalho winrt/Windows.Foundation.Collections.h.
É comum que um cabeçalho de projeção C++/WinRT inclua automaticamente ficheiros de cabeçalho de namespace relacionados. Por exemplo, winrt/Windows.Foundation.Collections.h inclui winrt/Windows.Foundation.h. Mas não deves confiar neste comportamento, pois é um detalhe de implementação que muda ao longo do tempo. Deve incluir explicitamente quaisquer cabeçalhos de que precise.
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Web::Syndication;
As using namespace diretivas são opcionais, mas convenientes. O padrão mostrado acima para essas diretivas (permitindo a procura de nomes não qualificados para qualquer elemento no espaço de nomes winrt) é adequado quando se está a iniciar um novo projeto e o C++/WinRT é a única projeção de linguagem utilizada nesse projeto. Se, por outro lado, estiver a misturar código C++/WinRT com C++/CX e/ou código de interface binária de aplicação (ABI) SDK (está a portar ou a interoperar com um ou ambos esses modelos), então veja os tópicos Interop entre C++/WinRT e C++/CX, Migrar para C++/WinRT a partir de C++/CX, e Interop entre C++/WinRT e a ABI.
winrt::init_apartment();
A chamada para winrt::init_apartment inicializa a thread no Windows Runtime; por predefinição, num apartamento multithreaded. A chamada também inicia o COM.
Uri rssFeedUri{ L"https://blogs.windows.com/feed" };
SyndicationClient syndicationClient;
Aloca na pilha dois objetos: que representam o URI do blogue do Windows e um cliente de sindicação. Construímos o uri com um literal de string simples e largo (veja Gestão de strings em C++/WinRT para mais formas de trabalhar com strings).
SyndicationFeed syndicationFeed = syndicationClient.RetrieveFeedAsync(rssFeedUri).get();
SyndicationClient::RetrieveFeedAsync é um exemplo de função de Windows Runtime assíncrona. O exemplo de código recebe um objeto de operação assíncrona de RetrieveFeedAsync e chama get nesse objeto para bloquear a thread de chamada e esperar pelo resultado (que, neste caso, é um feed de distribuição). Para mais informações sobre concorrência e para técnicas não bloqueantes, veja Concorrência e operações assíncronas com C++/WinRT.
for (const SyndicationItem syndicationItem : syndicationFeed.Items()) { ... }
SyndicationFeed.Items corresponde a um intervalo, definido pelos iteradores devolvidos pelas funções begin e end (ou pelas respetivas variantes constantes, inversas e constantes-inversas). Por esse motivo, pode enumerar Items quer com uma instrução for baseada em intervalos, quer com a função modelo std::for_each. Sempre que iterares sobre uma coleção do Windows Runtime como esta, vais precisar de #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;
Recebe o texto do título do feed, como objeto winrt::hstring (mais detalhes em Gestão de Strings em C++/WinRT). O hstring é então gerado, através da função c_str , que reflete o padrão usado com as cadeias da Biblioteca Padrão C++.
Como pode ver, C++/WinRT incentiva expressões modernas e semelhantes a classes em C++, como syndicationItem.Title().Text(). Este é um estilo de programação diferente e mais limpo da programação tradicional COM. Não precisas de inicializar diretamente o COM, nem de trabalhar com ponteiros COM.
Também não precisa de lidar com códigos de retorno HRESULT. C++/WinRT converte os HRESULTs de erro em exceções como winrt::hresult-error, proporcionando um estilo de programação natural e moderno. Para mais informações sobre gestão de erros e exemplos de código, veja Gestão de erros com C++/WinRT.
Modificar um projeto de aplicação Windows Desktop para adicionar suporte a C++/WinRT
Alguns projetos de ambiente de trabalho (por exemplo, os templates WinUI 3 no Visual Studio) têm suporte incorporado para C++/WinRT.
Mas esta secção mostra-te como podes adicionar suporte a C++/WinRT a qualquer projeto de aplicação do Windows Desktop que possas ter. Se não tiver um projeto de aplicação Windows Desktop existente, pode seguir estes passos criando primeiro um. Por exemplo, abra o Visual Studio e crie um projeto de Visual C++>Aplicação de Ambiente de Trabalho do Windows>.
Podes opcionalmente instalar a Extensão Visual Studio C++/WinRT (VSIX) e o pacote NuGet. Para mais detalhes, consulte o suporte do Visual Studio para C++/WinRT.
Definir propriedades do projeto
Vá para a propriedade do projeto General>Windows SDK Version e selecione All Configurations e All Platforms. Certifique-se de que a versão do SDK do Windows está definida para 10.0.17134.0 (Windows 10, versão 1803) ou superior.
Confirma que não és afetado por Porque é que o meu novo projeto não compila?.
Como o C++/WinRT utiliza funcionalidades do padrão C++17, defina a propriedade do projeto C/C++>Language>C++Language Standard para o ISO C++17 Standard (/std:c++17).
O cabeçalho pré-compilado
O modelo padrão do projeto cria um cabeçalho pré-compilado para si, chamado , framework.hou stdafx.h. Renomeie para pch.h. Se tiver um stdafx.cpp ficheiro, renomeie-o para pch.cpp. Defina a propriedade do projeto C/C++>Cabeçalhos pré-compilados>Cabeçalho pré-compilado para Create (/Yc), e Ficheiro de cabeçalho pré-compilado para pch.h.
Encontre e substitua todos #include "framework.h" (ou #include "stdafx.h") por #include "pch.h".
Em pch.h, inclua winrt/base.h.
// pch.h
...
#include <winrt/base.h>
Linking
A projeção de linguagem C++/WinRT depende de determinadas funções livres (não membros) do Windows Runtime e de pontos de entrada que requerem a ligação com a biblioteca abrangente WindowsApp.lib. Esta secção descreve três formas de cumprir os requisitos do linker.
A primeira opção é adicionar ao seu projeto Visual Studio todas as propriedades e alvos do MSBuild em C++/WinRT. Para isso, instale o pacote NuGet Microsoft.Windows.CppWinRT no seu projeto. Abra o projeto no Visual Studio, clique em Projeto>Gerir Pacotes NuGet...>Procurar, escreva ou cole Microsoft.Windows.CppWinRT na caixa de pesquisa, selecione o item nos resultados da pesquisa e, em seguida, clique em Instalar para instalar o pacote para esse projeto.
Também pode usar as definições de ligação do projeto para ligar explicitamente WindowsApp.lib. Ou pode fazê-lo em código-fonte (em pch.h, por exemplo) assim.
#pragma comment(lib, "windowsapp")
Agora pode compilar, ligar e adicionar código C++/WinRT ao seu projeto (por exemplo, código semelhante ao mostrado na secção de início rápido de A C++/WinRT , acima).
Os três cenários principais para C++/WinRT
À medida que usa e se familiariza com C++/WinRT, e trabalha no resto da documentação aqui, provavelmente notará que existem três cenários principais, conforme descrito nas secções seguintes.
Consumo de APIs e tipos do Windows
Ou seja, usar ou chamar APIs. Por exemplo, fazer chamadas API para comunicar via Bluetooth; transmitir e apresentar vídeo; para integrar com o shell do Windows; e assim sucessivamente. O C++/WinRT suporta totalmente e de forma intransigente esta categoria de cenários. Para mais informações, consulte Consume APIs com C++/WinRT.
Criação de APIs e tipos do Windows
Ou seja, gerar APIs e tipos. Por exemplo, produzir os tipos de APIs descritos na secção acima; ou as APIs gráficas; as APIs de armazenamento e sistema de ficheiros; as APIs de rede, e assim sucessivamente. Para mais informações, consulte APIs de autor com C++/WinRT.
Criar APIs com C++/WinRT é um pouco mais complexo do que consumi-las, porque tens de usar o IDL para definir a forma da API antes de a poderes implementar. Há um guia passo a passo para fazer isso em controlos XAML; associar a uma propriedade C++/WinRT.
Aplicações XAML
Este cenário é sobre construir aplicações e controlos no framework de interface XAML. Trabalhar numa aplicação XAML consiste numa combinação de utilização e criação. Mas como o XAML é atualmente a framework de interface dominante no Windows, e a sua influência sobre o Windows Runtime é proporcional a isso, merece uma categoria de cenário própria.
Tenha em atenção que o XAML funciona melhor com linguagens de programação que oferecem reflexão. Em C++/WinRT, por vezes é preciso fazer um pouco mais de trabalho para interoperar com o framework XAML. Todos esses casos estão incluídos na documentação. Bons pontos de partida são controlos XAML; associar a uma propriedade C++/WinRT e controlos XAML personalizados (com modelo) com C++/WinRT.
Aplicações de exemplo escritas em C++/WinRT
Veja Onde posso encontrar aplicações de exemplo em C++/WinRT?
APIs importantes
- SyndicationClient::RetrieveFeedAsync método
- propriedade Items de SyndicationFeed
- winrt::hstring struct
- winrt::hresult-error struct
Tópicos relacionados
Windows developer