DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations

C++ and Metro: Event Handling And MessageBox

Toni Petrina user avatar by
Toni Petrina
·
Apr. 22, 12 · Interview
Like (0)
Save
Tweet
Share
6.27K Views

Join the DZone community and get the full member experience.

Join For Free

In the previous post we have created simple Metro application using C++ as the language of choice. Now we are going to add some interactivity into it.

MessageDialog

Add a simple button and using the following XAML snippet:

<Button Content="Click me" Click="Button_Click_1" Margin="12,20" />

Right click on the Button_Click_1 attribute value and select the Navigate to Event Handler. You will be transferred to the cpp file and both header and source file will be properly updated. Add the following code inside:

using namespace Windows::UI::Popups;
auto msgDlg = ref new MessageDialog("We want to notify you that you have successfully handled this event", "Vexing information");
msgDlg->ShowAsync();

If you run the code now, you will get the screen looking something like this:

Click the button and you the message box will be shown.

The MessageDialog class is similar to MessageBox class, but with a minor details. The first thing that You will notice is that the Show method ends with the Async suffix. Usually when you show a MessageBox dialog, the function is suspended until you click the OK button. However, all code after the ShowAsync method call will invoke immediately. To demonstrate this, add the following code immediately after the above snippet:

auto btn = dynamic_cast<Button^>(sender);
if (btn != nullptr)
	btn->Content = "Don't click me";

Compile and run the application and click on the button. You can notice that the button’s caption has been changed.

Notice how we used dynamic_cast for casting even though these are all COM objects. This is the power of C++/CX extensions which greatly simplify dealing with the otherwise cumbersome code.

The design philosophy for Metro applications is that all applications must stay responsive. Both the framework and the libraries support asynchronous constructs which simplify dealing with the asynchronous coding.

If you want to act after the user has closed the MessageDialog, you can do that easily via tasks. First include the header <ppltasks.h> and use the following code for adding the continuation task after the message dialog is closed:

using namespace Concurrency;
task<IUICommand^>(msgDlg->ShowAsync())
	.then([this](IUICommand^ command)
	{
		// check command or do some work
	});

Since you cannot capture local variables if they are handle or tracking reference, if you want to change the content for the button inside the lambda, do the following:

  1. Add the following attribute to the button in XAML: x:Name="btnClick"
  2. .

  3. Add this to the lambda’s captures.
  4. Inside the lambda’s body, write the following line
    btnClick->Content = "Click me";
    

Custom commands

If you want to add your own buttons and then add the handlers for them, you can do it via the Commands property of the MessageDialog instance. Add a new button in the XAML:

<Button Content="Enter the matrix" Click="Button_Matrix_Click" Margin="12,20" x:Name="btnMatrix" />

Write the following code for the click handler:

// in the BlankPage.xaml.h add the following line
void IgnoreButtonCallback(Windows::UI::Popups::IUICommand^ command);

// this goes into the BlankPage.xaml.cpp
void SimpleNativeApp::BlankPage::Button_Matrix_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
	using namespace Windows::UI::Popups;
	auto msgDlg = ref new MessageDialog("What will it be, Neo?", "Plot defining moment");

	msgDlg->Commands->Append(ref new UICommand("Red pill", ref new UICommandInvokedHandler([this](IUICommand^)
	{
		btnMatrix->Background = ref new Windows::UI::Xaml::Media::SolidColorBrush(Windows::UI::Colors::Red);
	})));
	msgDlg->Commands->Append(ref new UICommand("Blue pill", ref new UICommandInvokedHandler([this](IUICommand^)
	{
		btnMatrix->Background = ref new Windows::UI::Xaml::Media::SolidColorBrush(Windows::UI::Colors::Blue);
	})));
	msgDlg->Commands->Append(ref new UICommand("Ignore...", ref new UICommandInvokedHandler(this, &BlankPage::IgnoreButtonCallback)));

	using namespace Concurrency;
	msgDlg->ShowAsync();
}

void BlankPage::IgnoreButtonCallback(Windows::UI::Popups::IUICommand^ command)
{
	btnMatrix->Background = ref new Windows::UI::Xaml::Media::SolidColorBrush(Windows::UI::Colors::Gray);
}

Notice the UICommandInvokedHandler class used for handling events. In the first two instances we have used lambdas as the event handlers, but for the third instance we have bound local class method. You can either use unnamed lambdas or named functions as the event handlers.

Run the application and choose the different commands in the dialog. One possible scenario is visible on the image below.

That is all for today, we have seen how to cast reference counted objects, how to handle asynchronous tasks, how to construct event handlers. In the next post I will show how to use the idiomatic MVVM architecture in C++/XAML applications.

You can download the full source code for this sample from the following link: link.

Entries in this series:
  1. C++ and Metro: basic application
  2. C++ and Metro: event handling and MessageBox
Event

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • How To Best Use Java Records as DTOs in Spring Boot 3
  • AWS CodeCommit and GitKraken Basics: Essential Skills for Every Developer
  • Asynchronous Messaging Service
  • Accelerating Enterprise Software Delivery Through Automated Release Processes in Scaled Agile Framework (SAFe)

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: