Поделиться через


Part 1: Create a "Hello, world" app (Windows Runtime apps using C++)

[ This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation ]

In Visual Studio 2013 with Update 2, you can use C++ to develop an app that runs on Windows 8.1 and Windows Phone 8.1, and has a UI that's defined in Extensible Application Markup Language (XAML).

This topic describes development for Windows 8.1. For an introductory tutorial for Windows 10 development in C++, seeCreate a "hello world" app in C++ (Windows 10). You can retarget apps written for Windows 8.1 and Windows Phone 8.1 to Windows 10.

For tutorials in other programming languages, see:

Before you start...

  • To complete this tutorial, you must use Microsoft Visual Studio Express 2013 for Windows with Update 2 or later, or one of the non-Express versions of Visual Studio 2013 with Update 2 or later, on a computer that's running Windows 8.1 or Windows 10. To download, see Get the tools. In the Visual Studio edition you're using, make sure you select the Visual C++ development settings.
  • You also must have a developer license. For instructions, see Get a developer license.
  • We assume you have a basic understanding of standard C++, XAML, and the concepts in the XAML overview.
  • We assume you're using the default window layout in Visual Studio. To reset to the default layout, on the menu bar, choose Window > Reset Window Layout.
  • You can view the complete code for this tutorial in the Hello World (C++) sample on Code Gallery.

The Visual C++ compiler in Microsoft Visual Studio 2015 does not support developing Windows Runtime apps that target Windows 8 or Windows 8.1. To target these platforms, make sure that Visual Studio 2013 Update 2 or later is installed on the computer, and then, in your Visual Studio 2015 project, open your Windows 8 or Windows 8.1 project, choose Project > Properties from the main menu, and in the General section, set the Platform Toolset property to Visual Studio 2013 (v120).

Comparing C++ desktop apps to Windows apps

If you're coming from a background in Windows desktop programming in C++, you'll probably find that some aspects of Windows Store app and Windows Phone app programming are familiar, but other aspects require some learning.

What's the same?

  • You can use the STL, the CRT (with some exceptions), and any other C++ library as long as the code does not attempt to call Windows functions that are not accessible from the Windows Runtime environment.

  • If you're accustomed to visual designers, you can still use the designer built into Microsoft Visual Studio, or you can use the more full-featured Blend for Microsoft Visual Studio 2013. If you're accustomed to coding UI by hand, you can hand-code your XAML.

  • You're still creating apps that use Windows operating system types and your own custom types.

  • You're still using the Visual Studio debugger, profiler, and other development tools.

  • You're still creating apps that are compiled to native machine code by the Visual C++ compiler. Windows Store apps in C++ don't execute in a managed runtime environment.

What's new?

  • The design principles for Windows Store apps are very different from those for desktop apps. Window borders, labels, dialog boxes, and so on, are de-emphasized. Content is foremost. Great Windows Store apps incorporate these principles from the very beginning of the planning stage.

  • You're using XAML to define the entire UI. The separation between UI and core program logic is much clearer in a Windows Store app than in an MFC or Win32 app. Other people can work on the appearance of the UI in the XAML file while you're working on the behavior in the code file.

  • You're primarily programming against a new, easy-to-navigate, object-oriented API, the Windows Runtime, although on Windows devices Win32 is still available for some functionality.

  • You use C++/CX to consume and create Windows Runtime objects. C++/CX enables C++ exception handling, delegates, events, and automatic reference counting of dynamically created objects. When you use C++/CX, the details of the underlying COM and Windows architecture are hidden from your app code. For more information, see C++/CX Language Reference.

  • Your app is compiled into a package that also contains metadata about the types that your app contains, the resources that it uses, and the capabilities that it requires (file access, internet access, camera access, and so forth).

  • In the Windows Store and Windows Phone Store your app is verified as safe by a certification process and made discoverable to millions of potential customers.

Hello World Store app in C++

Our first app is a "Hello World" that demonstrates some basic features of interactivity, layout, and styles. We'll create both a Windows Store 8.1 app and a Windows Phone 8.1 app from one universal app solution that contains a project for each version and a third project for the code they share.

We'll start with the basics:

  • How to create a universal app solution in Visual Studio Express 2013 for Windows with Update 2 or later.

  • How to understand the projects and files that are created.

  • How to understand the extensions in Visual C++ component extensions (C++/CX), and when to use them.

First, create a solution in Visual Studio

  1. In Visual Studio, on the menu bar, choose File > New > Project.

  2. In the New Project dialog box, in the left pane, expand Installed > Visual C++ > Store Apps > Universal Apps.

  3. In the center pane, select Blank App (Universal Apps).

  4. Enter a name for the project. We'll name it HelloWorld.

  5. Choose the OK button. Your project files are created.

Before we go on, let’s look at what's in the solution. First, notice that there's a Windows 8.1 project, a Windows Phone 8.1 project, and a shared project. The shared project doesn't produce any binary output; it contains code that both of the other projects use. Each platform-specific project contains the code that's specific to its UI.

Now, expand those nodes, select the Windows 8.1 project node and click the Show All Files icon. Do the same for the Windows Phone 8.1 project. Something like this should appear, depending on what you named your project:

About the project files

Every .xaml file in a project folder has a corresponding .xaml.h file and .xaml.cpp file in the same folder and a .g file and a .g.hpp file in the Generated Files folder. You modify the XAML files to create UI elements and connect them to data sources (DataBinding). You modify the .h and .cpp files to add custom logic for event handlers. The auto-generated files represent the transformation of the XAML markup into C++. Don't modify these files, but study them to better understand how the code-behind works. Basically, the generated file contains a partial class definition for a XAML root element; this class is the same class that you modify in the *.xaml.h and .cpp files. The generated files declare the XAML UI child elements as class members so that you can reference them in the code you write. At build time, the generated code and your code are merged into a complete class definition and then compiled.

Let's look first at the project files.

  • App.xaml, App.xaml.h, App.xaml.cpp: Represent the Application object, which is an app's entry point. App.xaml contains no page-specific UI markup, but you can add UI styles and other elements that you want to be accessible from any page. The code-behind files contain handlers for the OnLaunched and OnSuspending events. Typically, you add custom code here to initialize your app when it starts and perform cleanup when it's suspended or terminated.
  • **MainPage.xaml, MainPage.xaml.h, MainPage.xaml.cpp:**Contain the XAML markup and code-behind for the default "start" page in an app. It has no navigation support or built-in controls.
  • pch.h, pch.cpp: A precompiled header file and the file that includes it in your project. In pch.h, you can include any headers that do not change often and are included in other files in the solution.
  • package.appxmanifest: An XML file that describes the device capabilities that your app requires, and the app version info and other metadata. To open this file in the Manifest Designer, just double-click it.
  • **HelloWorld.Windows_TemporaryKey.pfx:**A key that enables deployment of the app on this machine, from Visual Studio.

A first look at the code

If you examine the code in App.xaml.h, App.xaml.cpp in the shared project, and MainPage.xaml.h and .cpp in each of the platform-specific projects, you'll notice that it's mostly ISO C++ code that looks familiar. However, some syntax elements might not be familiar. Here are the most common non-standard syntax elements you'll see in C++/CX:

  • Ref classes

    Almost all Windows Runtime classes, which includes all the types in the Windows API--XAML controls, the pages in your app, the App class itself, all device and network objects, all container types--are declared as a ref class. (A few Windows types are value class or value struct). A ref class is consumable from any language. In C++, the lifetime of these types is governed by automatic reference counting (not garbage collection) so that you never explicitly delete these objects. You can create your own ref classes as well.

    namespace HelloWorld
        public ref class MainPage sealed
        {
          public:
              MainPage();
            ...
        };
    }
    

    All Windows Runtime types must be declared within a namespace and unlike in ISO C++ the types themselves have an accessibility modifier. The public modifier makes the class visible to Windows Runtime components outside the namespace. The sealed keyword means the class cannot serve as a base class. Almost all ref classes are sealed; class inheritance is not broadly supported because Javascript does not understand it.

  • ref new and ^ (hats)

    You declare a variable of a ref class by using the ^ (hat) operator, and you instantiate the object with the ref new keyword. Thereafter you access the object's instance methods with the -> operator just like a C++ pointer. Static methods are accessed with the :: operator just as in ISO C++.

    In the following code, we use the fully qualified name to instantiate an object, and use the -> operator to call an instance method.

    Windows::UI::Xaml::Media::Imaging::BitmapImage^ bitmapImage =
        ref new Windows::UI::Xaml::Media::Imaging::BitmapImage();
    
    bitmapImage->SetSource(fileStream);
    

    Typically, in a .cpp file we would add a using namespace Windows::UI::Xaml::Media::Imaging directive and the auto keyword, so that the same code would look like this:

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

    A ref class can have properties, which, just as in managed languages, are special member functions that appear as fields to consuming code.

    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);
        }
    }
    
  • Delegates

    Just as in managed languages, a delegate is a reference type that encapsulates a function with a specific signature. They are most often used with events and event handlers

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

WINAPI_FAMILY macro

In a Universal Windows app, some code files are shared between the phone and Windows projects. In those files you will sometimes see or need to use the conditional compilation directive to exclude code that is only available on one or the other platform. For example, in app.xaml.cpp, the RootFrame_FirstNavigated method is only relevant for phone projects:

In app.xaml.cpp:

#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
/// <summary>
/// Restores the content transitions after the app is started.
/// </summary>
void App::RootFrame_FirstNavigated(Object^ sender, NavigationEventArgs^ e)
{
    ...
}
#endif

Adding content to the app

Let's add some content to the app. We'll work in both the Windows 8.1 and the Windows Phone 8.1 projects as we go along and have two running apps at the end.

Step 1: Modify your start page

  1. In Solution Explorer, in the Windows 8.1 project, open MainPage.xaml.

  2. Create controls for the UI by adding the following XAML to the root Grid, immediately before its closing tag. It contains a StackPanel that has a TextBlock that asks the user's name, a TextBox element that accepts the user's name, a Button, and another TextBlock element.

    <StackPanel  Margin="120,30,0,0">
        <TextBlock HorizontalAlignment="Left" Text="Hello World" FontSize="36"/>
        <TextBlock Text="What's your name?"/>
        <StackPanel Orientation="Horizontal" Margin="0,20,0,20">
            <TextBox x:Name="nameInput" Width="300" HorizontalAlignment="Left"/>
            <Button Content="Say &quot;Hello&quot;"/>
        </StackPanel>
        <TextBlock x:Name="greetingOutput"/>
    </StackPanel>
    

    We talk more about XAML layout in the Navigation, layout, and views article.

  3. At this point, you have created a very basic Windows Store app. (We'll work on the Windows Phone app next. The concepts are very similar.) To see what the Windows Store app looks like, right-click the Windows 8.1 project and choose Set as StartUp Project., and then press F5 to build, deploy, and run the app in debugging mode.

    The default splash screen appears first. It has an image—Assets\SplashScreen.scale-100.png—and a background color that are specified in the app's manifest file. To learn how to customize the splash screen, see Adding a splash screen.

    When the splash screen disappears, your app appears. It displays a black screen and the title "My Application".

    There's no button or command to close the app. Although you could use the close gesture or Alt+F4 to close it, you typically don't close Windows Store apps. (This is discussed in Part 2: Manage app lifecycle and state.) Press the Windows key to go to the Start screen and notice that deploying the app adds its tile to the Start screen. To run the app again, just tap or click its tile, or press F5 in Visual Studio to run it in debugging mode.

    It doesn't do much—yet—but congratulations, you've built your first Windows Store app!

    To stop debugging and close the app, return to Visual Studio and press Shift+F5.

    For more information, see Running Windows Store apps from Visual Studio.

    In the app, you can type in the TextBox, but clicking the Button doesn't do anything. In later steps, you create an event handler for the button's Click event, which displays a personalized greeting. You add the event handler code to your MainPage.xaml.h and MainPage.xaml.cpp files.

  4. Now, in the Windows Phone 8.1 project, open MainPage.xaml and add the same XAML that you added to the Windows Store app earlier.

  5. Because the phone screen is smaller, let's make two changes to the XAML: first, reduce the outer StackPanel's left margin to "20". Then change the orientation of the inner StackPanel to vertical, so that the button displays below the text box. The entire XAML now looks like this:

    <StackPanel  Margin="20,30,0,0">
        <TextBlock HorizontalAlignment="Left" Text="Hello World" FontSize="36"/>
        <TextBlock Text="What's your name?"/>
        <StackPanel Orientation="Vertical" Margin="0,20,0,20">
            <TextBox x:Name="nameInput" Width="300" HorizontalAlignment="Left"/>
            <Button Content="Say &quot;Hello&quot;"/>
        </StackPanel>
        <TextBlock x:Name="greetingOutput"/>
    </StackPanel>
    
  6. Right-click the Windows Phone 8.1 project choose Set as StartUp Project, and then press F5 to run the app in the Windows Phone Emulator. You should see this:

Step 2: Create an event handler

  1. (Complete these steps in the Windows project and in the Windows Phone project.) In MainPage.xaml, in either XAML or design view, select the "Say Hello" Button in the StackPanel you added earlier.

  2. Open the Properties Window by pressing Alt+Enter, and then choose the Events button ().

  3. Find the Click event. In its text box, type the name of the function that handles the Click event. For this example, type "Button_Click".

  4. Press Enter. The event handler method is created in MainPage.xaml.cpp and opened so that you can add the code that's executed when the event occurs.

    At the same time, in MainPage.xaml, the XAML for the Button is updated to declare the Click event handler, like this:

    <Button Content="Say &quot;Hello&quot;" Click="Button_Click"/>
    
  5. In MainPage.xaml.cpp, add the following code to the Button_Click event handler that you just created. This code retrieves the user's name from the nameInputTextBox control and uses it to create a greeting. The greetingOutputTextBlock displays the result.

    void HelloWorld::MainPage::Button_Clicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
    {
        greetingOutput->Text = "Hello, " + nameInput->Text + "!";
    }
    
  6. Set the project as the startup, and then press F5 to build and run the app. When you type a name in the text box and click the button, the app displays a personalized greeting.

Step 3: Style the start page

Choosing a theme

It's easy to customize the look and feel of your app. By default, your app uses resources that have a dark style. The system resources also include a light theme. Let's try it out and see what it looks like.

To switch to the light theme

  1. In the Shared project, open App.xaml.

  2. In the opening Application tag, add the RequestedTheme property and set its value to Light:

    RequestedTheme="Light"
    

    Here's the full Application tag with the light theme added:

    <Application
        x:Class="HelloWorld.App"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:HelloWorld" 
        RequestedTheme="Light">
    
  3. Make one of the platform projects the startup, and then press F5 to build and run it. Notice that it uses the light theme. Now set the other platform project as the startup, press F5, and notice that it, too, uses the light theme. That's because App.xaml is shared by both projects.

Which theme should you use? Whichever one you want. Here's our take: for apps that mostly display images or video, we recommend the dark theme; for apps that contain a lot of text, we recommend the light theme. If you're using a custom color scheme, use the theme that goes best with your app's look and feel.

Note  The theme is applied when the app is started and can't be changed while the app is running.

 

Using system styles

Right now, in the Windows app the text is very small and difficult to read. Let's fix that by applying a system style.

To change the style of an element

  1. In the Windows project, open MainPage.xaml.

  2. In either XAML or design view, select the "What's your name?"TextBlock that you added earlier.

  3. In the Properties window (F4), choose the Properties button () in the upper right.

  4. Expand the Text group and set the font size to 18 px.

  5. Expand the Miscellaneous group and find the Style property.

  6. Click the property marker (the green box to the right of the Style property), and then, on the menu, choose System Resource > BaseTextBlockStyle.

    BaseTextBlockStyle is a resource that's defined in the ResourceDictionary in <root>\Program Files\Windows Kits\8.1\Include\winrt\xaml\design\generic.xaml.

    On the XAML design surface, the appearance of the text changes. In the XAML editor, the XAML for the TextBlock is updated:

    <TextBlock Text="What's your name?" Style="{StaticResource BasicTextStyle}"/>
    
  7. Repeat the process to set the font size and assign the BaseTextBlockStyle to the greetingOutputTextBlock element.

    Tip  Although there's no text in this TextBlock, when you move the pointer over the XAML design surface, a blue outline shows where it is so that you can select it.

     

    Your XAML now looks like this:

    <StackPanel Margin="120,30,0,0">
        <TextBlock Style="{ThemeResource BaseTextBlockStyle}" FontSize="16" Text="What's your name?"/>
        <StackPanel Orientation="Horizontal" Margin="0,20,0,20">
            <TextBox x:Name="nameInput" Width="300" HorizontalAlignment="Left"/>
            <Button Content="Say &quot;Hello&quot;" Click="Button_Click"/>
        </StackPanel>
        <TextBlock Style="{ThemeResource BaseTextBlockStyle}" FontSize="16" x:Name="greetingOutput"/>
    </StackPanel>
    
  8. Press F5 to build and run the app. It now looks like this:

  9. You can repeat these steps for the Windows Phone project.

Summary

Congratulations, you've completed the first tutorial! It taught how to add content to Universal Windows apps, how to add interactivity to them, and how to change their appearance.

See the code

Did you get stuck, or do you want to check your work? If so, see the Hello World (C++) sample on Code Gallery.

Next steps

In the next tutorial in this series, Manage app lifecycle and state, you can learn how the app life cycle works and how to save your app's state.