RI release/1.2 preview1 to Main (#2939)
|
@ -8,4 +8,4 @@
|
|||
<disabledPackageSources>
|
||||
<clear />
|
||||
</disabledPackageSources>
|
||||
</configuration>
|
||||
</configuration>
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.2.32616.157
|
||||
|
@ -348,6 +348,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DeploymentAgent", "dev\Depl
|
|||
{B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AppNotificationBuilder", "dev\AppNotifications\AppNotificationBuilder\AppNotificationBuilder.vcxitems", "{E49329F3-5196-4BBA-B5C4-E11CE7EFB07A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AppNotificationBuilderTests", "test\AppNotificationBuilderTests\AppNotificationBuilderTests.vcxproj", "{131DE0C4-AA1E-4649-B5BC-7B43508FA93A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Windows.Security.AccessControl.Projection", "dev\Projections\CS\Microsoft.Windows.Security.AccessControl.Projection\Microsoft.Windows.Security.AccessControl.Projection.csproj", "{E6D59245-696F-4D13-ACF6-7ECE6E653367}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "API", "API", "{0D6B1FF3-A075-4194-9FC0-AF7BB89D0519}"
|
||||
|
@ -400,6 +404,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test_DeploymentManagerAutoI
|
|||
ProjectSection(ProjectDependencies) = postProject
|
||||
{B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1}
|
||||
EndProjectSection
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Windows.AppNotifications.Builder.Projection", "dev\Projections\CS\Microsoft.Windows.AppNotifications.Builder.Projection\Microsoft.Windows.AppNotifications.Builder.Projection.csproj", "{50BF3E96-3050-4053-B012-BF6993483DA5}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "VersionInfo", "VersionInfo", "{2A2D1131-273C-4E17-BCD3-8812170A4B95}"
|
||||
EndProject
|
||||
|
@ -444,6 +449,7 @@ Global
|
|||
dev\Deployment\Deployment.vcxitems*{db38fb4d-d04f-4c1d-93e0-f8ae259c5fd6}*SharedItemsImports = 9
|
||||
dev\EnvironmentManager\ChangeTracker\ChangeTracker.vcxitems*{e15c3465-9d45-495d-92ce-b91ef45e8623}*SharedItemsImports = 9
|
||||
dev\AppLifecycle\AppLifecycle.vcxitems*{e3a522a3-6635-4a42-bded-1af46a15f63c}*SharedItemsImports = 9
|
||||
dev\AppNotifications\AppNotificationBuilder\AppNotificationBuilder.vcxitems*{e49329f3-5196-4bba-b5c4-e11ce7efb07a}*SharedItemsImports = 9
|
||||
dev\VersionInfo\VersionInfo.vcxitems*{e3edec7f-a24e-4766-bb1d-6bdfba157c51}*SharedItemsImports = 9
|
||||
test\inc\inc.vcxitems*{e5659a29-fe68-417b-9bc5-613073dd54df}*SharedItemsImports = 4
|
||||
test\inc\inc.vcxitems*{e977b1bd-00dc-4085-a105-e0a18e0183d7}*SharedItemsImports = 4
|
||||
|
@ -1421,6 +1427,20 @@ Global
|
|||
{4410D374-A90C-4ADF-8B15-AA2AAE2636BF}.Release|x64.Build.0 = Release|x64
|
||||
{4410D374-A90C-4ADF-8B15-AA2AAE2636BF}.Release|x86.ActiveCfg = Release|Win32
|
||||
{4410D374-A90C-4ADF-8B15-AA2AAE2636BF}.Release|x86.Build.0 = Release|Win32
|
||||
{131DE0C4-AA1E-4649-B5BC-7B43508FA93A}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{131DE0C4-AA1E-4649-B5BC-7B43508FA93A}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{131DE0C4-AA1E-4649-B5BC-7B43508FA93A}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{131DE0C4-AA1E-4649-B5BC-7B43508FA93A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{131DE0C4-AA1E-4649-B5BC-7B43508FA93A}.Debug|x64.Build.0 = Debug|x64
|
||||
{131DE0C4-AA1E-4649-B5BC-7B43508FA93A}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{131DE0C4-AA1E-4649-B5BC-7B43508FA93A}.Debug|x86.Build.0 = Debug|Win32
|
||||
{131DE0C4-AA1E-4649-B5BC-7B43508FA93A}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{131DE0C4-AA1E-4649-B5BC-7B43508FA93A}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{131DE0C4-AA1E-4649-B5BC-7B43508FA93A}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{131DE0C4-AA1E-4649-B5BC-7B43508FA93A}.Release|x64.ActiveCfg = Release|x64
|
||||
{131DE0C4-AA1E-4649-B5BC-7B43508FA93A}.Release|x64.Build.0 = Release|x64
|
||||
{131DE0C4-AA1E-4649-B5BC-7B43508FA93A}.Release|x86.ActiveCfg = Release|Win32
|
||||
{131DE0C4-AA1E-4649-B5BC-7B43508FA93A}.Release|x86.Build.0 = Release|Win32
|
||||
{E6D59245-696F-4D13-ACF6-7ECE6E653367}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{E6D59245-696F-4D13-ACF6-7ECE6E653367}.Debug|ARM64.ActiveCfg = Debug|arm64
|
||||
{E6D59245-696F-4D13-ACF6-7ECE6E653367}.Debug|ARM64.Build.0 = Debug|arm64
|
||||
|
@ -1555,6 +1575,20 @@ Global
|
|||
{5A4FBF6D-04A2-4061-B11F-1A0E64129610}.Release|x64.Build.0 = Release|x64
|
||||
{5A4FBF6D-04A2-4061-B11F-1A0E64129610}.Release|x86.ActiveCfg = Release|x86
|
||||
{5A4FBF6D-04A2-4061-B11F-1A0E64129610}.Release|x86.Build.0 = Release|x86
|
||||
{50BF3E96-3050-4053-B012-BF6993483DA5}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{50BF3E96-3050-4053-B012-BF6993483DA5}.Debug|ARM64.ActiveCfg = Debug|arm64
|
||||
{50BF3E96-3050-4053-B012-BF6993483DA5}.Debug|ARM64.Build.0 = Debug|arm64
|
||||
{50BF3E96-3050-4053-B012-BF6993483DA5}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{50BF3E96-3050-4053-B012-BF6993483DA5}.Debug|x64.Build.0 = Debug|x64
|
||||
{50BF3E96-3050-4053-B012-BF6993483DA5}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{50BF3E96-3050-4053-B012-BF6993483DA5}.Debug|x86.Build.0 = Debug|x86
|
||||
{50BF3E96-3050-4053-B012-BF6993483DA5}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{50BF3E96-3050-4053-B012-BF6993483DA5}.Release|ARM64.ActiveCfg = Release|arm64
|
||||
{50BF3E96-3050-4053-B012-BF6993483DA5}.Release|ARM64.Build.0 = Release|arm64
|
||||
{50BF3E96-3050-4053-B012-BF6993483DA5}.Release|x64.ActiveCfg = Release|x64
|
||||
{50BF3E96-3050-4053-B012-BF6993483DA5}.Release|x64.Build.0 = Release|x64
|
||||
{50BF3E96-3050-4053-B012-BF6993483DA5}.Release|x86.ActiveCfg = Release|x86
|
||||
{50BF3E96-3050-4053-B012-BF6993483DA5}.Release|x86.Build.0 = Release|x86
|
||||
{442FB943-1197-48FE-B3B6-8C1BCA1E81E4}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{442FB943-1197-48FE-B3B6-8C1BCA1E81E4}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{442FB943-1197-48FE-B3B6-8C1BCA1E81E4}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
|
@ -1683,6 +1717,8 @@ Global
|
|||
{D9139E3C-8D21-4BD9-84E3-30A03A54D610} = {99C514E4-A6B3-4B09-B870-5511EF9D93AC}
|
||||
{4A74BBED-3B20-44A7-B6FF-3373160DE741} = {99C514E4-A6B3-4B09-B870-5511EF9D93AC}
|
||||
{4410D374-A90C-4ADF-8B15-AA2AAE2636BF} = {E378857C-D22A-4E5E-A6DA-A59C445CF22E}
|
||||
{E49329F3-5196-4BBA-B5C4-E11CE7EFB07A} = {1C9A0791-2BAA-420B-84B6-C0721F22A6E8}
|
||||
{131DE0C4-AA1E-4649-B5BC-7B43508FA93A} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D}
|
||||
{E6D59245-696F-4D13-ACF6-7ECE6E653367} = {716C26A0-E6B0-4981-8412-D14A4D410531}
|
||||
{0D6B1FF3-A075-4194-9FC0-AF7BB89D0519} = {68E63911-6283-4212-BFFE-3F972AF8F835}
|
||||
{2B653A15-2482-40E5-9509-C531E69D0749} = {68E63911-6283-4212-BFFE-3F972AF8F835}
|
||||
|
@ -1697,6 +1733,7 @@ Global
|
|||
{608A8D5A-A839-45F6-98E6-766FC096104A} = {3A37083C-AA67-461E-BA78-0E0A65FE0C22}
|
||||
{676BA502-4220-465A-A9ED-ED22CDE4A24B} = {3A37083C-AA67-461E-BA78-0E0A65FE0C22}
|
||||
{5A4FBF6D-04A2-4061-B11F-1A0E64129610} = {3A37083C-AA67-461E-BA78-0E0A65FE0C22}
|
||||
{50BF3E96-3050-4053-B012-BF6993483DA5} = {716C26A0-E6B0-4981-8412-D14A4D410531}
|
||||
{2A2D1131-273C-4E17-BCD3-8812170A4B95} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A}
|
||||
{E3EDEC7F-A24E-4766-BB1D-6BDFBA157C51} = {2A2D1131-273C-4E17-BCD3-8812170A4B95}
|
||||
{442FB943-1197-48FE-B3B6-8C1BCA1E81E4} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D}
|
||||
|
|
|
@ -41,6 +41,7 @@ PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\Microsoft.WindowsAppRuntime.p
|
|||
PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\Microsoft.WindowsAppRuntime.lib $FullPublishDir\Microsoft.WindowsAppRuntime\
|
||||
PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.AppLifecycle.winmd $FullPublishDir\Microsoft.WindowsAppRuntime\
|
||||
PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.AppNotifications.winmd $FullPublishDir\Microsoft.WindowsAppRuntime\
|
||||
PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.AppNotifications.Builder.winmd $FullPublishDir\Microsoft.WindowsAppRuntime\
|
||||
PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.PushNotifications.winmd $FullPublishDir\Microsoft.WindowsAppRuntime\
|
||||
PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.ApplicationModel.DynamicDependency.winmd $FullPublishDir\Microsoft.WindowsAppRuntime\
|
||||
PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.ApplicationModel.WindowsAppRuntime.winmd $FullPublishDir\Microsoft.WindowsAppRuntime\
|
||||
|
@ -105,6 +106,8 @@ PublishFile $FullBuildOutput\Microsoft.Windows.AppLifecycle.Projection\Microsoft
|
|||
PublishFile $FullBuildOutput\Microsoft.Windows.AppLifecycle.Projection\Microsoft.Windows.AppLifecycle.Projection.pdb $NugetDir\lib\net5.0-windows10.0.17763.0
|
||||
PublishFile $FullBuildOutput\Microsoft.Windows.AppNotifications.Projection\Microsoft.Windows.AppNotifications.Projection.dll $NugetDir\lib\net5.0-windows10.0.17763.0
|
||||
PublishFile $FullBuildOutput\Microsoft.Windows.AppNotifications.Projection\Microsoft.Windows.AppNotifications.Projection.pdb $NugetDir\lib\net5.0-windows10.0.17763.0
|
||||
PublishFile $FullBuildOutput\Microsoft.Windows.AppNotifications.Builder.Projection\Microsoft.Windows.AppNotifications.Builder.Projection.dll $NugetDir\lib\net5.0-windows10.0.17763.0
|
||||
PublishFile $FullBuildOutput\Microsoft.Windows.AppNotifications.Builder.Projection\Microsoft.Windows.AppNotifications.Builder.Projection.pdb $NugetDir\lib\net5.0-windows10.0.17763.0
|
||||
PublishFile $FullBuildOutput\Microsoft.Windows.PushNotifications.Projection\Microsoft.Windows.PushNotifications.Projection.dll $NugetDir\lib\net5.0-windows10.0.17763.0
|
||||
PublishFile $FullBuildOutput\Microsoft.Windows.PushNotifications.Projection\Microsoft.Windows.PushNotifications.Projection.pdb $NugetDir\lib\net5.0-windows10.0.17763.0
|
||||
PublishFile $FullBuildOutput\Microsoft.Windows.System.Projection\Microsoft.Windows.System.Projection.dll $NugetDir\lib\net5.0-windows10.0.17763.0
|
||||
|
@ -172,6 +175,7 @@ PublishFile $FullBuildOutput\WindowsAppRuntime_MSIXInstallFromPath\WindowsAppRun
|
|||
# WinMD for UWP apps
|
||||
PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.AppLifecycle.winmd $NugetDir\lib\uap10.0
|
||||
PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.AppNotifications.winmd $NugetDir\lib\uap10.0
|
||||
PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.AppNotifications.Builder.winmd $NugetDir\lib\uap10.0
|
||||
PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.PushNotifications.winmd $NugetDir\lib\uap10.0
|
||||
PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.ApplicationModel.DynamicDependency.winmd $NugetDir\lib\uap10.0
|
||||
PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.ApplicationModel.WindowsAppRuntime.winmd $NugetDir\lib\uap10.0
|
||||
|
|
|
@ -69,6 +69,23 @@
|
|||
|
||||
<!-- PowerNotifications -->
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Windows.System.Power.PowerManager" ThreadingModel="both" />
|
||||
|
||||
<!-- AppNotifications -->
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Windows.AppNotifications.AppNotificationManager" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Windows.AppNotifications.AppNotification" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Windows.AppNotifications.AppNotificationProgressData" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Windows.AppNotifications.AppNotificationActivatedEventArgs" ThreadingModel="both" />
|
||||
|
||||
<!-- AppNotificationBuilder -->
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Windows.AppNotifications.Builder.AppNotificationBuilder" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Windows.AppNotifications.Builder.AppNotificationTextProperties" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Windows.AppNotifications.Builder.AppNotificationButton" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Windows.AppNotifications.Builder.AppNotificationProgressBar" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Windows.AppNotifications.Builder.AppNotificationComboBox" ThreadingModel="both" />
|
||||
|
||||
<!-- AccessControl -->
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Windows.Security.AccessControl.SecurityDescriptorHelpers" ThreadingModel="both" />
|
||||
|
||||
</InProcessServer>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
|
|
|
@ -12,7 +12,7 @@ parameters:
|
|||
- name: "IgnoreFailures"
|
||||
type: boolean
|
||||
default: False
|
||||
- name: "PublishToMaestro"
|
||||
- name: "PublishPackage"
|
||||
type: boolean
|
||||
default: False
|
||||
- name: "WindowsAppRuntimeInsightsSourceDirectory"
|
||||
|
@ -512,18 +512,18 @@ jobs:
|
|||
itemPattern: |
|
||||
**/*.nupkg
|
||||
|
||||
# this mysterious guid fixes the "NuGetCommand@2 is ambiguous" error :-(
|
||||
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||
displayName: 'NuGet push to ProjectReunion.nuget.internal'
|
||||
inputs:
|
||||
command: 'push'
|
||||
packagesToPush: '$(Build.SourcesDirectory)/FullNuget/*.nupkg;!$(Build.SourcesDirectory)/FullNuget/*.symbols.nupkg'
|
||||
verbosityPush: 'Detailed'
|
||||
nuGetFeedType: 'internal'
|
||||
#Note: The project qualifier is always required when using a feed name. Also, do not use organization scoped feeds.
|
||||
publishVstsFeed: 'ProjectReunion/Project.Reunion.nuget.internal'
|
||||
- ${{ if or(eq(variables['Build.Reason'], 'Schedule'), eq(parameters.PublishPackage, 'true')) }}:
|
||||
# this mysterious guid fixes the "NuGetCommand@2 is ambiguous" error :-(
|
||||
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||
displayName: 'NuGet push to ProjectReunion.nuget.internal'
|
||||
inputs:
|
||||
command: 'push'
|
||||
packagesToPush: '$(Build.SourcesDirectory)/FullNuget/*.nupkg;!$(Build.SourcesDirectory)/FullNuget/*.symbols.nupkg'
|
||||
verbosityPush: 'Detailed'
|
||||
nuGetFeedType: 'internal'
|
||||
#Note: The project qualifier is always required when using a feed name. Also, do not use organization scoped feeds.
|
||||
publishVstsFeed: 'ProjectReunion/Project.Reunion.nuget.internal'
|
||||
|
||||
- ${{ if or(eq(variables['Build.Reason'], 'Schedule'), eq(parameters.publishToMaestro, 'true')) }}:
|
||||
- template: ..\eng\common\AzurePipelinesTemplates\Maestro-PublishBuildToMaestro-Steps.yml
|
||||
parameters:
|
||||
AssetNames: 'Microsoft.WindowsAppSDK.Foundation.TransportPackage'
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
|
||||
jobs:
|
||||
- job: Merge
|
||||
pool: $(ProjectReunionBuildPool)
|
||||
steps:
|
||||
- checkout: self
|
||||
persistCredentials: true
|
||||
|
||||
- task: CmdLine@2
|
||||
inputs:
|
||||
script: |
|
||||
git checkout develop
|
||||
git config user.name "reunion-maestro-bot"
|
||||
git config user.email "reunion-maestro-bot@microsoft.com"
|
||||
git pull origin main
|
||||
|
||||
- task: CmdLine@2
|
||||
inputs:
|
||||
script: |
|
||||
git push
|
|
@ -1,5 +1,5 @@
|
|||
variables:
|
||||
# Version Control
|
||||
major: "1"
|
||||
minor: "1"
|
||||
minor: "2"
|
||||
patch: "0"
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#include "pch.h"
|
||||
#include "AppNotificationActivatedEventArgs.h"
|
||||
#include "Microsoft.Windows.AppNotifications.AppNotificationActivatedEventArgs.g.cpp"
|
||||
#include "AppNotificationBuilder/AppNotificationBuilderUtility.h"
|
||||
|
||||
namespace winrt::Microsoft::Windows::AppNotifications::implementation
|
||||
{
|
||||
winrt::Windows::Foundation::Collections::IMap<hstring, hstring> AppNotificationActivatedEventArgs::DecodeArguments(std::wstring arguments)
|
||||
{
|
||||
auto result{ winrt::single_threaded_map<winrt::hstring, winrt::hstring>() };
|
||||
|
||||
std::vector<std::wstring> pairs{};
|
||||
size_t pos{ 0 };
|
||||
|
||||
// Separate the key/value pairs by ';' as the delimiter
|
||||
while ((pos = arguments.find(L';')) != std::wstring::npos)
|
||||
{
|
||||
pairs.push_back(arguments.substr(0, pos));
|
||||
arguments.erase(0, pos + 1);
|
||||
}
|
||||
|
||||
// Need to push back final string
|
||||
pairs.push_back(arguments);
|
||||
|
||||
for (auto pair : pairs)
|
||||
{
|
||||
// Get the key/value individual values separated by '='
|
||||
pos = pair.find(L'=');
|
||||
if (pos == std::wstring::npos)
|
||||
{
|
||||
result.Insert(Decode(pair).c_str(), L"");
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Insert(Decode(pair.substr(0, pos)).c_str(), Decode(pair.substr(pos + 1)).c_str());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
// Copyright (c) Microsoft Corporation and Contributors.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
|
@ -10,12 +11,17 @@ namespace winrt::Microsoft::Windows::AppNotifications::implementation
|
|||
{
|
||||
AppNotificationActivatedEventArgs() = default;
|
||||
|
||||
AppNotificationActivatedEventArgs(winrt::hstring const& arguments, winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> const& userInput) : m_arguments(arguments), m_userInput(userInput) {};
|
||||
winrt::hstring Argument() { return m_arguments; };
|
||||
AppNotificationActivatedEventArgs(winrt::hstring const& argument, winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> const& userInput)
|
||||
: m_argument(argument), m_userInput(userInput), m_arguments(DecodeArguments(argument.c_str())) {};
|
||||
winrt::hstring Argument() { return m_argument; };
|
||||
winrt::Windows::Foundation::Collections::IMap<hstring, hstring> UserInput() { return m_userInput; };
|
||||
winrt::Windows::Foundation::Collections::IMap<hstring, hstring> Arguments() { return m_arguments; };
|
||||
|
||||
private:
|
||||
winrt::hstring m_arguments;
|
||||
winrt::Windows::Foundation::Collections::IMap<hstring, hstring> DecodeArguments(std::wstring arguments);
|
||||
|
||||
winrt::hstring m_argument;
|
||||
winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> m_userInput;
|
||||
winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> m_arguments{ nullptr };
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,396 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#include "pch.h"
|
||||
#include "AppNotificationBuilder.h"
|
||||
#include <winrt/Windows.Globalization.h>
|
||||
#include <winrt/Windows.Globalization.DateTimeFormatting.h>
|
||||
#include "Microsoft.Windows.AppNotifications.Builder.AppNotificationBuilder.g.cpp"
|
||||
#include "AppNotificationBuilderUtility.h"
|
||||
#include <iomanip>
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
#include <IsWindowsVersion.h>
|
||||
|
||||
using namespace winrt::Windows::Globalization;
|
||||
using namespace winrt::Windows::Globalization::DateTimeFormatting;
|
||||
|
||||
namespace winrt::Microsoft::Windows::AppNotifications::Builder::implementation
|
||||
{
|
||||
void AppNotificationBuilder::ThrowIfMaxInputItemsExceeded()
|
||||
{
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, m_textBoxList.size() + m_comboBoxList.size() >= c_maxTextInputElements, "Maximum number of input elements added");
|
||||
}
|
||||
|
||||
bool AppNotificationBuilder::IsUrgentScenarioSupported()
|
||||
{
|
||||
return WindowsVersion::IsWindows10_20H1OrGreater();
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::AddArgument(hstring const& key, hstring const& value)
|
||||
{
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, key.empty(), "You must provide a key when adding an argument");
|
||||
|
||||
m_arguments.Insert(EncodeArgument(key.c_str()), EncodeArgument(value.c_str()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetTimeStamp(winrt::Windows::Foundation::DateTime const& value)
|
||||
{
|
||||
auto seconds{ winrt::clock::to_time_t(value) };
|
||||
struct tm buf {};
|
||||
localtime_s(&buf, &seconds);
|
||||
|
||||
std::wstringstream buffer;
|
||||
buffer << std::put_time(&buf, L"%FT%T%z");
|
||||
|
||||
std::wstring timestamp{ buffer.str() };
|
||||
timestamp.insert(timestamp.size() - c_offsetIndexValue, L":");
|
||||
m_timeStamp = wil::str_printf<std::wstring>(L" displayTimestamp='%ls'", timestamp.c_str());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetScenario(AppNotificationScenario const& value)
|
||||
{
|
||||
m_scenario = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetDuration(AppNotificationDuration const& value)
|
||||
{
|
||||
m_duration = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::AddText(hstring const& text)
|
||||
{
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, m_textLines.size() >= c_maxTextElements, "Maximum number of text elements added");
|
||||
|
||||
m_textLines.push_back(wil::str_printf<std::wstring>(L"<text>%ls</text>", EncodeXml(text).c_str()).c_str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::AddText(hstring const& text, AppNotificationTextProperties const& properties)
|
||||
{
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, m_textLines.size() >= c_maxTextElements, "Maximum number of text elements added");
|
||||
|
||||
std::wstring props{ properties.as<winrt::Windows::Foundation::IStringable>().ToString() };
|
||||
m_textLines.push_back(wil::str_printf<std::wstring>(L"%ls%ls</text>", props.c_str(), EncodeXml(text).c_str()).c_str());
|
||||
|
||||
if (properties.IncomingCallAlignment())
|
||||
{
|
||||
m_scenario = AppNotificationScenario::IncomingCall;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetAttributionText(hstring const& text)
|
||||
{
|
||||
m_attributionText = wil::str_printf<std::wstring>(L"<text placement='attribution'>%ls</text>", EncodeXml(text).c_str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetAttributionText(hstring const& text, hstring const& language)
|
||||
{
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, language.empty(), "You must provide a language calling SetAttributionText");
|
||||
|
||||
m_attributionText = wil::str_printf<std::wstring>(L"<text placement='attribution' lang='%ls'>%ls</text>", language.c_str(), EncodeXml(text).c_str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetInlineImage(winrt::Windows::Foundation::Uri const& imageUri)
|
||||
{
|
||||
m_inlineImage = wil::str_printf<std::wstring>(L"<image src='%ls'/>", imageUri.ToString().c_str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetInlineImage(winrt::Windows::Foundation::Uri const& imageUri, AppNotificationImageCrop const& imageCrop)
|
||||
{
|
||||
if (imageCrop == AppNotificationImageCrop::Circle)
|
||||
{
|
||||
m_inlineImage = wil::str_printf<std::wstring>(L"<image src='%ls' hint-crop='circle'/>", imageUri.ToString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
SetInlineImage(imageUri);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetInlineImage(winrt::Windows::Foundation::Uri const& imageUri, AppNotificationImageCrop const& imageCrop, hstring const& alternateText)
|
||||
{
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, alternateText.empty(), "You must provide an alternate text string calling SetInlineImage");
|
||||
|
||||
std::wstring hintCrop { imageCrop == AppNotificationImageCrop::Circle ? L" hint-crop='circle'" : L"" };
|
||||
m_inlineImage = wil::str_printf<std::wstring>(L"<image src='%ls' alt='%ls'%ls/>", imageUri.ToString().c_str(), EncodeXml(alternateText).c_str(), hintCrop.c_str());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetAppLogoOverride(winrt::Windows::Foundation::Uri const& imageUri)
|
||||
{
|
||||
m_appLogoOverride = wil::str_printf<std::wstring>(L"<image placement='appLogoOverride' src='%ls'/>", imageUri.ToString().c_str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetAppLogoOverride(winrt::Windows::Foundation::Uri const& imageUri, AppNotificationImageCrop const& imageCrop)
|
||||
{
|
||||
if (imageCrop == AppNotificationImageCrop::Circle)
|
||||
{
|
||||
m_appLogoOverride = wil::str_printf<std::wstring>(L"<image placement='appLogoOverride' src='%ls' hint-crop='circle'/>", imageUri.ToString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
SetAppLogoOverride(imageUri);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetAppLogoOverride(winrt::Windows::Foundation::Uri const& imageUri, AppNotificationImageCrop const& imageCrop, hstring const& alternateText)
|
||||
{
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, alternateText.empty(), "You must provide an alternate text string calling SetAppLogoOverride");
|
||||
|
||||
std::wstring hintCrop{ imageCrop == AppNotificationImageCrop::Circle ? L" hint-crop='circle'" : L"" };
|
||||
m_appLogoOverride = wil::str_printf<std::wstring>(L"<image placement='appLogoOverride' src='%ls' alt='%ls'%ls/>", imageUri.ToString().c_str(), EncodeXml(alternateText).c_str(), hintCrop.c_str());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetHeroImage(winrt::Windows::Foundation::Uri const& imageUri)
|
||||
{
|
||||
m_heroImage = wil::str_printf<std::wstring>(L"<image placement='hero' src='%ls'/>", imageUri.ToString().c_str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetHeroImage(winrt::Windows::Foundation::Uri const& imageUri, hstring const& alternateText)
|
||||
{
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, alternateText.empty(), "You must provide an alternate text string calling SetHeroImage");
|
||||
|
||||
m_heroImage = wil::str_printf<std::wstring>(L"<image placement='hero' src='%ls' alt='%ls'/>", imageUri.ToString().c_str(), EncodeXml(alternateText).c_str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetAudioUri(winrt::Windows::Foundation::Uri const& audioUri)
|
||||
{
|
||||
m_audio = wil::str_printf<std::wstring>(L"<audio src='%ls'/>", audioUri.ToString().c_str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetAudioUri(winrt::Windows::Foundation::Uri const& audioUri, AppNotificationAudioLooping const& loop)
|
||||
{
|
||||
m_audio = wil::str_printf<std::wstring>(L"<audio src='%ls' loop='%ls'/>", audioUri.ToString().c_str(), loop == AppNotificationAudioLooping::Loop ? L"true" : L"false");
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetAudioEvent(AppNotificationSoundEvent const& soundEvent)
|
||||
{
|
||||
m_audio = wil::str_printf<std::wstring>(L"<audio src='%ls'/>", GetWinSoundEventString(soundEvent));
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetAudioEvent(AppNotificationSoundEvent const& soundEvent, AppNotificationAudioLooping const& loop)
|
||||
{
|
||||
m_audio = wil::str_printf<std::wstring>(L"<audio src='%ls' loop='%ls'/>", GetWinSoundEventString(soundEvent), loop == AppNotificationAudioLooping::Loop ? L"true" : L"false");
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::MuteAudio()
|
||||
{
|
||||
m_audio = L"<audio silent='true'/>";
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::AddProgressBar(AppNotificationProgressBar const& value)
|
||||
{
|
||||
m_progressBarList.push_back(value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::AddTextBox(hstring id)
|
||||
{
|
||||
ThrowIfMaxInputItemsExceeded();
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, id.empty(), "You must provide an id for the TextBox");
|
||||
|
||||
m_textBoxList.push_back(wil::str_printf<std::wstring>(L"<input id='%ls' type='text'/>", EncodeXml(id).c_str()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::AddTextBox(hstring id, hstring placeHolderText, hstring title)
|
||||
{
|
||||
ThrowIfMaxInputItemsExceeded();
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, id.empty(), "You must provide an id for the TextBox");
|
||||
|
||||
m_textBoxList.push_back(wil::str_printf<std::wstring>(L"<input id='%ls' type='text' placeHolderContent='%ls' title='%ls'/>", EncodeXml(id).c_str(), EncodeXml(placeHolderText).c_str(), EncodeXml(title).c_str()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::AddButton(AppNotificationButton const& value)
|
||||
{
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, m_buttonList.size() >= c_maxButtonElements, "Maximum number of buttons added");
|
||||
|
||||
m_buttonList.push_back(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::AddComboBox(AppNotificationComboBox const& value)
|
||||
{
|
||||
ThrowIfMaxInputItemsExceeded();
|
||||
|
||||
m_comboBoxList.push_back(value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetTag(hstring const& value)
|
||||
{
|
||||
m_tag = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AppNotificationBuilder::SetGroup(hstring const& value)
|
||||
{
|
||||
m_group = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::wstring AppNotificationBuilder::GetDuration()
|
||||
{
|
||||
return m_duration == AppNotificationDuration::Default ? L"" : L" duration='long'";
|
||||
}
|
||||
|
||||
std::wstring AppNotificationBuilder::GetScenario()
|
||||
{
|
||||
// Add scenario attribute if set
|
||||
switch (m_scenario)
|
||||
{
|
||||
case AppNotificationScenario::Alarm:
|
||||
return L" scenario='alarm'";
|
||||
case AppNotificationScenario::Reminder:
|
||||
return L" scenario='reminder'";
|
||||
case AppNotificationScenario::IncomingCall:
|
||||
return L" scenario='incomingCall'";
|
||||
case AppNotificationScenario::Urgent:
|
||||
return L" scenario='urgent'";
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring AppNotificationBuilder::GetArguments()
|
||||
{
|
||||
// Add launch arguments if given arguments
|
||||
if (m_arguments.Size())
|
||||
{
|
||||
std::wstring arguments;
|
||||
for (auto pair : m_arguments)
|
||||
{
|
||||
if (!pair.Value().empty())
|
||||
{
|
||||
arguments.append(wil::str_printf<std::wstring>(L"%ls=%ls;", pair.Key().c_str(), pair.Value().c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
arguments.append(wil::str_printf<std::wstring>(L"%ls;", pair.Key().c_str()));
|
||||
}
|
||||
}
|
||||
arguments.pop_back();
|
||||
|
||||
return wil::str_printf<std::wstring>(L" launch='%ls'", arguments.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring AppNotificationBuilder::GetText()
|
||||
{
|
||||
std::wstring result{};
|
||||
for (auto text : m_textLines)
|
||||
{
|
||||
result.append(text);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring AppNotificationBuilder::GetImages()
|
||||
{
|
||||
return wil::str_printf<std::wstring>(L"%ls%ls%ls", m_inlineImage.c_str(), m_heroImage.c_str(), m_appLogoOverride.c_str());
|
||||
}
|
||||
|
||||
std::wstring AppNotificationBuilder::GetActions()
|
||||
{
|
||||
|
||||
std::wstring result{};
|
||||
for (auto input : m_textBoxList)
|
||||
{
|
||||
result.append(input.c_str());
|
||||
}
|
||||
|
||||
for (auto input : m_comboBoxList)
|
||||
{
|
||||
result.append(input.as<winrt::Windows::Foundation::IStringable>().ToString().c_str());
|
||||
}
|
||||
|
||||
for (auto input : m_buttonList)
|
||||
{
|
||||
if (input.ButtonStyle() != AppNotificationButtonStyle::Default)
|
||||
{
|
||||
m_useButtonStyle = true;
|
||||
}
|
||||
|
||||
result.append(input.as<winrt::Windows::Foundation::IStringable>().ToString().c_str());
|
||||
}
|
||||
|
||||
return (result.empty()) ? result : wil::str_printf<std::wstring>(L"<actions>%ls</actions>", result.c_str());
|
||||
}
|
||||
|
||||
// You must call GetActions first to retrieve this value.
|
||||
std::wstring AppNotificationBuilder::GetButtonStyle()
|
||||
{
|
||||
return m_useButtonStyle ? L" useButtonStyle='true'" : L"";
|
||||
}
|
||||
|
||||
std::wstring AppNotificationBuilder::GetProgressBars()
|
||||
{
|
||||
std::wstring result{};
|
||||
for (auto progressBar : m_progressBarList)
|
||||
{
|
||||
result.append(progressBar.as<winrt::Windows::Foundation::IStringable>().ToString());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::AppNotification AppNotificationBuilder::BuildNotification()
|
||||
{
|
||||
// Build the actions string and fill m_useButtonStyle
|
||||
std::wstring actions{ GetActions() };
|
||||
|
||||
auto xmlResult{ wil::str_printf<std::wstring>(L"<toast%ls%ls%ls%ls%ls><visual><binding template='ToastGeneric'>%ls%ls%ls%ls</binding></visual>%ls%ls</toast>",
|
||||
m_timeStamp.c_str(),
|
||||
GetDuration().c_str(),
|
||||
GetScenario().c_str(),
|
||||
GetArguments().c_str(),
|
||||
GetButtonStyle().c_str(),
|
||||
GetText().c_str(),
|
||||
m_attributionText.c_str(),
|
||||
GetImages().c_str(),
|
||||
GetProgressBars().c_str(),
|
||||
m_audio.c_str(),
|
||||
actions.c_str()) };
|
||||
|
||||
THROW_HR_IF_MSG(E_FAIL, xmlResult.size() > c_maxAppNotificationPayload, "Maximum payload size exceeded");
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::AppNotification appNotification{ xmlResult };
|
||||
appNotification.Tag(m_tag);
|
||||
appNotification.Group(m_group);
|
||||
|
||||
return appNotification;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#pragma once
|
||||
#include "Microsoft.Windows.AppNotifications.Builder.AppNotificationBuilder.g.h"
|
||||
|
||||
namespace winrt::Microsoft::Windows::AppNotifications::Builder::implementation
|
||||
{
|
||||
struct AppNotificationBuilder : AppNotificationBuilderT<AppNotificationBuilder>
|
||||
{
|
||||
AppNotificationBuilder() = default;
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AddArgument(hstring const& key, hstring const& value);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetTimeStamp(winrt::Windows::Foundation::DateTime const& value);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetScenario(AppNotificationScenario const& value);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetDuration(AppNotificationDuration const& value);
|
||||
|
||||
// Text component APIs
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AddText(hstring const& text);
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AddText(hstring const& text, AppNotificationTextProperties const& properties);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetAttributionText(hstring const& text);
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetAttributionText(hstring const& text, hstring const& language);
|
||||
|
||||
// Inline image component APIs
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetInlineImage(winrt::Windows::Foundation::Uri const& imageUri);
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetInlineImage(winrt::Windows::Foundation::Uri const& imageUri, AppNotificationImageCrop const& imageCrop);
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetInlineImage(winrt::Windows::Foundation::Uri const& imageUri, AppNotificationImageCrop const& imageCrop, winrt::hstring const& alternateText);
|
||||
|
||||
// AppLogoOverride component APIs
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetAppLogoOverride(winrt::Windows::Foundation::Uri const& imageUri);
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetAppLogoOverride(winrt::Windows::Foundation::Uri const& imageUri, AppNotificationImageCrop const& imageCrop);
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetAppLogoOverride(winrt::Windows::Foundation::Uri const& imageUri, AppNotificationImageCrop const& imageCrop, winrt::hstring const& alternateText);
|
||||
|
||||
// Hero image component APIs
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetHeroImage(winrt::Windows::Foundation::Uri const& imageUri);
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetHeroImage(winrt::Windows::Foundation::Uri const& imageUri, winrt::hstring const& alternateText);
|
||||
|
||||
// SetAudio
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetAudioUri(winrt::Windows::Foundation::Uri const& audioUri);
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetAudioUri(winrt::Windows::Foundation::Uri const& audioUri, AppNotificationAudioLooping const& loop);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetAudioEvent(AppNotificationSoundEvent const& soundEvent);
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetAudioEvent(AppNotificationSoundEvent const& soundEvent, AppNotificationAudioLooping const& loop);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder MuteAudio();
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AddTextBox(hstring id);
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AddTextBox(hstring id, hstring placeHolderText, hstring title);
|
||||
|
||||
// Adds a button to the AppNotificationBuilder
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AddButton(AppNotificationButton const& value);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AddProgressBar(AppNotificationProgressBar const& value);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder AddComboBox(AppNotificationComboBox const& value);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetTag(winrt::hstring const& value);
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationBuilder SetGroup(winrt::hstring const& value);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::AppNotification BuildNotification();
|
||||
|
||||
static bool IsUrgentScenarioSupported();
|
||||
|
||||
private:
|
||||
void ThrowIfMaxInputItemsExceeded();
|
||||
std::wstring GetDuration();
|
||||
std::wstring GetScenario();
|
||||
std::wstring GetArguments();
|
||||
std::wstring GetButtonStyle();
|
||||
std::wstring GetText();
|
||||
std::wstring GetImages();
|
||||
std::wstring GetActions();
|
||||
std::wstring GetProgressBars();
|
||||
|
||||
std::wstring m_timeStamp{};
|
||||
AppNotificationDuration m_duration{ AppNotificationDuration::Default };
|
||||
AppNotificationScenario m_scenario{ AppNotificationScenario::Default };
|
||||
bool m_useButtonStyle{};
|
||||
std::vector<winrt::hstring> m_textLines{};
|
||||
winrt::hstring m_attributionText{};
|
||||
winrt::hstring m_inlineImage{};
|
||||
winrt::hstring m_appLogoOverride{};
|
||||
winrt::hstring m_heroImage{};
|
||||
winrt::hstring m_audio{};
|
||||
winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> m_arguments{ winrt::single_threaded_map<winrt::hstring, winrt::hstring>() };
|
||||
std::vector<AppNotificationButton> m_buttonList{};
|
||||
std::vector<AppNotificationProgressBar> m_progressBarList{};
|
||||
std::vector<std::wstring> m_textBoxList{};
|
||||
std::vector<AppNotificationComboBox> m_comboBoxList{};
|
||||
winrt::hstring m_tag{};
|
||||
winrt::hstring m_group{};
|
||||
};
|
||||
}
|
||||
namespace winrt::Microsoft::Windows::AppNotifications::Builder::factory_implementation
|
||||
{
|
||||
struct AppNotificationBuilder : AppNotificationBuilderT<AppNotificationBuilder, implementation::AppNotificationBuilder>
|
||||
{
|
||||
};
|
||||
}
|
|
@ -0,0 +1,246 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
import "..\AppNotifications\AppNotifications.idl";
|
||||
|
||||
namespace Microsoft.Windows.AppNotifications.Builder
|
||||
{
|
||||
[contractversion(1)]
|
||||
apicontract AppNotificationBuilderContract {}
|
||||
|
||||
[contract(AppNotificationBuilderContract, 1)]
|
||||
runtimeclass AppNotificationTextProperties
|
||||
{
|
||||
// Contains the set of <text> attributes
|
||||
AppNotificationTextProperties();
|
||||
|
||||
String Language;
|
||||
Boolean IncomingCallAlignment;
|
||||
Int32 MaxLines;
|
||||
|
||||
AppNotificationTextProperties SetLanguage(String value);
|
||||
AppNotificationTextProperties SetIncomingCallAlignment();
|
||||
AppNotificationTextProperties SetMaxLines(Int32 value);
|
||||
};
|
||||
|
||||
[contract(AppNotificationBuilderContract, 1)]
|
||||
enum AppNotificationButtonStyle
|
||||
{
|
||||
Default,
|
||||
Success,
|
||||
Critical,
|
||||
};
|
||||
|
||||
[contract(AppNotificationBuilderContract, 1)]
|
||||
runtimeclass AppNotificationButton
|
||||
{
|
||||
AppNotificationButton();
|
||||
AppNotificationButton(String content);
|
||||
|
||||
String Content;
|
||||
Windows.Foundation.Collections.IMap<String, String> Arguments;
|
||||
Windows.Foundation.Uri Icon;
|
||||
String ToolTip;
|
||||
Boolean ContextMenuPlacement;
|
||||
AppNotificationButtonStyle ButtonStyle;
|
||||
String InputId;
|
||||
Windows.Foundation.Uri InvokeUri;
|
||||
String TargetAppId;
|
||||
|
||||
AppNotificationButton AddArgument(String key, String value);
|
||||
|
||||
// Sets the Icon for the button.
|
||||
AppNotificationButton SetIcon(Windows.Foundation.Uri value);
|
||||
|
||||
// The tooltip for a button, if the button has an empty content string.
|
||||
AppNotificationButton SetToolTip(String value);
|
||||
static Boolean IsToolTipSupported();
|
||||
|
||||
// Sets the Button as context menu action.
|
||||
AppNotificationButton SetContextMenuPlacement();
|
||||
|
||||
// Sets the ButtonStyle to Success or Critical
|
||||
AppNotificationButton SetButtonStyle(AppNotificationButtonStyle value);
|
||||
static Boolean IsButtonStyleSupported();
|
||||
|
||||
// Specifies the ID of an existing TextBox next to which the button will be placed.
|
||||
AppNotificationButton SetInputId(String value);
|
||||
|
||||
// Launches the URI passed into the button when activated.
|
||||
AppNotificationButton SetInvokeUri(Windows.Foundation.Uri protocolUri);
|
||||
AppNotificationButton SetInvokeUri(Windows.Foundation.Uri protocolUri, String targetAppId);
|
||||
};
|
||||
|
||||
[contract(AppNotificationBuilderContract, 1)]
|
||||
runtimeclass AppNotificationProgressBar
|
||||
{
|
||||
// AppNotificationProgressBar binds to AppNotificationProgressData so the AppNotification will
|
||||
// receive every update to the status and value. In the WinAppSDK, these binding
|
||||
// values are static, so developers won't need to define these binding values
|
||||
// themselves.
|
||||
AppNotificationProgressBar();
|
||||
|
||||
// Setting these properties will remove the data binding with a static value
|
||||
String Title;
|
||||
String Status;
|
||||
Double Value;
|
||||
String ValueStringOverride;
|
||||
|
||||
AppNotificationProgressBar SetTitle(String value);
|
||||
AppNotificationProgressBar BindTitle();
|
||||
|
||||
AppNotificationProgressBar SetStatus(String value);
|
||||
AppNotificationProgressBar BindStatus();
|
||||
|
||||
AppNotificationProgressBar SetValue(Double value);
|
||||
AppNotificationProgressBar BindValue();
|
||||
|
||||
AppNotificationProgressBar SetValueStringOverride(String value);
|
||||
AppNotificationProgressBar BindValueStringOverride();
|
||||
};
|
||||
|
||||
[contract(AppNotificationBuilderContract, 1)]
|
||||
runtimeclass AppNotificationComboBox
|
||||
{
|
||||
AppNotificationComboBox(String id);
|
||||
|
||||
Windows.Foundation.Collections.IMap<String, String> Items;
|
||||
String Title;
|
||||
String SelectedItem;
|
||||
|
||||
// Add a selection to the AppNotificationComboBox. The id parameter identifies the item the user selected.
|
||||
AppNotificationComboBox AddItem(String id, String content);
|
||||
|
||||
// Adds a title to display on top
|
||||
AppNotificationComboBox SetTitle(String value);
|
||||
|
||||
// Sets the default selection to be displayed by the AppNotificationComboBox
|
||||
AppNotificationComboBox SetSelectedItem(String id);
|
||||
};
|
||||
|
||||
[contract(AppNotificationBuilderContract, 1)]
|
||||
enum AppNotificationSoundEvent
|
||||
{
|
||||
Default,
|
||||
IM,
|
||||
Mail,
|
||||
Reminder,
|
||||
SMS,
|
||||
Alarm,
|
||||
Alarm2,
|
||||
Alarm3,
|
||||
Alarm4,
|
||||
Alarm5,
|
||||
Alarm6,
|
||||
Alarm7,
|
||||
Alarm8,
|
||||
Alarm9,
|
||||
Alarm10,
|
||||
Call,
|
||||
Call2,
|
||||
Call3,
|
||||
Call4,
|
||||
Call5,
|
||||
Call6,
|
||||
Call7,
|
||||
Call8,
|
||||
Call9,
|
||||
Call10,
|
||||
};
|
||||
|
||||
[contract(AppNotificationBuilderContract, 1)]
|
||||
enum AppNotificationScenario
|
||||
{
|
||||
Default, // The normal AppNotification behavior. The AppNotification appears for a short duration, and then automatically dismisses into Notification Center.
|
||||
Reminder, // The notification will stay on screen until the user dismisses it or takes action.
|
||||
Alarm, // Alarms behave like Reminder, but alarms will additionally loop audio with a default alarm sound.
|
||||
IncomingCall, // Incoming call notifications are displayed pre-expanded in a special call format and stay on the user's screen till dismissed.
|
||||
Urgent, // Important notifications allow users to have more control over what 1st party and 3rd party apps can send them high-priority AppNotifications (urgent/important) that can break through Focus Assist.
|
||||
};
|
||||
|
||||
[contract(AppNotificationBuilderContract, 1)]
|
||||
enum AppNotificationAudioLooping
|
||||
{
|
||||
None, // Audio will not loop
|
||||
Loop, // Audio will loop for the duration of the AppNotification
|
||||
};
|
||||
|
||||
[contract(AppNotificationBuilderContract, 1)]
|
||||
enum AppNotificationDuration
|
||||
{
|
||||
Default, // Default value. AppNotification appears for a short while and then goes into Notification Center.
|
||||
Long, // AppNotification stays on-screen for longer, and then goes into Notification Center.
|
||||
};
|
||||
|
||||
[contract(AppNotificationBuilderContract, 1)]
|
||||
enum AppNotificationImageCrop
|
||||
{
|
||||
Default, // Uses the default renderer to display the image
|
||||
Circle, // Crops the image as a circle.
|
||||
};
|
||||
|
||||
[contract(AppNotificationBuilderContract, 1)]
|
||||
runtimeclass AppNotificationBuilder
|
||||
{
|
||||
AppNotificationBuilder();
|
||||
|
||||
// Adds arguments to the launch attribute to return when AppNotification is clicked.
|
||||
AppNotificationBuilder AddArgument(String key, String value);
|
||||
|
||||
// Sets the timeStamp of the AppNotification to when it was constructed instead of when it was sent.
|
||||
AppNotificationBuilder SetTimeStamp(Windows.Foundation.DateTime value);
|
||||
|
||||
AppNotificationBuilder SetDuration(AppNotificationDuration duration);
|
||||
|
||||
// Sets the scenario of the AppNotification.
|
||||
AppNotificationBuilder SetScenario(AppNotificationScenario value);
|
||||
static Boolean IsUrgentScenarioSupported();
|
||||
|
||||
// Adds text to the AppNotification.
|
||||
AppNotificationBuilder AddText(String text);
|
||||
AppNotificationBuilder AddText(String text, AppNotificationTextProperties properties);
|
||||
|
||||
AppNotificationBuilder SetAttributionText(String text);
|
||||
AppNotificationBuilder SetAttributionText(String text, String language);
|
||||
|
||||
// Sets the full-width inline-image that appears when you expand the AppNotification
|
||||
AppNotificationBuilder SetInlineImage(Windows.Foundation.Uri imageUri);
|
||||
AppNotificationBuilder SetInlineImage(Windows.Foundation.Uri imageUri, AppNotificationImageCrop imageCrop);
|
||||
AppNotificationBuilder SetInlineImage(Windows.Foundation.Uri imageUri, AppNotificationImageCrop imagecrop, String alternateText);
|
||||
|
||||
// Sets the image that replaces the app logo
|
||||
AppNotificationBuilder SetAppLogoOverride(Windows.Foundation.Uri imageUri);
|
||||
AppNotificationBuilder SetAppLogoOverride(Windows.Foundation.Uri imageUri, AppNotificationImageCrop imageCrop);
|
||||
AppNotificationBuilder SetAppLogoOverride(Windows.Foundation.Uri imageUri, AppNotificationImageCrop imageCrop, String alternateText);
|
||||
|
||||
// Sets the image that displays within the banner of the AppNotification.
|
||||
AppNotificationBuilder SetHeroImage(Windows.Foundation.Uri imageUri);
|
||||
AppNotificationBuilder SetHeroImage(Windows.Foundation.Uri imageUri, String alternateText);
|
||||
|
||||
// SetAudio
|
||||
AppNotificationBuilder SetAudioUri(Windows.Foundation.Uri audioUri);
|
||||
AppNotificationBuilder SetAudioUri(Windows.Foundation.Uri audioUri, AppNotificationAudioLooping loop);
|
||||
|
||||
AppNotificationBuilder SetAudioEvent(AppNotificationSoundEvent appNotificationSoundEvent);
|
||||
AppNotificationBuilder SetAudioEvent(AppNotificationSoundEvent appNotificationSoundEvent, AppNotificationAudioLooping loop);
|
||||
|
||||
AppNotificationBuilder MuteAudio();
|
||||
|
||||
AppNotificationBuilder AddTextBox(String id);
|
||||
AppNotificationBuilder AddTextBox(String id, String placeHolderText, String title);
|
||||
|
||||
// Adds a button to the AppNotificationBuilder
|
||||
AppNotificationBuilder AddButton(AppNotificationButton value);
|
||||
|
||||
AppNotificationBuilder AddComboBox(AppNotificationComboBox value);
|
||||
|
||||
AppNotificationBuilder AddProgressBar(AppNotificationProgressBar value);
|
||||
|
||||
// Constructs a WindowsAppSDK AppNotification object with the XML payload
|
||||
Microsoft.Windows.AppNotifications.AppNotification BuildNotification();
|
||||
|
||||
// AppNotification properties
|
||||
AppNotificationBuilder SetTag(String value);
|
||||
AppNotificationBuilder SetGroup(String group);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' < '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
<HasSharedItems>true</HasSharedItems>
|
||||
<ItemsProjectGuid>{e49329f3-5196-4bba-b5c4-e11ce7efb07a}</ItemsProjectGuid>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ProjectCapability Include="SourceItemsFromImports" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="$(MSBuildThisFileDirectory)AppNotificationBuilder.idl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)AppNotificationBuilder.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)AppNotificationButton.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)AppNotificationProgressBar.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)AppNotificationComboBox.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)AppNotificationTextProperties.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)AppNotificationBuilder.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)AppNotificationBuilderUtility.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)AppNotificationButton.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)AppNotificationProgressBar.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)AppNotificationComboBox.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)AppNotificationTextProperties.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,167 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#include "pch.h"
|
||||
#include "winrt/Microsoft.Windows.AppNotifications.Builder.h"
|
||||
#include <algorithm>
|
||||
#include <regex>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
constexpr size_t c_maxAppNotificationPayload{ 5120 };
|
||||
constexpr uint8_t c_maxTextElements{ 3 };
|
||||
constexpr uint8_t c_maxButtonElements{ 5 };
|
||||
constexpr size_t c_maxEncodingSize{ 3 };
|
||||
constexpr uint8_t c_maxTextInputElements{ 5 };
|
||||
constexpr uint8_t c_maxSelectionElements{ 5 };
|
||||
constexpr uint8_t c_offsetIndexValue{ 2 };
|
||||
|
||||
namespace AppNotificationBuilder
|
||||
{
|
||||
using namespace winrt::Microsoft::Windows::AppNotifications::Builder;
|
||||
}
|
||||
|
||||
inline std::unordered_map<wchar_t, std::wstring> GetXmlEscapeEncodings()
|
||||
{
|
||||
static std::unordered_map<wchar_t, std::wstring> encodings = { { L'&', L"&"}, { L'\"', L"""}, {L'<', L"<"}, {L'>', L">"}, {L'\'', L"'"}};
|
||||
return encodings;
|
||||
}
|
||||
|
||||
inline std::unordered_map<wchar_t, std::wstring> GetPercentEncodings()
|
||||
{
|
||||
static std::unordered_map<wchar_t, std::wstring> encodings = {{ L'%', L"%25"}, {L';', L"%3B"}, {L'=', L"%3D"} };
|
||||
return encodings;
|
||||
}
|
||||
|
||||
inline std::unordered_map<std::wstring, wchar_t> GetPercentEncodingsReverse()
|
||||
{
|
||||
static std::unordered_map<std::wstring, wchar_t> encodings = { { L"%25", L'%' }, {L"%3B", L';' }, { L"%3D", L'=' } };
|
||||
return encodings;
|
||||
}
|
||||
|
||||
inline PCWSTR GetWinSoundEventString(AppNotificationBuilder::AppNotificationSoundEvent soundEvent)
|
||||
{
|
||||
switch (soundEvent)
|
||||
{
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::IM:
|
||||
return L"ms-winsoundevent:Notification.IM";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Mail:
|
||||
return L"ms-winsoundevent:Notification.Mail";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Reminder:
|
||||
return L"ms-winsoundevent:Notification.Reminder";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::SMS:
|
||||
return L"ms-winsoundevent:Notification.SMS";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Alarm:
|
||||
return L"ms-winsoundevent:Notification.Looping.Alarm";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Alarm2:
|
||||
return L"ms-winsoundevent:Notification.Looping.Alarm2";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Alarm3:
|
||||
return L"ms-winsoundevent:Notification.Looping.Alarm3";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Alarm4:
|
||||
return L"ms-winsoundevent:Notification.Looping.Alarm4";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Alarm5:
|
||||
return L"ms-winsoundevent:Notification.Looping.Alarm5";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Alarm6:
|
||||
return L"ms-winsoundevent:Notification.Looping.Alarm6";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Alarm7:
|
||||
return L"ms-winsoundevent:Notification.Looping.Alarm7";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Alarm8:
|
||||
return L"ms-winsoundevent:Notification.Looping.Alarm8";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Alarm9:
|
||||
return L"ms-winsoundevent:Notification.Looping.Alarm9";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Alarm10:
|
||||
return L"ms-winsoundevent:Notification.Looping.Alarm10";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Call:
|
||||
return L"ms-winsoundevent:Notification.Looping.Call";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Call2:
|
||||
return L"ms-winsoundevent:Notification.Looping.Call2";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Call3:
|
||||
return L"ms-winsoundevent:Notification.Looping.Call3";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Call4:
|
||||
return L"ms-winsoundevent:Notification.Looping.Call4";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Call5:
|
||||
return L"ms-winsoundevent:Notification.Looping.Call5";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Call6:
|
||||
return L"ms-winsoundevent:Notification.Looping.Call6";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Call7:
|
||||
return L"ms-winsoundevent:Notification.Looping.Call7";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Call8:
|
||||
return L"ms-winsoundevent:Notification.Looping.Call8";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Call9:
|
||||
return L"ms-winsoundevent:Notification.Looping.Call9";
|
||||
case AppNotificationBuilder::AppNotificationSoundEvent::Call10:
|
||||
return L"ms-winsoundevent:Notification.Looping.Call10";
|
||||
default:
|
||||
return L"ms-winsoundevent:Notification.Default";
|
||||
}
|
||||
}
|
||||
|
||||
inline std::wstring EncodeArgument(std::wstring const& value)
|
||||
{
|
||||
std::wstring encodedValue{};
|
||||
|
||||
auto percentEncodings{ GetPercentEncodings() };
|
||||
auto xmlEncodings{ GetXmlEscapeEncodings() };
|
||||
for (auto ch : value)
|
||||
{
|
||||
if (percentEncodings.find(ch) != percentEncodings.end())
|
||||
{
|
||||
encodedValue.append(percentEncodings[ch]);
|
||||
}
|
||||
else if (xmlEncodings.find(ch) != xmlEncodings.end())
|
||||
{
|
||||
encodedValue.append(xmlEncodings[ch]);
|
||||
}
|
||||
else
|
||||
{
|
||||
encodedValue.push_back(ch);
|
||||
}
|
||||
}
|
||||
|
||||
return encodedValue;
|
||||
}
|
||||
|
||||
inline std::wstring EncodeXml(winrt::hstring const& value)
|
||||
{
|
||||
std::wstring encodedValue{};
|
||||
|
||||
auto xmlEncodings{ GetXmlEscapeEncodings() };
|
||||
for (auto ch : value)
|
||||
{
|
||||
if (xmlEncodings.find(ch) != xmlEncodings.end())
|
||||
{
|
||||
encodedValue.append(xmlEncodings[ch]);
|
||||
}
|
||||
else
|
||||
{
|
||||
encodedValue.push_back(ch);
|
||||
}
|
||||
}
|
||||
|
||||
return encodedValue;
|
||||
}
|
||||
|
||||
// Decoding process based off the Windows Community Toolkit:
|
||||
// https://github.com/CommunityToolkit/WindowsCommunityToolkit/blob/rel/7.1.0/Microsoft.Toolkit.Uwp.Notifications/Toasts/ToastArguments.cs#L389inline
|
||||
inline std::wstring Decode(std::wstring const& value)
|
||||
{
|
||||
std::wstring result{};
|
||||
auto percentEncodings{ GetPercentEncodingsReverse() };
|
||||
|
||||
// Need to unescape special characters
|
||||
for (size_t index = 0; index < value.size();)
|
||||
{
|
||||
std::wstring curr{ value.substr(index, c_maxEncodingSize) };
|
||||
if (percentEncodings.find(curr) != percentEncodings.end())
|
||||
{
|
||||
result.push_back(percentEncodings[curr]);
|
||||
index += c_maxEncodingSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(value.at(index));
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#include "pch.h"
|
||||
#include "AppNotificationButton.h"
|
||||
#include "Microsoft.Windows.AppNotifications.Builder.AppNotificationButton.g.cpp"
|
||||
#include <IsWindowsVersion.h>
|
||||
#include "AppNotificationBuilderUtility.h"
|
||||
|
||||
namespace winrt::Microsoft::Windows::AppNotifications::Builder::implementation
|
||||
{
|
||||
AppNotificationButton::AppNotificationButton(winrt::hstring const& content) : m_content(content) { };
|
||||
|
||||
bool AppNotificationButton::IsToolTipSupported()
|
||||
{
|
||||
return WindowsVersion::IsWindows10_20H1OrGreater();
|
||||
}
|
||||
|
||||
bool AppNotificationButton::IsButtonStyleSupported()
|
||||
{
|
||||
return WindowsVersion::IsWindows10_20H1OrGreater();
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationButton AppNotificationButton::AddArgument(winrt::hstring const& key, winrt::hstring const& value)
|
||||
{
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, key.empty(), "You must provide a key when adding an argument");
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, m_protocolUri, "You cannot add an argument after calling SetInvokeUri");
|
||||
|
||||
m_arguments.Insert(EncodeArgument(key.c_str()), EncodeArgument(value.c_str()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationButton AppNotificationButton::SetIcon(winrt::Windows::Foundation::Uri const& value)
|
||||
{
|
||||
m_iconUri = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationButton AppNotificationButton::SetToolTip(winrt::hstring const& value)
|
||||
{
|
||||
m_toolTip = EncodeXml(value.c_str()).c_str();
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationButton AppNotificationButton::SetContextMenuPlacement()
|
||||
{
|
||||
m_useContextMenuPlacement = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationButton AppNotificationButton::SetButtonStyle(AppNotificationButtonStyle const& value)
|
||||
{
|
||||
m_buttonStyle = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationButton AppNotificationButton::SetInputId(winrt::hstring const& value)
|
||||
{
|
||||
m_inputId = EncodeXml(value.c_str()).c_str();
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationButton AppNotificationButton::SetInvokeUri(winrt::Windows::Foundation::Uri const& protocolUri)
|
||||
{
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, m_arguments.Size() > 0u, "You cannot add a protocol activation uri after calling AddArgument");
|
||||
|
||||
m_protocolUri = protocolUri;
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationButton AppNotificationButton::SetInvokeUri(winrt::Windows::Foundation::Uri const& protocolUri, winrt::hstring const& targetAppId)
|
||||
{
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, m_arguments.Size() > 0u, "You cannot add a protocol activation uri after calling AddArgument");
|
||||
|
||||
m_protocolUri = protocolUri;
|
||||
m_targetApplicationPfn = targetAppId;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::wstring AppNotificationButton::GetActivationArguments()
|
||||
{
|
||||
if (m_protocolUri)
|
||||
{
|
||||
std::wstring protocolTargetPfn{ !m_targetApplicationPfn.empty() ? wil::str_printf<std::wstring>(L" protocolActivationTargetApplicationPfn='%ls'", m_targetApplicationPfn.c_str()) : L"" };
|
||||
return wil::str_printf<std::wstring>(L" arguments='%ws' activationType='protocol'%ls", m_protocolUri.ToString().c_str(), protocolTargetPfn.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring arguments;
|
||||
for (auto pair : m_arguments)
|
||||
{
|
||||
if (!pair.Value().empty())
|
||||
{
|
||||
arguments.append(wil::str_printf<std::wstring>(L"%ls=%ls;", pair.Key().c_str(), pair.Value().c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
arguments.append(wil::str_printf<std::wstring>(L"%ls;", pair.Key().c_str()));
|
||||
}
|
||||
}
|
||||
arguments.pop_back();
|
||||
|
||||
return wil::str_printf<std::wstring>(L" arguments='%ls'", arguments.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring AppNotificationButton::GetButtonStyle()
|
||||
{
|
||||
if (m_buttonStyle == AppNotificationButtonStyle::Default)
|
||||
{
|
||||
return L"";
|
||||
}
|
||||
|
||||
std::wstring style{ m_buttonStyle == AppNotificationButtonStyle::Success ? L"Success" : L"Critical" };
|
||||
return wil::str_printf<std::wstring>(L" hint-buttonStyle='%ls'", style.c_str());
|
||||
}
|
||||
|
||||
winrt::hstring AppNotificationButton::ToString()
|
||||
{
|
||||
std::wstring xmlResult{ wil::str_printf<std::wstring>(L"<action content='%ls'%ls%ls%ls%ls%ls%ls/>",
|
||||
m_content.c_str(),
|
||||
GetActivationArguments().c_str(),
|
||||
m_useContextMenuPlacement ? L" placement='contextMenu'" : L"",
|
||||
m_iconUri ? wil::str_printf<std::wstring>(L" imageUri='%ls'", m_iconUri.ToString().c_str()).c_str() : L"",
|
||||
!m_inputId.empty() ? wil::str_printf<std::wstring>(L" hint-inputId='%ls'", m_inputId.c_str()).c_str() : L"",
|
||||
GetButtonStyle().c_str(),
|
||||
!m_toolTip.empty() ? wil::str_printf<std::wstring>(L" hint-toolTip='%ls'", m_toolTip.c_str()).c_str() : L"") };
|
||||
|
||||
return xmlResult.c_str();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#pragma once
|
||||
#include "Microsoft.Windows.AppNotifications.Builder.AppNotificationButton.g.h"
|
||||
|
||||
namespace winrt::Microsoft::Windows::AppNotifications::Builder::implementation
|
||||
{
|
||||
|
||||
struct AppNotificationButton : AppNotificationButtonT<AppNotificationButton, winrt::Windows::Foundation::IStringable>
|
||||
{
|
||||
AppNotificationButton() = default;
|
||||
AppNotificationButton(winrt::hstring const& content);
|
||||
|
||||
// Properties
|
||||
void Content(winrt::hstring const& value) { m_content = value; };
|
||||
winrt::hstring Content() { return m_content; };
|
||||
|
||||
void Arguments(winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> const& value) { m_arguments = value; };
|
||||
winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> Arguments() { return m_arguments; };
|
||||
|
||||
void Icon(winrt::Windows::Foundation::Uri const& value) { m_iconUri = value; };
|
||||
winrt::Windows::Foundation::Uri Icon() { return m_iconUri; };
|
||||
|
||||
void ToolTip(winrt::hstring const& value) { m_toolTip = value; };
|
||||
winrt::hstring ToolTip() { return m_toolTip; };
|
||||
|
||||
void ContextMenuPlacement(bool const& value) { m_useContextMenuPlacement = value; };
|
||||
bool ContextMenuPlacement() { return m_useContextMenuPlacement; };
|
||||
|
||||
void ButtonStyle(AppNotificationButtonStyle const& value) { m_buttonStyle = value; };
|
||||
AppNotificationButtonStyle ButtonStyle() { return m_buttonStyle; };
|
||||
|
||||
void InputId(winrt::hstring const& value) { m_inputId = value; };
|
||||
winrt::hstring InputId() { return m_inputId; };
|
||||
|
||||
void InvokeUri(winrt::Windows::Foundation::Uri const& value) { m_protocolUri = value; };
|
||||
winrt::Windows::Foundation::Uri InvokeUri() { return m_protocolUri; };
|
||||
|
||||
void TargetAppId(winrt::hstring const& value) { m_targetApplicationPfn = value; };
|
||||
winrt::hstring TargetAppId() { return m_targetApplicationPfn; };
|
||||
|
||||
// Fluent setters
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationButton AddArgument(winrt::hstring const& key, winrt::hstring const& value);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationButton SetIcon(winrt::Windows::Foundation::Uri const& value);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationButton SetToolTip(winrt::hstring const& value);
|
||||
static bool IsToolTipSupported();
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationButton SetContextMenuPlacement();
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationButton SetButtonStyle(AppNotificationButtonStyle const& value);
|
||||
static bool IsButtonStyleSupported();
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationButton SetInputId(winrt::hstring const& value);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationButton SetInvokeUri(winrt::Windows::Foundation::Uri const& protocolUri);
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationButton SetInvokeUri(winrt::Windows::Foundation::Uri const& protocolUri, winrt::hstring const& targetAppId);
|
||||
|
||||
winrt::hstring ToString();
|
||||
|
||||
private:
|
||||
std::wstring GetActivationArguments();
|
||||
std::wstring GetButtonStyle();
|
||||
|
||||
winrt::hstring m_content{};
|
||||
winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> m_arguments { winrt::single_threaded_map<winrt::hstring, winrt::hstring>() };
|
||||
winrt::Windows::Foundation::Uri m_iconUri{ nullptr };
|
||||
winrt::Windows::Foundation::Uri m_protocolUri{ nullptr };
|
||||
winrt::hstring m_targetApplicationPfn{};
|
||||
winrt::hstring m_toolTip{};
|
||||
winrt::hstring m_inputId{};
|
||||
bool m_useContextMenuPlacement{};
|
||||
AppNotificationButtonStyle m_buttonStyle { AppNotificationButtonStyle::Default };
|
||||
};
|
||||
}
|
||||
namespace winrt::Microsoft::Windows::AppNotifications::Builder::factory_implementation
|
||||
{
|
||||
struct AppNotificationButton : AppNotificationButtonT<AppNotificationButton, implementation::AppNotificationButton>
|
||||
{
|
||||
};
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#include "pch.h"
|
||||
#include "AppNotificationComboBox.h"
|
||||
#include "Microsoft.Windows.AppNotifications.Builder.AppNotificationComboBox.g.cpp"
|
||||
#include "AppNotificationBuilderUtility.h"
|
||||
|
||||
namespace winrt::Microsoft::Windows::AppNotifications::Builder::implementation
|
||||
{
|
||||
AppNotificationComboBox::AppNotificationComboBox(hstring const& id)
|
||||
{
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, id.empty(), "You must provide an id for the ComboBox");
|
||||
m_id = EncodeXml(id).c_str();
|
||||
};
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationComboBox AppNotificationComboBox::AddItem(winrt::hstring const& id, winrt::hstring const& content)
|
||||
{
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, m_items.Size() >= c_maxSelectionElements, "Maximum number of items added");
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, id.empty(), "You must provide an id for the item");
|
||||
|
||||
m_items.Insert(EncodeXml(id).c_str(), EncodeXml(content).c_str());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationComboBox AppNotificationComboBox::SetTitle(winrt::hstring const& value)
|
||||
{
|
||||
m_title = EncodeXml(value).c_str();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationComboBox AppNotificationComboBox::SetSelectedItem(winrt::hstring const& id)
|
||||
{
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, id.empty(), "You must provide an id for the selected item");
|
||||
|
||||
m_selectedItem = EncodeXml(id).c_str();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::wstring AppNotificationComboBox::GetSelectionItems()
|
||||
{
|
||||
std::wstring items{};
|
||||
|
||||
for (auto pair : m_items)
|
||||
{
|
||||
items.append(wil::str_printf<std::wstring>(L"<selection id='%ls' content='%ls'/>", pair.Key().c_str(), pair.Value().c_str()));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
winrt::hstring AppNotificationComboBox::ToString()
|
||||
{
|
||||
std::wstring xmlResult{ wil::str_printf<std::wstring>(L"<input id='%ls' type='selection'%ls%ls>%ls</input>",
|
||||
m_id.c_str(),
|
||||
m_title.empty() ? L"" : wil::str_printf<std::wstring>(L" title='%ls'", m_title.c_str()).c_str(),
|
||||
m_selectedItem.empty() ? L"" : wil::str_printf<std::wstring>(L" defaultInput='%ls'", m_selectedItem.c_str()).c_str(),
|
||||
GetSelectionItems().c_str()) };
|
||||
|
||||
return xmlResult.c_str();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#pragma once
|
||||
#include "Microsoft.Windows.AppNotifications.Builder.AppNotificationComboBox.g.h"
|
||||
|
||||
namespace winrt::Microsoft::Windows::AppNotifications::Builder::implementation
|
||||
{
|
||||
struct AppNotificationComboBox : AppNotificationComboBoxT<AppNotificationComboBox, winrt::Windows::Foundation::IStringable>
|
||||
{
|
||||
AppNotificationComboBox(winrt::hstring const& id);
|
||||
|
||||
// Properties
|
||||
void Items(winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> const& value) { m_items = value; };
|
||||
winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> Items() { return m_items; };
|
||||
|
||||
void Title(winrt::hstring const& value) { m_title = value; };
|
||||
winrt::hstring Title() { return m_title; };
|
||||
|
||||
void SelectedItem(winrt::hstring const& value) { m_selectedItem = value; };
|
||||
winrt::hstring SelectedItem() { return m_selectedItem; };
|
||||
|
||||
// Fluent Setters
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationComboBox AddItem(winrt::hstring const& id, winrt::hstring const& content);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationComboBox SetTitle(winrt::hstring const& value);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationComboBox SetSelectedItem(winrt::hstring const& id);
|
||||
|
||||
// IStringable
|
||||
winrt::hstring ToString();
|
||||
|
||||
private:
|
||||
winrt::hstring m_id{};
|
||||
winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> m_items{ winrt::single_threaded_map<winrt::hstring, winrt::hstring>() };
|
||||
winrt::hstring m_title{};
|
||||
winrt::hstring m_selectedItem{};
|
||||
|
||||
std::wstring GetSelectionItems();
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Windows::AppNotifications::Builder::factory_implementation
|
||||
{
|
||||
struct AppNotificationComboBox : AppNotificationComboBoxT<AppNotificationComboBox, implementation::AppNotificationComboBox>
|
||||
{
|
||||
};
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#include "pch.h"
|
||||
#include "AppNotificationProgressBar.h"
|
||||
#include "Microsoft.Windows.AppNotifications.Builder.AppNotificationProgressBar.g.cpp"
|
||||
#include "AppNotificationBuilderUtility.h"
|
||||
|
||||
namespace winrt::Microsoft::Windows::AppNotifications::Builder::implementation
|
||||
{
|
||||
AppNotificationProgressBar::AppNotificationProgressBar()
|
||||
:m_titleBindMode{ BindMode::NotSet },
|
||||
m_statusBindMode{ BindMode::NotSet },
|
||||
m_valueBindMode{ BindMode::NotSet },
|
||||
m_valueStringOverrideBindMode{ BindMode::NotSet }
|
||||
{};
|
||||
|
||||
void AppNotificationProgressBar::Title(winrt::hstring const& value)
|
||||
{
|
||||
m_title = EncodeXml(value).c_str();
|
||||
m_titleBindMode = BindMode::Value;
|
||||
}
|
||||
|
||||
void AppNotificationProgressBar::Status(winrt::hstring const& value)
|
||||
{
|
||||
m_status = EncodeXml(value).c_str();
|
||||
m_statusBindMode = BindMode::Value;
|
||||
}
|
||||
|
||||
void AppNotificationProgressBar::Value(double value)
|
||||
{
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, value < 0.0 || value > 1.0, "You must provide a value between 0.0 and 1.0");
|
||||
|
||||
m_value = value;
|
||||
m_valueBindMode = BindMode::Value;
|
||||
}
|
||||
|
||||
void AppNotificationProgressBar::ValueStringOverride(winrt::hstring const& value)
|
||||
{
|
||||
m_valueStringOverride = EncodeXml(value).c_str();
|
||||
m_valueStringOverrideBindMode = BindMode::Value;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationProgressBar AppNotificationProgressBar::SetTitle(winrt::hstring const& value)
|
||||
{
|
||||
Title(value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationProgressBar AppNotificationProgressBar::BindTitle()
|
||||
{
|
||||
m_titleBindMode = BindMode::Bind;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationProgressBar AppNotificationProgressBar::SetStatus(winrt::hstring const& value)
|
||||
{
|
||||
Status(value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationProgressBar AppNotificationProgressBar::BindStatus()
|
||||
{
|
||||
m_statusBindMode = BindMode::Bind;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationProgressBar AppNotificationProgressBar::SetValue(double value)
|
||||
{
|
||||
Value(value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationProgressBar AppNotificationProgressBar::BindValue()
|
||||
{
|
||||
m_valueBindMode = BindMode::Bind;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationProgressBar AppNotificationProgressBar::SetValueStringOverride(winrt::hstring const& value)
|
||||
{
|
||||
ValueStringOverride(value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationProgressBar AppNotificationProgressBar::BindValueStringOverride()
|
||||
{
|
||||
m_valueStringOverrideBindMode = BindMode::Bind;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::hstring AppNotificationProgressBar::ToString()
|
||||
{
|
||||
auto title{ wil::str_printf<std::wstring>(L" title='%ls'", m_titleBindMode == BindMode::Value ? m_title.c_str() : L"{progressTitle}") };
|
||||
auto status{ wil::str_printf<std::wstring>(L" status='%ls'", m_statusBindMode == BindMode::Value ? m_status.c_str() : L"{progressStatus}") };
|
||||
auto value{ wil::str_printf<std::wstring>(L" value='%ls'", m_valueBindMode == BindMode::Value ? wil::str_printf<std::wstring>(L"%g", m_value).c_str() : L"{progressValue}") };
|
||||
auto valueStringOverride{ wil::str_printf < std::wstring>(L" valueStringOverride='%ls'", m_valueStringOverrideBindMode == BindMode::Value ? m_valueStringOverride.c_str() : L"{progressValueString}") };
|
||||
|
||||
return wil::str_printf<std::wstring>(L"<progress%ls%ls%ls%ls/>",
|
||||
m_titleBindMode == BindMode::NotSet ? L"" : title.c_str(),
|
||||
status.c_str(),
|
||||
value.c_str(),
|
||||
m_valueStringOverrideBindMode == BindMode::NotSet ? L"" : valueStringOverride.c_str()).c_str();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#pragma once
|
||||
#include "Microsoft.Windows.AppNotifications.Builder.AppNotificationProgressBar.g.h"
|
||||
|
||||
namespace winrt::Microsoft::Windows::AppNotifications::Builder::implementation
|
||||
{
|
||||
|
||||
struct AppNotificationProgressBar : AppNotificationProgressBarT<AppNotificationProgressBar, winrt::Windows::Foundation::IStringable>
|
||||
{
|
||||
AppNotificationProgressBar();
|
||||
|
||||
// Properties
|
||||
void Title(winrt::hstring const& value);
|
||||
winrt::hstring Title() { return m_title; };
|
||||
|
||||
void Status(winrt::hstring const& value);
|
||||
winrt::hstring Status() { return m_status; };
|
||||
|
||||
void Value(double value);
|
||||
double Value() { return m_value; };
|
||||
|
||||
void ValueStringOverride(winrt::hstring const& value);
|
||||
winrt::hstring ValueStringOverride() { return m_valueStringOverride; };
|
||||
|
||||
// Fluent setters
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationProgressBar SetTitle(winrt::hstring const& value);
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationProgressBar BindTitle();
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationProgressBar SetStatus(winrt::hstring const& value);
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationProgressBar BindStatus();
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationProgressBar SetValue(double value);
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationProgressBar BindValue();
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationProgressBar SetValueStringOverride(winrt::hstring const& value);
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationProgressBar BindValueStringOverride();
|
||||
|
||||
// IStringable
|
||||
winrt::hstring ToString();
|
||||
|
||||
private:
|
||||
enum class BindMode {NotSet, Bind, Value};
|
||||
|
||||
BindMode m_titleBindMode;
|
||||
winrt::hstring m_title;
|
||||
BindMode m_statusBindMode;
|
||||
winrt::hstring m_status;
|
||||
BindMode m_valueBindMode;
|
||||
double m_value;
|
||||
BindMode m_valueStringOverrideBindMode;
|
||||
winrt::hstring m_valueStringOverride;
|
||||
};
|
||||
}
|
||||
namespace winrt::Microsoft::Windows::AppNotifications::Builder::factory_implementation
|
||||
{
|
||||
struct AppNotificationProgressBar : AppNotificationProgressBarT<AppNotificationProgressBar, implementation::AppNotificationProgressBar>
|
||||
{
|
||||
};
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#include "pch.h"
|
||||
#include "AppNotificationTextProperties.h"
|
||||
#include "Microsoft.Windows.AppNotifications.Builder.AppNotificationTextProperties.g.cpp"
|
||||
|
||||
namespace winrt::Microsoft::Windows::AppNotifications::Builder::implementation
|
||||
{
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationTextProperties AppNotificationTextProperties::SetLanguage(winrt::hstring const& value)
|
||||
{
|
||||
m_language = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationTextProperties AppNotificationTextProperties::SetIncomingCallAlignment()
|
||||
{
|
||||
m_useCallScenarioAlign = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationTextProperties AppNotificationTextProperties::SetMaxLines(int const& value)
|
||||
{
|
||||
m_maxLines = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::hstring AppNotificationTextProperties::ToString()
|
||||
{
|
||||
std::wstring language{ !m_language.empty() ? wil::str_printf<std::wstring>(L" lang='%ls'", m_language.c_str()) : L""};
|
||||
std::wstring callScenarioAlign{ m_useCallScenarioAlign ? L" hint-callScenarioCenterAlign='true'" : L""};
|
||||
std::wstring hintMaxLines{ m_maxLines ? wil::str_printf<std::wstring>(L" hint-maxLines='%d'", m_maxLines) : L"" };
|
||||
|
||||
return wil::str_printf<std::wstring>(L"<text%ls%ls%ls>", language.c_str(), hintMaxLines.c_str(), callScenarioAlign.c_str()).c_str();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#pragma once
|
||||
#include "Microsoft.Windows.AppNotifications.Builder.AppNotificationTextProperties.g.h"
|
||||
|
||||
namespace winrt::Microsoft::Windows::AppNotifications::Builder::implementation
|
||||
{
|
||||
struct AppNotificationTextProperties : AppNotificationTextPropertiesT<AppNotificationTextProperties, winrt::Windows::Foundation::IStringable>
|
||||
{
|
||||
AppNotificationTextProperties() = default;
|
||||
|
||||
// Properties
|
||||
void Language(winrt::hstring const& value) { m_language = value; };
|
||||
winrt::hstring Language() { return m_language; };
|
||||
|
||||
void MaxLines(int const& value) { m_maxLines = value; };
|
||||
int MaxLines() { return m_maxLines; };
|
||||
|
||||
void IncomingCallAlignment(bool const& value) { m_useCallScenarioAlign = value; };
|
||||
bool IncomingCallAlignment() { return m_useCallScenarioAlign; };
|
||||
|
||||
// Fluent Setters
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationTextProperties SetLanguage(winrt::hstring const& value);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationTextProperties SetIncomingCallAlignment();
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::Builder::AppNotificationTextProperties SetMaxLines(int const& value);
|
||||
|
||||
// IStringable
|
||||
winrt::hstring ToString();
|
||||
|
||||
private:
|
||||
int m_maxLines{ 0 };
|
||||
winrt::hstring m_language{};
|
||||
bool m_useCallScenarioAlign{};
|
||||
};
|
||||
}
|
||||
namespace winrt::Microsoft::Windows::AppNotifications::Builder::factory_implementation
|
||||
{
|
||||
struct AppNotificationTextProperties : AppNotificationTextPropertiesT<AppNotificationTextProperties, implementation::AppNotificationTextProperties>
|
||||
{
|
||||
};
|
||||
}
|
|
@ -24,10 +24,11 @@
|
|||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <WindowsAppRuntime.SelfContained.h>
|
||||
#include <ShellLocalization.h>
|
||||
#include <filesystem>
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
constexpr std::wstring_view expectedAppServerArgs = L"----AppNotificationActivated:"sv;
|
||||
constexpr std::wstring_view c_expectedAppServerArgs = L"----AppNotificationActivated:"sv;
|
||||
|
||||
namespace winrt
|
||||
{
|
||||
|
@ -129,50 +130,22 @@ namespace winrt::Microsoft::Windows::AppNotifications::implementation
|
|||
m_registering = false;
|
||||
}) };
|
||||
|
||||
winrt::guid storedComActivatorGuid{ GUID_NULL };
|
||||
if (!PushNotificationHelpers::IsPackagedAppScenario())
|
||||
{
|
||||
if (!AppModel::Identity::IsPackagedProcess())
|
||||
{
|
||||
THROW_IF_FAILED(PushNotifications_RegisterFullTrustApplication(m_appId.c_str(), GUID_NULL));
|
||||
|
||||
storedComActivatorGuid = RegisterComActivatorGuidAndAssets();
|
||||
}
|
||||
|
||||
if (!WindowsAppRuntime::SelfContained::IsSelfContained())
|
||||
{
|
||||
auto notificationPlatform{ PushNotificationHelpers::GetNotificationPlatform() };
|
||||
THROW_IF_FAILED(notificationPlatform->AddToastRegistrationMapping(m_processName.c_str(), m_appId.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
winrt::guid registeredClsid{ GUID_NULL };
|
||||
winrt::guid registeredClsid{};
|
||||
if (AppModel::Identity::IsPackagedProcess())
|
||||
{
|
||||
registeredClsid = PushNotificationHelpers::GetComRegistrationFromRegistry(expectedAppServerArgs.data());
|
||||
registeredClsid = RegisterPackagedApp();
|
||||
}
|
||||
else
|
||||
{
|
||||
AppNotificationAssets assets{ GetAssets() };
|
||||
registeredClsid = RegisterUnpackagedApp(assets);
|
||||
}
|
||||
|
||||
// Create event handle before COM Registration otherwise if a notification arrives will lead to race condition
|
||||
m_waitHandleForArgs.create();
|
||||
|
||||
{
|
||||
auto lock{ m_lock.lock_exclusive() };
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, m_notificationComActivatorRegistration, "Already Registered for App Notifications!");
|
||||
|
||||
// Check if the caller has registered event handlers, if so the REGCLS_MULTIPLEUSE flag will cause COM to ensure that all activators
|
||||
// are routed inproc, otherwise with REGCLS_SINGLEUSE COM will launch a new process of the Win32 app for each invocation.
|
||||
auto activationFlag{ m_notificationHandlers ? REGCLS_MULTIPLEUSE : REGCLS_SINGLEUSE };
|
||||
|
||||
// Register an INotificationActivationCallback to receive background activations from AppNotification.
|
||||
// Also, STA threads that call CoRegisterClassObject need to use the REGCLS_AGILE flag so that the object is
|
||||
// associated with the neutral apartment. This allows other threads to activate the STA registered thread.
|
||||
THROW_IF_FAILED(::CoRegisterClassObject(
|
||||
AppModel::Identity::IsPackagedProcess() ? registeredClsid : storedComActivatorGuid,
|
||||
winrt::make<AppNotificationManagerFactory>().get(),
|
||||
CLSCTX_LOCAL_SERVER,
|
||||
activationFlag | REGCLS_AGILE,
|
||||
&m_notificationComActivatorRegistration));
|
||||
}
|
||||
// Register the AppNotificationManager as a COM server for Shell to Activate and Invoke
|
||||
RegisterComServer(registeredClsid);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
@ -181,6 +154,110 @@ namespace winrt::Microsoft::Windows::AppNotifications::implementation
|
|||
}
|
||||
}
|
||||
|
||||
void AppNotificationManager::Register(hstring const& displayName, winrt::Windows::Foundation::Uri const& iconUri)
|
||||
{
|
||||
if (!IsSupported())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HRESULT hr{ S_OK };
|
||||
|
||||
auto logTelemetry{ wil::scope_exit([&]() {
|
||||
AppNotificationTelemetry::LogRegister(hr, m_appId);
|
||||
}) };
|
||||
|
||||
try
|
||||
{
|
||||
THROW_HR_IF_MSG(E_ILLEGAL_METHOD_CALL, AppModel::Identity::IsPackagedProcess(), "Not applicable for packaged applications");
|
||||
|
||||
THROW_HR_IF(E_INVALIDARG, displayName.empty() || (iconUri == nullptr));
|
||||
|
||||
AppNotificationAssets assets{ ValidateAssets(displayName, iconUri.RawUri().c_str()) };
|
||||
|
||||
{
|
||||
auto lock{ m_lock.lock_exclusive() };
|
||||
THROW_HR_IF_MSG(HRESULT_FROM_WIN32(ERROR_OPERATION_IN_PROGRESS), m_registering, "Registration is in progress!");
|
||||
m_registering = true;
|
||||
}
|
||||
|
||||
auto registeringScopeExit{ wil::scope_exit([&]()
|
||||
{
|
||||
auto lock { m_lock.lock_exclusive() };
|
||||
m_registering = false;
|
||||
}) };
|
||||
|
||||
winrt::guid registeredClsid{ RegisterUnpackagedApp(assets) };
|
||||
|
||||
// Create event handle before COM Registration otherwise if a notification arrives will lead to race condition
|
||||
m_waitHandleForArgs.create();
|
||||
|
||||
// Register the AppNotificationManager as a COM server for Shell to Activate and Invoke
|
||||
RegisterComServer(registeredClsid);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
hr = wil::ResultFromCaughtException();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void AppNotificationManager::RegisterComServer(winrt::guid const& registeredClsid)
|
||||
{
|
||||
auto lock{ m_lock.lock_exclusive() };
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, m_notificationComActivatorRegistration, "Already Registered for App Notifications!");
|
||||
|
||||
// Check if the caller has registered event handlers, if so the REGCLS_MULTIPLEUSE flag will cause COM to ensure that all activators
|
||||
// are routed inproc, otherwise with REGCLS_SINGLEUSE COM will launch a new process of the Win32 app for each invocation.
|
||||
auto activationFlag{ m_notificationHandlers ? REGCLS_MULTIPLEUSE : REGCLS_SINGLEUSE };
|
||||
|
||||
// Register an INotificationActivationCallback to receive background activations from AppNotification.
|
||||
// Also, STA threads that call CoRegisterClassObject need to use the REGCLS_AGILE flag so that the object is
|
||||
// associated with the neutral apartment. This allows other threads to activate the STA registered thread.
|
||||
THROW_IF_FAILED(::CoRegisterClassObject(
|
||||
registeredClsid,
|
||||
winrt::make<AppNotificationManagerFactory>().get(),
|
||||
CLSCTX_LOCAL_SERVER,
|
||||
activationFlag | REGCLS_AGILE,
|
||||
&m_notificationComActivatorRegistration));
|
||||
}
|
||||
|
||||
void AppNotificationManager::RegisterAppNotificationSinkWithLongRunningPlatform()
|
||||
{
|
||||
auto notificationPlatform{ PushNotificationHelpers::GetNotificationPlatform() };
|
||||
THROW_IF_FAILED(notificationPlatform->AddToastRegistrationMapping(m_processName.c_str(), m_appId.c_str()));
|
||||
}
|
||||
|
||||
winrt::guid AppNotificationManager::RegisterPackagedApp()
|
||||
{
|
||||
winrt::guid registeredClsid{ PushNotificationHelpers::GetComRegistrationFromRegistry(c_expectedAppServerArgs.data()) };
|
||||
|
||||
if (!PushNotificationHelpers::IsPackagedAppScenario() && !WindowsAppRuntime::SelfContained::IsSelfContained())
|
||||
{
|
||||
RegisterAppNotificationSinkWithLongRunningPlatform();
|
||||
}
|
||||
|
||||
return registeredClsid;
|
||||
}
|
||||
|
||||
winrt::guid AppNotificationManager::RegisterUnpackagedApp(AppNotificationAssets const& assets)
|
||||
{
|
||||
THROW_IF_FAILED(PushNotifications_RegisterFullTrustApplication(m_appId.c_str(), GUID_NULL));
|
||||
|
||||
std::wstring notificationAppId{ RetrieveNotificationAppId() };
|
||||
std::wstring comActivatorGuidString{ GetOrCreateComActivatorGuid() };
|
||||
|
||||
RegisterAssets(notificationAppId, comActivatorGuidString, assets);
|
||||
|
||||
if (!WindowsAppRuntime::SelfContained::IsSelfContained())
|
||||
{
|
||||
RegisterAppNotificationSinkWithLongRunningPlatform();
|
||||
}
|
||||
|
||||
// Remove braces around the guid string
|
||||
return winrt::guid(comActivatorGuidString.substr(1, comActivatorGuidString.size() - 2));
|
||||
}
|
||||
|
||||
// This assumes that the caller has taken an exclusive lock
|
||||
void AppNotificationManager::UnregisterHelper()
|
||||
{
|
||||
|
@ -337,11 +414,15 @@ namespace winrt::Microsoft::Windows::AppNotifications::implementation
|
|||
winrt::guid registeredClsid{ GUID_NULL };
|
||||
if (AppModel::Identity::IsPackagedProcess())
|
||||
{
|
||||
registeredClsid = PushNotificationHelpers::GetComRegistrationFromRegistry(expectedAppServerArgs.data());
|
||||
registeredClsid = PushNotificationHelpers::GetComRegistrationFromRegistry(c_expectedAppServerArgs.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
registeredClsid = RegisterComActivatorGuidAndAssets();
|
||||
std::wstring registeredClsidString;
|
||||
THROW_IF_FAILED(GetActivatorGuid(registeredClsidString));
|
||||
|
||||
// Remove braces around the guid string
|
||||
registeredClsid = winrt::guid(registeredClsidString.substr(1, registeredClsidString.size() - 2));
|
||||
}
|
||||
|
||||
auto notificationCallback{ winrt::create_instance<INotificationActivationCallback>(registeredClsid, CLSCTX_ALL) };
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "NotificationActivationCallback.h"
|
||||
#include "AppNotificationUtility.h"
|
||||
#include "externs.h"
|
||||
#include "ShellLocalization.h"
|
||||
|
||||
constexpr PCWSTR c_appNotificationContractId = L"Windows.Toast";
|
||||
|
||||
|
@ -22,6 +23,7 @@ namespace winrt::Microsoft::Windows::AppNotifications::implementation
|
|||
static winrt::Microsoft::Windows::AppNotifications::AppNotificationManager Default();
|
||||
static winrt::Windows::Foundation::IInspectable AppNotificationDeserialize(winrt::Windows::Foundation::Uri const& uri);
|
||||
void Register();
|
||||
void Register(hstring const& displayName, winrt::Windows::Foundation::Uri const& iconUri);
|
||||
void Unregister();
|
||||
void UnregisterAll();
|
||||
static bool IsSupported();
|
||||
|
@ -49,6 +51,11 @@ namespace winrt::Microsoft::Windows::AppNotifications::implementation
|
|||
winrt::Windows::Foundation::IInspectable Deserialize(winrt::Windows::Foundation::Uri const& uri);
|
||||
private:
|
||||
|
||||
winrt::guid RegisterPackagedApp();
|
||||
winrt::guid RegisterUnpackagedApp(::Microsoft::Windows::AppNotifications::ShellLocalization::AppNotificationAssets const& assets);
|
||||
void RegisterAppNotificationSinkWithLongRunningPlatform();
|
||||
void RegisterComServer(winrt::guid const& registeredClsid);
|
||||
|
||||
void UnregisterHelper();
|
||||
|
||||
wil::unique_com_class_object_cookie m_notificationComActivatorRegistration;
|
||||
|
|
|
@ -38,6 +38,8 @@ namespace ToastABI
|
|||
using namespace ::ABI::Microsoft::Internal::ToastNotifications;
|
||||
}
|
||||
|
||||
using namespace Microsoft::Windows::AppNotifications::ShellLocalization;
|
||||
|
||||
std::wstring Microsoft::Windows::AppNotifications::Helpers::RetrieveUnpackagedNotificationAppId()
|
||||
{
|
||||
wil::unique_cotaskmem_string appId;
|
||||
|
@ -241,7 +243,7 @@ std::wstring Microsoft::Windows::AppNotifications::Helpers::GetDisplayNameBasedO
|
|||
return displayName;
|
||||
}
|
||||
|
||||
winrt::guid Microsoft::Windows::AppNotifications::Helpers::RegisterComActivatorGuidAndAssets()
|
||||
std::wstring Microsoft::Windows::AppNotifications::Helpers::GetOrCreateComActivatorGuid()
|
||||
{
|
||||
std::wstring registeredGuid;
|
||||
auto hr = GetActivatorGuid(registeredGuid);
|
||||
|
@ -264,14 +266,36 @@ winrt::guid Microsoft::Windows::AppNotifications::Helpers::RegisterComActivatorG
|
|||
THROW_IF_FAILED(hr);
|
||||
}
|
||||
|
||||
std::wstring notificationAppId{ Microsoft::Windows::AppNotifications::Helpers::RetrieveNotificationAppId() };
|
||||
RegisterAssets(notificationAppId, registeredGuid);
|
||||
|
||||
// Remove braces around the guid string
|
||||
return winrt::guid(registeredGuid.substr(1, registeredGuid.size() - 2));
|
||||
return registeredGuid;
|
||||
}
|
||||
|
||||
void Microsoft::Windows::AppNotifications::Helpers::RegisterAssets(std::wstring const& appId, std::wstring const& clsid)
|
||||
// Try the following techniques to retrieve display name and icon:
|
||||
// 1. Based on the best app shortcut, using the FrameworkUdk.
|
||||
// 2. From the current process.
|
||||
// 3. Set a default DisplayName, but leave empty the icon file path so Shell can set a default icon.
|
||||
AppNotificationAssets Microsoft::Windows::AppNotifications::Helpers::GetAssets()
|
||||
{
|
||||
AppNotificationAssets assets{};
|
||||
|
||||
if (FAILED(RetrieveAssetsFromShortcut(assets)) &&
|
||||
FAILED(RetrieveAssetsFromProcess(assets)))
|
||||
{
|
||||
assets.displayName = GetDisplayNameBasedOnProcessName();
|
||||
}
|
||||
|
||||
return assets;
|
||||
}
|
||||
|
||||
AppNotificationAssets Microsoft::Windows::AppNotifications::Helpers::ValidateAssets(winrt::hstring const& displayName, std::filesystem::path const& iconFilePath)
|
||||
{
|
||||
winrt::check_bool(std::filesystem::exists(iconFilePath));
|
||||
|
||||
THROW_HR_IF_MSG(E_INVALIDARG, !IsIconFileExtensionSupported(iconFilePath), "Icon format not supported");
|
||||
|
||||
return AppNotificationAssets{ displayName.c_str(), iconFilePath.wstring() };
|
||||
}
|
||||
|
||||
void Microsoft::Windows::AppNotifications::Helpers::RegisterAssets(std::wstring const& appId, std::wstring const& clsid, AppNotificationAssets const& assets)
|
||||
{
|
||||
wil::unique_hkey hKey;
|
||||
// subKey: \Software\Classes\AppUserModelId\{AppGUID}
|
||||
|
@ -288,18 +312,6 @@ void Microsoft::Windows::AppNotifications::Helpers::RegisterAssets(std::wstring
|
|||
&hKey,
|
||||
nullptr /* lpdwDisposition */));
|
||||
|
||||
// Try the following techniques to retrieve display name and icon:
|
||||
// 1. Based on the best app shortcut, using the FrameworkUdk.
|
||||
// 2. From the current process.
|
||||
// 3. Set a default DisplayName, but leave empty the icon file path so Shell can set a default icon.
|
||||
Microsoft::Windows::AppNotifications::ShellLocalization::AppNotificationAssets assets{};
|
||||
|
||||
if (FAILED(Microsoft::Windows::AppNotifications::ShellLocalization::RetrieveAssetsFromShortcut(assets)) &&
|
||||
FAILED(Microsoft::Windows::AppNotifications::ShellLocalization::RetrieveAssetsFromProcess(assets)))
|
||||
{
|
||||
assets.displayName = GetDisplayNameBasedOnProcessName();
|
||||
}
|
||||
|
||||
RegisterValue(hKey, L"DisplayName", reinterpret_cast<const BYTE*>(assets.displayName.c_str()), REG_EXPAND_SZ, assets.displayName.size() * sizeof(wchar_t));
|
||||
|
||||
// If no icon is specified in the Registry, the OS will render a default icon for App Notifications.
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <wil/resource.h>
|
||||
#include <AppNotificationActivatedEventArgs.h>
|
||||
#include <FrameworkUdk/toastnotificationsrt.h>
|
||||
#include <ShellLocalization.h>
|
||||
|
||||
namespace Microsoft::Windows::AppNotifications::Helpers
|
||||
{
|
||||
|
@ -53,13 +54,17 @@ namespace Microsoft::Windows::AppNotifications::Helpers
|
|||
|
||||
HRESULT GetActivatorGuid(std::wstring& activatorGuid) noexcept;
|
||||
|
||||
winrt::guid RegisterComActivatorGuidAndAssets();
|
||||
std::wstring GetOrCreateComActivatorGuid();
|
||||
|
||||
void RegisterAssets(std::wstring const& appId, std::wstring const& clsid);
|
||||
void RegisterAssets(std::wstring const& appId, std::wstring const& clsid, Microsoft::Windows::AppNotifications::ShellLocalization::AppNotificationAssets const& assets);
|
||||
|
||||
wil::unique_cotaskmem_string ConvertUtf8StringToWideString(unsigned long length, const BYTE* utf8String);
|
||||
|
||||
winrt::Microsoft::Windows::AppNotifications::AppNotification ToastNotificationFromToastProperties(ABI::Microsoft::Internal::ToastNotifications::INotificationProperties* properties);
|
||||
|
||||
std::wstring GetDisplayNameBasedOnProcessName();
|
||||
|
||||
Microsoft::Windows::AppNotifications::ShellLocalization::AppNotificationAssets GetAssets();
|
||||
|
||||
Microsoft::Windows::AppNotifications::ShellLocalization::AppNotificationAssets ValidateAssets(winrt::hstring const& displayName, std::filesystem::path const& iconFilePath);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import "..\AppLifecycle\AppLifecycle.idl";
|
|||
|
||||
namespace Microsoft.Windows.AppNotifications
|
||||
{
|
||||
[contractversion(2)]
|
||||
[contractversion(3)]
|
||||
apicontract AppNotificationsContract {}
|
||||
|
||||
// Event args for the Notification Activation
|
||||
|
@ -16,6 +16,10 @@ namespace Microsoft.Windows.AppNotifications
|
|||
|
||||
// The data from the input elements of a Notification like a TextBox
|
||||
Windows.Foundation.Collections.IMap<String, String> UserInput{ get; };
|
||||
|
||||
// Arguments from the invoked button built from AppNotificationBuilder
|
||||
[contract(AppNotificationsContract, 3)]
|
||||
Windows.Foundation.Collections.IMap<String, String> Arguments{ get; };
|
||||
}
|
||||
|
||||
// Notification Progress Data
|
||||
|
@ -121,6 +125,10 @@ namespace Microsoft.Windows.AppNotifications
|
|||
// For Unpackaged apps, the caller process will be registered as the COM server. And assets like displayname and icon will be gleaned from Shell and registered as well.
|
||||
void Register();
|
||||
|
||||
// Unpackaged Apps can call this API to register custom displayname and icon for AppNotifications and register themselves as a COM server.
|
||||
[contract(AppNotificationsContract, 2)]
|
||||
void Register(String displayName, Windows.Foundation.Uri iconUri);
|
||||
|
||||
// Unregisters the COM Service so that a subsequent activation will launch a new process
|
||||
void Unregister();
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)ShellLocalization.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)AppNotificationActivatedEventArgs.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)AppNotificationManager.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)AppNotification.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)AppNotificationProgressData.cpp" />
|
||||
|
|
|
@ -167,7 +167,8 @@ void WriteHIconToPngFile(wil::unique_hicon const& hIcon, _In_ PCWSTR pszFileName
|
|||
THROW_IF_FAILED(spStreamOut->Commit(STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE));
|
||||
}
|
||||
|
||||
bool IsIconFileExtensionSupported(std::filesystem::path const& iconFilePath)
|
||||
|
||||
bool Microsoft::Windows::AppNotifications::ShellLocalization::IsIconFileExtensionSupported(std::filesystem::path const& iconFilePath)
|
||||
{
|
||||
static PCWSTR c_supportedExtensions[]{ L".bmp", L".ico", L".jpg", L".png" };
|
||||
|
||||
|
@ -258,10 +259,7 @@ HRESULT Microsoft::Windows::AppNotifications::ShellLocalization::DeleteIconFromC
|
|||
std::path iconFilePath{ RetrieveLocalFolderPath() / (notificationAppId + c_pngExtension) };
|
||||
|
||||
// If DeleteFile returned FALSE, then deletion failed and we should return the corresponding error code.
|
||||
if (DeleteFile(iconFilePath.c_str()) == FALSE)
|
||||
{
|
||||
THROW_HR(HRESULT_FROM_WIN32(GetLastError()));
|
||||
}
|
||||
RETURN_IF_WIN32_BOOL_FALSE(DeleteFileW(iconFilePath.c_str()));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -22,4 +22,6 @@ namespace Microsoft::Windows::AppNotifications::ShellLocalization
|
|||
HRESULT RetrieveAssetsFromShortcut(_Out_ Microsoft::Windows::AppNotifications::ShellLocalization::AppNotificationAssets& assets) noexcept;
|
||||
|
||||
HRESULT DeleteIconFromCache() noexcept;
|
||||
|
||||
bool IsIconFileExtensionSupported(std::filesystem::path const& iconFilePath);
|
||||
}
|
||||
|
|
|
@ -165,7 +165,7 @@
|
|||
<Import Project="..\..\packages\Microsoft.SourceLink.Common.1.1.0-beta-21055-01\build\Microsoft.SourceLink.Common.targets" Condition="Exists('..\..\packages\Microsoft.SourceLink.Common.1.1.0-beta-21055-01\build\Microsoft.SourceLink.Common.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.Build.Tasks.Git.1.1.0-beta-20204-02\build\Microsoft.Build.Tasks.Git.targets" Condition="Exists('..\..\packages\Microsoft.Build.Tasks.Git.1.1.0-beta-20204-02\build\Microsoft.Build.Tasks.Git.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.SourceLink.GitHub.1.1.0-beta-20204-02\build\Microsoft.SourceLink.GitHub.targets" Condition="Exists('..\..\packages\Microsoft.SourceLink.GitHub.1.1.0-beta-20204-02\build\Microsoft.SourceLink.GitHub.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.FrameworkUdk.1.1.2-CI-25087.1001.220410-1342.0\build\native\Microsoft.FrameworkUdk.targets" Condition="Exists('..\..\packages\Microsoft.FrameworkUdk.1.1.2-CI-25087.1001.220410-1342.0\build\native\Microsoft.FrameworkUdk.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.FrameworkUdk.1.0.5-CI-25099.1001.220418-1000.0\build\native\Microsoft.FrameworkUdk.targets" Condition="Exists('..\..\packages\Microsoft.FrameworkUdk.1.0.5-CI-25099.1001.220418-1000.0\build\native\Microsoft.FrameworkUdk.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
|
@ -179,6 +179,6 @@
|
|||
<Error Condition="!Exists('..\..\packages\Microsoft.Build.Tasks.Git.1.1.0-beta-20204-02\build\Microsoft.Build.Tasks.Git.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Build.Tasks.Git.1.1.0-beta-20204-02\build\Microsoft.Build.Tasks.Git.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.SourceLink.GitHub.1.1.0-beta-20204-02\build\Microsoft.SourceLink.GitHub.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.SourceLink.GitHub.1.1.0-beta-20204-02\build\Microsoft.SourceLink.GitHub.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.SourceLink.GitHub.1.1.0-beta-20204-02\build\Microsoft.SourceLink.GitHub.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.SourceLink.GitHub.1.1.0-beta-20204-02\build\Microsoft.SourceLink.GitHub.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.FrameworkUdk.1.1.2-CI-25087.1001.220410-1342.0\build\native\Microsoft.FrameworkUdk.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.FrameworkUdk.1.1.2-CI-25087.1001.220410-1342.0\build\native\Microsoft.FrameworkUdk.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.FrameworkUdk.1.0.5-CI-25099.1001.220418-1000.0\build\native\Microsoft.FrameworkUdk.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.FrameworkUdk.1.0.5-CI-25099.1001.220418-1000.0\build\native\Microsoft.FrameworkUdk.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Build.Tasks.Git" version="1.1.0-beta-20204-02" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.FrameworkUdk" version="1.1.2-CI-25087.1001.220410-1342.0" targetFramework="native" />
|
||||
<package id="Microsoft.FrameworkUdk" version="1.0.5-CI-25099.1001.220418-1000.0" targetFramework="native" />
|
||||
<package id="Microsoft.SourceLink.Common" version="1.1.0-beta-21055-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.GitHub" version="1.1.0-beta-20204-02" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.220531.1" targetFramework="native" />
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0-windows10.0.17763.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<Platforms>x64;x86;arm64</Platforms>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.Common" Version="1.1.0-beta-21055-01">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.0-beta-20204-02">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="$(MicrosoftWindowsCsWinRTPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<CSWinRTIncludes>Microsoft.Windows.AppNotifications.Builder</CSWinRTIncludes>
|
||||
<CSWinRTWindowsMetadata>10.0.17763.0</CSWinRTWindowsMetadata>
|
||||
<WindowsSdkPackageVersion>10.0.17763.$(CsWinRTDependencyWindowsSdkVersionSuffixPackageVersion)</WindowsSdkPackageVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Configure the release build binary to be as required by internal API scanning tools. -->
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<CsWinRTInputs Include="$(OutDir)/**/*.winmd" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.Windows.AppNotifications.Projection\Microsoft.Windows.AppNotifications.Projection.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Windows.AppNotifications">
|
||||
<HintPath>$(OutDir)..\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.AppNotifications.winmd</HintPath>
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Windows.AppNotifications.Builder">
|
||||
<HintPath>$(OutDir)..\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.AppNotifications.Builder.winmd</HintPath>
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -197,7 +197,7 @@
|
|||
<Import Project="..\..\..\packages\Microsoft.SourceLink.GitHub.1.1.0-beta-20204-02\build\Microsoft.SourceLink.GitHub.targets" Condition="Exists('..\..\..\packages\Microsoft.SourceLink.GitHub.1.1.0-beta-20204-02\build\Microsoft.SourceLink.GitHub.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.FrameworkUdk.1.1.2-CI-25087.1001.220410-1342.0\build\native\Microsoft.FrameworkUdk.targets" Condition="Exists('..\..\..\packages\Microsoft.FrameworkUdk.1.1.2-CI-25087.1001.220410-1342.0\build\native\Microsoft.FrameworkUdk.targets')" />
|
||||
<Import Project="..\..\..\packages\Microsoft.FrameworkUdk.1.0.5-CI-25099.1001.220418-1000.0\build\native\Microsoft.FrameworkUdk.targets" Condition="Exists('..\..\..\packages\Microsoft.FrameworkUdk.1.0.5-CI-25099.1001.220418-1000.0\build\native\Microsoft.FrameworkUdk.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
|
@ -212,6 +212,6 @@
|
|||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.FrameworkUdk.1.1.2-CI-25087.1001.220410-1342.0\build\native\Microsoft.FrameworkUdk.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.FrameworkUdk.1.1.2-CI-25087.1001.220410-1342.0\build\native\Microsoft.FrameworkUdk.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\packages\Microsoft.FrameworkUdk.1.0.5-CI-25099.1001.220418-1000.0\build\native\Microsoft.FrameworkUdk.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\Microsoft.FrameworkUdk.1.0.5-CI-25099.1001.220418-1000.0\build\native\Microsoft.FrameworkUdk.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Build.Tasks.Git" version="1.1.0-beta-20204-02" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.FrameworkUdk" version="1.1.2-CI-25087.1001.220410-1342.0" targetFramework="native" />
|
||||
<package id="Microsoft.FrameworkUdk" version="1.0.5-CI-25099.1001.220418-1000.0" targetFramework="native" />
|
||||
<package id="Microsoft.SourceLink.Common" version="1.1.0-beta-21055-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.GitHub" version="1.1.0-beta-20204-02" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.220531.1" targetFramework="native" />
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
<Import Project="..\AppLifecycle\AppLifecycle.vcxitems" Label="AppLifecycle" />
|
||||
<Import Project="..\PushNotifications\PushNotifications.vcxitems" Label="PushNotifications" />
|
||||
<Import Project="..\AppNotifications\AppNotifications.vcxitems" Label="AppNotifications" />
|
||||
<Import Project="..\AppNotifications\AppNotificationBuilder\AppNotificationBuilder.vcxitems" Label="AppNotificationBuilder" />
|
||||
<Import Project="..\DynamicDependency\API\DynamicDependency.vcxitems" Label="Shared" />
|
||||
<Import Project="..\UndockedRegFreeWinRT\UndockedRegFreeWinRT.vcxitems" Label="Shared" />
|
||||
<Import Project="..\Common\Common.vcxitems" Label="Shared" />
|
||||
|
@ -279,9 +280,9 @@
|
|||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\packages\Microsoft.FrameworkUdk.1.1.2-CI-25087.1001.220410-1342.0\build\native\Microsoft.FrameworkUdk.targets" Condition="Exists('..\..\packages\Microsoft.FrameworkUdk.1.1.2-CI-25087.1001.220410-1342.0\build\native\Microsoft.FrameworkUdk.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.FrameworkUdk.1.0.5-CI-25099.1001.220418-1000.0\build\native\Microsoft.FrameworkUdk.targets" Condition="Exists('..\..\packages\Microsoft.FrameworkUdk.1.0.5-CI-25099.1001.220418-1000.0\build\native\Microsoft.FrameworkUdk.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.SourceLink.Common.1.1.0-beta-21055-01\build\Microsoft.SourceLink.Common.targets" Condition="Exists('..\..\packages\Microsoft.SourceLink.Common.1.1.0-beta-21055-01\build\Microsoft.SourceLink.Common.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.Build.Tasks.Git.1.1.0-beta-20204-02\build\Microsoft.Build.Tasks.Git.targets" Condition="Exists('..\..\packages\Microsoft.Build.Tasks.Git.1.1.0-beta-20204-02\build\Microsoft.Build.Tasks.Git.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.SourceLink.GitHub.1.1.0-beta-20204-02\build\Microsoft.SourceLink.GitHub.targets" Condition="Exists('..\..\packages\Microsoft.SourceLink.GitHub.1.1.0-beta-20204-02\build\Microsoft.SourceLink.GitHub.targets')" />
|
||||
|
@ -297,10 +298,10 @@
|
|||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.FrameworkUdk.1.1.2-CI-25087.1001.220410-1342.0\build\native\Microsoft.FrameworkUdk.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.FrameworkUdk.1.1.2-CI-25087.1001.220410-1342.0\build\native\Microsoft.FrameworkUdk.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.FrameworkUdk.1.0.5-CI-25099.1001.220418-1000.0\build\native\Microsoft.FrameworkUdk.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.FrameworkUdk.1.0.5-CI-25099.1001.220418-1000.0\build\native\Microsoft.FrameworkUdk.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.SourceLink.Common.1.1.0-beta-21055-01\build\Microsoft.SourceLink.Common.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.SourceLink.Common.1.1.0-beta-21055-01\build\Microsoft.SourceLink.Common.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.SourceLink.Common.1.1.0-beta-21055-01\build\Microsoft.SourceLink.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.SourceLink.Common.1.1.0-beta-21055-01\build\Microsoft.SourceLink.Common.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Build.Tasks.Git.1.1.0-beta-20204-02\build\Microsoft.Build.Tasks.Git.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Build.Tasks.Git.1.1.0-beta-20204-02\build\Microsoft.Build.Tasks.Git.props'))" />
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Build.Tasks.Git" version="1.1.0-beta-20204-02" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.FrameworkUdk" version="1.1.2-CI-25087.1001.220410-1342.0" targetFramework="native" />
|
||||
<package id="Microsoft.FrameworkUdk" version="1.0.5-CI-25099.1001.220418-1000.0" targetFramework="native" />
|
||||
<package id="Microsoft.SourceLink.Common" version="1.1.0-beta-21055-01" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.SourceLink.GitHub" version="1.1.0-beta-20204-02" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.220531.1" targetFramework="native" />
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
`develop` Branch
|
||||
===
|
||||
|
||||
Building the full Windows App SDK package involves multiple repos and build pipelines.
|
||||
Beyond the publicly-visible repos, we also have closed-source repos that produce public packages which
|
||||
are then consumed by this repo ([WindowsAppSDK](https://github.com/microsoft/WindowsAppSDK)).
|
||||
|
||||
Some of those packages can't yet be pushed to the public feed on a CI/nightly basis though.
|
||||
Until that's resolved, we could get this repo into a state of being buildable only internally,
|
||||
by restoring the latest package from an internal feed.
|
||||
|
||||
To allow either configuration to be built (using the public dependent package or the internal one),
|
||||
we maintain two branches (similar to the GitFlow process):
|
||||
|
||||
* `main` branch consumes the latest public package
|
||||
* `develop` branch consumes the latest internal package.
|
||||
|
||||
The `develop` branch code is in the repo and still open, but can only be built internally.
|
||||
The `main` branch is always buildable at HEAD.
|
||||
External contributions to the repo are made to the `main` branch,
|
||||
and are merged internally into `develop` when completed.
|
||||
|
||||
Whenever a new public version of the dependent packages are pushed to the public feed,
|
||||
the `develop` branch can be merged into `main`.
|
||||
For example as part of (pre)releases.
|
||||
|
||||
Merging between `develop` and `main` is normal (not squashed),
|
||||
so that both branches can show the correct history, just with a few extra merge commits.
|
||||
Once the packages can be kept immediately updated we can drop the `develop` branch
|
||||
and not lose any history.
|
||||
|
||||
The long-lasting difference between `main` and `develop` is the `nuget.config` file;
|
||||
in `main` it references the public feed and in `develop` it references the internal feed.
|
||||
Package references might be different too if `develop` branch is consuming a package that's
|
||||
not yet on the public feed.
|
||||
|
||||
![Example of main and develop branching](images/develop-branch-example.jpg)
|
После Ширина: | Высота: | Размер: 90 KiB |
|
@ -0,0 +1,7 @@
|
|||
For status checks on the develop branch, please use TransportPackage-Foundation
|
||||
(https://microsoft.visualstudio.com/ProjectReunion/_build?definitionId=57248)
|
||||
and run the build against your PR branch with the default parameters.
|
||||
|
||||
For status checks on the main branch, please use microsoft.ProjectReunion
|
||||
(https://dev.azure.com/ms/ProjectReunion/_build?definitionId=391&_a=summary)
|
||||
and run the build against your PR branch with the default paramters.
|
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Dependencies>
|
||||
<ProductDependencies>
|
||||
<Dependency Name="Microsoft.WindowsAppSDK.AppLicensingInternal.TransportPackage" Version="1.1.0-stable.20220518.4">
|
||||
<Dependency Name="Microsoft.WindowsAppSDK.AppLicensingInternal.TransportPackage" Version="1.2.0-main.20220810.1">
|
||||
<Uri>https://dev.azure.com/microsoft/ProjectReunion/_git/ProjectReunionClosed</Uri>
|
||||
<Sha>0f4add1a10caa92e635919b81a678d2f1bcf229b</Sha>
|
||||
<Sha>1261bb31992442bf7e560330524002ea3a3e9d85</Sha>
|
||||
</Dependency>
|
||||
</ProductDependencies>
|
||||
<ToolsetDependencies>
|
||||
|
|
|
@ -22,7 +22,7 @@ parameters:
|
|||
default: 'ProjectReunionInternal'
|
||||
|
||||
steps:
|
||||
- checkout: git://ProjectReunion/ProjectReunionInternal
|
||||
- checkout: git://ProjectReunion/ProjectReunionInternal@release/1.2-preview1
|
||||
|
||||
- task: AzureKeyVault@1
|
||||
inputs:
|
||||
|
|
Двоичные данные
specs/AppNotifications/AppNotificationContentSpec/AppLogoOverrideImageExample.png
Normal file
После Ширина: | Высота: | Размер: 66 KiB |
Двоичные данные
specs/AppNotifications/AppNotificationContentSpec/AppNotificationExample.png
Normal file
После Ширина: | Высота: | Размер: 410 KiB |
Двоичные данные
specs/AppNotifications/AppNotificationContentSpec/AppNotificationTextExample.png
Normal file
После Ширина: | Высота: | Размер: 51 KiB |
Двоичные данные
specs/AppNotifications/AppNotificationContentSpec/AppNotificationWithAvatarImage.png
Normal file
После Ширина: | Высота: | Размер: 62 KiB |
Двоичные данные
specs/AppNotifications/AppNotificationContentSpec/ButtonContextMenuExample.png
Normal file
После Ширина: | Высота: | Размер: 278 KiB |
После Ширина: | Высота: | Размер: 73 KiB |
Двоичные данные
specs/AppNotifications/AppNotificationContentSpec/ButtonSuccessExample.png
Normal file
После Ширина: | Высота: | Размер: 74 KiB |
Двоичные данные
specs/AppNotifications/AppNotificationContentSpec/ButtonToolTipExample.png
Normal file
После Ширина: | Высота: | Размер: 92 KiB |
После Ширина: | Высота: | Размер: 109 KiB |
Двоичные данные
specs/AppNotifications/AppNotificationContentSpec/CroppedAppLogoOverrideExample.png
Normal file
После Ширина: | Высота: | Размер: 76 KiB |
После Ширина: | Высота: | Размер: 322 KiB |
Двоичные данные
specs/AppNotifications/AppNotificationContentSpec/IncomingCallExample.png
Normal file
После Ширина: | Высота: | Размер: 148 KiB |
Двоичные данные
specs/AppNotifications/AppNotificationContentSpec/IncomingCallSimpleExample.png
Normal file
После Ширина: | Высота: | Размер: 142 KiB |
Двоичные данные
specs/AppNotifications/AppNotificationContentSpec/InlineImageExample.png
Normal file
После Ширина: | Высота: | Размер: 272 KiB |
Двоичные данные
specs/AppNotifications/AppNotificationContentSpec/ProgressBarExample1.png
Normal file
После Ширина: | Высота: | Размер: 128 KiB |
Двоичные данные
specs/AppNotifications/AppNotificationContentSpec/ProgressBarExample2.png
Normal file
После Ширина: | Высота: | Размер: 124 KiB |
После Ширина: | Высота: | Размер: 87 KiB |
После Ширина: | Высота: | Размер: 22 KiB |
|
@ -139,6 +139,53 @@ int main()
|
|||
}
|
||||
```
|
||||
|
||||
## Registering for App Notifications using assets
|
||||
|
||||
For Unpackaged applications, the developer can Register using a custom Display Name and Icon.
|
||||
WinAppSDK will register the application and display these assets when an App Notification is received.
|
||||
The developer should provide both the assets or not provide them at all. Icon provided by the developer
|
||||
should be a valid supported format. The API supports the formats - png, bmp, jpg, ico. The icon
|
||||
should reside on the local machine only otherwise the API throws an exception. For Packaged applications,
|
||||
this API is not applicable and will throw an exception. Below are some examples of usage:
|
||||
|
||||
```cpp
|
||||
int main()
|
||||
{
|
||||
auto manager = winrt::AppNotificationManager::Default();
|
||||
|
||||
std::wstring iconFilepath{ std::filesystem::current_path() / "icon.ico" };
|
||||
winrt::hstring displayName{ L"AppNotifications" };
|
||||
|
||||
manager.Register(displayName, winrt::Windows::Foundation::Uri {iconFilepath});
|
||||
|
||||
// other app init and then message loop here
|
||||
|
||||
// Call Unregister() before exiting main so that subsequent invocations will launch a new process
|
||||
manager.Unregister();
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
```cpp
|
||||
int main()
|
||||
{
|
||||
auto manager = winrt::AppNotificationManager::Default();
|
||||
|
||||
std::wstring iconFilepath{ std::filesystem::current_path() / "icon.ico" };
|
||||
|
||||
std::wstring displayName{};
|
||||
wil::GetModuleFileNameExW(GetCurrentProcess(), nullptr, displayName);
|
||||
|
||||
manager.Register(displayName.c_str(), winrt::Windows::Foundation::Uri {iconFilepath});
|
||||
|
||||
// other app init and then message loop here
|
||||
|
||||
// Call Unregister() before exiting main so that subsequent invocations will launch a new process
|
||||
manager.Unregister();
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## Displaying an App Notification
|
||||
|
||||
To display a Notification, an app needs to define a payload in xml. In the example below, the
|
||||
|
@ -451,6 +498,9 @@ namespace Microsoft.Windows.AppNotifications
|
|||
// For Unpackaged apps, the caller process will be registered as the COM server. And assets like displayname and icon will be gleaned from Shell and registered as well.
|
||||
void Register();
|
||||
|
||||
// For Unpackaged apps only, the caller process will be registered as the COM server.
|
||||
void Register(String displayName, Windows.Foundation.Uri iconUri);
|
||||
|
||||
// Unregisters the COM Service so that a subsequent activation will launch a new process
|
||||
void Unregister();
|
||||
|
||||
|
|
|
@ -0,0 +1,670 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
namespace winrt
|
||||
{
|
||||
using namespace winrt::Microsoft::Windows::AppNotifications::Builder;
|
||||
}
|
||||
|
||||
namespace Test::AppNotification::Builder
|
||||
{
|
||||
inline const winrt::Windows::Foundation::Uri c_sampleUri{ L"http://www.microsoft.com" };
|
||||
|
||||
class APITests
|
||||
{
|
||||
public:
|
||||
BEGIN_TEST_CLASS(APITests)
|
||||
TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA")
|
||||
TEST_CLASS_PROPERTY(L"RunFixtureAs:Class", L"RestrictedUser")
|
||||
END_TEST_CLASS()
|
||||
|
||||
TEST_CLASS_SETUP(ClassInit)
|
||||
{
|
||||
::Test::Bootstrap::Setup();
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_CLASS_CLEANUP(ClassUninit)
|
||||
{
|
||||
::Test::Bootstrap::Cleanup();
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_METHOD_SETUP(MethodSetup)
|
||||
{
|
||||
|
||||
::Test::Bootstrap::SetupBootstrap();
|
||||
::WindowsAppRuntime::VersionInfo::TestInitialize(::Test::Bootstrap::TP::WindowsAppRuntimeFramework::c_PackageFamilyName,
|
||||
::Test::Bootstrap::TP::WindowsAppRuntimeMain::c_PackageFamilyName);
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_METHOD_CLEANUP(MethodCleanup)
|
||||
{
|
||||
::WindowsAppRuntime::VersionInfo::TestShutdown();
|
||||
::Test::Bootstrap::CleanupBootstrap();
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderDefault)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder() };
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'></binding></visual></toast>"};
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderSetTimeStamp)
|
||||
{
|
||||
auto time{ winrt::Windows::Foundation::DateTime::clock::now() };
|
||||
auto builder{ winrt::AppNotificationBuilder().SetTimeStamp(time) };
|
||||
|
||||
struct tm dateTime {};
|
||||
auto timeAsTimeT{ winrt::clock::to_time_t(time) };
|
||||
localtime_s(&dateTime, &timeAsTimeT);
|
||||
|
||||
std::wstringstream buffer;
|
||||
buffer << std::put_time(&dateTime, L"%FT%T%z");
|
||||
|
||||
std::wstring expectedTimestamp{ buffer.str() };
|
||||
expectedTimestamp.insert(expectedTimestamp.size() - c_offsetIndexValue, L":");
|
||||
std::wstring expected{ wil::str_printf<std::wstring>(L"<toast displayTimestamp='%ls'><visual><binding template='ToastGeneric'></binding></visual></toast>", expectedTimestamp.c_str()) };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddOneArgument)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().AddArgument(L"key", L"value") };
|
||||
auto expected{ L"<toast launch='key=value'><visual><binding template='ToastGeneric'></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddTwoArguments)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().AddArgument(L"key1", L"value1").AddArgument(L"key2", L"value2") };
|
||||
auto expected{ L"<toast launch='key1=value1;key2=value2'><visual><binding template='ToastGeneric'></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddArgumentEmptyValue)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().AddArgument(L"key", L"") };
|
||||
auto expected{ L"<toast launch='key'><visual><binding template='ToastGeneric'></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddArgumentWithPercentChar)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().AddArgument(L"k%ey", L"v%alue") };
|
||||
auto expected{ L"<toast launch='k%25ey=v%25alue'><visual><binding template='ToastGeneric'></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddArgumentWithEqualChar)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().AddArgument(L"k=ey", L"v=alue") };
|
||||
auto expected{ L"<toast launch='k%3Dey=v%3Dalue'><visual><binding template='ToastGeneric'></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddArgumentWithSemicolonChar)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().AddArgument(L"k;ey", L"v;alue") };
|
||||
auto expected{ L"<toast launch='k%3Bey=v%3Balue'><visual><binding template='ToastGeneric'></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(DecodeArguments)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(Decode(L"key%3B"), L"key;");
|
||||
VERIFY_ARE_EQUAL(Decode(L"key%3D"), L"key=");
|
||||
VERIFY_ARE_EQUAL(Decode(L"key%25"), L"key%");
|
||||
VERIFY_ARE_EQUAL(Decode(L"key%3B%3D%25"), L"key;=%");
|
||||
VERIFY_ARE_EQUAL(Decode(L"%25%25%25"), L"%%%");
|
||||
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddArgumentEmptyKey)
|
||||
{
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationBuilder().AddArgument(L"", L""), E_INVALIDARG);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderSetReminderScenario)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().SetScenario(winrt::AppNotificationScenario::Reminder) };
|
||||
auto expected{ L"<toast scenario='reminder'><visual><binding template='ToastGeneric'></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderSetAlarmScenario)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().SetScenario(winrt::AppNotificationScenario::Alarm) };
|
||||
auto expected{ L"<toast scenario='alarm'><visual><binding template='ToastGeneric'></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderSetIncomingCallScenario)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().SetScenario(winrt::AppNotificationScenario::IncomingCall) };
|
||||
auto expected{ L"<toast scenario='incomingCall'><visual><binding template='ToastGeneric'></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderSetUrgentScenario)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().SetScenario(winrt::AppNotificationScenario::Urgent) };
|
||||
auto expected{ L"<toast scenario='urgent'><visual><binding template='ToastGeneric'></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddText)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().AddText(L"content") };
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'><text>content</text></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddTextWithLanguage)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.AddText(L"content", winrt::AppNotificationTextProperties()
|
||||
.SetLanguage(L"en-US"))
|
||||
};
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'><text lang='en-US'>content</text></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddTextWithMaxLines)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.AddText(L"content", winrt::AppNotificationTextProperties()
|
||||
.SetMaxLines(2))
|
||||
};
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'><text hint-maxLines='2'>content</text></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddTextWithCallScenarioAlign)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.AddText(L"content", winrt::AppNotificationTextProperties()
|
||||
.SetIncomingCallAlignment())
|
||||
};
|
||||
auto expected{ L"<toast scenario='incomingCall'><visual><binding template='ToastGeneric'><text hint-callScenarioCenterAlign='true'>content</text></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddTextWithAllProperties)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.AddText(L"content", winrt::AppNotificationTextProperties()
|
||||
.SetLanguage(L"en-US")
|
||||
.SetMaxLines(2)
|
||||
.SetIncomingCallAlignment())
|
||||
};
|
||||
auto expected{ L"<toast scenario='incomingCall'><visual><binding template='ToastGeneric'><text lang='en-US' hint-maxLines='2' hint-callScenarioCenterAlign='true'>content</text></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddTextThrows)
|
||||
{
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationBuilder()
|
||||
.AddText(L"content")
|
||||
.AddText(L"content")
|
||||
.AddText(L"content")
|
||||
.AddText(L"content"), E_INVALIDARG);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddAttributionText)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().SetAttributionText(L"content") };
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'><text placement='attribution'>content</text></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddAttributionTextWithLanguage)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().SetAttributionText(L"content", L"en-US")};
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'><text placement='attribution' lang='en-US'>content</text></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderSetInlineImage)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().SetInlineImage(c_sampleUri) };
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'><image src='http://www.microsoft.com/'/></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderSetInlineImageWithProperties)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().SetInlineImage(c_sampleUri, winrt::AppNotificationImageCrop::Circle, L"altText")};
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'><image src='http://www.microsoft.com/' alt='altText' hint-crop='circle'/></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderSetAppLogoOverride)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().SetAppLogoOverride(c_sampleUri) };
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'><image placement='appLogoOverride' src='http://www.microsoft.com/'/></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderSetAppLogoOverrideProperties)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().SetAppLogoOverride(c_sampleUri, winrt::AppNotificationImageCrop::Circle, L"altText") };
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'><image placement='appLogoOverride' src='http://www.microsoft.com/' alt='altText' hint-crop='circle'/></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderSetHeroImage)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().SetHeroImage(c_sampleUri) };
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'><image placement='hero' src='http://www.microsoft.com/'/></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderSetHeroImageWithAlt)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().SetHeroImage(c_sampleUri, L"altText") };
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'><image placement='hero' src='http://www.microsoft.com/' alt='altText'/></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddButton)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.AddButton(winrt::AppNotificationButton(L"content")
|
||||
.AddArgument(L"key", L"value"))
|
||||
};
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'></binding></visual><actions><action content='content' arguments='key=value'/></actions></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddButtonWithPlacement)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.AddButton(winrt::AppNotificationButton(L"content")
|
||||
.AddArgument(L"key", L"value")
|
||||
.SetContextMenuPlacement())
|
||||
};
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'></binding></visual><actions><action content='content' arguments='key=value' placement='contextMenu'/></actions></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderTooManyButtons)
|
||||
{
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationBuilder()
|
||||
.AddButton(winrt::AppNotificationButton(L"content").AddArgument(L"key1", L"value1"))
|
||||
.AddButton(winrt::AppNotificationButton(L"content").AddArgument(L"key2", L"value2"))
|
||||
.AddButton(winrt::AppNotificationButton(L"content").AddArgument(L"key3", L"value3"))
|
||||
.AddButton(winrt::AppNotificationButton(L"content").AddArgument(L"key4", L"value4"))
|
||||
.AddButton(winrt::AppNotificationButton(L"content").AddArgument(L"key5", L"value5"))
|
||||
.AddButton(winrt::AppNotificationButton(L"content").AddArgument(L"key6", L"value6")), E_INVALIDARG);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddButtonWithProtocolActivation)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.AddButton(winrt::AppNotificationButton(L"content")
|
||||
.SetInvokeUri(c_sampleUri))
|
||||
};
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'></binding></visual><actions><action content='content' arguments='http://www.microsoft.com/' activationType='protocol'/></actions></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddButtonWithProperties)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.AddButton(winrt::AppNotificationButton(L"content")
|
||||
.AddArgument(L"key", L"value")
|
||||
.SetButtonStyle(winrt::AppNotificationButtonStyle::Success)
|
||||
.SetIcon(c_sampleUri)
|
||||
.SetInputId(L"inputId")
|
||||
.SetToolTip(L"toolTip"))
|
||||
};
|
||||
auto expected{ L"<toast useButtonStyle='true'><visual><binding template='ToastGeneric'></binding></visual><actions><action content='content' arguments='key=value' imageUri='http://www.microsoft.com/' hint-inputId='inputId' hint-buttonStyle='Success' hint-toolTip='toolTip'/></actions></toast>"};
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddButtonWithEmptyKey)
|
||||
{
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationBuilder()
|
||||
.AddButton(winrt::AppNotificationButton(L"content")
|
||||
.AddArgument(L"", L"value")), E_INVALIDARG);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddButtonWithArgumentAndProtocol)
|
||||
{
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationBuilder()
|
||||
.AddButton(winrt::AppNotificationButton(L"content")
|
||||
.AddArgument(L"key", L"value")
|
||||
.SetInvokeUri(c_sampleUri)), E_INVALIDARG);
|
||||
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationBuilder()
|
||||
.AddButton(winrt::AppNotificationButton(L"content")
|
||||
.SetInvokeUri(c_sampleUri)
|
||||
.AddArgument(L"key", L"value")), E_INVALIDARG);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderSetAudioWithUri)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.SetAudioUri(c_sampleUri) };
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'></binding></visual><audio src='http://www.microsoft.com/'/></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderSetAudioWithUriAndDuration)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.SetDuration(winrt::AppNotificationDuration::Long)
|
||||
.SetAudioUri(c_sampleUri, winrt::AppNotificationAudioLooping::Loop) };
|
||||
auto expected{ L"<toast duration='long'><visual><binding template='ToastGeneric'></binding></visual><audio src='http://www.microsoft.com/' loop='true'/></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderSetAudioWithSoundEvent)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.SetAudioEvent(winrt::AppNotificationSoundEvent::Reminder) };
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'></binding></visual><audio src='ms-winsoundevent:Notification.Reminder'/></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderSetAudioWithSoundEventAndDuration)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.SetDuration(winrt::AppNotificationDuration::Long)
|
||||
.SetAudioEvent(winrt::AppNotificationSoundEvent::Reminder, winrt::AppNotificationAudioLooping::Loop) };
|
||||
auto expected{ L"<toast duration='long'><visual><binding template='ToastGeneric'></binding></visual><audio src='ms-winsoundevent:Notification.Reminder' loop='true'/></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderMuteAudio)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().MuteAudio() };
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'></binding></visual><audio silent='true'/></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderBuildNotificationWithTooLargePayload)
|
||||
{
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationBuilder()
|
||||
.AddText(std::wstring(5120, 'A').c_str())
|
||||
.BuildNotification(), E_FAIL);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationAddProgressBar)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.AddText(L"Downloading this week's new music...")
|
||||
.AddProgressBar(winrt::AppNotificationProgressBar()
|
||||
.BindTitle()
|
||||
.BindValueStringOverride()) };
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'><text>Downloading this week's new music...</text><progress title='{progressTitle}' status='{progressStatus}' value='{progressValue}' valueStringOverride='{progressValueString}'/></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationAddMoreThanOneProgressBar)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.AddText(L"Downloading this week's new music...")
|
||||
.AddProgressBar(winrt::AppNotificationProgressBar()
|
||||
.BindTitle()
|
||||
.BindValueStringOverride())
|
||||
.AddProgressBar(winrt::AppNotificationProgressBar()
|
||||
.SetValue(0.8)
|
||||
.SetStatus(L"Still downloading...")) };
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'><text>Downloading this week's new music...</text><progress title='{progressTitle}' status='{progressStatus}' value='{progressValue}' valueStringOverride='{progressValueString}'/><progress status='Still downloading...' value='0.8'/></binding></visual></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationProgressBarDefaults)
|
||||
{
|
||||
auto progressBar{ winrt::AppNotificationProgressBar() };
|
||||
auto expected{ L"<progress status='{progressStatus}' value='{progressValue}'/>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(progressBar.as<winrt::Windows::Foundation::IStringable>().ToString(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationProgressBarSetSpecificValue)
|
||||
{
|
||||
auto progressBar{ winrt::AppNotificationProgressBar() };
|
||||
progressBar.Value(0.8);
|
||||
auto expected{ L"<progress status='{progressStatus}' value='0.8'/>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(progressBar.as<winrt::Windows::Foundation::IStringable>().ToString(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationProgressBarSetValueLargerThanOne)
|
||||
{
|
||||
auto progressBar{ winrt::AppNotificationProgressBar() };
|
||||
VERIFY_THROWS_HR(progressBar.Value(1.01), E_INVALIDARG);
|
||||
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationProgressBar().SetValue(1.01), E_INVALIDARG);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationProgressBarSetValueSmallerThanZero)
|
||||
{
|
||||
auto progressBar{ winrt::AppNotificationProgressBar() };
|
||||
VERIFY_THROWS_HR(progressBar.Value(-0.1), E_INVALIDARG);
|
||||
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationProgressBar().SetValue(-0.1), E_INVALIDARG);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationProgressBarSetSpecificValueThenChangeToBind)
|
||||
{
|
||||
auto progressBar{ winrt::AppNotificationProgressBar() };
|
||||
progressBar.Value(0.8);
|
||||
progressBar.BindValue();
|
||||
auto expected{ L"<progress status='{progressStatus}' value='{progressValue}'/>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(progressBar.as<winrt::Windows::Foundation::IStringable>().ToString(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationProgressBarBindTitleThenChangeToSpecificText)
|
||||
{
|
||||
auto progressBar{ winrt::AppNotificationProgressBar()
|
||||
.BindTitle()
|
||||
.SetTitle(L"Specific title") };
|
||||
auto expected{ L"<progress title='Specific title' status='{progressStatus}' value='{progressValue}'/>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(progressBar.as<winrt::Windows::Foundation::IStringable>().ToString(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddTextBox)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.AddTextBox(L"input1") };
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'></binding></visual><actions><input id='input1' type='text'/></actions></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddTextBoxWithEmptyId)
|
||||
{
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationBuilder()
|
||||
.AddTextBox(L""), E_INVALIDARG);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddTextBoxWithEmptyIdAndPlaceHolderTextAndTitle)
|
||||
{
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationBuilder()
|
||||
.AddTextBox(L"", L"placeholder text", L"title"), E_INVALIDARG);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddTooManyTextBoxes)
|
||||
{
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationBuilder()
|
||||
.AddTextBox(L"input1")
|
||||
.AddTextBox(L"input2")
|
||||
.AddTextBox(L"input3")
|
||||
.AddTextBox(L"input4")
|
||||
.AddTextBox(L"input5")
|
||||
.AddTextBox(L"input6"), E_INVALIDARG);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddTextBoxWithPlaceHolderTextAndTitle)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.AddTextBox(L"some input id", L"Some placeholder text", L"A Title")};
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'></binding></visual><actions><input id='some input id' type='text' placeHolderContent='Some placeholder text' title='A Title'/></actions></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddComboBox)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.AddComboBox(winrt::AppNotificationComboBox(L"comboBox1")
|
||||
.AddItem(L"item1", L"item1 text")
|
||||
.AddItem(L"item2", L"item2 text")
|
||||
.AddItem(L"item3", L"item3 text")
|
||||
.SetTitle(L"ComboBox Title")
|
||||
.SetSelectedItem(L"item2"))};
|
||||
auto expected{ L"<toast><visual><binding template='ToastGeneric'></binding></visual><actions><input id='comboBox1' type='selection' title='ComboBox Title' defaultInput='item2'><selection id='item1' content='item1 text'/><selection id='item2' content='item2 text'/><selection id='item3' content='item3 text'/></input></actions></toast>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddTooManyComboBox)
|
||||
{
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationBuilder()
|
||||
.AddTextBox(L"input1")
|
||||
.AddTextBox(L"input2")
|
||||
.AddTextBox(L"input3")
|
||||
.AddComboBox(winrt::AppNotificationComboBox(L"comboBox1")
|
||||
.AddItem(L"item1", L"item1 text"))
|
||||
.AddComboBox(winrt::AppNotificationComboBox(L"comboBox2")
|
||||
.AddItem(L"item1", L"item1 text"))
|
||||
.AddComboBox(winrt::AppNotificationComboBox(L"comboBox3")
|
||||
.AddItem(L"item1", L"item1 text")), E_INVALIDARG);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderAddTooManyInputElements)
|
||||
{
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationBuilder()
|
||||
.AddComboBox(winrt::AppNotificationComboBox(L"comboBox1")
|
||||
.AddItem(L"item1", L"item1 text"))
|
||||
.AddComboBox(winrt::AppNotificationComboBox(L"comboBox2")
|
||||
.AddItem(L"item1", L"item1 text"))
|
||||
.AddComboBox(winrt::AppNotificationComboBox(L"comboBox3")
|
||||
.AddItem(L"item1", L"item1 text"))
|
||||
.AddComboBox(winrt::AppNotificationComboBox(L"comboBox4")
|
||||
.AddItem(L"item1", L"item1 text"))
|
||||
.AddComboBox(winrt::AppNotificationComboBox(L"comboBox5")
|
||||
.AddItem(L"item1", L"item1 text"))
|
||||
.AddComboBox(winrt::AppNotificationComboBox(L"comboBox6")
|
||||
.AddItem(L"item1", L"item1 text")), E_INVALIDARG);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationComboBoxAddTooManySelectionItems)
|
||||
{
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationComboBox(L"comboBox1")
|
||||
.AddItem(L"item1", L"item1 text")
|
||||
.AddItem(L"item2", L"item2 text")
|
||||
.AddItem(L"item3", L"item3 text")
|
||||
.AddItem(L"item4", L"item4 text")
|
||||
.AddItem(L"item5", L"item5 text")
|
||||
.AddItem(L"item6", L"item6 text"), E_INVALIDARG);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationComboBoxAddFiveSelectionItems)
|
||||
{
|
||||
auto comboBox{ winrt::AppNotificationComboBox(L"comboBox1")
|
||||
.AddItem(L"item1", L"item1 text")
|
||||
.AddItem(L"item2", L"item2 text")
|
||||
.AddItem(L"item3", L"item3 text")
|
||||
.AddItem(L"item4", L"item4 text")
|
||||
.AddItem(L"item5", L"item5 text") };
|
||||
auto expected{ L"<input id='comboBox1' type='selection'><selection id='item1' content='item1 text'/><selection id='item2' content='item2 text'/><selection id='item3' content='item3 text'/><selection id='item4' content='item4 text'/><selection id='item5' content='item5 text'/></input>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(comboBox.as<winrt::Windows::Foundation::IStringable>().ToString(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationComboBoxAddSelectionItemWithoutAnId)
|
||||
{
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationComboBox(L"comboBox1")
|
||||
.AddItem(L"", L"item text"), E_INVALIDARG);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationComboBoxAddTwoSelectionItemsWithSameId)
|
||||
{
|
||||
auto comboBox{ winrt::AppNotificationComboBox(L"comboBox1")
|
||||
.AddItem(L"item1", L"item1 text")
|
||||
.AddItem(L"item1", L"item2 text") };
|
||||
auto expected{ L"<input id='comboBox1' type='selection'><selection id='item1' content='item2 text'/></input>" };
|
||||
|
||||
VERIFY_ARE_EQUAL(comboBox.as<winrt::Windows::Foundation::IStringable>().ToString(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationComboBoxSetSelectedItemWithoutAnId)
|
||||
{
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationComboBox(L"comboBox1")
|
||||
.SetSelectedItem(L""), E_INVALIDARG);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationCreateComboBoxWithoutAnId)
|
||||
{
|
||||
VERIFY_THROWS_HR(winrt::AppNotificationComboBox(L""), E_INVALIDARG);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderEscapeXmlCharacters)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder().AddText(LR"(&"'<>)") };
|
||||
std::wstring expected{ L"<toast><visual><binding template='ToastGeneric'><text>&"'<></text></binding></visual></toast>"};
|
||||
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
}
|
||||
|
||||
TEST_METHOD(AppNotificationBuilderArgumentsWithXmlCharacters)
|
||||
{
|
||||
auto builder{ winrt::AppNotificationBuilder()
|
||||
.AddArgument(LR"(&;"='%<>)", L"")
|
||||
.AddArgument(LR"(&"'<>)", L";=%")};
|
||||
|
||||
std::wstring expected{ L"<toast launch='&%3B"%3D'%25<>;&"'<>=%3B%3D%25'><visual><binding template='ToastGeneric'></binding></visual></toast>" };
|
||||
VERIFY_ARE_EQUAL(builder.BuildNotification().Payload(), expected);
|
||||
|
||||
VERIFY_ARE_EQUAL(Decode(LR"(&%3B"%3D'%25<>)"), LR"(&;"='%<>)");
|
||||
VERIFY_ARE_EQUAL(Decode(L"%3B%3D%25"), L";=%");
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#include "pch.h"
|
||||
#include "AppNotificationBuilderTests.h"
|
|
@ -0,0 +1,4 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#pragma once
|
|
@ -0,0 +1,156 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{131de0c4-aa1e-4649-b5bc-7b43508fa93a}</ProjectGuid>
|
||||
<RootNamespace>AppNotificationBuilderTests</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'">
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared" />
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>$(RepoRoot)\test\inc;$(RepoRoot)\Dev\Common;$(RepoRoot)\Dev\AppNotifications\AppNotificationBuilder;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories Condition="$(WindowsAppSDKBuildPipeline) == '1'">$(RepoRoot);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<AdditionalDependencies>onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL</AdditionalLibraryDirectories>
|
||||
<DelayLoadDLLs>Microsoft.WindowsAppRuntime.Bootstrap.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
<DelayLoadDLLs>Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="APITests.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Windows.AppNotifications.Builder">
|
||||
<HintPath>$(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.AppNotifications.Builder.winmd</HintPath>
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Windows.AppNotifications">
|
||||
<HintPath>$(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.AppNotifications.winmd</HintPath>
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\dev\WindowsAppRuntime_BootstrapDLL\WindowsAppRuntime_BootstrapDLL.vcxproj">
|
||||
<Project>{f76b776e-86f5-48c5-8fc7-d2795ecc9746}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\packages\Microsoft.Taef.10.58.210222006-develop\build\Microsoft.Taef.targets" Condition="Exists('..\..\packages\Microsoft.Taef.10.58.210222006-develop\build\Microsoft.Taef.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="CopyFiles" AfterTargets="AfterBuild">
|
||||
<Copy SourceFiles="$(OutDir)\..\WindowsAppRuntime_BootstrapDLL\Microsoft.WindowsAppRuntime.Bootstrap.dll" DestinationFolder="$(OutDir)" />
|
||||
<Copy SourceFiles="$(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Internal.FrameworkUdk.dll" DestinationFolder="$(OutDir)" />
|
||||
</Target>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Taef.10.58.210222006-develop\build\Microsoft.Taef.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Taef.10.58.210222006-develop\build\Microsoft.Taef.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Windows.CppWinRT.2.0.220531.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4b514c96-7ee8-44e5-aeb3-64c1bc0d6b91}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{9f96baa5-3d60-4ef4-9ff2-5a5fe8d7367b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="APITests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Taef" version="10.58.210222006-develop" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.220531.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.220201.1" targetFramework="native" />
|
||||
</packages>
|
|
@ -0,0 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
|
|
@ -0,0 +1,63 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
#ifndef PCH_H
|
||||
#define PCH_H
|
||||
|
||||
#include <unknwn.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
#include <windows.h>
|
||||
#include <sddl.h>
|
||||
#include <appmodel.h>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <wil/resource.h>
|
||||
#include <wil/stl.h>
|
||||
#include <wil/result.h>
|
||||
#include <wil/cppwinrt.h>
|
||||
#include <wil/token_helpers.h>
|
||||
#include <wrl.h>
|
||||
#include <WexTestClass.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include <wil/result_macros.h>
|
||||
#include <wil/com.h>
|
||||
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
|
||||
#include <winrt/Windows.Networking.PushNotifications.h>
|
||||
#include <winrt/Windows.ApplicationModel.Activation.h>
|
||||
#include <winrt/Windows.Management.Deployment.h>
|
||||
#include <winrt/Windows.Security.Cryptography.h>
|
||||
#include <winrt/Windows.Storage.h>
|
||||
#include <winrt/Windows.System.h>
|
||||
#include <WindowsAppRuntime.Test.Package.h>
|
||||
#include <WindowsAppRuntime.Test.TAEF.h>
|
||||
#include <WindowsAppRuntime.Test.Bootstrap.h>
|
||||
#include <windows.applicationmodel.h>
|
||||
#include <windows.applicationmodel.background.h>
|
||||
#include <ShObjIdl_core.h>
|
||||
|
||||
#include <winrt/Microsoft.Windows.AppNotifications.h>
|
||||
#include <winrt/Microsoft.Windows.AppNotifications.Builder.h>
|
||||
#include <AppNotificationBuilderUtility.h>
|
||||
#include <WindowsAppRuntime.SelfContained.h>
|
||||
#include <WindowsAppRuntime.VersionInfo.h>
|
||||
|
||||
#define VERIFY_THROWS_HR(expression, hr) \
|
||||
VERIFY_THROWS_SPECIFIC(expression, \
|
||||
winrt::hresult_error, \
|
||||
[&](winrt::hresult_error e) -> bool \
|
||||
{ \
|
||||
return (e.code() == hr); \
|
||||
})
|
||||
|
||||
namespace TP = ::Test::Packages;
|
||||
namespace TAEF = ::Test::TAEF;
|
||||
#endif //PCH_H
|
|
@ -94,6 +94,16 @@
|
|||
<ActivatableClass ActivatableClassId="Microsoft.Windows.Security.AccessControl.SecurityDescriptorHelpers" ThreadingModel="both" />
|
||||
</InProcessServer>
|
||||
</Extension>
|
||||
<Extension Category="windows.activatableClass.inProcessServer">
|
||||
<InProcessServer>
|
||||
<Path>Microsoft.WindowsAppRuntime.dll</Path>
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Windows.AppNotifications.Builder.AppNotificationBuilder" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Windows.AppNotifications.Builder.AppNotificationTextProperties" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Windows.AppNotifications.Builder.AppNotificationButton" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Windows.AppNotifications.Builder.AppNotificationProgressBar" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="Microsoft.Windows.AppNotifications.Builder.AppNotificationComboBox" ThreadingModel="both" />
|
||||
</InProcessServer>
|
||||
</Extension>
|
||||
<Extension Category="windows.activatableClass.inProcessServer">
|
||||
<InProcessServer>
|
||||
<Path>Microsoft.WindowsAppRuntime.dll</Path>
|
||||
|
|
|
@ -211,6 +211,11 @@
|
|||
<IsWinMDFile>true</IsWinMDFile>
|
||||
<Implementation>$(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.WindowsAppRuntime.dll</Implementation>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Windows.AppNotifications.Builder">
|
||||
<HintPath>$(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.AppNotifications.Builder.winmd</HintPath>
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
<Implementation>$(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.WindowsAppRuntime.dll</Implementation>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\dev\WindowsAppRuntime_BootstrapDLL\WindowsAppRuntime_BootstrapDLL.vcxproj">
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace winrt
|
|||
using namespace winrt::Microsoft::Windows::AppLifecycle;
|
||||
using namespace winrt::Microsoft::Windows::PushNotifications;
|
||||
using namespace winrt::Microsoft::Windows::AppNotifications;
|
||||
using namespace winrt::Microsoft::Windows::AppNotifications::Builder;
|
||||
using namespace winrt::Windows::ApplicationModel::Activation;
|
||||
using namespace winrt::Windows::ApplicationModel::Background; // BackgroundTask APIs
|
||||
using namespace winrt::Windows::Foundation;
|
||||
|
@ -124,7 +125,9 @@ bool PostToastHelper(std::wstring const& tag, std::wstring const& group)
|
|||
toast.Tag(tag.c_str());
|
||||
toast.Group(group.c_str());
|
||||
|
||||
winrt::AppNotificationManager::Default().Show(toast);
|
||||
auto builder{ winrt::AppNotificationBuilder().AddArgument(L"key", L"value").AddArgument(L"key", L"value").SetTag(tag.c_str()).SetGroup(group.c_str())};
|
||||
|
||||
winrt::AppNotificationManager::Default().Show(builder.BuildNotification());
|
||||
|
||||
if (toast.Id() == 0)
|
||||
{
|
||||
|
@ -170,11 +173,11 @@ int main()
|
|||
winrt::event_token token = appNotificationManager.NotificationInvoked([](const auto&, winrt::AppNotificationActivatedEventArgs const& toastArgs)
|
||||
{
|
||||
std::wcout << L"AppNotification received foreground!\n";
|
||||
winrt::hstring arguments{ toastArgs.Argument() };
|
||||
std::wcout << arguments.c_str() << L"\n\n";
|
||||
winrt::hstring argument{ toastArgs.Argument() };
|
||||
std::wcout << argument.c_str() << L"\n\n";
|
||||
|
||||
winrt::IMap<winrt::hstring, winrt::hstring> userInput{ toastArgs.UserInput() };
|
||||
for (auto pair : userInput)
|
||||
winrt::IMap<winrt::hstring, winrt::hstring> arguments{ toastArgs.Arguments() };
|
||||
for (auto pair : arguments)
|
||||
{
|
||||
std::wcout << "Key= " << pair.Key().c_str() << " " << "Value= " << pair.Value().c_str() << L"\n";
|
||||
}
|
||||
|
@ -200,11 +203,11 @@ int main()
|
|||
{
|
||||
std::wcout << L"Activated by AppNotification from background.\n";
|
||||
winrt::AppNotificationActivatedEventArgs appNotificationArgs{ args.Data().as<winrt::AppNotificationActivatedEventArgs>() };
|
||||
winrt::hstring arguments{ appNotificationArgs.Argument() };
|
||||
std::wcout << arguments.c_str() << std::endl << std::endl;
|
||||
winrt::hstring argument{ appNotificationArgs.Argument() };
|
||||
std::wcout << argument.c_str() << std::endl << std::endl;
|
||||
|
||||
winrt::IMap<winrt::hstring, winrt::hstring> userInput = appNotificationArgs.UserInput();
|
||||
for (auto pair : userInput)
|
||||
winrt::IMap<winrt::hstring, winrt::hstring> arguments = appNotificationArgs.Arguments();
|
||||
for (auto pair : arguments)
|
||||
{
|
||||
std::wcout << "Key= " << pair.Key().c_str() << " " << "Value= " << pair.Value().c_str() << L"\n";
|
||||
}
|
||||
|
|
|
@ -17,3 +17,4 @@
|
|||
#include <winrt/Microsoft.Windows.AppLifecycle.h>
|
||||
#include <winrt/Microsoft.Windows.PushNotifications.h>
|
||||
#include <winrt/Microsoft.Windows.AppNotifications.h>
|
||||
#include <winrt/Microsoft.Windows.AppNotifications.Builder.h>
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace winrt
|
|||
const std::wstring c_localWindowsAppSDKFolder{ LR"(\Microsoft\WindowsAppSDK\)" };
|
||||
const std::wstring c_pngExtension{ LR"(.png)" };
|
||||
const std::wstring c_appUserModelId{ LR"(TaefTestAppId)" };
|
||||
const std::wstring c_iconFilepath{ std::filesystem::current_path() / "icon1.ico" };
|
||||
|
||||
bool BackgroundActivationTest() // Activating application for background test.
|
||||
{
|
||||
|
@ -1327,6 +1328,122 @@ bool VerifyIconPathExists_Unpackaged()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool VerifyRegisterWithNullDisplayNameFail_Unpackaged()
|
||||
{
|
||||
// Register is already called in main with an explicit appusermodelId
|
||||
winrt::AppNotificationManager::Default().UnregisterAll();
|
||||
try
|
||||
{
|
||||
winrt::AppNotificationManager::Default().Register(winrt::hstring{}, winrt::Uri{ c_iconFilepath });
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return winrt::to_hresult() == E_INVALIDARG;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VerifyRegisterWithNullIconFail_Unpackaged()
|
||||
{
|
||||
// Register is already called in main with an explicit appusermodelId
|
||||
winrt::AppNotificationManager::Default().UnregisterAll();
|
||||
try
|
||||
{
|
||||
winrt::AppNotificationManager::Default().Register(L"AppNotificationApp", nullptr);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return winrt::to_hresult() == E_INVALIDARG;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VerifyRegisterWithNullDisplayNameAndNullIconFail_Unpackaged()
|
||||
{
|
||||
// Register is already called in main with an explicit appusermodelId
|
||||
winrt::AppNotificationManager::Default().UnregisterAll();
|
||||
try
|
||||
{
|
||||
winrt::AppNotificationManager::Default().Register(winrt::hstring{}, nullptr);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return winrt::to_hresult() == E_INVALIDARG;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VerifyShowToastWithCustomDisplayNameAndIcon_Unpackaged()
|
||||
{
|
||||
// Register is already called in main with an explicit appusermodelId
|
||||
winrt::AppNotificationManager::Default().UnregisterAll();
|
||||
try
|
||||
{
|
||||
winrt::AppNotificationManager::Default().Register(L"AppNotificationApp", winrt::Uri{ c_iconFilepath });
|
||||
|
||||
winrt::check_bool(VerifyShowToast_Unpackaged());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VerifyRegisterWithDisplayNameAndInvalidIconPathFail_Unpackaged()
|
||||
{
|
||||
// Register is already called in main with an explicit appusermodelId
|
||||
winrt::AppNotificationManager::Default().UnregisterAll();
|
||||
try
|
||||
{
|
||||
winrt::AppNotificationManager::Default().Register(L"AppNotificationApp", winrt::Uri{ LR"(C:\InvalidPath\)" });
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return winrt::to_hresult() == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VerifyRegisterWithEmptyDisplayNameFail_Unpackaged()
|
||||
{
|
||||
// Register is already called in main with an explicit appusermodelId
|
||||
winrt::AppNotificationManager::Default().UnregisterAll();
|
||||
try
|
||||
{
|
||||
// hstring treats L"" as assigning nullptr
|
||||
winrt::AppNotificationManager::Default().Register(L"", winrt::Uri{ c_iconFilepath });
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return winrt::to_hresult() == E_INVALIDARG;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VerifyRegisterWithAssetsFail()
|
||||
{
|
||||
// Register is already called in main with an explicit appusermodelId
|
||||
winrt::AppNotificationManager::Default().UnregisterAll();
|
||||
try
|
||||
{
|
||||
// API fails for Packaged Scenario
|
||||
winrt::AppNotificationManager::Default().Register(L"AppNotificationApp", winrt::Uri{ LR"(C:\InvalidPath\)" });
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return winrt::to_hresult() == E_ILLEGAL_METHOD_CALL;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<std::string, bool(*)()> const& GetSwitchMapping()
|
||||
{
|
||||
static std::map<std::string, bool(*)()> switchMapping = {
|
||||
|
@ -1385,6 +1502,14 @@ std::map<std::string, bool(*)()> const& GetSwitchMapping()
|
|||
{ "VerifyToastProgressDataSequence0Fail", &VerifyToastProgressDataSequence0Fail },
|
||||
{ "VerifyToastUpdateZeroSequenceFail_Unpackaged", &VerifyToastUpdateZeroSequenceFail_Unpackaged },
|
||||
{ "VerifyIconPathExists_Unpackaged", &VerifyIconPathExists_Unpackaged},
|
||||
|
||||
{ "VerifyRegisterWithNullDisplayNameFail_Unpackaged", &VerifyRegisterWithNullDisplayNameFail_Unpackaged},
|
||||
{ "VerifyRegisterWithNullIconFail_Unpackaged", &VerifyRegisterWithNullIconFail_Unpackaged},
|
||||
{ "VerifyRegisterWithNullDisplayNameAndNullIconFail_Unpackaged", &VerifyRegisterWithNullDisplayNameAndNullIconFail_Unpackaged},
|
||||
{ "VerifyShowToastWithCustomDisplayNameAndIcon_Unpackaged", &VerifyShowToastWithCustomDisplayNameAndIcon_Unpackaged},
|
||||
{ "VerifyRegisterWithDisplayNameAndInvalidIconPathFail_Unpackaged", &VerifyRegisterWithDisplayNameAndInvalidIconPathFail_Unpackaged},
|
||||
{ "VerifyRegisterWithEmptyDisplayNameFail_Unpackaged", &VerifyRegisterWithEmptyDisplayNameFail_Unpackaged},
|
||||
{ "VerifyRegisterWithAssetsFail", &VerifyRegisterWithAssetsFail},
|
||||
};
|
||||
|
||||
return switchMapping;
|
||||
|
|
|
@ -586,5 +586,40 @@ namespace Test::ToastNotifications
|
|||
{
|
||||
RunTestUnpackaged(L"VerifyIconPathExists_Unpackaged", testWaitTime());
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyRegisterWithNullDisplayNameFail_Unpackaged)
|
||||
{
|
||||
RunTestUnpackaged(L"VerifyRegisterWithNullDisplayNameFail_Unpackaged", testWaitTime());
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyRegisterWithNullIconFail_Unpackaged)
|
||||
{
|
||||
RunTestUnpackaged(L"VerifyRegisterWithNullIconFail_Unpackaged", testWaitTime());
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyRegisterWithNullDisplayNameAndNullIconFail_Unpackaged)
|
||||
{
|
||||
RunTestUnpackaged(L"VerifyRegisterWithNullDisplayNameAndNullIconFail_Unpackaged", testWaitTime());
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyShowToastWithCustomDisplayNameAndIcon_Unpackaged)
|
||||
{
|
||||
RunTestUnpackaged(L"VerifyShowToastWithCustomDisplayNameAndIcon_Unpackaged", testWaitTime());
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyRegisterWithDisplayNameAndInvalidIconPathFail_Unpackaged)
|
||||
{
|
||||
RunTestUnpackaged(L"VerifyRegisterWithDisplayNameAndInvalidIconPathFail_Unpackaged", testWaitTime());
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyRegisterWithEmptyDisplayNameFail_Unpackaged)
|
||||
{
|
||||
RunTestUnpackaged(L"VerifyRegisterWithEmptyDisplayNameFail_Unpackaged", testWaitTime());
|
||||
}
|
||||
|
||||
TEST_METHOD(VerifyRegisterWithAssetsFail)
|
||||
{
|
||||
RunTest(L"VerifyRegisterWithAssetsFail", testWaitTime());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|