Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added sample for WinAppSDK BackgroundTaskBuilder #392

Open
wants to merge 3 commits into
base: release/experimental
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ This repository hosts samples for the [Windows App SDK](https://github.com/micro
- [Restart](Samples/AppLifecycle/Restart): These samples demonstrate synchronously restarting an app with command-line restart arguments.
- [Share Target](Samples\AppLifecycle\ShareTarget\WinUI-CS-ShareTargetSampleApp): This sample demonstrates an app that can be activated as a share target.

#### Background Task
- [Background Task](Samples/BackgroundTask): These samples demonstrates usage of Background Task feature in WinAppSDK apps leveraging the WinAppSDK Background Task API.

#### Data and Files
- [Resource Management](Samples/ResourceManagement): These samples demonstrates app resource management using the MRT Core APIs.

Expand Down
16 changes: 16 additions & 0 deletions Samples/BackgroundTask/cpp-winui/BackgroundTaskBuilder/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Application
x:Class="BackgroundTaskBuilder.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BackgroundTaskBuilder">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<!-- Other merged dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Other app resources here -->
</ResourceDictionary>
</Application.Resources>
</Application>
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include "pch.h"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add copyright statement to all new files?

#include "App.xaml.h"
#include "MainWindow.xaml.h"
#include "RegisterForCOM.h"

using namespace winrt;
using namespace Microsoft::UI::Xaml;
using namespace BackgroundTaskBuilder;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace winrt::BackgroundTaskBuilder::implementation
{
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
App::App()
{
// Xaml objects should not call InitializeComponent during construction.
// See https://github.com/microsoft/cppwinrt/tree/master/nuget#initializecomponent

#if defined _DEBUG && !defined DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException([](IInspectable const&, UnhandledExceptionEventArgs const& e)
{
if (IsDebuggerPresent())
{
auto errorMessage = e.Message();
__debugbreak();
}
});
#endif
}

/// <summary>
/// Invoked when the application is launched.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
void App::OnLaunched([[maybe_unused]] LaunchActivatedEventArgs const& e)
{
window = make<MainWindow>();
window.Activate();
}
}


int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nShowCmd)
{
winrt::init_apartment(winrt::apartment_type::single_threaded);

if (std::wcsncmp(lpCmdLine, RegisterForCom::RegisterForComToken, sizeof(RegisterForCom::RegisterForComToken)) == 0)
{
RegisterForCom comRegister;
comRegister.RegisterAndWait(__uuidof(BackgroundTask));
MSG msg;

while (-1 != GetMessage(&msg, NULL, 0, 0) &&
WM_QUIT != msg.message)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
// put your fancy code somewhere here
::winrt::Microsoft::UI::Xaml::Application::Start(
[](auto&&)
{
::winrt::make<::winrt::BackgroundTaskBuilder::implementation::App>();
});
}

return 0;
}
16 changes: 16 additions & 0 deletions Samples/BackgroundTask/cpp-winui/BackgroundTaskBuilder/App.xaml.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include "App.xaml.g.h"

namespace winrt::BackgroundTaskBuilder::implementation
{
struct App : AppT<App>
{
App();

void OnLaunched(Microsoft::UI::Xaml::LaunchActivatedEventArgs const&);

private:
winrt::Microsoft::UI::Xaml::Window window{ nullptr };
};
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include "pch.h"
#include "BackgroundTask.h"
#include "winrt/Windows.Data.Xml.Dom.h"
#include "winrt/Windows.UI.Notifications.h"

using namespace winrt;
namespace winrt
{
using namespace winrt::Windows::ApplicationModel::Background;
using namespace Windows::Data::Xml::Dom;
using namespace Windows::UI::Notifications;
}

namespace winrt::BackgroundTaskBuilder
{
void BackgroundTask::Run(_In_ IBackgroundTaskInstance taskInstance)
{
// Get the deferral object from the task instance
TaskDeferral = taskInstance.GetDeferral();
taskInstance.Canceled({ this, &BackgroundTask::OnCanceled });
// Create a toast XML template
XmlDocument toastXml;
toastXml.LoadXml(LR"(
<toast>
<visual>
<binding template="ToastGeneric">
<text>Notification: BackgroundTaskBuilder</text>
<text>Background Task triggered</text>
</binding>
</visual>
</toast>)");
// Create the toast notification
ToastNotification toast(toastXml);
// Create a ToastNotifier and show the toast
ToastNotificationManager::CreateToastNotifier().Show(toast);
// Inform the system that the background task is completed
TaskDeferral.Complete();
}

void BackgroundTask::CreateNotification()
{
// Create the toast XML template
XmlDocument toastXml;
toastXml.LoadXml(LR"(
<toast>
<visual>
<binding template="ToastGeneric">
<text>Notification: BackgroundTaskBuilder</text>
<text>Change system timezone to trigger Background Task</text>
</binding>
</visual>
</toast>)");
// Create the toast notification
ToastNotification toast(toastXml);
// Create a ToastNotifier and show the toast
ToastNotificationManager::CreateToastNotifier().Show(toast);
}

void BackgroundTask::OnCanceled(_In_ IBackgroundTaskInstance /* taskInstance */, _In_ BackgroundTaskCancellationReason /* cancelReason */)
{
IsCanceled = true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once

#include "pch.h"

#define CLSID_BackgroundTask "12345678-1234-1234-1234-1234567890CD"
namespace winrt::BackgroundTaskBuilder
{
struct __declspec(uuid(CLSID_BackgroundTask))
BackgroundTask : implements<BackgroundTask, winrt::Windows::ApplicationModel::Background::IBackgroundTask>
{
volatile bool IsCanceled = false;
winrt::Windows::ApplicationModel::Background::BackgroundTaskDeferral TaskDeferral = nullptr;
void Run(_In_ winrt::Windows::ApplicationModel::Background::IBackgroundTaskInstance taskInstance);
void CreateNotification();
void OnCanceled(_In_ winrt::Windows::ApplicationModel::Background::IBackgroundTaskInstance /* taskInstance */, _In_ winrt::Windows::ApplicationModel::Background::BackgroundTaskCancellationReason /* cancelReason */);

};

struct BackgroundTaskFactory : implements<BackgroundTaskFactory, IClassFactory>
{
HRESULT __stdcall CreateInstance(_In_opt_ IUnknown* aggregateInterface, _In_ REFIID interfaceId, _Outptr_ VOID** object) noexcept final
{
if (aggregateInterface != NULL) {
return CLASS_E_NOAGGREGATION;
}

return make<BackgroundTask>().as(interfaceId, object);
}

HRESULT __stdcall LockServer(BOOL lock) noexcept final
{
UNREFERENCED_PARAMETER(lock);
return S_OK;
}
};
}

Loading