Introdução ao C++/WinRTGet started with C++/WinRT

Para você se familiarizar com o uso de C++/WinRT, este tópico apresenta um exemplo de código simples com base em um novo projeto de Aplicativo de Console do Windows (C++/WinRT) .To get you up to speed with using C++/WinRT, this topic walks through a simple code example based on a new Windows Console Application (C++/WinRT) project. Este tópico também mostra como adicionar suporte ao C++/WinRT a um projeto de aplicativo de área de trabalho do Windows.This topic also shows how to add C++/WinRT support to a Windows Desktop application project.

Observação

Embora a recomendação seja de que você desenvolva usando as últimas versões do Visual Studio e do SDK do Windows, se estiver usando o Visual Studio 2017 (versão 15.8.0 ou superior) e visando o SDK do Windows versão 10.0.17134.0 (Windows 10, versão 1803), haverá falha de compilação de um projeto do C++/WinRT recentemente criado com o erro "erro C3861: 'from_abi': identificador não encontrado" e com outros erros que são originados em base.h.While we recommend that you develop with the latest versions of Visual Studio and the Windows SDK, if you're using Visual Studio 2017 (version 15.8.0 or higher), and targeting the Windows SDK version 10.0.17134.0 (Windows 10, version 1803), then a newly created C++/WinRT project may fail to compile with the error "error C3861: 'from_abi': identifier not found", and with other errors originating in base.h. A solução é visar uma versão posterior (mais compatível) do SDK do Windows ou definir a propriedade do projeto C/C++ > Language > Conformance mode: No (além disso, se /permissive- for exibido na propriedade do projeto C/C++ > Language > Command Line em Additional Options, exclua-o).The solution is to either target a later (more conformant) version of the Windows SDK, or set project property C/C++ > Language > Conformance mode: No (also, if /permissive- appears in project property C/C++ > Language > Command Line under Additional Options, then delete it).

Um início rápido do C++/WinRTA C++/WinRT quick-start

Observação

Para saber mais sobre como configurar o Visual Studio para desenvolvimento em C++/WinRT, incluindo instalação e uso da VSIX (Extensão do Visual Studio) para C++/WinRT e o pacote NuGet (que juntos fornecem um modelo de projeto e suporte ao build), confira Suporte ao Visual Studio para C++/WinRT.For info about setting up Visual Studio for C++/WinRT development—including installing and using the C++/WinRT Visual Studio Extension (VSIX) and the NuGet package (which together provide project template and build support)—see Visual Studio support for C++/WinRT.

Crie um novo projeto de Aplicativo de Console do Windows (C++/WinRT) .Create a new Windows Console Application (C++/WinRT) project.

Edite pch.h e main.cpp para que tenha a aparência a seguir.Edit pch.h and main.cpp to look like this.

// 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;
    SyndicationFeed syndicationFeed = syndicationClient.RetrieveFeedAsync(rssFeedUri).get();
    for (const SyndicationItem syndicationItem : syndicationFeed.Items())
    {
        winrt::hstring titleAsHstring = syndicationItem.Title().Text();
        std::wcout << titleAsHstring.c_str() << std::endl;
    }
}

Vamos usar o exemplo de código acima detalhadamente e explicar o que está acontecendo em cada parte.Let's take the short code example above piece by piece, and explain what's going on in each part.

#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Web.Syndication.h>

Com as configurações de projeto padrão, os cabeçalhos incluídos são originados no SDK do Windows, dentro da pasta%WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt.With the default project settings, the included headers come from the Windows SDK, inside the folder%WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt. O Visual Studio inclui esse caminho em sua macro IncludePath.Visual Studio includes that path in its IncludePath macro. Mas não há dependência estrita sobre o SDK do Windows, pois seu projeto (por meio da ferramenta cppwinrt.exe) gera os mesmos cabeçalhos na pasta $(GeneratedFilesDir) do seu projeto.But there's no strict dependency on the Windows SDK, because your project (via the cppwinrt.exe tool) generates those same headers into your project's $(GeneratedFilesDir) folder. Eles serão carregados dessa pasta se não puderem ser encontrados em outro lugar, ou se você alterar as configurações do projeto.They'll be loaded from that folder if they can't be found elsewhere, or if you change your project settings.

Os cabeçalhos contêm APIs do Windows projetadas em C++/WinRT.The headers contain Windows APIs projected into C++/WinRT. Em outras palavras, para cada tipo de Windows, o C++/WinRT define um equivalente amigável de C++ (chamado de tipo projetado).In other words, for each Windows type, C++/WinRT defines a C++-friendly equivalent (called the projected type). Um tipo projetado tem o mesmo nome totalmente qualificado do tipo do Windows, mas ele é colocado no namespace winrt de C++.A projected type has the same fully-qualified name as the Windows type, but it's placed in the C++ winrt namespace. Colocar essas inclusões no cabeçalho pré-compilado reduz os tempos incrementais da compilação.Putting these includes in your precompiled header reduces incremental build times.

Importante

Sempre que desejar usar um tipo de um namespace do Windows, você deverá #include o arquivo de cabeçalho do namespace C++/WinRT do Windows correspondente, como mostrado acima.Whenever you want to use a type from a Windows namespaces, you must #include the corresponding C++/WinRT Windows namespace header file, as shown above. O cabeçalho correspondente é aquele com o mesmo nome do namespace do tipo.The corresponding header is the one with the same name as the type's namespace. Por exemplo, para usar a projeção do C++/WinRT para a classe de runtime Windows::Foundation::Collections::PropertySet, inclua o cabeçalho winrt/Windows.Foundation.Collections.h.For example, to use the C++/WinRT projection for the Windows::Foundation::Collections::PropertySet runtime class, include the winrt/Windows.Foundation.Collections.h header.

É comum que o cabeçalho da projeção do C++/WinRT inclua automaticamente o arquivo de cabeçalho do namespace pai dele.It's usual for a C++/WinRT projection header to automatically include its parent namespace header file. Portanto, por exemplo, winrt/Windows.Foundation.Collections.h inclui winrt/Windows.Foundation.h.So, for example, winrt/Windows.Foundation.Collections.h includes winrt/Windows.Foundation.h. Mas você não deve contar com esse comportamento, pois é um detalhe de implementação que muda com o tempo.But you shouldn't rely on this behavior, since it's an implementation detail that changes over time. Você deve incluir explicitamente todos os cabeçalhos necessários.You must explicitly include any headers that you need.

using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Web::Syndication;

As diretivas using namespace são opcionais, mas convenientes.The using namespace directives are optional, but convenient. O padrão mostrado acima para essas diretivas (permitindo a pesquisa de nome não qualificado para qualquer item no namespace winrt) é adequado para quando você estiver iniciando um novo projeto e C++/WinRT for a única projeção de linguagem que está sendo usada dentro desse projeto.The pattern shown above for such directives (allowing unqualified name lookup for anything in the winrt namespace) is suitable for when you're beginning a new project and C++/WinRT is the only language projection you're using inside of that project. Por outro lado, se você estiver misturando código de C++/WinRT com C++/CX e/ou código ABI (interface binária de aplicativo) do SDK (você está fazendo a portabilidade de ou a interoperabilidade com um ou ambos os modelos), veja os tópicos Interoperabilidade entre C++/WinRT e C++/CX, Mover do C++/CX para C++/WinRT e Interoperabilidade entre C++/WinRT e ABI.If, on the other hand, you're mixing C++/WinRT code with C++/CX and/or SDK application binary interface (ABI) code (you're either porting from, or interoperating with, one or both of those models), then see the topics Interop between C++/WinRT and C++/CX, Move to C++/WinRT from C++/CX, and Interop between C++/WinRT and the ABI.

winrt::init_apartment();

A chamada a winrt::init_apartment inicializa o thread no Windows Runtime; por padrão, em um apartment multi-threaded.The call to winrt::init_apartment initializes the thread in the Windows Runtime; by default, in a multithreaded apartment. A chamada também inicializa o COM.The call also initializes COM.

Uri rssFeedUri{ L"https://blogs.windows.com/feed" };
SyndicationClient syndicationClient;

Aloque dois objetos em pilha: eles representam o uri do blog do Windows e um cliente de sindicalização.Stack-allocate two objects: they represent the uri of the Windows blog, and a syndication client. Construímos o uri com um literal de cadeia de caracteres simples (veja Processamento da cadeia de caracteres em C++/WinRT para ver outras formas de trabalhar com cadeias de caracteres).We construct the uri with a simple wide string literal (see String handling in C++/WinRT for more ways you can work with strings).

SyndicationFeed syndicationFeed = syndicationClient.RetrieveFeedAsync(rssFeedUri).get();

SyndicationClient::RetrieveFeedAsync é um exemplo de uma função assíncrona do Windows Runtime.SyndicationClient::RetrieveFeedAsync is an example of an asynchronous Windows Runtime function. O exemplo de código recebe um objeto de operação assíncrona do RetrieveFeedAsync e chama get nesse objeto para bloquear o thread de chamada e aguardar os resultados (no caso, um feed de sindicalização).The code example receives an asynchronous operation object from RetrieveFeedAsync, and it calls get on that object to block the calling thread and wait for the result (which is a syndication feed, in this case). Para saber mais sobre simultaneidade e técnicas de não bloqueio, confira Simultaneidade e operações assíncronas com C++/WinRT.For more about concurrency, and for non-blocking techniques, see Concurrency and asynchronous operations with C++/WinRT.

for (const SyndicationItem syndicationItem : syndicationFeed.Items()) { ... }

SyndicationFeed.Items é um intervalo, definido pelos iteradores retornados pelas funções begin e end (ou por suas variantes constantes, reversas e constante-reversas).SyndicationFeed.Items is a range, defined by the iterators returned from begin and end functions (or their constant, reverse, and constant-reverse variants). Por isso, você pode enumerar itens com uma instrução for baseada em intervalo ou com a função de modelo std::for_each.Because of this, you can enumerate Items with either a range-based for statement, or with the std::for_each template function. Sempre que você iterar em uma coleção do Windows Runtime como essa, você precisará #include <winrt/Windows.Foundation.Collections.h>.Whenever you iterate over a Windows Runtime collection like this, you'll need to #include <winrt/Windows.Foundation.Collections.h>.

winrt::hstring titleAsHstring = syndicationItem.Title().Text();
std::wcout << titleAsHstring.c_str() << std::endl;

Veja o texto do título do feed como um objeto winrt::hstring (mais detalhes em Processamento de cadeia de caracteres em C++/WinRT).Gets the feed's title text, as a winrt::hstring object (more details in String handling in C++/WinRT). Em seguida, hstring é enviado pela função c_str, que reflete o padrão usado com cadeias de caracteres da biblioteca padrão C++.The hstring is then output, via the c_str function, which reflects the pattern used with C++ Standard Library strings.

Como você pode ver, o C++/WinRT incentiva o uso de expressões C++ modernas e semelhantes a classes, como syndicationItem.Title().Text().As you can see, C++/WinRT encourages modern, and class-like, C++ expressions such as syndicationItem.Title().Text(). Esse é um estilo de programação diferente e mais limpo em contraposição à programação COM tradicional.This is a different, and cleaner, programming style from traditional COM programming. Não é necessário inicializar diretamente o COM nem trabalhar com ponteiros do COM.You don't need to directly initialize COM, nor work with COM pointers.

Nem tampouco é necessário processar os códigos de retorno de HRESULT.Nor do you need to handle HRESULT return codes. O C++/WinRT converte os HRESULTs de erro em exceções, como winrt::hresult-error para oferecer um estilo de programação moderno e natural.C++/WinRT converts error HRESULTs to exceptions such as winrt::hresult-error for a natural and modern programming style. Para saber mais sobre o processamento de erros e ver exemplos de código, confira Processamento de erros com C++/WinRT.For more info about error-handling, and code examples, see Error handling with C++/WinRT.

Modificar um projeto de aplicativo de Área de Trabalho do Windows para adicionar suporte ao C++/WinRTModify a Windows Desktop application project to add C++/WinRT support

Esta seção mostra como é possível adicionar suporte ao C++/WinRT a um projeto de aplicativo de Área de Trabalho do Windows que você possa ter.This section shows you how you can add C++/WinRT support to a Windows Desktop application project that you might have. Se você não tiver um projeto de aplicativo de Área de Trabalho do Windows existente, siga estas etapas para criar um.If you don't have an existing Windows Desktop application project, then you can follow along with these steps by first creating one. Por exemplo, abra o Visual Studio e crie um projeto Visual C++ > Área de Trabalho do Windows > Aplicativo da Área de Trabalho do Windows.For example, open Visual Studio and create a Visual C++ > Windows Desktop > Windows Desktop Application project.

Se desejar, você pode instalar a VSIX (Extensão do Visual Studio) para C++/WinRT e o pacote NuGet.You can optionally install the C++/WinRT Visual Studio Extension (VSIX) and the NuGet package. Para obter detalhes, confira Suporte ao Visual Studio para C++/WinRT.For details, see Visual Studio support for C++/WinRT.

Definir propriedades do projetoSet project properties

Vá para a propriedade do projeto Geral > Versão do SDK do Windows e selecione Todas as Configurações e Todas as Plataformas.Go to project property General > Windows SDK Version, and select All Configurations and All Platforms. Certifique-se de que a Versão do SDK do Windows esteja definida para 10.0.17134.0 (Windows 10, versão 1803) ou superior.Ensure that Windows SDK Version is set to 10.0.17134.0 (Windows 10, version 1803) or greater.

Confirme que você não será afetado por Por que meu novo projeto não será compilado?.Confirm that you're not affected by Why won't my new project compile?.

Como o C++/WinRT usa recursos do padrão C++17, defina a propriedade do projeto C/C++ > Linguagem > Padrão da Linguagem C++ para Padrão ISO C++17 (/std:c++17) .Because C++/WinRT uses features from the C++17 standard, set project property C/C++ > Language > C++ Language Standard to ISO C++17 Standard (/std:c++17).

O cabeçalho pré-compiladoThe precompiled header

O modelo de projeto padrão cria um cabeçalho pré-compilado para você, denominado framework.h ou stdafx.h.The default project template creates a precompiled header for you, named either framework.h, or stdafx.h. Renomeie-o para pch.h.Rename that to pch.h. Se você tiver um arquivo stdafx.cpp, renomeie-o para pch.cpp.If you have a stdafx.cpp file, then rename that to pch.cpp. Defina a propriedade do projeto C/C++ > Cabeçalhos Pré-compilados > Cabeçalho Pré-compilado para Criar (/Yc) e Arquivo de Cabeçalho Pré-compilado para pch.h.Set project property C/C++ > Precompiled Headers > Precompiled Header to Create (/Yc), and Precompiled Header File to pch.h.

Localize e substitua todo o #include "framework.h" (ou #include "stdafx.h") por #include "pch.h".Find and replace all #include "framework.h" (or #include "stdafx.h") with #include "pch.h".

Em pch.h, inclua winrt/base.h.In pch.h, include winrt/base.h.

// pch.h
...
#include <winrt/base.h>

VinculaçãoLinking

A projeção de linguagem de C++/WinRT depende de determinadas funções livres (não membros) do Windows Runtime, que exigem vinculação à biblioteca WindowsApp.lib.The C++/WinRT language projection depends on certain Windows Runtime free (non-member) functions, and entry points, that require linking to the WindowsApp.lib umbrella library. Esta seção descreve três maneiras de atender ao vinculador.This section describes three ways of satisfying the linker.

A primeira opção é adicionar ao seu projeto do Visual Studio todos os destinos e propriedades MSBuild de C++/WinRT.The first option is to add to your Visual Studio project all of the C++/WinRT MSBuild properties and targets. Para isso, instale o pacote NuGet Microsoft.Windows.CppWinRT em seu projeto.To do this, install the Microsoft.Windows.CppWinRT NuGet package into your project. Abra o projeto no Visual Studio, clique em Projeto > Gerenciar Pacotes NuGet... > Procurar, digite ou cole Microsoft.Windows.CppWinRT na caixa de pesquisa, selecione o item nos resultados da pesquisa e clique em Instalar para instalar o pacote do projeto.Open the project in Visual Studio, click Project > Manage NuGet Packages... > Browse, type or paste Microsoft.Windows.CppWinRT in the search box, select the item in search results, and then click Install to install the package for that project.

Você também pode usar as configurações de link do projeto para vincular WindowsApp.lib explicitamente.You can also use project link settings to explicitly link WindowsApp.lib. Ou você pode fazê-lo no código-fonte (em pch.h, por exemplo) como se segue.Or, you can do it in source code (in pch.h, for example) like this.

#pragma comment(lib, "windowsapp")

Agora, você pode compilar e vincular, bem como adicionar código de C++/WinRT ao seu projeto (por exemplo, código semelhante a esse mostrado na seção Um início rápido do C++/WinRT, acima).You can now compile and link, and add C++/WinRT code to your project (for example, code similar to that shown in the A C++/WinRT quick-start section, above).

Os três principais cenários para C++/WinRTThe three main scenarios for C++/WinRT

Conforme você usar e se familiarizar com o C++/WinRT e trabalhar com o restante da documentação aqui, você provavelmente observará que há três principais cenários, conforme descrito nas seções a seguir.As you use and become familiar with C++/WinRT, and work through the rest of the documentation here, you'll likely notice that there are three main scenarios, as described in the following sections.

Consumir tipos e APIs do Windows RuntimeConsuming Windows Runtime APIs and types

Em outras palavras, usar ou chamar APIs.In other words, using, or calling APIs. Por exemplo, fazer chamadas à API para se comunicar usando Bluetooth; para transmitir e apresentar vídeo; para integrar-se ao shell do Windows; e assim por diante.For example, making API calls to communicate using Bluetooth; to stream and present video; to integrate with the Windows shell; and so on. O C++/WinRT dá suporte total e inflexível a essa categoria de cenário.C++/WinRT fully and uncompromisingly supports this category of scenario. Para saber mais, confira Consumir APIs com C++/WinRT.For more info, see Consume APIs with C++/WinRT.

Criar tipos e APIs do Windows RuntimeAuthoring Windows Runtime APIs and types

Em outras palavras, produzir tipos e APIs.In other words, producing APIs and types. Por exemplo, produzir os tipos de APIs descritos na seção acima; ou as APIs gráficas; as APIs de armazenamento e do sistema de arquivos; as APIs de rede e assim por diante.For example, producing the kinds of APIs described in the section above; or the graphics APIs; the storage and file system APIs; the networking APIs, and so on. Para obter mais informações, confira Criar APIs com C++/WinRT.For more info, see Author APIs with C++/WinRT.

Criar APIs com o C++/WinRT é um pouco mais complicado do que consumi-las, porque você deve usar o IDL para definir a forma da API antes de poder implementá-la.Authoring APIs with C++/WinRT is a little more involved than consuming them, because you must use IDL to define the shape of the API before you can implement it. Há um passo a passo para fazer isso nos Controles XAML; associar a uma propriedade de C++/WinRT.There's a walkthrough of doing that in XAML controls; bind to a C++/WinRT property.

Aplicativos XAMLXAML applications

Esse cenário trata-se de compilar aplicativos e controles na estrutura de interface do usuário XAML.This scenario is about building applications and controls on the XAML UI framework. Trabalhar em um aplicativo XAML resulta em uma combinação de consumo e criação.Working in a XAML application amounts to a combination of consuming and authoring. Mas como o XAML é a estrutura de interface do usuário dominante no Windows atualmente e sua influência sobre o Windows Runtime é proporcional a isso, ele merece sua própria categoria de cenário.But since XAML is the dominant UI framework on Windows today, and its influence over the Windows Runtime is proportionate to that, it deserves its own category of scenario.

Lembre-se de que o XAML funciona melhor com linguagens de programação que oferecem reflexão.Be aware that XAML works best with programming languages that offer reflection. No C++/WinRT, às vezes você precisa ter um pouco mais de trabalho para interoperar com a estrutura XAML.In C++/WinRT, you sometimes have to do a little extra work in order to interoperate with the XAML framework. Todos esses casos são abordados na documentação.All of those cases are covered in the documentation. Bons locais para começar são Controles XAML; associar a uma propriedade de C++/WinRT e controles personalizados XAML (com modelo) com o C++/WinRT.Good places to start are XAML controls; bind to a C++/WinRT property and XAML custom (templated) controls with C++/WinRT.

Aplicativos de exemplo escritos em C++/WinRTSample apps written in C++/WinRT

Confira Onde posso encontrar aplicativos de exemplo do C++/WinRT?.See Where can I find C++/WinRT sample apps?.

APIs importantesImportant APIs