| description | Learn how to send a local app notification from a C++ UWP app and handle the user clicking the notification. | ||||
|---|---|---|---|---|---|
| title | Send a local app notification from a C++ UWP app | ||||
| ms.assetid | E9AB7156-A29E-4ED7-B286-DA4A6E683638 | ||||
| label | Send a local app notification from a C++ UWP app | ||||
| template | detail.hbs | ||||
| ms.date | 07/28/2025 | ||||
| ms.topic | how-to | ||||
| keywords | windows 10, uwp, send toast notifications, notifications, send notifications, toast notifications, how to, quickstart, getting started, code sample, walkthrough, cpp, c++, uwp | ||||
| ms.localizationpriority | medium | ||||
| no-loc |
|
[!INCLUDE intro]
Note
The term "toast notification" is being replaced with "app notification". These terms both refer to the same feature of Windows, but over time we will phase out the use of "toast notification" in the documentation.
Important
If you're writing a C++ non-UWP app, please see the C++ WRL documentation. If you're writing a C# app, please see the C# documentation.
You can create app notifications with the Windows Community Toolkit (WCT)'s builder syntax OR with XML. If you prefer the latter, please skip to Step 2 and refer to the Without builder syntax code examples.
[!INCLUDE nuget package]
Our Builder syntax code examples will use this package. This package allows you to create app notifications without using XML.
using namespace Microsoft::Toolkit::Uwp::Notifications;using namespace winrt::Windows::UI::Notifications;
using namespace Windows::Data::Xml::Dom;[!INCLUDE basic toast intro]
If you are not using the WCT Notifications library builder syntax, you will instead construct the XML app notification template, populate it with text and values, construct the notification, and show it.
// Construct the content and show the toast!
(ref new ToastContentBuilder())
->AddArgument("action", "viewConversation")
->AddArgument("conversationId", 9813)
->AddText("Andrew sent you a picture")
->AddText("Check this out, The Enchantments in Washington!")
->Show();// Construct the XML toast template
XmlDocument doc;
doc.LoadXml(L"\
<toast>\
<visual>\
<binding template=\"ToastGeneric\">\
<text></text>\
<text></text>\
</binding>\
</visual>\
</toast>");
// Populate with text and values
doc.DocumentElement().SetAttribute(L"launch", L"action=viewConversation&conversationId=9813");
doc.SelectSingleNode(L"//text[1]").InnerText(L"Andrew sent you a picture");
doc.SelectSingleNode(L"//text[2]").InnerText(L"Check this out, Happy Canyon in Utah!");
// Construct the notification
winrt::Windows::UI::Notifications::ToastNotification notif{ doc };
winrt::Windows::UI::Notifications::ToastNotificationManager toastManager{};
ToastNotifier toastNotifier{ toastManager.CreateToastNotifier() };
// And show it!
toastNotifier.Show(notif);When the user clicks your notification (or a button on the notification with foreground activation), your app's App.xaml.cpp OnActivated will be invoked.
App.xaml.cpp
void App::OnActivated(IActivatedEventArgs^ e)
{
// Handle notification activation
if (e->Kind == ActivationKind::ToastNotification)
{
ToastNotificationActivatedEventArgs^ toastActivationArgs = (ToastNotificationActivatedEventArgs^)e;
// Obtain the arguments from the notification
ToastArguments^ args = ToastArguments::Parse(toastActivationArgs->Argument);
// Obtain any user input (text boxes, menu selections) from the notification
auto userInput = toastActivationArgs->UserInput;
// TODO: Show the corresponding content
}
}[!INCLUDE OnLaunched warning]
The first step in making your notifications actionable is to add some launch args to your notification, so that your app can know what to launch when the user clicks the notification (in this case, we're including some information that later tells us we should open a conversation, and we know which specific conversation to open).
// Construct the content and show the toast!
(ref new ToastContentBuilder())
// Arguments returned when user taps body of notification
->AddArgument("action", "viewConversation")
->AddArgument("conversationId", 9813)
->AddText("Andrew sent you a picture")
->Show();// Construct the XML toast template
XmlDocument doc;
doc.LoadXml(L"\
<toast>\
<visual>\
<binding template=\"ToastGeneric\">\
<text></text>\
<text></text>\
</binding>\
</visual>\
</toast>");
// Populate with text and values
doc.SelectSingleNode(L"//text[1]").InnerText(L"Andrew sent you a picture");
doc.SelectSingleNode(L"//text[2]").InnerText(L"Check this out, Happy Canyon in Utah!");
// Arguments returned when user taps body of notification
doc.DocumentElement().SetAttribute(L"launch", L"action=viewConversation&conversationId=9813");
// Construct the notification
winrt::Windows::UI::Notifications::ToastNotification notif{ doc };
winrt::Windows::UI::Notifications::ToastNotificationManager toastManager{};
ToastNotifier toastNotifier{ toastManager.CreateToastNotifier() };
// And show it!
toastNotifier.Show(notif);You can add rich content to notifications. We'll add an inline image and a profile (app logo override) image.
[!INCLUDE images note]
// Construct the content and show the toast!
(ref new ToastContentBuilder())
...
// Inline image
->AddInlineImage(ref new Uri("https://picsum.photos/360/202?image=883"))
// Profile (app logo override) image
->AddAppLogoOverride(ref new Uri("ms-appdata:///local/Andrew.jpg"), ToastGenericAppLogoCrop::Circle)
->Show();// Construct the XML toast template
XmlDocument doc;
doc.LoadXml(L"\
<toast>\
<visual>\
<binding template=\"ToastGeneric\">\
<text></text>\
<text></text>\
<image/>\
<image placement=\"appLogoOverride\" hint-crop=\"circle\"/>\
</binding>\
</visual>\
</toast>");
// Populate with text and values
doc.DocumentElement().SetAttribute(L"launch", L"action=viewConversation&conversationId=9813");
doc.SelectSingleNode(L"//text[1]").InnerText(L"Andrew sent you a picture");
doc.SelectSingleNode(L"//text[2]").InnerText(L"Check this out, Happy Canyon in Utah!");
// Inline image
doc.SelectSingleNode(L"//image[1]").as<XmlElement>().SetAttribute(L"src", L"https://picsum.photos/360/202?image=883");
// Profie (app logo override) image
doc.SelectSingleNode(L"//image[2]").as<XmlElement>().SetAttribute(L"src", L"ms-appdata:///local/Andrew.jpg");
// Construct the notification
winrt::Windows::UI::Notifications::ToastNotification notif{ doc };
winrt::Windows::UI::Notifications::ToastNotificationManager toastManager{};
ToastNotifier toastNotifier{ toastManager.CreateToastNotifier() };
// And show it!
toastNotifier.Show(notif);You can add buttons and inputs to make your notifications interactive. Buttons can launch your foreground app, a protocol, or your background task. We'll add a reply text box, a "Like" button, and a "View" button that opens the image.
// Construct the content
(ref new ToastContentBuilder())
->AddArgument("conversationId", 9813)
...
// Text box for replying
->AddInputTextBox("tbReply", "Type a response")
// Buttons
->AddButton((ref new ToastButton())
->SetContent("Reply")
->AddArgument("action", "reply")
->SetBackgroundActivation())
->AddButton((ref new ToastButton())
->SetContent("Like")
->AddArgument("action", "like")
->SetBackgroundActivation())
->AddButton((ref new ToastButton())
->SetContent("View")
->AddArgument("action", "view"))
->Show();// Construct the XML toast template
XmlDocument doc;
doc.LoadXml(L"\
<toast>\
<visual>\
<binding template=\"ToastGeneric\">\
<text></text>\
<text></text>\
<image/>\
<image placement=\"appLogoOverride\" hint-crop=\"circle\"/>\
</binding>\
</visual>\
<actions>\
<input\
id=\"tbReply\"\
type=\"text\"\
placeHolderContent=\"Type a reply\"/>\
<action\
content=\"Reply\"\
activationType=\"background\"/>\
<action\
content=\"Like\"\
activationType=\"background\"/>\
<action\
content=\"View\"\
activationType=\"foreground\"/>\
</actions>\
</toast>");
// Populate with text and values
doc.DocumentElement().SetAttribute(L"launch", L"action=viewConversation&conversationId=9813");
...
// Buttons
doc.SelectSingleNode(L"//action[1]").as<XmlElement>().SetAttribute(L"arguments", L"action=reply&conversationId=9813");
doc.SelectSingleNode(L"//action[2]").as<XmlElement>().SetAttribute(L"arguments", L"action=like&conversationId=9813");
doc.SelectSingleNode(L"//action[3]").as<XmlElement>().SetAttribute(L"arguments", L"action=viewImage&imageUrl=https://picsum.photos/364/202?image=883");
// Construct the notification
winrt::Windows::UI::Notifications::ToastNotification notif{ doc };
winrt::Windows::UI::Notifications::ToastNotificationManager toastManager{};
ToastNotifier toastNotifier{ toastManager.CreateToastNotifier() };
// And show it!
toastNotifier.Show(notif);The activation of foreground buttons are handled in the same way as the main notification body (your App.xaml.cpp OnActivated will be called).
When you specify background activation on your app notification (or on a button inside the notification), your background task will be executed instead of activating your foreground app.
For more information on background tasks, please see Support your app with background tasks.
If you are targeting build 14393 or later, you can use in-process background tasks, which greatly simplify things. Note that in-process background tasks will fail to run on older versions of Windows. We'll use an in-process background task in this code sample.
const string taskName = "ToastBackgroundTask";
// If background task is already registered, do nothing
if (BackgroundTaskRegistration.AllTasks.Any(i => i.Value.Name.Equals(taskName)))
return;
// Otherwise request access
BackgroundAccessStatus status = await BackgroundExecutionManager.RequestAccessAsync();
// Create the background task
BackgroundTaskBuilder builder = new BackgroundTaskBuilder()
{
Name = taskName
};
// Assign the toast action trigger
builder.SetTrigger(new ToastNotificationActionTrigger());
// And register the task
BackgroundTaskRegistration registration = builder.Register();Then in your App.xaml.cs, override the OnBackgroundActivated method. You can then retrieve the pre-defined arguments and user input, similar to the foreground activation.
App.xaml.cs
protected override async void OnBackgroundActivated(BackgroundActivatedEventArgs args)
{
var deferral = args.TaskInstance.GetDeferral();
switch (args.TaskInstance.Task.Name)
{
case "ToastBackgroundTask":
var details = args.TaskInstance.TriggerDetails as ToastNotificationActionTriggerDetail;
if (details != null)
{
string arguments = details.Argument;
var userInput = details.UserInput;
// Perform tasks
}
break;
}
deferral.Complete();
}In Windows 10 and 11, all app notifications go in Action Center after they are dismissed or ignored by the user, so users can look at your notification after the popup is gone.
However, if the message in your notification is only relevant for a period of time, you should set an expiration time on the app notification so the users do not see stale information from your app. For example, if a promotion is only valid for 12 hours, set the expiration time to 12 hours. In the code below, we set the expiration time to be 2 days.
Note
The default and maximum expiration time for local app notifications is 3 days.
// Create toast content and show the toast!
(ref new ToastContentBuilder())
->AddText("Expires in 2 days...")
->Show(toast =>
{
toast->ExpirationTime = DateTime::Now->AddDays(2);
});If you want to programmatically remove or replace the notification you send, you need to use the Tag property (and optionally the Group property) to provide a primary key for your notification. Then, you can use this primary key in the future to remove or replace the notification.
To see more details on replacing/removing already delivered app notifications, please see Quickstart: Managing toast notifications in action center (XAML).
Tag and Group combined act as a composite primary key. Group is the more generic identifier, where you can assign groups like "wallPosts", "messages", "friendRequests", etc. And then Tag should uniquely identify the notification itself from within the group. By using a generic group, you can then remove all notifications from that group by using the RemoveGroup API.
// Create toast content and show the toast!
(ref new ToastContentBuilder())
->AddText("New post on your wall!")
->Show(toast =>
{
toast.Tag = "18365";
toast.Group = "wallPosts";
});Apps are responsible for removing and clearing their own notifications. When your app is launched, we do NOT automatically clear your notifications.
Windows will only automatically remove a notification if the user explicitly clicks the notification.
Here's an example of what a messaging app should do…
- User receives multiple app notifications about new messages in a conversation
- User taps one of those notifications to open the conversation
- The app opens the conversation and then clears all notifications for that conversation (by using RemoveGroup on the app-supplied group for that conversation)
- User's Action Center now properly reflects the notification state, since there are no stale notifications for that conversation left in Action Center.
To learn about clearing all notifications or removing specific notifications, see Quickstart: Managing toast notifications in action center (XAML).
ToastNotificationManagerCompat::History->Clear();
