Dela via


Skapa ett "Hello, World!" UWP-app i C++/CX

Viktigt!

I den här självstudien används C++/CX. Microsoft har släppt C++/WinRT: en helt standardmodern C++17-språkprojektion för Windows Runtime-API:er (WinRT). Mer information om det här språket finns i C++/WinRT.

Med Microsoft Visual Studio kan du använda C++/CX för att utveckla en app som körs i Windows med ett användargränssnitt som definieras i XAML (Extensible Application Markup Language).

Anmärkning

I den här självstudien används Visual Studio Community 2019. Om du använder en annan version av Visual Studio kan det se lite annorlunda ut för dig.

Innan du börjar

  • För att kunna slutföra den här självstudien måste du använda Visual Studio Community, eller någon av de andra versionerna av Visual Studio, på en dator som kör Windows. Information om hur du laddar ned finns i Hämta verktygen.
  • Om du vill följa med bör du ha en grundläggande förståelse för C++/CX, XAML och begreppen i XAML-översikt.
  • Om du vill följa med bör du använda standardfönsterlayouten i Visual Studio. Om du vill återställa till standardlayouten går du till menyraden och väljer Fönster>Återställ fönsterlayout.

Jämföra C++-skrivbordsappar med UWP-appar

Om du kommer från en bakgrund i Windows-skrivbordsprogrammering i C++, kommer du förmodligen att märka att vissa aspekter av att skriva appar för UWP är bekanta, men andra aspekter kräver viss inlärning.

Vad är samma sak?

  • Du kan använda STL, CRT (med vissa undantag) och andra C++-bibliotek så länge koden endast anropar Windows-funktioner som är tillgängliga från Windows Runtime-miljön.

  • Om du är van vid visuella designytor kan du fortfarande använda designern som är inbyggd i Microsoft Visual Studio, eller så kan du använda den mer kompletta blenden för Visual Studio. Om du är van vid att koda användargränssnittet för hand kan du handkoda din XAML.

  • Du skapar fortfarande appar som använder Windows-operativsystemtyper och dina egna anpassade typer.

  • Du använder fortfarande Visual Studio-felsökningsprogrammet, profileraren och andra utvecklingsverktyg.

  • Du skapar fortfarande appar som kompileras till inbyggd datorkod av Visual C++-kompilatorn. UWP-appar i C++/CX körs inte i en hanterad körningsmiljö.

Vad är nytt?

  • Designprinciperna för UWP-appar skiljer sig mycket från dem för skrivbordsappar. Fönsterkantlinjer, etiketter, dialogrutor och så vidare betonas mindre. Innehållet är först och främst. Stora UWP-appar innehåller dessa principer från början av planeringsfasen.

  • Du använder XAML för att definiera hela användargränssnittet. Separationen mellan användargränssnittet och kärnprogramlogik är mycket tydligare i en UWP-app än i en MFC- eller Win32-app. Andra kan arbeta med utseendet på användargränssnittet i XAML-filen medan du arbetar med beteendet i kodfilen.

  • Du programmerar främst mot ett nytt, lättnavigerat, objektorienterat API, Windows Runtime, men på Windows-enheter är Win32 fortfarande tillgängligt för vissa funktioner.

  • Du använder C++/CX för att använda och skapa Windows Runtime-objekt. C++/CX möjliggör C++-undantagshantering, ombud, händelser och automatisk referensräkning av dynamiskt skapade objekt. När du använder C++/CX döljs informationen om den underliggande COM- och Windows-arkitekturen från din appkod. Mer information finns i C++/CX Language Reference.

  • Din app kompileras till ett paket som också innehåller metadata om de typer som appen innehåller, de resurser som den använder och de funktioner som krävs (filåtkomst, internetåtkomst, kameraåtkomst och så vidare).

  • I Microsoft Store och Windows Phone Store verifieras din app som säker genom en certifieringsprocess och kan identifieras för miljontals potentiella kunder.

Hello World Store-app i C++/CX

Vår första app är en "Hello World" som visar några grundläggande funktioner i interaktivitet, layout och format. Vi skapar en app från projektmallen för Windows Universal-appen. Om du har utvecklat appar för Windows 8.1 och Windows Phone 8.1 tidigare kanske du kommer ihåg att du var tvungen att ha tre projekt i Visual Studio, ett för Windows-appen, ett för telefonappen och ett annat med delad kod. Windows Universal Windows Platform (UWP) gör det möjligt att bara ha ett projekt, som körs på alla enheter, inklusive stationära och bärbara datorer som kör Windows, enheter som surfplattor, mobiltelefoner, VR-enheter och så vidare.

Vi börjar med grunderna:

  • Så här skapar du ett Universellt Windows-projekt i Visual Studio.

  • Så här förstår du de projekt och filer som skapas.

  • Förstå tilläggen i Visual C++-komponenttillägg (C++/CX) och när de ska användas.

Först skapar du en lösning i Visual Studio

  1. I Visual Studio går du till menyraden och väljer File>New>Project....

  2. I dialogrutan Skapa ett nytt projekt väljer du Tom app (Universell Windows - C++/CX). Om du inte ser det här alternativet kontrollerar du att de universella Utvecklingsverktygen för Windows-appar är installerade. För mer information, se Kom igång.

C++/CX-projektmallar i dialogrutan Skapa ett nytt projekt

  1. Välj Nästaoch ange sedan ett namn för projektet. Vi ger den namnet HelloWorld.

  2. Välj knappen Skapa.

Anmärkning

Om det här är första gången du använder Visual Studio kan du se en inställningsdialogruta där du uppmanas att aktivera utvecklarläge. Utvecklarläge är en särskild inställning som gör det möjligt för vissa funktioner, till exempel behörighet att köra appar direkt, i stället för endast från Store. För mer information, vänligen läs Aktivera enheten för utveckling. Om du vill fortsätta med den här guiden väljer du utvecklarläge, klickar på Jaoch stänger dialogrutan.

Dina projektfiler skapas.

Innan vi går vidare ska vi titta på vad som finns i lösningen.

universell applösning med noder komprimerade

Om projektfilerna

Varje .xaml-fil i en projektmapp har en motsvarande .xaml.h-fil och .xaml.cpp fil i samma mapp och en .g-fil och en .g.hpp-fil i mappen Genererade filer, som finns på disken men inte en del av projektet. Du ändrar XAML-filerna för att skapa användargränssnittselement och ansluta dem till datakällor (DataBinding). Du ändrar .h- och .cpp-filerna för att lägga till anpassad logik för händelsehanterare. De automatiskt genererade filerna representerar omvandlingen av XAML-markering till C++/CX. Ändra inte dessa filer, men du kan studera dem för att bättre förstå hur koden bakom fungerar. I grund och botten innehåller den genererade filen en partiell klassdefinition för ett XAML-rotelement. den här klassen är samma klass som du ändrar i filerna *.xaml.h och .cpp. De genererade filerna deklarerar de underordnade XAML-gränssnittselementen som klassmedlemmar så att du kan referera till dem i koden du skriver. Under byggprocessen sammanfogas den genererade koden och din kod till en fullständig klassdefinition och kompileras sedan.

Vi tittar först på projektfilerna.

  • App.xaml, App.xaml.h, App.xaml.cpp: Representera programobjektet, som är en apps startpunkt. App.xaml innehåller ingen sidspecifik UI-markering, men du kan lägga till gränssnittsformat och andra element som du vill ska vara tillgängliga från valfri sida. Kod-bakomsfilerna innehåller hanterare för OnLaunched och OnSuspending händelser. Vanligtvis lägger du till anpassad kod här för att initiera din app när den startas och utföra rensning när den pausas eller avslutas.
  • MainPage.xaml, MainPage.xaml.h, MainPage.xaml.cpp: Innehåller XAML-markering och kod bakom för standardsidan "start" i en app. Den har inget navigeringsstöd eller inbyggda kontroller.
  • pch.h pch.cpp: En fördefinierad rubrikfil och filen som innehåller den i projektet. I pch.h kan du inkludera alla rubriker som inte ändras ofta och som ingår i andra filer i lösningen.
  • Package.appxmanifest: En XML-fil som beskriver de enhetsfunktioner som din app kräver, samt information om appversion och andra metadata. Om du vill öppna filen i Manifest Designerdubbelklickar du bara på den.
  • HelloWorld_TemporaryKey.pfx: En nyckel som möjliggör distribution av appen på den här datorn, från Visual Studio.

En första titt på koden

Om du undersöker koden i App.xaml.h, App.xaml.cpp i det delade projektet, ser du att det mest är C++-kod som ser bekant ut. Vissa syntaxelement kanske dock inte är lika bekanta om du är nybörjare på Windows Runtime-appar eller om du har arbetat med C++/CLI. Här är de vanligaste syntaxelementen som inte är standard i C++/CX:

Referensklasser

Nästan alla Windows Runtime-klasser, som innehåller alla typer i Windows API- XAML-kontroller, sidorna i din app, själva appklassen, alla enhets- och nätverksobjekt, alla containertyper – deklareras som en ref-klass. (Några Windows-typer är värdeklass eller värdestruktur). En referensklass kan användas från vilket språk som helst. I C++/CX styrs livslängden för dessa typer av automatisk referensräkning (inte skräpinsamling) så att du aldrig uttryckligen tar bort dessa objekt. Du kan också skapa egna referensklasser.

namespace HelloWorld
{
   /// <summary>
   /// An empty page that can be used on its own or navigated to within a Frame.
   /// </summary>
   public ref class MainPage sealed
   {
      public:
      MainPage();
   };
}

Alla Windows Runtime-typer måste deklareras inom ett namnområde och till skillnad från i ISO C++ har själva typerna en hjälpmedelsmodifierare. Den offentliga modifieraren gör klassen synlig för Windows Runtime-komponenter utanför namnområdet. Nyckelordet sluten innebär att klassen inte kan användas som en basklass. Nästan alla referensklasser är förseglade; klassarv används inte brett eftersom JavaScript inte förstår det.

ref nya och ^ (hattar)

Du deklarerar en variabel för en referensklass med operatorn ^ (hat) och instansierar objektet med det nya nyckelordet ref. Därefter kommer du åt objektets instansmetoder med operatorn -> precis som en C++-pekare. Statiska metoder används med operatorn :: precis som i ISO C++.

I följande kod använder vi det fullständigt kvalificerade namnet för att instansiera ett objekt och använder operatorn -> för att anropa en instansmetod.

Windows::UI::Xaml::Media::Imaging::BitmapImage^ bitmapImage =
     ref new Windows::UI::Xaml::Media::Imaging::BitmapImage();

bitmapImage->SetSource(fileStream);

I en .cpp fil lägger vi vanligtvis till ett using namespace Windows::UI::Xaml::Media::Imaging-direktiv och det automatiska nyckelordet, så att samma kod ser ut så här:

auto bitmapImage = ref new BitmapImage();
bitmapImage->SetSource(fileStream);

Egenskaper

En referensklass kan ha egenskaper, som precis som i hanterade språk är särskilda medlemsfunktioner som visas som fält för att använda kod.

public ref class SaveStateEventArgs sealed
{
   public:
   // Declare the property
   property Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ PageState
   {
      Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ get();
   }
   ...
};

   ...
   // consume the property like a public field
   void PhotoPage::SaveState(Object^ sender, Common::SaveStateEventArgs^ e)
   {    
      if (mruToken != nullptr && !mruToken->IsEmpty())
   {
      e->PageState->Insert("mruToken", mruToken);
   }
}

Ombuden

Precis som i hanterade språk är ett ombud en referenstyp som kapslar in en funktion med en specifik signatur. De används oftast med händelser och händelsehanterare

// Delegate declaration (within namespace scope)
public delegate void LoadStateEventHandler(Platform::Object^ sender, LoadStateEventArgs^ e);

// Event declaration (class scope)
public ref class NavigationHelper sealed
{
   public:
   event LoadStateEventHandler^ LoadState;
};

// Create the event handler in consuming class
MainPage::MainPage()
{
   auto navigationHelper = ref new Common::NavigationHelper(this);
   navigationHelper->LoadState += ref new Common::LoadStateEventHandler(this, &MainPage::LoadState);
}

Lägga till innehåll i appen

Nu ska vi lägga till lite innehåll i appen.

steg 1: Ändra startsidan

  1. I Solution Exploreröppnar du MainPage.xaml.

  2. Skapa kontroller för användargränssnittet genom att lägga till följande XAML i roten Grid, omedelbart före den avslutande taggen. Den innehåller en StackPanel- som har en TextBlock- som frågar användarens namn, ett TextBox--element som accepterar användarens namn, en Buttonoch ett annat TextBlock-element.

    <StackPanel x:Name="contentPanel" Margin="120,30,0,0">
        <TextBlock HorizontalAlignment="Left" Text="Hello World" FontSize="36"/>
        <TextBlock Text="What's your name?"/>
        <StackPanel x:Name="inputPanel" Orientation="Horizontal" Margin="0,20,0,20">
            <TextBox x:Name="nameInput" Width="300" HorizontalAlignment="Left"/>
            <Button x:Name="inputButton" Content="Say &quot;Hello&quot;"/>
        </StackPanel>
        <TextBlock x:Name="greetingOutput"/>
    </StackPanel>
    
  3. Nu har du skapat en mycket grundläggande Universell Windows-app. Om du vill se hur UWP-appen ser ut trycker du på F5 för att skapa, distribuera och köra appen i felsökningsläge.

Standardskärmen för välkomstskärmen visas först. Den har en bild – Tillgångar\SplashScreen.scale-100.png– och en bakgrundsfärg som anges i appens manifestfil. Mer information om hur du anpassar välkomstskärmen finns i Lägga till en välkomstskärm.

När välkomstskärmen försvinner visas appen. Den visar huvudsidan för appen.

UWP-appskärm med kontroller

Det gör inte mycket – ännu – men grattis, du har skapat din första Universella Windows-plattformsapp!

Om du vill sluta felsöka och stänga appen går du tillbaka till Visual Studio och trycker på Skift+F5.

Mer information finns i Kör en Store-app från Visual Studio.

I appen kan du skriva in i TextBox-, men att klicka på Knapp gör inget. I senare steg skapar du en händelsehanterare för knappens Klicka på händelse, som visar en anpassad hälsning.

Steg 2: Skapa en händelsehanterare

  1. I MainPage.xaml i XAML- eller designvyn väljer du "Säg hej"-knappen i StackPanel som du lade till tidigare.

  2. Öppna fönstret egenskaper genom att trycka på F4 och välj sedan knappen Händelser ( knappenHändelser).

  3. Leta reda på händelsen Klicka på. I textrutan skriver du namnet på den funktion som hanterar Klicka på händelse. I det här exemplet skriver du "Button_Click".

    fönstret Egenskaper, händelsevyn

  4. Tryck på Enter. Händelsehanterarmetoden skapas i MainPage.xaml.cpp och öppnas så att du kan lägga till koden som körs när händelsen inträffar.

Samtidigt uppdateras i MainPage.xaml XAML-koden för -knappen för att deklarera händelsehanteraren för Klick, så här:

<Button Content="Say &quot;Hello&quot;" Click="Button_Click"/>

Du skulle också helt enkelt kunna ha lagt till detta i xaml-koden manuellt, vilket kan vara användbart om designern inte läses in. Om du anger detta manuellt skriver du "Klicka" och låter sedan IntelliSense visa alternativet för att lägga till en ny händelsehanterare. På så sätt skapar Visual Studio nödvändig metoddeklaration och stub.

Designern kan inte läsas in om ett ohanterat undantag inträffar under rendering. Rendering i designern innebär att du kör en designtidsversion av sidan. Det kan vara bra att inaktivera körning av användarkod. Du kan göra detta genom att ändra inställningen i dialogrutan Verktyg, Alternativ. Under XAML Designeravmarkerar du Kör projektkod i XAML-designern (om det stöds).

  1. I MainPage.xaml.cpp lägger du till följande kod i den Button_Click händelsehanterare som du nyss skapade. Den här koden hämtar användarens namn från kontrollen nameInputTextBox och använder den för att skapa en hälsning. greetingOutput TextBlock visar resultatet.
void HelloWorld::MainPage::Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    greetingOutput->Text = "Hello, " + nameInput->Text + "!";
}
  1. Ange projektet som start och tryck sedan på F5 för att skapa och köra appen. När du skriver ett namn i textrutan och klickar på knappen visar appen en anpassad hälsning.

appskärm med meddelandevisning

Steg 3: Formatera startsidan

Välja ett tema

Det är enkelt att anpassa appens utseende och känsla. Som standard använder appen resurser som har ett ljust format. Systemresurserna innehåller också ett ljust tema. Nu ska vi prova och se hur det ser ut.

Växla till det mörka temat

  1. Öppna App.xaml.

  2. I den inledande taggen Application redigerar du egenskapen RequestedTheme och anger dess värde till Dark:

    RequestedTheme="Dark"
    

    Här är den fullständiga taggen Application med det mörka temat :

    <Application
    x:Class="HelloWorld.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloWorld"
    RequestedTheme="Dark">
    
  3. Tryck på F5 för att skapa och köra den. Observera att det använder det mörka temat.

    appskärm med mörkt tema

Vilket tema ska du använda? Vilken du vill. Här är vår tagning: för appar som mestadels visar bilder eller video rekommenderar vi det mörka temat; för appar som innehåller mycket text rekommenderar vi ljustemat. Om du använder ett anpassat färgschema använder du det tema som passar bäst för appens utseende och känsla. I resten av den här självstudien använder vi temat Ljus i skärmbilder.

Obs Temat används när appen startas och kan inte ändras när appen körs.

Använda systemstilar

Just nu är texten mycket liten och svår att läsa i Windows-appen. Låt oss åtgärda det genom att använda en systemstil.

Ändra formatmallen för ett element

  1. Öppna MainPage.xaml i Windows-projektet.

  2. I XAML- eller designvyn väljer du "Vad heter du?"TextBlock- som du lade till tidigare.

  3. I fönstret Egenskaper (F4) väljer du knappen Egenskaper (egenskaper) i det övre högra hörnet.

  4. Expandera gruppen Text och ange teckenstorleken till 18 px.

  5. Expandera gruppen Diverse och leta reda på egenskapen Style.

  6. Klicka på egenskapsmarkören (den gröna rutan till höger om egenskapen Style) och välj sedan System Resource>BaseTextBlockStylepå menyn.

    BaseTextBlockStyle är en resurs som definieras i ResourceDictionary i <rot>\Program Files\Windows Kits\10\Include\winrt\xaml\design\generic.xaml.

    egenskapsfönstret,egenskapsvyn

    På XAML-designytan ändras textens utseende. I XAML-redigeraren uppdateras XAML för TextBlock-:

<TextBlock Text="What's your name?" Style="{ThemeResource BaseTextBlockStyle}"/>
  1. Upprepa processen för att ange teckenstorleken och tilldela BaseTextBlockStyle- till elementet greetingOutputTextBlock.

    Tips Även om det inte finns någon text i den här TextBlock, visas en blå kontur över XAML-designytan när du flyttar pekaren, vilket visar var den är så att du kan välja den.  

    Din XAML ser nu ut så här:

<StackPanel x:Name="contentPanel" Margin="120,30,0,0">
    <TextBlock Style="{ThemeResource BaseTextBlockStyle}" FontSize="18" Text="What's your name?"/>
    <StackPanel x:Name="inputPanel" Orientation="Horizontal" Margin="0,20,0,20">
        <TextBox x:Name="nameInput" Width="300" HorizontalAlignment="Left"/>
        <Button x:Name="inputButton" Content="Say &quot;Hello&quot;" Click="Button_Click"/>
    </StackPanel>
    <TextBlock Style="{ThemeResource BaseTextBlockStyle}" FontSize="18" x:Name="greetingOutput"/>
</StackPanel>
  1. Tryck på F5 för att skapa och köra appen. Nu ser det ut så här:

appskärmen med större text

Steg 4: Anpassa användargränssnittet till olika fönsterstorlekar

Nu ska vi anpassa användargränssnittet till olika skärmstorlekar så att det ser bra ut på mobila enheter. För att göra detta lägger du till en VisualStateManager- och anger egenskaper som tillämpas för olika visuella tillstånd.

Så här justerar du layouten för användargränssnittet

  1. I XAML-redigeraren lägger du till det här blocket med XAML efter den inledande taggen för elementet root Grid.
<VisualStateManager.VisualStateGroups>
    <VisualStateGroup>
        <VisualState x:Name="wideState">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="641" />
            </VisualState.StateTriggers>
        </VisualState>
        <VisualState x:Name="narrowState">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="0" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="contentPanel.Margin" Value="20,30,0,0"/>
                <Setter Target="inputPanel.Orientation" Value="Vertical"/>
                <Setter Target="inputButton.Margin" Value="0,4,0,0"/>
            </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>
  1. Felsöka appen på den lokala datorn. Observera att användargränssnittet ser likadant ut som tidigare om inte fönstret blir smalare än 641 enhetsoberoende bildpunkter (DIP:er).
  2. Felsöka appen i den mobila enhetsemulatorn. Observera att användargränssnittet använder de egenskaper som du definierade i narrowState och visas korrekt på den lilla skärmen.

Mobilappskärm med formaterad text

Om du har använt en VisualStateManager- i tidigare versioner av XAML kanske du märker att XAML här använder en förenklad syntax.

VisualState med variabeln wideState har en AdaptiveTrigger med egenskapen MinWindowWidth inställd på 641. Det innebär att tillståndet endast ska tillämpas när fönsterbredden inte är mindre än minst 641 DIP:er. Du definierar inte någon Setter objekt för det här tillståndet, så den använder layoutegenskaperna som du definierade i XAML för sidinnehållet.

Den andra VisualState, narrowState, har en AdaptiveTrigger med egenskapen MinWindowWidth inställd på 0. Det här tillståndet tillämpas när fönsterbredden är större än 0, men mindre än 641 DIP:er. (Vid 641 DIP:er tillämpas wideState.) I det här tillståndet definierar du vissa Setter objekt för att ändra layoutegenskaperna för kontroller i användargränssnittet:

  • Du minskar vänstermarginalen för contentPanel-elementet från 120 till 20.
  • Du ändrar för elementet inputPanel från Horizontal till Vertical.
  • Du lägger till en toppmarginal på 4 DIP:er till elementet inputButton.

Sammanfattning

Grattis, du har slutfört den första självstudien! Den lärde dig hur du lägger till innehåll i Windows Universal-appar, hur du lägger till interaktivitet i dem och hur du ändrar deras utseende.

Nästa steg

Om du har ett Windows Universal-appprojekt som riktar sig mot Windows 8.1 och/eller Windows Phone 8.1 kan du portera det till Windows 10 eller Windows 11. Det finns ingen automatisk process för detta, men du kan göra det manuellt. Börja med ett nytt Windows Universal-projekt för att hämta den senaste projektsystemstrukturen och manifestfilerna, kopiera kodfilerna till projektets katalogstruktur, lägg till objekten i projektet och skriv om XAML med hjälp av VisualStateManager- enligt riktlinjerna i det här avsnittet. Mer information finns i Portering av ett Windows Runtime 8-projekt till ett Universal Windows Platform (UWP)-projekt och Portering till Universal Windows Platform (C++).

Om du har befintlig C++-kod som du vill integrera med en UWP-app, till exempel för att skapa ett nytt UWP-användargränssnitt för ett befintligt program, kan du läsa Så här använder du befintlig C++-kod i ett Universellt Windows-projekt.