Writing C++ /CX code to generate XAML UI

Quite often I get asked a very simple question: Can I skip using XAML for creating the User Interface for my app and use C++ instead? The answer is yes you can, but the bigger question is: why do you want to go down that route? I guess, to each his/her own. I must say, I do not relish the idea of writing so much C++ code. Anyways, here is our sample.

Our example today relies on the very basic Blank Metro app template that ships along with Visual Studio.

  1. Create a solution based on the Blank Metro app template and in the MainPage.xaml, delete the Grid section.
  2. Add a new function to the MainPage.xaml.h file, say, CreateUI. This function takes no parameters and returns void.
  3. In the MainPage.xaml.cpp, add the call to CreateUI inside the MainPage constructor, just after the InitializeComponent function call.
  4. Now for the cool part.
  5. For our sample today, we will create a Grid and add a TextBlock with the message Hello World. This is our pure-code only equivalent of the canonical Hello World samples. Smile
  6. Here is the full listing of the function
    auto grid = ref new Grid();
    auto gridBackground = ref new SolidColorBrush();
    gridBackground->Color = Windows::UI::Colors::Black;

    this->Content = grid;

    auto helloText = ref new TextBlock();
    helloText->Text = "Hello World";
    helloText->HorizontalAlignment = Windows::UI::Xaml::HorizontalAlignment::Center;
    helloText->VerticalAlignment = Windows::UI::Xaml::VerticalAlignment::Center;

    helloText->FontSize = 30;
    helloText->FontWeight = Windows::UI::Text::FontWeights::Bold;
    helloText->FontStyle = Windows::UI::Text::FontStyle::Oblique;
    auto fontFamily = ref new Windows::UI::Xaml::Media::FontFamily("Segoe UI");
    helloText->FontFamily = fontFamily;

    auto textForeground = ref new SolidColorBrush();
    textForeground->Color = Windows::UI::Colors::Green;
    helloText->Foreground = textForeground;

    grid->Children->Append(helloText);

Enjoy!!

3 Comments

  1. Andrew Webb

    Here is a way to create a button handler without XAML.

    void MainPage::myMethod( Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
    {
    int w= 4;
    }

    myMethodButton->Click += ref new Windows::UI::Xaml::RoutedEventHandler(this, &MainPage::myMethod);

    ————

    I found the code in mainPage.g.hpp interesting. It interprets the XAML at runtime:

    Windows::UI::Xaml::Application::LoadComponent(this,
    ref new Windows::Foundation::Uri(L”ms-appx:///MainPage.xaml”), Windows::UI::Xaml::Controls::Primitives::ComponentResourceLocation::Application);

    and then uses the string for the name of the control to find the actual object
    CompressionOfJPG = safe_cast(static_cast(this)->FindName(L”CompressionOfJPG”));

    and then links the click method to the object:

    (safe_cast(target))->Click +=
    ref new Windows::UI::Xaml::RoutedEventHandler(this, (void (MainPage::*)(Platform::Object^, Windows::UI::Xaml::RoutedEventArgs^))&MainPage::CompressionOfJPG_Click_1);

    All this being under the hood in the generated code. However, generating code that parses XAML at runtime is quite different than generating code that does not need a runtime parsing mechanism.

  2. Hi Andrew,
    The code that is generated in mainpage.g.hpp is not interpreted at runtime. When you build your project in Visual Studio, the XAML Compiler runs and generates this code. So if you have a MainPage.xaml, the Xaml compiler generates mainpage.g.h and mainpage.g.hpp. Once the xaml code generation is complete, the C++ compiler takes over. It statically compiles mainpage.cpp along with mainpage.g.hpp to create the much needed object files which are then linked together to generate the final executable.
    The only thing that is loaded at runtime is the actual markup itself, which is why you see the call to ms-appx:///MainPage.xaml.
    I do agree with your statement that generating code that parses XAML at runtime is quite different than generating code that does not need a runtime parsing mechanism. Which is why i advocate using VS and C++ /CX along with XAML rather than creating everything in code-behind. 🙂

  3. Andrew Webb

    Hi Sridhar,
    Yes, I think we agree; the only runtime interpretation takes place inside the LoadComponent( ) call.

    I’m just fooling with skipping the XAML so I can understand better. Now if there was a C++/CX book out ….

Comments are closed