diff --git a/DFAssist.Core/DFAssist.Core.csproj b/DFAssist.Core/DFAssist.Core.csproj
index a2ea2b0..97d9129 100644
--- a/DFAssist.Core/DFAssist.Core.csproj
+++ b/DFAssist.Core/DFAssist.Core.csproj
@@ -10,6 +10,7 @@
DFAssist.Core
DFAssist.Core
v4.7.2
+ 10.0.10240.0
512
true
@@ -57,9 +58,12 @@
+
+
+
@@ -77,10 +81,17 @@
-
Properties\SharedAssemblyInfo.cs
+
+
+
+
+
+
+
+
diff --git a/DFAssist.Core/Toast/Base/DesktopBridgeHelpers.cs b/DFAssist.Core/Toast/Base/DesktopBridgeHelpers.cs
new file mode 100644
index 0000000..b4848a8
--- /dev/null
+++ b/DFAssist.Core/Toast/Base/DesktopBridgeHelpers.cs
@@ -0,0 +1,70 @@
+// ******************************************************************
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the MIT License (MIT).
+// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
+// ******************************************************************
+
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace DFAssist.Core.Toast.Base
+{
+ ///
+ /// Code from https://github.com/qmatteoq/DesktopBridgeHelpers/edit/master/DesktopBridge.Helpers/Helpers.cs
+ ///
+ public static class DesktopBridgeHelpers
+ {
+ // ReSharper disable InconsistentNaming
+ // ReSharper disable ArrangeTypeMemberModifiers
+ const long APPMODEL_ERROR_NO_PACKAGE = 15700L;
+ // ReSharper restore ArrangeTypeMemberModifiers
+ // ReSharper restore InconsistentNaming
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
+ private static extern int GetCurrentPackageFullName(ref int packageFullNameLength, StringBuilder packageFullName);
+
+ private static bool? _isRunningAsUwp;
+ public static bool IsRunningAsUwp()
+ {
+ if (_isRunningAsUwp != null)
+ return _isRunningAsUwp.Value;
+
+ if (IsWindows7OrLower)
+ {
+ _isRunningAsUwp = false;
+ }
+ else
+ {
+ var length = 0;
+ var sb = new StringBuilder(0);
+ // ReSharper disable RedundantAssignment
+ var result = GetCurrentPackageFullName(ref length, sb);
+ // ReSharper restore RedundantAssignment
+ sb = new StringBuilder(length);
+ result = GetCurrentPackageFullName(ref length, sb);
+
+ _isRunningAsUwp = result != APPMODEL_ERROR_NO_PACKAGE;
+ }
+
+ return _isRunningAsUwp.Value;
+ }
+
+ private static bool IsWindows7OrLower
+ {
+ get
+ {
+ var versionMajor = Environment.OSVersion.Version.Major;
+ var versionMinor = Environment.OSVersion.Version.Minor;
+ var version = versionMajor + (double)versionMinor / 10;
+ return version <= 6.1;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DFAssist.Core/Toast/Base/DesktopNotificationHistoryCompat.cs b/DFAssist.Core/Toast/Base/DesktopNotificationHistoryCompat.cs
new file mode 100644
index 0000000..341995c
--- /dev/null
+++ b/DFAssist.Core/Toast/Base/DesktopNotificationHistoryCompat.cs
@@ -0,0 +1,98 @@
+// ******************************************************************
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the MIT License (MIT).
+// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
+// ******************************************************************
+
+using Windows.UI.Notifications;
+
+namespace DFAssist.Core.Toast.Base
+{
+ ///
+ /// Manages the toast notifications for an app including the ability the clear all toast history and removing individual toasts.
+ ///
+ public sealed class DesktopNotificationHistoryCompat
+ {
+ private readonly string _aumid;
+ private readonly ToastNotificationHistory _history;
+
+ ///
+ /// Do not call this. Instead, call to obtain an instance.
+ ///
+ internal DesktopNotificationHistoryCompat(string aumid)
+ {
+ _aumid = aumid;
+ _history = ToastNotificationManager.History;
+ }
+
+ ///
+ /// Removes all notifications sent by this app from action center.
+ ///
+ public void Clear()
+ {
+ if (_aumid != null)
+ {
+ _history.Clear(_aumid);
+ }
+ else
+ {
+ _history.Clear();
+ }
+ }
+
+ ///
+ /// Removes an individual toast, with the specified tag label, from action center.
+ ///
+ /// The tag label of the toast notification to be removed.
+ public void Remove(string tag)
+ {
+ if (_aumid != null)
+ {
+ _history.Remove(tag, string.Empty, _aumid);
+ }
+ else
+ {
+ _history.Remove(tag);
+ }
+ }
+
+ ///
+ /// Removes a toast notification from the action using the notification's tag and group labels.
+ ///
+ /// The tag label of the toast notification to be removed.
+ /// The group label of the toast notification to be removed.
+ public void Remove(string tag, string group)
+ {
+ if (_aumid != null)
+ {
+ _history.Remove(tag, group, _aumid);
+ }
+ else
+ {
+ _history.Remove(tag, group);
+ }
+ }
+
+ ///
+ /// Removes a group of toast notifications, identified by the specified group label, from action center.
+ ///
+ /// The group label of the toast notifications to be removed.
+ public void RemoveGroup(string group)
+ {
+ if (_aumid != null)
+ {
+ _history.RemoveGroup(group, _aumid);
+ }
+ else
+ {
+ _history.RemoveGroup(group);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DFAssist.Core/Toast/Base/DesktopNotificationManagerCompat.cs b/DFAssist.Core/Toast/Base/DesktopNotificationManagerCompat.cs
new file mode 100644
index 0000000..4faa368
--- /dev/null
+++ b/DFAssist.Core/Toast/Base/DesktopNotificationManagerCompat.cs
@@ -0,0 +1,153 @@
+// ******************************************************************
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the MIT License (MIT).
+// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
+// ******************************************************************
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using Windows.UI.Notifications;
+
+namespace DFAssist.Core.Toast.Base
+{
+ public class DesktopNotificationManagerCompat
+ {
+ // ReSharper disable InconsistentNaming
+ public const string TOAST_ACTIVATED_LAUNCH_ARG = "-ToastActivated";
+ // ReSharper restore InconsistentNaming
+
+ private static bool _registeredAumidAndComServer;
+ private static string _aumid;
+ private static bool _registeredActivator;
+
+ ///
+ /// If not running under the Desktop Bridge, you must call this method to register your AUMID with the Compat library and to
+ /// register your COM CLSID and EXE in LocalServer32 registry. Feel free to call this regardless, and we will no-op if running
+ /// under Desktop Bridge. Call this upon application startup, before calling any other APIs.
+ ///
+ /// An AUMID that uniquely identifies your application.
+ public static void RegisterAumidAndComServer(string aumid)
+ where T : NotificationActivator
+ {
+ if (string.IsNullOrWhiteSpace(aumid))
+ {
+ throw new ArgumentException("You must provide an AUMID.", nameof(aumid));
+ }
+
+ // If running as Desktop Bridge
+ if (DesktopBridgeHelpers.IsRunningAsUwp())
+ {
+ // Clear the AUMID since Desktop Bridge doesn't use it, and then we're done.
+ // Desktop Bridge apps are registered with platform through their manifest.
+ // Their LocalServer32 key is also registered through their manifest.
+ _aumid = null;
+ _registeredAumidAndComServer = true;
+ return;
+ }
+
+ _aumid = aumid;
+
+ var exePath = Process.GetCurrentProcess().MainModule?.FileName;
+ RegisterComServer(exePath);
+
+ _registeredAumidAndComServer = true;
+ }
+
+ private static void RegisterComServer(string exePath)
+ where T : NotificationActivator
+ {
+ // We register the EXE to start up when the notification is activated
+ var regString = $"SOFTWARE\\Classes\\CLSID\\{{{typeof(T).GUID}}}\\LocalServer32";
+ var key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(regString);
+
+ // Include a flag so we know this was a toast activation and should wait for COM to process
+ // We also wrap EXE path in quotes for extra security
+ key?.SetValue(null, '"' + exePath + '"' + " " + TOAST_ACTIVATED_LAUNCH_ARG);
+ }
+
+ ///
+ /// Registers the activator type as a COM server client so that Windows can launch your activator.
+ ///
+ /// Your implementation of NotificationActivator. Must have GUID and ComVisible attributes on class.
+ public static void RegisterActivator()
+ where T : NotificationActivator
+ {
+ // Register type
+ var regService = new RegistrationServices();
+
+ regService.RegisterTypeForComClients(
+ typeof(T),
+ RegistrationClassContext.LocalServer,
+ RegistrationConnectionType.MultipleUse);
+
+ _registeredActivator = true;
+ }
+
+ ///
+ /// Creates a toast notifier. You must have called first (and also if you're a classic Win32 app), or this will throw an exception.
+ ///
+ ///
+ public static ToastNotifier CreateToastNotifier()
+ {
+ EnsureRegistered();
+
+ return _aumid != null
+ ? ToastNotificationManager.CreateToastNotifier(_aumid) // non Desktop-Bridge
+ : ToastNotificationManager.CreateToastNotifier();
+ }
+
+ ///
+ /// Gets the object. You must have called first (and also if you're a classic Win32 app), or this will throw an exception.
+ ///
+ public static DesktopNotificationHistoryCompat History
+ {
+ get
+ {
+ EnsureRegistered();
+
+ return new DesktopNotificationHistoryCompat(_aumid);
+ }
+ }
+
+ private static void EnsureRegistered()
+ {
+ // If not registered AUMID yet
+ if (!_registeredAumidAndComServer)
+ {
+ // Check if Desktop Bridge
+ if (DesktopBridgeHelpers.IsRunningAsUwp())
+ {
+ // Implicitly registered, all good!
+ _registeredAumidAndComServer = true;
+ }
+
+ else
+ {
+ // Otherwise, incorrect usage
+ throw new Exception("You must call RegisterAumidAndComServer first.");
+ }
+ }
+
+ // If not registered activator yet
+ if (!_registeredActivator)
+ {
+ // Incorrect usage
+ throw new Exception("You must call RegisterActivator first.");
+ }
+ }
+
+ ///
+ /// Gets a boolean representing whether http images can be used within toasts. This is true if running under Desktop Bridge.
+ ///
+ // ReSharper disable UnusedMember.Global
+ public static bool CanUseHttpImages => DesktopBridgeHelpers.IsRunningAsUwp();
+ // ReSharper restore UnusedMember.Global
+ }
+}
\ No newline at end of file
diff --git a/DFAssist.Core/Toast/Base/INotificationActivationCallback.cs b/DFAssist.Core/Toast/Base/INotificationActivationCallback.cs
new file mode 100644
index 0000000..f91f83b
--- /dev/null
+++ b/DFAssist.Core/Toast/Base/INotificationActivationCallback.cs
@@ -0,0 +1,44 @@
+// ******************************************************************
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the MIT License (MIT).
+// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
+// ******************************************************************
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace DFAssist.Core.Toast.Base
+{
+ [StructLayout(LayoutKind.Sequential), Serializable]
+ // ReSharper disable InconsistentNaming
+ public struct NOTIFICATION_USER_INPUT_DATA
+
+ {
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string Key;
+
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string Value;
+ }
+ // ReSharper restore InconsistentNaming
+
+ [ComImport, Guid("53E31837-6600-4A81-9395-75CFFE746F94"), ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ public interface INotificationActivationCallback
+ {
+ void Activate(
+ [In, MarshalAs(UnmanagedType.LPWStr)]
+ string appUserModelId,
+ [In, MarshalAs(UnmanagedType.LPWStr)]
+ string invokedArgs,
+ [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]
+ NOTIFICATION_USER_INPUT_DATA[] data,
+ [In, MarshalAs(UnmanagedType.U4)]
+ uint dataCount);
+ }
+}
\ No newline at end of file
diff --git a/DFAssist.Core/Toast/Base/NotificationActivator.cs b/DFAssist.Core/Toast/Base/NotificationActivator.cs
new file mode 100644
index 0000000..5364640
--- /dev/null
+++ b/DFAssist.Core/Toast/Base/NotificationActivator.cs
@@ -0,0 +1,33 @@
+// ******************************************************************
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the MIT License (MIT).
+// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
+// ******************************************************************
+
+namespace DFAssist.Core.Toast.Base
+{
+ ///
+ /// Apps must implement this activator to handle notification activation.
+ ///
+ public abstract class NotificationActivator : INotificationActivationCallback
+ {
+ public void Activate(string appUserModelId, string invokedArgs, NOTIFICATION_USER_INPUT_DATA[] data, uint dataCount)
+ {
+ OnActivated(invokedArgs, new NotificationUserInput(data), appUserModelId);
+ }
+
+ ///
+ /// This method will be called when the user clicks on a foreground or background activation on a toast. Parent app must implement this method.
+ ///
+ /// The arguments from the original notification. This is either the launch argument if the user clicked the body of your toast, or the arguments from a button on your toast.
+ /// Text and selection values that the user entered in your toast.
+ /// Your AUMID.
+ public abstract void OnActivated(string arguments, NotificationUserInput userInput, string appUserModelId);
+ }
+}
\ No newline at end of file
diff --git a/DFAssist.Core/Toast/Base/NotificationUserInput.cs b/DFAssist.Core/Toast/Base/NotificationUserInput.cs
new file mode 100644
index 0000000..26fe07b
--- /dev/null
+++ b/DFAssist.Core/Toast/Base/NotificationUserInput.cs
@@ -0,0 +1,69 @@
+// ******************************************************************
+// Copyright (c) Microsoft. All rights reserved.
+// This code is licensed under the MIT License (MIT).
+// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
+// ******************************************************************
+
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace DFAssist.Core.Toast.Base
+{
+ ///
+ /// Text and selection values that the user entered on your notification. The Key is the ID of the input, and the Value is what the user entered.
+ ///
+ public class NotificationUserInput : IReadOnlyDictionary
+ {
+ private readonly NOTIFICATION_USER_INPUT_DATA[] _data;
+
+ internal NotificationUserInput(NOTIFICATION_USER_INPUT_DATA[] data)
+ {
+ _data = data;
+ }
+
+ public string this[string key] => _data.First(i => i.Key == key).Value;
+
+ public IEnumerable Keys => _data.Select(i => i.Key);
+
+ public IEnumerable Values => _data.Select(i => i.Value);
+
+ public int Count => _data.Length;
+
+ public bool ContainsKey(string key)
+ {
+ return _data.Any(i => i.Key == key);
+ }
+
+ public IEnumerator> GetEnumerator()
+ {
+ return _data.Select(i => new KeyValuePair(i.Key, i.Value)).GetEnumerator();
+ }
+
+ public bool TryGetValue(string key, out string value)
+ {
+ foreach (var item in _data)
+ {
+ if (item.Key == key)
+ {
+ value = item.Value;
+ return true;
+ }
+ }
+
+ value = null;
+ return false;
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+ }
+}
\ No newline at end of file
diff --git a/DFAssist.Core/Toast/ToastManager.cs b/DFAssist.Core/Toast/ToastManager.cs
new file mode 100644
index 0000000..e682b61
--- /dev/null
+++ b/DFAssist.Core/Toast/ToastManager.cs
@@ -0,0 +1,48 @@
+using System;
+using Windows.Data.Xml.Dom;
+using Windows.UI.Notifications;
+using DFAssist.Core.Toast.Base;
+using Splat;
+
+namespace DFAssist.Core.Toast
+{
+ public class ToastManager
+ {
+ public static void ShowToast(string title, string message, string testing = null)
+ {
+ var logger = Locator.Current.GetService();
+ try
+ {
+ if (!string.IsNullOrWhiteSpace(testing))
+ testing = $"\nCode [{testing}]";
+
+ var toastXmlString =
+ $@"
+
+
+ {title}
+ {message}
+ {testing}
+ DFAssist
+
+
+ "
+ .Replace("\r\n", string.Empty)
+ .Replace("\t", string.Empty);
+
+ var xmlDoc = new XmlDocument();
+ xmlDoc.LoadXml(toastXmlString);
+ var toast = new ToastNotification(xmlDoc);
+
+ var toastNotifier = DesktopNotificationManagerCompat.CreateToastNotifier();
+ toastNotifier.Show(toast);
+ logger.Write("UI: Toast Showing!", LogLevel.Debug);
+ }
+ catch (Exception e)
+ {
+ logger.Write(e, "UI: Unable to show the toast...", LogLevel.Error);
+ throw;
+ }
+ }
+ }
+}
diff --git a/DFAssist.Core/Toast/ToastNotificationActivator.cs b/DFAssist.Core/Toast/ToastNotificationActivator.cs
new file mode 100644
index 0000000..6938053
--- /dev/null
+++ b/DFAssist.Core/Toast/ToastNotificationActivator.cs
@@ -0,0 +1,18 @@
+using System.Runtime.InteropServices;
+using DFAssist.Core.Toast.Base;
+using Splat;
+
+namespace DFAssist.Core.Toast
+{
+ [ClassInterface(ClassInterfaceType.None)]
+ [ComSourceInterfaces(typeof(INotificationActivationCallback))]
+ [Guid("67d5ccfb-c77f-4a77-a37d-ecce57279150"), ComVisible(true)]
+ public class ToastNotificationActivator : NotificationActivator
+ {
+ public override void OnActivated(string invokedArgs, NotificationUserInput userInput, string appUserModelId)
+ {
+ var logger = Locator.Current.GetService();
+ logger.Write("UI: Toast Activated...", LogLevel.Debug);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DFAssist.Core/Toast/WinToastWrapper.cs b/DFAssist.Core/Toast/WinToastWrapper.cs
deleted file mode 100644
index 334f6a5..0000000
--- a/DFAssist.Core/Toast/WinToastWrapper.cs
+++ /dev/null
@@ -1,150 +0,0 @@
-using System;
-using System.IO;
-using System.Runtime.InteropServices;
-
-namespace DFAssist.Core.Toast
-{
- public enum Duration
- {
- // ReSharper disable InconsistentNaming
- // ReSharper disable UnusedMember.Global
- System = 0,
- Short,
- Long
- // ReSharper restore UnusedMember.Global
- // ReSharper restore InconsistentNaming
- };
-
- public enum AudioOption
- {
- // ReSharper disable InconsistentNaming
- // ReSharper disable UnusedMember.Global
- Default = 0,
- Silent,
- Loop
- // ReSharper restore UnusedMember.Global
- // ReSharper restore InconsistentNaming
- };
-
- public enum AudioSystemFile
- {
- // ReSharper disable InconsistentNaming
- // ReSharper disable UnusedMember.Global
- DefaultSound = 0,
- IM,
- Mail,
- Reminder,
- SMS,
- Alarm,
- Alarm2,
- Alarm3,
- Alarm4,
- Alarm5,
- Alarm6,
- Alarm7,
- Alarm8,
- Alarm9,
- Alarm10,
- Call,
- Call1,
- Call2,
- Call3,
- Call4,
- Call5,
- Call6,
- Call7,
- Call8,
- Call9,
- Call10,
- // ReSharper restore UnusedMember.Global
- // ReSharper restore InconsistentNaming
- };
-
- public static class WinToastWrapper
- {
- private const string DllFilePath = "DFAssist.WinToast.dll";
-
- [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- public static extern bool SetDllDirectory(string lpPathName);
-
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate void ToastEventCallback(int messageCode);
-
- [DllImport(DllFilePath, EntryPoint = "CreateToast_Text01", ExactSpelling = true)]
- public static extern void CreateToast(
- [MarshalAs(UnmanagedType.LPWStr)]string appName,
- [MarshalAs(UnmanagedType.LPWStr)]string appUserModelId,
- [MarshalAs(UnmanagedType.LPWStr)]string toastMessage,
- [MarshalAs(UnmanagedType.FunctionPtr)]ToastEventCallback eventCallback,
- [MarshalAs(UnmanagedType.LPWStr)]string attribution = null,
- [MarshalAs(UnmanagedType.I4)]Duration duration = Duration.System,
- [MarshalAs(UnmanagedType.I4)]AudioSystemFile audioFile = AudioSystemFile.DefaultSound,
- [MarshalAs(UnmanagedType.I4)]AudioOption audioOption = AudioOption.Default);
-
- [DllImport(DllFilePath, EntryPoint = "CreateToast_Text02", ExactSpelling = true)]
- public static extern void CreateToast(
- [MarshalAs(UnmanagedType.LPWStr)]string appName,
- [MarshalAs(UnmanagedType.LPWStr)]string appUserModelId,
- [MarshalAs(UnmanagedType.LPWStr)]string toastTitle,
- [MarshalAs(UnmanagedType.LPWStr)]string toastMessage,
- [MarshalAs(UnmanagedType.FunctionPtr)]ToastEventCallback eventCallback,
- [MarshalAs(UnmanagedType.LPWStr)]string attribution = null,
- bool wrapFirstLine = true,
- [MarshalAs(UnmanagedType.I4)]Duration duration = Duration.System,
- [MarshalAs(UnmanagedType.I4)]AudioSystemFile audioFile = AudioSystemFile.DefaultSound,
- [MarshalAs(UnmanagedType.I4)]AudioOption audioOption = AudioOption.Default);
-
- [DllImport(DllFilePath, EntryPoint = "CreateToast_Text03", ExactSpelling = true)]
- public static extern void CreateToast(
- [MarshalAs(UnmanagedType.LPWStr)]string appName,
- [MarshalAs(UnmanagedType.LPWStr)]string appUserModelId,
- [MarshalAs(UnmanagedType.LPWStr)]string toastTitle,
- [MarshalAs(UnmanagedType.LPWStr)]string toastMessage,
- [MarshalAs(UnmanagedType.LPWStr)]string toastAdditionalMessage,
- [MarshalAs(UnmanagedType.FunctionPtr)]ToastEventCallback eventCallback,
- [MarshalAs(UnmanagedType.LPWStr)]string attribution = null,
- [MarshalAs(UnmanagedType.I4)]Duration duration = Duration.System,
- [MarshalAs(UnmanagedType.I4)]AudioSystemFile audioFile = AudioSystemFile.DefaultSound,
- [MarshalAs(UnmanagedType.I4)]AudioOption audioOption = AudioOption.Default);
-
- [DllImport(DllFilePath, EntryPoint = "CreateToast_ImageAndText01", ExactSpelling = true)]
- public static extern void CreateToast(
- [MarshalAs(UnmanagedType.LPWStr)]string appName,
- [MarshalAs(UnmanagedType.LPWStr)]string appUserModelId,
- [MarshalAs(UnmanagedType.LPWStr)]string toastMessage,
- [MarshalAs(UnmanagedType.LPWStr)]string toastImagePath,
- [MarshalAs(UnmanagedType.FunctionPtr)]ToastEventCallback eventCallback,
- [MarshalAs(UnmanagedType.LPWStr)]string attribution = null,
- [MarshalAs(UnmanagedType.I4)]Duration duration = Duration.System,
- [MarshalAs(UnmanagedType.I4)]AudioSystemFile audioFile = AudioSystemFile.DefaultSound,
- [MarshalAs(UnmanagedType.I4)]AudioOption audioOption = AudioOption.Default);
-
- [DllImport(DllFilePath, EntryPoint = "CreateToast_ImageAndText02", ExactSpelling = true)]
- public static extern void CreateToast(
- [MarshalAs(UnmanagedType.LPWStr)]string appName,
- [MarshalAs(UnmanagedType.LPWStr)]string appUserModelId,
- [MarshalAs(UnmanagedType.LPWStr)]string toastTitle,
- [MarshalAs(UnmanagedType.LPWStr)]string toastMessage,
- [MarshalAs(UnmanagedType.LPWStr)]string toastImagePath,
- [MarshalAs(UnmanagedType.FunctionPtr)]ToastEventCallback eventCallback,
- [MarshalAs(UnmanagedType.LPWStr)]string attribution = null,
- bool wrapFirstLine = true,
- [MarshalAs(UnmanagedType.I4)]Duration duration = Duration.System,
- [MarshalAs(UnmanagedType.I4)]AudioSystemFile audioFile = AudioSystemFile.DefaultSound,
- [MarshalAs(UnmanagedType.I4)]AudioOption audioOption = AudioOption.Default);
-
- [DllImport(DllFilePath, EntryPoint = "CreateToast_ImageAndText03", ExactSpelling = true)]
- public static extern void CreateToast(
- [MarshalAs(UnmanagedType.LPWStr)]string appName,
- [MarshalAs(UnmanagedType.LPWStr)]string appUserModelId,
- [MarshalAs(UnmanagedType.LPWStr)]string toastTitle,
- [MarshalAs(UnmanagedType.LPWStr)]string toastMessage,
- [MarshalAs(UnmanagedType.LPWStr)]string toastAdditionalMessage,
- [MarshalAs(UnmanagedType.LPWStr)]string toastImagePath,
- [MarshalAs(UnmanagedType.FunctionPtr)]ToastEventCallback eventCallback,
- [MarshalAs(UnmanagedType.LPWStr)]string attribution = null,
- [MarshalAs(UnmanagedType.I4)]Duration duration = Duration.System,
- [MarshalAs(UnmanagedType.I4)]AudioSystemFile audioFile = AudioSystemFile.DefaultSound,
- [MarshalAs(UnmanagedType.I4)]AudioOption audioOption = AudioOption.Default);
- }
-}
diff --git a/DFAssist.Loader/AssemblyResolver.cs b/DFAssist.Loader/AssemblyResolver.cs
index 233eeee..54e8134 100644
--- a/DFAssist.Loader/AssemblyResolver.cs
+++ b/DFAssist.Loader/AssemblyResolver.cs
@@ -110,8 +110,7 @@ private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs a
if (requestingAssemblyName != "DFAssist"
&& requestingAssemblyName != "DFAssist.Plugin"
&& requestingAssemblyName != "DFAssist.Core"
- && requestingAssemblyName != "DFAssist.Contracts"
- && requestingAssemblyName != "DFAssist.WinToast")
+ && requestingAssemblyName != "DFAssist.Contracts")
return null;
var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName == args.Name);
diff --git a/DFAssist.WinToast/DFAssist.WinToast.rc b/DFAssist.WinToast/DFAssist.WinToast.rc
deleted file mode 100644
index 850e337..0000000
Binary files a/DFAssist.WinToast/DFAssist.WinToast.rc and /dev/null differ
diff --git a/DFAssist.WinToast/DFAssist.WinToast.vcxproj b/DFAssist.WinToast/DFAssist.WinToast.vcxproj
deleted file mode 100644
index f262148..0000000
--- a/DFAssist.WinToast/DFAssist.WinToast.vcxproj
+++ /dev/null
@@ -1,181 +0,0 @@
-
-
-
-
- Debug
- Win32
-
-
- Release
- Win32
-
-
- Debug
- x64
-
-
- Release
- x64
-
-
-
- 15.0
- {E20D32F4-26E0-4B7A-B2FE-590FA4867E61}
- Win32Proj
- DFAssistWinToast
- 10.0
-
-
-
- DynamicLibrary
- true
- v142
- Unicode
-
-
- DynamicLibrary
- false
- v142
- true
- Unicode
-
-
- DynamicLibrary
- true
- v142
- Unicode
-
-
- DynamicLibrary
- false
- v142
- true
- Unicode
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- ..\Release\libs\
-
-
- true
-
-
- false
-
-
- false
- ..\Release\libs\
-
-
-
- Use
- Level3
- Disabled
- true
- _DEBUG;DFASSISTWINTOAST_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
- true
-
-
- Windows
- true
- kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;WindowsApp.lib;%(AdditionalDependencies)
- MachineX64
-
-
-
-
- Use
- Level3
- Disabled
- true
- WIN32;_DEBUG;DFASSISTWINTOAST_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
- true
-
-
- Windows
- true
-
-
-
-
- Use
- Level3
- MaxSpeed
- true
- true
- true
- WIN32;NDEBUG;DFASSISTWINTOAST_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
- true
-
-
- Windows
- true
- true
- true
-
-
-
-
- Use
- Level3
- MaxSpeed
- true
- true
- true
- NDEBUG;DFASSISTWINTOAST_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
- true
-
-
- Windows
- true
- true
- true
- kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;WindowsApp.lib;%(AdditionalDependencies)
- UseLinkTimeCodeGeneration
- MachineX64
-
-
-
-
-
-
-
-
-
-
-
-
-
- Create
- Create
- Create
- Create
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/DFAssist.WinToast/DFAssist.WinToast.vcxproj.filters b/DFAssist.WinToast/DFAssist.WinToast.vcxproj.filters
deleted file mode 100644
index 2a72042..0000000
--- a/DFAssist.WinToast/DFAssist.WinToast.vcxproj.filters
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
-
- {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
- cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
-
-
- {93995380-89BD-4b04-88EB-625FBE52EBFB}
- h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
-
-
- {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
-
-
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
-
-
- Resource Files
-
-
-
\ No newline at end of file
diff --git a/DFAssist.WinToast/dllmain.cpp b/DFAssist.WinToast/dllmain.cpp
deleted file mode 100644
index 465ae72..0000000
--- a/DFAssist.WinToast/dllmain.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-// dllmain.cpp : Defines the entry point for the DLL application.
-#include "stdafx.h"
-
-BOOL APIENTRY DllMain( HMODULE hModule,
- DWORD ul_reason_for_call,
- LPVOID lpReserved
- )
-{
- switch (ul_reason_for_call)
- {
- case DLL_PROCESS_ATTACH:
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- case DLL_PROCESS_DETACH:
- break;
- }
- return TRUE;
-}
-
diff --git a/DFAssist.WinToast/resource.h b/DFAssist.WinToast/resource.h
deleted file mode 100644
index 3caecb4..0000000
--- a/DFAssist.WinToast/resource.h
+++ /dev/null
@@ -1,14 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by DFAssist.WinToast.rc
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 101
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1001
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif
diff --git a/DFAssist.WinToast/stdafx.cpp b/DFAssist.WinToast/stdafx.cpp
deleted file mode 100644
index fd4f341..0000000
--- a/DFAssist.WinToast/stdafx.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "stdafx.h"
diff --git a/DFAssist.WinToast/stdafx.h b/DFAssist.WinToast/stdafx.h
deleted file mode 100644
index f380517..0000000
--- a/DFAssist.WinToast/stdafx.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// stdafx.h : include file for standard system include files,
-// or project specific include files that are used frequently, but
-// are changed infrequently
-//
-
-#pragma once
-
-#include "targetver.h"
-
-#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
-// Windows Header Files
-#include
-
-
-
-// reference additional headers your program requires here
diff --git a/DFAssist.WinToast/targetver.h b/DFAssist.WinToast/targetver.h
deleted file mode 100644
index 87c0086..0000000
--- a/DFAssist.WinToast/targetver.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-
-// Including SDKDDKVer.h defines the highest available Windows platform.
-
-// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
-// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
-
-#include
diff --git a/DFAssist.WinToast/version.h b/DFAssist.WinToast/version.h
deleted file mode 100644
index 3c1b8e1..0000000
--- a/DFAssist.WinToast/version.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-#define STRINGIZE2(s) #s
-#define STRINGIZE(s) STRINGIZE2(s)
-
-// versions must be updated manually, based on the version of the main assembly
-#define VERSION_MAJOR 2
-#define VERSION_MINOR 0
-#define VERSION_REVISION 0
-#define VERSION_BUILD 0
-
-#if DEBUG
-#define VER_FILE_DESCRIPTION_STR "Flavor=Debug"
-#else
-#define VER_FILE_DESCRIPTION_STR "Flavor=Retail"
-#endif
-#define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD
-#define VER_FILE_VERSION_STR STRINGIZE(VERSION_MAJOR) \
- "." STRINGIZE(VERSION_MINOR) \
- "." STRINGIZE(VERSION_REVISION) \
- "." STRINGIZE(VERSION_BUILD) \
-
-#define VER_PRODUCTNAME_STR "DFAssist.WinToast"
-#define VER_PRODUCT_VERSION VER_FILE_VERSION
-#define VER_PRODUCT_VERSION_STR VER_FILE_VERSION_STR
-#define VER_ORIGINAL_FILENAME_STR VER_PRODUCTNAME_STR ".dll"
-#define VER_INTERNAL_NAME_STR VER_ORIGINAL_FILENAME_STR
-#define VER_COPYRIGHT_STR "Copyright Carlo Ruggiero (easly1989) 2018/2019"
-
-#ifdef _DEBUG
- #define VER_VER_DEBUG VS_FF_DEBUG
-#else
- #define VER_VER_DEBUG 0
-#endif
-
-#define VER_FILEOS VOS_NT_WINDOWS32
-#define VER_FILEFLAGS VER_VER_DEBUG
-#define VER_FILETYPE VFT_APP
diff --git a/DFAssist.WinToast/wintoastimpl.cpp b/DFAssist.WinToast/wintoastimpl.cpp
deleted file mode 100644
index d528f74..0000000
--- a/DFAssist.WinToast/wintoastimpl.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-#include "stdafx.h"
-#include "wintoastimpl.h"
-#include
-
-using namespace WinToastLib;
-
-class WinToastHandler : public IWinToastHandler {
-public:
-
- explicit WinToastHandler(ToastEventCallback eventCallback)
- {
- m_eventCallback = eventCallback;
- }
-
- void toastActivated() const override
- {
- std::wcout << L"The user clicked in this toast" << std::endl;
- m_eventCallback(0);
- }
-
- void toastActivated(int actionIndex) const override
- {
- std::wcout << L"The user clicked on action #" << actionIndex << std::endl;
- m_eventCallback(16 + actionIndex);
- }
-
- void toastDismissed(WinToastDismissalReason state) const override
- {
- switch (state) {
- case UserCanceled:
- std::wcout << L"The user dismissed this toast" << std::endl;
- m_eventCallback(1);
- break;
- case TimedOut:
- std::wcout << L"The toast has timed out" << std::endl;
- m_eventCallback(2);
- break;
- case ApplicationHidden:
- std::wcout << L"The application hid the toast using ToastNotifier.hide()" << std::endl;
- m_eventCallback(3);
- break;
- default:
- std::wcout << L"Toast not activated" << std::endl;
- m_eventCallback(4);
- break;
- }
- }
-
- void toastFailed() const override
- {
- std::wcout << L"Error showing current toast" << std::endl;
- m_eventCallback(5);
- }
-private:
- ToastEventCallback m_eventCallback;
-};
-
-// -------------------------- Exported methods
-DLLEXPORT void CreateToast_Text01(const wchar_t* appName,
- const wchar_t* appUserModelID,
- const wchar_t* toastMessage,
- ToastEventCallback eventCallback,
- const wchar_t* attribution,
- int duration,
- int audioFile,
- int audioOption)
-{
- CreateToast(
- appName,
- appUserModelID,
- WinToastTemplate::WinToastTemplateType::Text01,
- eventCallback,
- toastMessage,
- nullptr,
- nullptr,
- nullptr,
- attribution,
- static_cast(duration),
- static_cast(audioFile),
- static_cast(audioOption));
-}
-
-DLLEXPORT void CreateToast_Text02(const wchar_t* appName,
- const wchar_t* appUserModelID,
- const wchar_t* toastTitle,
- const wchar_t* toastMessage,
- ToastEventCallback eventCallback,
- const wchar_t* attribution,
- bool wrapFirstLine,
- int duration,
- int audioFile,
- int audioOption)
-{
- CreateToast(
- appName,
- appUserModelID,
- wrapFirstLine ? WinToastTemplate::WinToastTemplateType::Text02 : WinToastTemplate::WinToastTemplateType::Text03,
- eventCallback,
- toastTitle,
- toastMessage,
- nullptr,
- nullptr,
- attribution,
- static_cast(duration),
- static_cast(audioFile),
- static_cast(audioOption));
-}
-
-DLLEXPORT void CreateToast_Text03(const wchar_t* appName,
- const wchar_t* appUserModelID,
- const wchar_t* toastTitle,
- const wchar_t* toastMessage,
- const wchar_t* toastAdditionalMessage,
- ToastEventCallback eventCallback,
- const wchar_t* attribution,
- int duration,
- int audioFile,
- int audioOption)
-{
- CreateToast(
- appName,
- appUserModelID,
- WinToastTemplate::WinToastTemplateType::Text04,
- eventCallback,
- toastTitle,
- toastMessage,
- toastAdditionalMessage,
- nullptr,
- attribution,
- static_cast(duration),
- static_cast(audioFile),
- static_cast(audioOption));
-}
-
-DLLEXPORT void CreateToast_ImageAndText01(const wchar_t* appName,
- const wchar_t* appUserModelID,
- const wchar_t* toastMessage,
- const wchar_t* toastImagePath,
- ToastEventCallback eventCallback,
- const wchar_t* attribution,
- int duration,
- int audioFile,
- int audioOption)
-{
- CreateToast(
- appName,
- appUserModelID,
- WinToastTemplate::WinToastTemplateType::ImageAndText01,
- eventCallback,
- toastMessage,
- nullptr,
- nullptr,
- toastImagePath,
- attribution,
- static_cast(duration),
- static_cast(audioFile),
- static_cast(audioOption));
-}
-
-DLLEXPORT void CreateToast_ImageAndText02(const wchar_t* appName,
- const wchar_t* appUserModelID,
- const wchar_t* toastTitle,
- const wchar_t* toastMessage,
- const wchar_t* toastImagePath,
- ToastEventCallback eventCallback,
- const wchar_t* attribution,
- bool wrapFirstLine,
- int duration,
- int audioFile,
- int audioOption)
-{
- CreateToast(
- appName,
- appUserModelID,
- wrapFirstLine ? WinToastTemplate::WinToastTemplateType::ImageAndText02 : WinToastTemplate::WinToastTemplateType::ImageAndText03,
- eventCallback,
- toastTitle,
- toastMessage,
- nullptr,
- toastImagePath,
- attribution,
- static_cast(duration),
- static_cast(audioFile),
- static_cast(audioOption));
-}
-
-DLLEXPORT void CreateToast_ImageAndText03(const wchar_t* appName,
- const wchar_t* appUserModelID,
- const wchar_t* toastTitle,
- const wchar_t* toastMessage,
- const wchar_t* toastAdditionalMessage,
- const wchar_t* toastImagePath,
- ToastEventCallback eventCallback,
- const wchar_t* attribution,
- int duration,
- int audioFile,
- int audioOption)
-{
- CreateToast(
- appName,
- appUserModelID,
- WinToastTemplate::WinToastTemplateType::ImageAndText04,
- eventCallback,
- toastTitle,
- toastMessage,
- toastAdditionalMessage,
- toastImagePath,
- attribution,
- static_cast(duration),
- static_cast(audioFile),
- static_cast(audioOption));
-}
-
-void CreateToast(const wchar_t* appName,
- const wchar_t* appUserModelID,
- WinToastTemplate::WinToastTemplateType toastTemplate,
- ToastEventCallback eventCallback,
- const wchar_t* toastTitle,
- const wchar_t* toastMessage,
- const wchar_t* toastAdditionlMessage,
- const wchar_t* toastImagePath,
- const wchar_t* attribution,
- WinToastTemplate::Duration duration,
- WinToastTemplate::AudioSystemFile audioFile,
- WinToastTemplate::AudioOption audioOption,
- INT64 expiration,
- bool createShortcut) {
-
- if (!WinToast::isCompatible()) {
- std::wcerr << L"Error, your system in not supported!" << std::endl;
- eventCallback(SystemNotSupported);
- }
-
- WinToast::instance()->setAppName(appName);
- WinToast::instance()->setAppUserModelId(appUserModelID);
-
- if (createShortcut) {
- const auto shortcutResult = WinToast::instance()->createShortcut();
- if (shortcutResult < 0)
- eventCallback(InitializationFailure);
- }
-
- if (!WinToast::instance()->initialize()) {
- std::wcerr << L"Error, your system in not compatible!" << std::endl;
- eventCallback(InitializationFailure);
- }
-
- WinToastTemplate templ(toastTemplate);
-
- if (toastTitle)
- templ.setFirstLine(toastTitle);
- if (toastMessage)
- templ.setSecondLine(toastMessage);
- if (toastAdditionlMessage)
- templ.setThirdLine(toastAdditionlMessage);
- if (duration)
- templ.setDuration(duration);
- if (audioFile)
- templ.setAudioPath(audioFile);
- if (audioOption)
- templ.setAudioOption(audioOption);
- if (attribution)
- templ.setAttributionText(attribution);
- if (toastImagePath)
- templ.setImagePath(toastImagePath);
-
- if (expiration > 0)
- templ.setExpiration(expiration);
-
- if (WinToast::instance()->showToast(templ, new WinToastHandler(eventCallback)) < 0) {
- std::wcerr << L"Could not launch your toast notification!";
- eventCallback(ToastFailed);
- }
-
- eventCallback(AwaitingInteractions);
-}
\ No newline at end of file
diff --git a/DFAssist.WinToast/wintoastimpl.h b/DFAssist.WinToast/wintoastimpl.h
deleted file mode 100644
index 8c0caf7..0000000
--- a/DFAssist.WinToast/wintoastimpl.h
+++ /dev/null
@@ -1,105 +0,0 @@
-#pragma once
-
-#include "wintoastlib.h"
-
-#define DLLEXPORT extern "C" __declspec(dllexport)
-
-using namespace WinToastLib;
-
-typedef void(*ToastEventCallback)(int messageCode);
-
-enum Results {
- ToastClicked, // user clicked on the toast
- ToastDismissed, // user dismissed the toast
- ToastTimeOut, // toast timed out
- ToastHided, // application hid the toast
- ToastNotActivated, // toast was not activated
- ToastFailed, // toast failed
- SystemNotSupported, // system does not support toasts
- UnhandledOption, // unhandled option
- MultipleTextNotSupported, // multiple texts were provided
- InitializationFailure, // toast notification manager initialization failure
- ToastNotLaunched, // toast could not be launched,
- AwaitingInteractions // when the toast is shown, awaiting for user interaction, timeone or an eventual error
-};
-
-DLLEXPORT void CreateToast_Text01(const wchar_t* appName,
- const wchar_t* appUserModelID,
- const wchar_t* toastMessage,
- ToastEventCallback eventCallback,
- const wchar_t* attribution = nullptr,
- int duration = 0,
- int audioFile = 0,
- int audioOption = 0);
-
-DLLEXPORT void CreateToast_Text02(const wchar_t* appName,
- const wchar_t* appUserModelID,
- const wchar_t* toastTitle,
- const wchar_t* toastMessage,
- ToastEventCallback eventCallback,
- const wchar_t* attribution = nullptr,
- bool wrapFirstLine = true,
- int duration = 0,
- int audioFile = 0,
- int audioOption = 0);
-
-DLLEXPORT void CreateToast_Text03(const wchar_t* appName,
- const wchar_t* appUserModelID,
- const wchar_t* toastTitle,
- const wchar_t* toastMessage,
- const wchar_t* toastAdditionalMessage,
- ToastEventCallback eventCallback,
- const wchar_t* attribution = nullptr,
- int duration = 0,
- int audioFile = 0,
- int audioOption = 0);
-
-DLLEXPORT void CreateToast_ImageAndText01(const wchar_t* appName,
- const wchar_t* appUserModelID,
- const wchar_t* toastMessage,
- const wchar_t* toastImagePath,
- ToastEventCallback eventCallback,
- const wchar_t* attribution = nullptr,
- int duration = 0,
- int audioFile = 0,
- int audioOption = 0);
-
-DLLEXPORT void CreateToast_ImageAndText02(const wchar_t* appName,
- const wchar_t* appUserModelID,
- const wchar_t* toastTitle,
- const wchar_t* toastMessage,
- const wchar_t* toastImagePath,
- ToastEventCallback eventCallback,
- const wchar_t* attribution = nullptr,
- bool wrapFirstLine = true,
- int duration = 0,
- int audioFile = 0,
- int audioOption = 0);
-
-DLLEXPORT void CreateToast_ImageAndText03(const wchar_t* appName,
- const wchar_t* appUserModelID,
- const wchar_t* toastTitle,
- const wchar_t* toastMessage,
- const wchar_t* toastAdditionalMessage,
- const wchar_t* toastImagePath,
- ToastEventCallback eventCallback,
- const wchar_t* attribution = nullptr,
- int duration = 0,
- int audioFile = 0,
- int audioOption = 0);
-
-// internal call, to generate every toast
-void CreateToast(const wchar_t* appName,
- const wchar_t* appUserModelID,
- WinToastTemplate::WinToastTemplateType toastTemplate,
- ToastEventCallback eventCallback,
- const wchar_t* toastTitle = nullptr,
- const wchar_t* toastMessage = nullptr,
- const wchar_t* toastAdditionlMessage = nullptr,
- const wchar_t* toastImagePath = nullptr,
- const wchar_t* attribution = nullptr,
- WinToastTemplate::Duration duration = WinToastTemplate::Duration::System,
- WinToastTemplate::AudioSystemFile audioFile = WinToastTemplate::AudioSystemFile::DefaultSound,
- WinToastTemplate::AudioOption audioOption = WinToastTemplate::AudioOption::Default,
- INT64 expiration = -1,
- bool createShortcut = true);
\ No newline at end of file
diff --git a/DFAssist.WinToast/wintoastlib.cpp b/DFAssist.WinToast/wintoastlib.cpp
deleted file mode 100644
index 4ff4d30..0000000
--- a/DFAssist.WinToast/wintoastlib.cpp
+++ /dev/null
@@ -1,1131 +0,0 @@
-/* * Copyright (C) 2016-2019 Mohammed Boujemaoui
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "stdafx.h"
-#include "wintoastlib.h"
-#include
-#include
-#include
-#include
-
-#pragma comment(lib,"shlwapi")
-#pragma comment(lib,"user32")
-
-#ifdef NDEBUG
- #define DEBUG_MSG(str) do { } while ( false )
-#else
- #define DEBUG_MSG(str) do { std::wcout << str << std::endl; } while( false )
-#endif
-
-#define DEFAULT_SHELL_LINKS_PATH L"\\Microsoft\\Windows\\Start Menu\\Programs\\"
-#define DEFAULT_LINK_FORMAT L".lnk"
-#define STATUS_SUCCESS (0x00000000)
-
-
-// Quickstart: Handling toast activations from Win32 apps in Windows 10
-// https://blogs.msdn.microsoft.com/tiles_and_toasts/2015/10/16/quickstart-handling-toast-activations-from-win32-apps-in-windows-10/
-using namespace WinToastLib;
-namespace DllImporter {
-
- // Function load a function from library
- template
- HRESULT loadFunctionFromLibrary(HINSTANCE library, LPCSTR name, Function &func) {
- if (!library) {
- return E_INVALIDARG;
- }
- func = reinterpret_cast(GetProcAddress(library, name));
- return (func != nullptr) ? S_OK : E_FAIL;
- }
-
- typedef HRESULT(FAR STDAPICALLTYPE *f_SetCurrentProcessExplicitAppUserModelID)(__in PCWSTR AppID);
- typedef HRESULT(FAR STDAPICALLTYPE *f_PropVariantToString)(_In_ REFPROPVARIANT propvar, _Out_writes_(cch) PWSTR psz, _In_ UINT cch);
- typedef HRESULT(FAR STDAPICALLTYPE *f_RoGetActivationFactory)(_In_ HSTRING activatableClassId, _In_ REFIID iid, _COM_Outptr_ void ** factory);
- typedef HRESULT(FAR STDAPICALLTYPE *f_WindowsCreateStringReference)(_In_reads_opt_(length + 1) PCWSTR sourceString, UINT32 length, _Out_ HSTRING_HEADER * hstringHeader, _Outptr_result_maybenull_ _Result_nullonfailure_ HSTRING * string);
- typedef PCWSTR(FAR STDAPICALLTYPE *f_WindowsGetStringRawBuffer)(_In_ HSTRING string, _Out_ UINT32 *length);
- typedef HRESULT(FAR STDAPICALLTYPE *f_WindowsDeleteString)(_In_opt_ HSTRING string);
-
- static f_SetCurrentProcessExplicitAppUserModelID SetCurrentProcessExplicitAppUserModelID;
- static f_PropVariantToString PropVariantToString;
- static f_RoGetActivationFactory RoGetActivationFactory;
- static f_WindowsCreateStringReference WindowsCreateStringReference;
- static f_WindowsGetStringRawBuffer WindowsGetStringRawBuffer;
- static f_WindowsDeleteString WindowsDeleteString;
-
-
- template
- _Check_return_ __inline HRESULT _1_GetActivationFactory(_In_ HSTRING activatableClassId, _COM_Outptr_ T** factory) {
- return RoGetActivationFactory(activatableClassId, IID_INS_ARGS(factory));
- }
-
- template
- inline HRESULT Wrap_GetActivationFactory(_In_ HSTRING activatableClassId, _Inout_ Details::ComPtrRef factory) noexcept {
- return _1_GetActivationFactory(activatableClassId, factory.ReleaseAndGetAddressOf());
- }
-
- inline HRESULT initialize() {
- HINSTANCE LibShell32 = LoadLibraryW(L"SHELL32.DLL");
- HRESULT hr = loadFunctionFromLibrary(LibShell32, "SetCurrentProcessExplicitAppUserModelID", SetCurrentProcessExplicitAppUserModelID);
- if (SUCCEEDED(hr)) {
- HINSTANCE LibPropSys = LoadLibraryW(L"PROPSYS.DLL");
- hr = loadFunctionFromLibrary(LibPropSys, "PropVariantToString", PropVariantToString);
- if (SUCCEEDED(hr)) {
- HINSTANCE LibComBase = LoadLibraryW(L"COMBASE.DLL");
- const bool succeded = SUCCEEDED(loadFunctionFromLibrary(LibComBase, "RoGetActivationFactory", RoGetActivationFactory))
- && SUCCEEDED(loadFunctionFromLibrary(LibComBase, "WindowsCreateStringReference", WindowsCreateStringReference))
- && SUCCEEDED(loadFunctionFromLibrary(LibComBase, "WindowsGetStringRawBuffer", WindowsGetStringRawBuffer))
- && SUCCEEDED(loadFunctionFromLibrary(LibComBase, "WindowsDeleteString", WindowsDeleteString));
- return succeded ? S_OK : E_FAIL;
- }
- }
- return hr;
- }
-}
-
-class WinToastStringWrapper {
-public:
- WinToastStringWrapper(_In_reads_(length) PCWSTR stringRef, _In_ UINT32 length) noexcept {
- HRESULT hr = DllImporter::WindowsCreateStringReference(stringRef, length, &_header, &_hstring);
- if (!SUCCEEDED(hr)) {
- RaiseException(static_cast(STATUS_INVALID_PARAMETER), EXCEPTION_NONCONTINUABLE, 0, nullptr);
- }
- }
-
- WinToastStringWrapper(_In_ const std::wstring &stringRef) noexcept {
- HRESULT hr = DllImporter::WindowsCreateStringReference(stringRef.c_str(), static_cast(stringRef.length()), &_header, &_hstring);
- if (FAILED(hr)) {
- RaiseException(static_cast(STATUS_INVALID_PARAMETER), EXCEPTION_NONCONTINUABLE, 0, nullptr);
- }
- }
-
- ~WinToastStringWrapper() {
- DllImporter::WindowsDeleteString(_hstring);
- }
-
- inline HSTRING Get() const noexcept {
- return _hstring;
- }
-private:
- HSTRING _hstring;
- HSTRING_HEADER _header;
-
-};
-
-class InternalDateTime : public IReference {
-public:
- static INT64 Now() {
- FILETIME now;
- GetSystemTimeAsFileTime(&now);
- return ((((INT64)now.dwHighDateTime) << 32) | now.dwLowDateTime);
- }
-
- InternalDateTime(DateTime dateTime) : _dateTime(dateTime) {}
-
- InternalDateTime(INT64 millisecondsFromNow) {
- _dateTime.UniversalTime = Now() + millisecondsFromNow * 10000;
- }
-
- virtual ~InternalDateTime() = default;
-
- operator INT64() {
- return _dateTime.UniversalTime;
- }
-
- HRESULT STDMETHODCALLTYPE get_Value(DateTime *dateTime) {
- *dateTime = _dateTime;
- return S_OK;
- }
-
- HRESULT STDMETHODCALLTYPE QueryInterface(const IID& riid, void** ppvObject) {
- if (!ppvObject) {
- return E_POINTER;
- }
- if (riid == __uuidof(IUnknown) || riid == __uuidof(IReference)) {
- *ppvObject = static_cast(static_cast*>(this));
- return S_OK;
- }
- return E_NOINTERFACE;
- }
-
- ULONG STDMETHODCALLTYPE Release() {
- return 1;
- }
-
- ULONG STDMETHODCALLTYPE AddRef() {
- return 2;
- }
-
- HRESULT STDMETHODCALLTYPE GetIids(ULONG*, IID**) {
- return E_NOTIMPL;
- }
-
- HRESULT STDMETHODCALLTYPE GetRuntimeClassName(HSTRING*) {
- return E_NOTIMPL;
- }
-
- HRESULT STDMETHODCALLTYPE GetTrustLevel(TrustLevel*) {
- return E_NOTIMPL;
- }
-
-protected:
- DateTime _dateTime;
-};
-
-namespace Util {
-
- typedef LONG NTSTATUS, *PNTSTATUS;
- typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
- inline RTL_OSVERSIONINFOW getRealOSVersion() {
- HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
- if (hMod) {
- RtlGetVersionPtr fxPtr = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");
- if (fxPtr != nullptr) {
- RTL_OSVERSIONINFOW rovi = { 0 };
- rovi.dwOSVersionInfoSize = sizeof(rovi);
- if (STATUS_SUCCESS == fxPtr(&rovi)) {
- return rovi;
- }
- }
- }
- RTL_OSVERSIONINFOW rovi = { 0 };
- return rovi;
- }
-
- inline HRESULT defaultExecutablePath(_In_ WCHAR* path, _In_ DWORD nSize = MAX_PATH) {
- DWORD written = GetModuleFileNameExW(GetCurrentProcess(), nullptr, path, nSize);
- DEBUG_MSG("Default executable path: " << path);
- return (written > 0) ? S_OK : E_FAIL;
- }
-
-
- inline HRESULT defaultShellLinksDirectory(_In_ WCHAR* path, _In_ DWORD nSize = MAX_PATH) {
- DWORD written = GetEnvironmentVariableW(L"APPDATA", path, nSize);
- HRESULT hr = written > 0 ? S_OK : E_INVALIDARG;
- if (SUCCEEDED(hr)) {
- errno_t result = wcscat_s(path, nSize, DEFAULT_SHELL_LINKS_PATH);
- hr = (result == 0) ? S_OK : E_INVALIDARG;
- DEBUG_MSG("Default shell link path: " << path);
- }
- return hr;
- }
-
- inline HRESULT defaultShellLinkPath(const std::wstring& appname, _In_ WCHAR* path, _In_ DWORD nSize = MAX_PATH) {
- HRESULT hr = defaultShellLinksDirectory(path, nSize);
- if (SUCCEEDED(hr)) {
- const std::wstring appLink(appname + DEFAULT_LINK_FORMAT);
- errno_t result = wcscat_s(path, nSize, appLink.c_str());
- hr = (result == 0) ? S_OK : E_INVALIDARG;
- DEBUG_MSG("Default shell link file path: " << path);
- }
- return hr;
- }
-
-
- inline PCWSTR AsString(ComPtr &xmlDocument) {
- HSTRING xml;
- ComPtr ser;
- HRESULT hr = xmlDocument.As(&ser);
- hr = ser->GetXml(&xml);
- if (SUCCEEDED(hr))
- return DllImporter::WindowsGetStringRawBuffer(xml, nullptr);
- return nullptr;
- }
-
- inline PCWSTR AsString(HSTRING hstring) {
- return DllImporter::WindowsGetStringRawBuffer(hstring, nullptr);
- }
-
- inline HRESULT setNodeStringValue(const std::wstring& string, IXmlNode *node, IXmlDocument *xml) {
- ComPtr textNode;
- HRESULT hr = xml->CreateTextNode( WinToastStringWrapper(string).Get(), &textNode);
- if (SUCCEEDED(hr)) {
- ComPtr stringNode;
- hr = textNode.As(&stringNode);
- if (SUCCEEDED(hr)) {
- ComPtr appendedChild;
- hr = node->AppendChild(stringNode.Get(), &appendedChild);
- }
- }
- return hr;
- }
-
- inline HRESULT setEventHandlers(_In_ IToastNotification* notification, _In_ std::shared_ptr eventHandler, _In_ INT64 expirationTime) {
- EventRegistrationToken activatedToken, dismissedToken, failedToken;
- HRESULT hr = notification->add_Activated(
- Callback < Implements < RuntimeClassFlags,
- ITypedEventHandler> >(
- [eventHandler](IToastNotification*, IInspectable* inspectable)
- {
- IToastActivatedEventArgs *activatedEventArgs;
- HRESULT hr = inspectable->QueryInterface(&activatedEventArgs);
- if (SUCCEEDED(hr)) {
- HSTRING argumentsHandle;
- hr = activatedEventArgs->get_Arguments(&argumentsHandle);
- if (SUCCEEDED(hr)) {
- PCWSTR arguments = Util::AsString(argumentsHandle);
- if (arguments && *arguments) {
- eventHandler->toastActivated(static_cast(wcstol(arguments, nullptr, 10)));
- return S_OK;
- }
- }
- }
- eventHandler->toastActivated();
- return S_OK;
- }).Get(), &activatedToken);
-
- if (SUCCEEDED(hr)) {
- hr = notification->add_Dismissed(Callback < Implements < RuntimeClassFlags,
- ITypedEventHandler> >(
- [eventHandler, expirationTime](IToastNotification*, IToastDismissedEventArgs* e)
- {
- ToastDismissalReason reason;
- if (SUCCEEDED(e->get_Reason(&reason)))
- {
- if (reason == ToastDismissalReason_UserCanceled && expirationTime && InternalDateTime::Now() >= expirationTime)
- reason = ToastDismissalReason_TimedOut;
- eventHandler->toastDismissed(static_cast(reason));
- }
- return S_OK;
- }).Get(), &dismissedToken);
- if (SUCCEEDED(hr)) {
- hr = notification->add_Failed(Callback < Implements < RuntimeClassFlags,
- ITypedEventHandler> >(
- [eventHandler](IToastNotification*, IToastFailedEventArgs*)
- {
- eventHandler->toastFailed();
- return S_OK;
- }).Get(), &failedToken);
- }
- }
- return hr;
- }
-
- inline HRESULT addAttribute(_In_ IXmlDocument *xml, const std::wstring &name, IXmlNamedNodeMap *attributeMap) {
- ComPtr srcAttribute;
- HRESULT hr = xml->CreateAttribute(WinToastStringWrapper(name).Get(), &srcAttribute);
- if (SUCCEEDED(hr)) {
- ComPtr node;
- hr = srcAttribute.As(&node);
- if (SUCCEEDED(hr)) {
- ComPtr pNode;
- hr = attributeMap->SetNamedItem(node.Get(), &pNode);
- }
- }
- return hr;
- }
-
- inline HRESULT createElement(_In_ IXmlDocument *xml, _In_ const std::wstring& root_node, _In_ const std::wstring& element_name, _In_ const std::vector& attribute_names) {
- ComPtr rootList;
- HRESULT hr = xml->GetElementsByTagName(WinToastStringWrapper(root_node).Get(), &rootList);
- if (SUCCEEDED(hr)) {
- ComPtr root;
- hr = rootList->Item(0, &root);
- if (SUCCEEDED(hr)) {
- ComPtr audioElement;
- hr = xml->CreateElement(WinToastStringWrapper(element_name).Get(), &audioElement);
- if (SUCCEEDED(hr)) {
- ComPtr audioNodeTmp;
- hr = audioElement.As(&audioNodeTmp);
- if (SUCCEEDED(hr)) {
- ComPtr audioNode;
- hr = root->AppendChild(audioNodeTmp.Get(), &audioNode);
- if (SUCCEEDED(hr)) {
- ComPtr attributes;
- hr = audioNode->get_Attributes(&attributes);
- if (SUCCEEDED(hr)) {
- for (const auto& it : attribute_names) {
- hr = addAttribute(xml, it, attributes.Get());
- }
- }
- }
- }
- }
- }
- }
- return hr;
- }
-}
-
-WinToast* WinToast::instance() {
- static WinToast instance;
- return &instance;
-}
-
-WinToast::WinToast() :
- _isInitialized(false),
- _hasCoInitialized(false)
-{
- if (!isCompatible()) {
- DEBUG_MSG(L"Warning: Your system is not compatible with this library ");
- }
-}
-
-WinToast::~WinToast() {
- if (_hasCoInitialized) {
- CoUninitialize();
- }
-}
-
-void WinToast::setAppName(_In_ const std::wstring& appName) {
- _appName = appName;
-}
-
-
-void WinToast::setAppUserModelId(_In_ const std::wstring& aumi) {
- _aumi = aumi;
- DEBUG_MSG(L"Default App User Model Id: " << _aumi.c_str());
-}
-
-bool WinToast::isCompatible() {
- DllImporter::initialize();
- return !((DllImporter::SetCurrentProcessExplicitAppUserModelID == nullptr)
- || (DllImporter::PropVariantToString == nullptr)
- || (DllImporter::RoGetActivationFactory == nullptr)
- || (DllImporter::WindowsCreateStringReference == nullptr)
- || (DllImporter::WindowsDeleteString == nullptr));
-}
-
-bool WinToastLib::WinToast::isSupportingModernFeatures() {
- constexpr auto MinimumSupportedVersion = 6;
- return Util::getRealOSVersion().dwMajorVersion > MinimumSupportedVersion;
-
-}
-std::wstring WinToast::configureAUMI(_In_ const std::wstring &companyName,
- _In_ const std::wstring &productName,
- _In_ const std::wstring &subProduct,
- _In_ const std::wstring &versionInformation)
-{
- std::wstring aumi = companyName;
- aumi += L"." + productName;
- if (subProduct.length() > 0) {
- aumi += L"." + subProduct;
- if (versionInformation.length() > 0) {
- aumi += L"." + versionInformation;
- }
- }
-
- if (aumi.length() > SCHAR_MAX) {
- DEBUG_MSG("Error: max size allowed for AUMI: 128 characters.");
- }
- return aumi;
-}
-
-const std::wstring& WinToast::strerror(WinToastError error) {
- static const std::unordered_map Labels = {
- {WinToastError::NoError, L"No error. The process was executed correctly"},
- {WinToastError::NotInitialized, L"The library has not been initialized"},
- {WinToastError::SystemNotSupported, L"The OS does not support WinToast"},
- {WinToastError::ShellLinkNotCreated, L"The library was not able to create a Shell Link for the app"},
- {WinToastError::InvalidAppUserModelID, L"The AUMI is not a valid one"},
- {WinToastError::InvalidParameters, L"The parameters used to configure the library are not valid normally because an invalid AUMI or App Name"},
- {WinToastError::NotDisplayed, L"The toast was created correctly but WinToast was not able to display the toast"},
- {WinToastError::UnknownError, L"Unknown error"}
- };
-
- const auto iter = Labels.find(error);
- assert(iter != Labels.end());
- return iter->second;
-}
-
-enum WinToast::ShortcutResult WinToast::createShortcut() {
- if (_aumi.empty() || _appName.empty()) {
- DEBUG_MSG(L"Error: App User Model Id or Appname is empty!");
- return SHORTCUT_MISSING_PARAMETERS;
- }
-
- if (!isCompatible()) {
- DEBUG_MSG(L"Your OS is not compatible with this library! =(");
- return SHORTCUT_INCOMPATIBLE_OS;
- }
-
- if (!_hasCoInitialized) {
- HRESULT initHr = CoInitializeEx(nullptr, COINIT::COINIT_MULTITHREADED);
- if (initHr != RPC_E_CHANGED_MODE) {
- if (FAILED(initHr) && initHr != S_FALSE) {
- DEBUG_MSG(L"Error on COM library initialization!");
- return SHORTCUT_COM_INIT_FAILURE;
- }
- else {
- _hasCoInitialized = true;
- }
- }
- }
-
- bool wasChanged;
- HRESULT hr = validateShellLinkHelper(wasChanged);
- if (SUCCEEDED(hr))
- return wasChanged ? SHORTCUT_WAS_CHANGED : SHORTCUT_UNCHANGED;
-
- hr = createShellLinkHelper();
- return SUCCEEDED(hr) ? SHORTCUT_WAS_CREATED : SHORTCUT_CREATE_FAILED;
-}
-
-bool WinToast::initialize(_Out_ WinToastError* error) {
- _isInitialized = false;
- setError(error, WinToastError::NoError);
-
- if (!isCompatible()) {
- setError(error, WinToastError::SystemNotSupported);
- DEBUG_MSG(L"Error: system not supported.");
- return false;
- }
-
-
- if (_aumi.empty() || _appName.empty()) {
- setError(error, WinToastError::InvalidParameters);
- DEBUG_MSG(L"Error while initializing, did you set up a valid AUMI and App name?");
- return false;
- }
-
- if (createShortcut() < 0) {
- setError(error, WinToastError::ShellLinkNotCreated);
- DEBUG_MSG(L"Error while attaching the AUMI to the current proccess =(");
- return false;
- }
-
- if (FAILED(DllImporter::SetCurrentProcessExplicitAppUserModelID(_aumi.c_str()))) {
- setError(error, WinToastError::InvalidAppUserModelID);
- DEBUG_MSG(L"Error while attaching the AUMI to the current proccess =(");
- return false;
- }
-
- _isInitialized = true;
- return _isInitialized;
-}
-
-bool WinToast::isInitialized() const {
- return _isInitialized;
-}
-
-const std::wstring& WinToast::appName() const {
- return _appName;
-}
-
-const std::wstring& WinToast::appUserModelId() const {
- return _aumi;
-}
-
-
-HRESULT WinToast::validateShellLinkHelper(_Out_ bool& wasChanged) {
- WCHAR path[MAX_PATH] = { L'\0' };
- Util::defaultShellLinkPath(_appName, path);
- // Check if the file exist
- DWORD attr = GetFileAttributesW(path);
- if (attr >= 0xFFFFFFF) {
- DEBUG_MSG("Error, shell link not found. Try to create a new one in: " << path);
- return E_FAIL;
- }
-
- // Let's load the file as shell link to validate.
- // - Create a shell link
- // - Create a persistant file
- // - Load the path as data for the persistant file
- // - Read the property AUMI and validate with the current
- // - Review if AUMI is equal.
- ComPtr shellLink;
- HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shellLink));
- if (SUCCEEDED(hr)) {
- ComPtr persistFile;
- hr = shellLink.As(&persistFile);
- if (SUCCEEDED(hr)) {
- hr = persistFile->Load(path, STGM_READWRITE);
- if (SUCCEEDED(hr)) {
- ComPtr propertyStore;
- hr = shellLink.As(&propertyStore);
- if (SUCCEEDED(hr)) {
- PROPVARIANT appIdPropVar;
- hr = propertyStore->GetValue(PKEY_AppUserModel_ID, &appIdPropVar);
- if (SUCCEEDED(hr)) {
- WCHAR AUMI[MAX_PATH];
- hr = DllImporter::PropVariantToString(appIdPropVar, AUMI, MAX_PATH);
- wasChanged = false;
- if (FAILED(hr) || _aumi != AUMI) {
- // AUMI Changed for the same app, let's update the current value! =)
- wasChanged = true;
- PropVariantClear(&appIdPropVar);
- hr = InitPropVariantFromString(_aumi.c_str(), &appIdPropVar);
- if (SUCCEEDED(hr)) {
- hr = propertyStore->SetValue(PKEY_AppUserModel_ID, appIdPropVar);
- if (SUCCEEDED(hr)) {
- hr = propertyStore->Commit();
- if (SUCCEEDED(hr) && SUCCEEDED(persistFile->IsDirty())) {
- hr = persistFile->Save(path, TRUE);
- }
- }
- }
- }
- PropVariantClear(&appIdPropVar);
- }
- }
- }
- }
- }
- return hr;
-}
-
-
-
-HRESULT WinToast::createShellLinkHelper() {
- WCHAR exePath[MAX_PATH]{L'\0'};
- WCHAR slPath[MAX_PATH]{L'\0'};
- Util::defaultShellLinkPath(_appName, slPath);
- Util::defaultExecutablePath(exePath);
- ComPtr shellLink;
- HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shellLink));
- if (SUCCEEDED(hr)) {
- hr = shellLink->SetPath(exePath);
- if (SUCCEEDED(hr)) {
- hr = shellLink->SetArguments(L"");
- if (SUCCEEDED(hr)) {
- hr = shellLink->SetWorkingDirectory(exePath);
- if (SUCCEEDED(hr)) {
- ComPtr propertyStore;
- hr = shellLink.As(&propertyStore);
- if (SUCCEEDED(hr)) {
- PROPVARIANT appIdPropVar;
- hr = InitPropVariantFromString(_aumi.c_str(), &appIdPropVar);
- if (SUCCEEDED(hr)) {
- hr = propertyStore->SetValue(PKEY_AppUserModel_ID, appIdPropVar);
- if (SUCCEEDED(hr)) {
- hr = propertyStore->Commit();
- if (SUCCEEDED(hr)) {
- ComPtr persistFile;
- hr = shellLink.As(&persistFile);
- if (SUCCEEDED(hr)) {
- hr = persistFile->Save(slPath, TRUE);
- }
- }
- }
- PropVariantClear(&appIdPropVar);
- }
- }
- }
- }
- }
- }
- return hr;
-}
-
-INT64 WinToast::showToast(_In_ const WinToastTemplate& toast, _In_ IWinToastHandler* handler, _Out_ WinToastError* error) {
- setError(error, WinToastError::NoError);
- INT64 id = -1;
- if (!isInitialized()) {
- setError(error, WinToastError::NotInitialized);
- DEBUG_MSG("Error when launching the toast. WinToast is not initialized.");
- return id;
- }
- if (!handler) {
- setError(error, WinToastError::InvalidHandler);
- DEBUG_MSG("Error when launching the toast. Handler cannot be nullptr.");
- return id;
- }
-
- ComPtr notificationManager;
- HRESULT hr = DllImporter::Wrap_GetActivationFactory(WinToastStringWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(), ¬ificationManager);
- if (SUCCEEDED(hr)) {
- ComPtr notifier;
- hr = notificationManager->CreateToastNotifierWithId(WinToastStringWrapper(_aumi).Get(), ¬ifier);
- if (SUCCEEDED(hr)) {
- ComPtr notificationFactory;
- hr = DllImporter::Wrap_GetActivationFactory(WinToastStringWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(), ¬ificationFactory);
- if (SUCCEEDED(hr)) {
- ComPtr xmlDocument;
- HRESULT hr = notificationManager->GetTemplateContent(ToastTemplateType(toast.type()), &xmlDocument);
- if (SUCCEEDED(hr)) {
- for (size_t i = 0, fieldsCount = toast.textFieldsCount(); i < fieldsCount && SUCCEEDED(hr); i++) {
- const auto position = static_cast(i);
- hr = setTextFieldHelper(xmlDocument.Get(), toast.textField(WinToastTemplate::TextField(i)), position);
- }
-
- // Modern feature are supported Windows > Windows 10
- if (SUCCEEDED(hr) && isSupportingModernFeatures()) {
-
- // Note that we do this *after* using toast.textFieldsCount() to
- // iterate/fill the template's text fields, since we're adding yet another text field.
- if (SUCCEEDED(hr)
- && !toast.attributionText().empty()) {
- hr = setAttributionTextFieldHelper(xmlDocument.Get(), toast.attributionText());
- }
-
- std::array buf;
- for (std::size_t i = 0, actionsCount = toast.actionsCount(); i < actionsCount && SUCCEEDED(hr); i++) {
- _snwprintf_s(buf.data(), buf.size(), _TRUNCATE, L"%zd", i);
- hr = addActionHelper(xmlDocument.Get(), toast.actionLabel(i), buf.data());
- }
-
- if (SUCCEEDED(hr)) {
- hr = (toast.audioPath().empty() && toast.audioOption() == WinToastTemplate::AudioOption::Default)
- ? hr : setAudioFieldHelper(xmlDocument.Get(), toast.audioPath(), toast.audioOption());
- }
-
- if (SUCCEEDED(hr) && toast.duration() != WinToastTemplate::Duration::System) {
- hr = addDurationHelper(xmlDocument.Get(),
- (toast.duration() == WinToastTemplate::Duration::Short) ? L"short" : L"long");
- }
-
- } else {
- DEBUG_MSG("Modern features (Actions/Sounds/Attributes) not supported in this os version");
- }
-
- if (SUCCEEDED(hr)) {
- hr = toast.hasImage() ? setImageFieldHelper(xmlDocument.Get(), toast.imagePath()) : hr;
- if (SUCCEEDED(hr)) {
- ComPtr notification;
- hr = notificationFactory->CreateToastNotification(xmlDocument.Get(), ¬ification);
- if (SUCCEEDED(hr)) {
- INT64 expiration = 0, relativeExpiration = toast.expiration();
- if (relativeExpiration > 0) {
- InternalDateTime expirationDateTime(relativeExpiration);
- expiration = expirationDateTime;
- hr = notification->put_ExpirationTime(&expirationDateTime);
- }
-
- if (SUCCEEDED(hr)) {
- hr = Util::setEventHandlers(notification.Get(), std::shared_ptr(handler), expiration);
- if (FAILED(hr)) {
- setError(error, WinToastError::InvalidHandler);
- }
- }
-
- if (SUCCEEDED(hr)) {
- GUID guid;
- hr = CoCreateGuid(&guid);
- if (SUCCEEDED(hr)) {
- id = guid.Data1;
- _buffer[id] = notification;
- DEBUG_MSG("xml: " << Util::AsString(xmlDocument));
- hr = notifier->Show(notification.Get());
- if (FAILED(hr)) {
- setError(error, WinToastError::NotDisplayed);
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- return FAILED(hr) ? -1 : id;
-}
-
-ComPtr WinToast::notifier(_In_ bool* succeded) const {
- ComPtr notificationManager;
- ComPtr notifier;
- HRESULT hr = DllImporter::Wrap_GetActivationFactory(WinToastStringWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(), ¬ificationManager);
- if (SUCCEEDED(hr)) {
- hr = notificationManager->CreateToastNotifierWithId(WinToastStringWrapper(_aumi).Get(), ¬ifier);
- }
- *succeded = SUCCEEDED(hr);
- return notifier;
-}
-
-bool WinToast::hideToast(_In_ INT64 id) {
- if (!isInitialized()) {
- DEBUG_MSG("Error when hiding the toast. WinToast is not initialized.");
- return false;
- }
-
- if (_buffer.find(id) != _buffer.end()) {
- auto succeded = false;
- auto notify = notifier(&succeded);
- if (succeded) {
- auto result = notify->Hide(_buffer[id].Get());
- _buffer.erase(id);
- return SUCCEEDED(result);
- }
- }
- return false;
-}
-
-void WinToast::clear() {
- auto succeded = false;
- auto notify = notifier(&succeded);
- if (succeded) {
- auto end = _buffer.end();
- for (auto it = _buffer.begin(); it != end; ++it) {
- notify->Hide(it->second.Get());
- }
- _buffer.clear();
- }
-}
-
-//
-// Available as of Windows 10 Anniversary Update
-// Ref: https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/adaptive-interactive-toasts
-//
-// NOTE: This will add a new text field, so be aware when iterating over
-// the toast's text fields or getting a count of them.
-//
-HRESULT WinToast::setAttributionTextFieldHelper(_In_ IXmlDocument *xml, _In_ const std::wstring& text) {
- Util::createElement(xml, L"binding", L"text", { L"placement" });
- ComPtr nodeList;
- HRESULT hr = xml->GetElementsByTagName(WinToastStringWrapper(L"text").Get(), &nodeList);
- if (SUCCEEDED(hr)) {
- UINT32 nodeListLength;
- hr = nodeList->get_Length(&nodeListLength);
- if (SUCCEEDED(hr)) {
- for (UINT32 i = 0; i < nodeListLength; i++) {
- ComPtr textNode;
- hr = nodeList->Item(i, &textNode);
- if (SUCCEEDED(hr)) {
- ComPtr attributes;
- hr = textNode->get_Attributes(&attributes);
- if (SUCCEEDED(hr)) {
- ComPtr editedNode;
- if (SUCCEEDED(hr)) {
- hr = attributes->GetNamedItem(WinToastStringWrapper(L"placement").Get(), &editedNode);
- if (FAILED(hr) || !editedNode) {
- continue;
- }
- hr = Util::setNodeStringValue(L"attribution", editedNode.Get(), xml);
- if (SUCCEEDED(hr)) {
- return setTextFieldHelper(xml, text, i);
- }
- }
- }
- }
- }
- }
- }
- return hr;
-}
-
-HRESULT WinToast::addDurationHelper(_In_ IXmlDocument *xml, _In_ const std::wstring& duration) {
- ComPtr nodeList;
- HRESULT hr = xml->GetElementsByTagName(WinToastStringWrapper(L"toast").Get(), &nodeList);
- if (SUCCEEDED(hr)) {
- UINT32 length;
- hr = nodeList->get_Length(&length);
- if (SUCCEEDED(hr)) {
- ComPtr toastNode;
- hr = nodeList->Item(0, &toastNode);
- if (SUCCEEDED(hr)) {
- ComPtr toastElement;
- hr = toastNode.As(&toastElement);
- if (SUCCEEDED(hr)) {
- hr = toastElement->SetAttribute(WinToastStringWrapper(L"duration").Get(),
- WinToastStringWrapper(duration).Get());
- }
- }
- }
- }
- return hr;
-}
-
-HRESULT WinToast::setTextFieldHelper(_In_ IXmlDocument *xml, _In_ const std::wstring& text, _In_ UINT32 pos) {
- ComPtr nodeList;
- HRESULT hr = xml->GetElementsByTagName(WinToastStringWrapper(L"text").Get(), &nodeList);
- if (SUCCEEDED(hr)) {
- ComPtr node;
- hr = nodeList->Item(pos, &node);
- if (SUCCEEDED(hr)) {
- hr = Util::setNodeStringValue(text, node.Get(), xml);
- }
- }
- return hr;
-}
-
-
-HRESULT WinToast::setImageFieldHelper(_In_ IXmlDocument *xml, _In_ const std::wstring& path) {
- assert(path.size() < MAX_PATH);
-
- wchar_t imagePath[MAX_PATH] = L"file:///";
- HRESULT hr = StringCchCatW(imagePath, MAX_PATH, path.c_str());
- if (SUCCEEDED(hr)) {
- ComPtr nodeList;
- HRESULT hr = xml->GetElementsByTagName(WinToastStringWrapper(L"image").Get(), &nodeList);
- if (SUCCEEDED(hr)) {
- ComPtr node;
- hr = nodeList->Item(0, &node);
- if (SUCCEEDED(hr)) {
- ComPtr attributes;
- hr = node->get_Attributes(&attributes);
- if (SUCCEEDED(hr)) {
- ComPtr editedNode;
- hr = attributes->GetNamedItem(WinToastStringWrapper(L"src").Get(), &editedNode);
- if (SUCCEEDED(hr)) {
- Util::setNodeStringValue(imagePath, editedNode.Get(), xml);
- }
- }
- }
- }
- }
- return hr;
-}
-
-HRESULT WinToast::setAudioFieldHelper(_In_ IXmlDocument *xml, _In_ const std::wstring& path, _In_opt_ WinToastTemplate::AudioOption option) {
- std::vector attrs;
- if (!path.empty()) attrs.push_back(L"src");
- if (option == WinToastTemplate::AudioOption::Loop) attrs.push_back(L"loop");
- if (option == WinToastTemplate::AudioOption::Silent) attrs.push_back(L"silent");
- Util::createElement(xml, L"toast", L"audio", attrs);
-
- ComPtr nodeList;
- HRESULT hr = xml->GetElementsByTagName(WinToastStringWrapper(L"audio").Get(), &nodeList);
- if (SUCCEEDED(hr)) {
- ComPtr node;
- hr = nodeList->Item(0, &node);
- if (SUCCEEDED(hr)) {
- ComPtr attributes;
- hr = node->get_Attributes(&attributes);
- if (SUCCEEDED(hr)) {
- ComPtr editedNode;
- if (!path.empty()) {
- if (SUCCEEDED(hr)) {
- hr = attributes->GetNamedItem(WinToastStringWrapper(L"src").Get(), &editedNode);
- if (SUCCEEDED(hr)) {
- hr = Util::setNodeStringValue(path, editedNode.Get(), xml);
- }
- }
- }
-
- if (SUCCEEDED(hr)) {
- switch (option) {
- case WinToastTemplate::AudioOption::Loop:
- hr = attributes->GetNamedItem(WinToastStringWrapper(L"loop").Get(), &editedNode);
- if (SUCCEEDED(hr)) {
- hr = Util::setNodeStringValue(L"true", editedNode.Get(), xml);
- }
- break;
- case WinToastTemplate::AudioOption::Silent:
- hr = attributes->GetNamedItem(WinToastStringWrapper(L"silent").Get(), &editedNode);
- if (SUCCEEDED(hr)) {
- hr = Util::setNodeStringValue(L"true", editedNode.Get(), xml);
- }
- default:
- break;
- }
- }
- }
- }
- }
- return hr;
-}
-
-HRESULT WinToast::addActionHelper(_In_ IXmlDocument *xml, _In_ const std::wstring& content, _In_ const std::wstring& arguments) {
- ComPtr nodeList;
- HRESULT hr = xml->GetElementsByTagName(WinToastStringWrapper(L"actions").Get(), &nodeList);
- if (SUCCEEDED(hr)) {
- UINT32 length;
- hr = nodeList->get_Length(&length);
- if (SUCCEEDED(hr)) {
- ComPtr actionsNode;
- if (length > 0) {
- hr = nodeList->Item(0, &actionsNode);
- } else {
- hr = xml->GetElementsByTagName(WinToastStringWrapper(L"toast").Get(), &nodeList);
- if (SUCCEEDED(hr)) {
- hr = nodeList->get_Length(&length);
- if (SUCCEEDED(hr)) {
- ComPtr toastNode;
- hr = nodeList->Item(0, &toastNode);
- if (SUCCEEDED(hr)) {
- ComPtr toastElement;
- hr = toastNode.As(&toastElement);
- if (SUCCEEDED(hr))
- hr = toastElement->SetAttribute(WinToastStringWrapper(L"template").Get(), WinToastStringWrapper(L"ToastGeneric").Get());
- if (SUCCEEDED(hr))
- hr = toastElement->SetAttribute(WinToastStringWrapper(L"duration").Get(), WinToastStringWrapper(L"long").Get());
- if (SUCCEEDED(hr)) {
- ComPtr actionsElement;
- hr = xml->CreateElement(WinToastStringWrapper(L"actions").Get(), &actionsElement);
- if (SUCCEEDED(hr)) {
- hr = actionsElement.As(&actionsNode);
- if (SUCCEEDED(hr)) {
- ComPtr appendedChild;
- hr = toastNode->AppendChild(actionsNode.Get(), &appendedChild);
- }
- }
- }
- }
- }
- }
- }
- if (SUCCEEDED(hr)) {
- ComPtr actionElement;
- hr = xml->CreateElement(WinToastStringWrapper(L"action").Get(), &actionElement);
- if (SUCCEEDED(hr))
- hr = actionElement->SetAttribute(WinToastStringWrapper(L"content").Get(), WinToastStringWrapper(content).Get());
- if (SUCCEEDED(hr))
- hr = actionElement->SetAttribute(WinToastStringWrapper(L"arguments").Get(), WinToastStringWrapper(arguments).Get());
- if (SUCCEEDED(hr)) {
- ComPtr actionNode;
- hr = actionElement.As(&actionNode);
- if (SUCCEEDED(hr)) {
- ComPtr appendedChild;
- hr = actionsNode->AppendChild(actionNode.Get(), &appendedChild);
- }
- }
- }
- }
- }
- return hr;
-}
-
-void WinToast::setError(_Out_ WinToastError* error, _In_ WinToastError value) {
- if (error) {
- *error = value;
- }
-}
-
-WinToastTemplate::WinToastTemplate(_In_ WinToastTemplateType type) : _type(type) {
- static constexpr std::size_t TextFieldsCount[] = { 1, 2, 2, 3, 1, 2, 2, 3};
- _textFields = std::vector(TextFieldsCount[type], L"");
-}
-
-WinToastTemplate::~WinToastTemplate() {
- _textFields.clear();
-}
-
-void WinToastTemplate::setTextField(_In_ const std::wstring& txt, _In_ WinToastTemplate::TextField pos) {
- const auto position = static_cast(pos);
- assert(position < _textFields.size());
- _textFields[position] = txt;
-}
-
-void WinToastTemplate::setImagePath(_In_ const std::wstring& imgPath) {
- _imagePath = imgPath;
-}
-
-void WinToastTemplate::setAudioPath(_In_ const std::wstring& audioPath) {
- _audioPath = audioPath;
-}
-
-void WinToastTemplate::setAudioPath(_In_ AudioSystemFile file) {
- static const std::unordered_map Files = {
- {AudioSystemFile::DefaultSound, L"ms-winsoundevent:Notification.Default"},
- {AudioSystemFile::IM, L"ms-winsoundevent:Notification.IM"},
- {AudioSystemFile::Mail, L"ms-winsoundevent:Notification.Mail"},
- {AudioSystemFile::Reminder, L"ms-winsoundevent:Notification.Reminder"},
- {AudioSystemFile::SMS, L"ms-winsoundevent:Notification.SMS"},
- {AudioSystemFile::Alarm, L"ms-winsoundevent:Notification.Looping.Alarm"},
- {AudioSystemFile::Alarm2, L"ms-winsoundevent:Notification.Looping.Alarm2"},
- {AudioSystemFile::Alarm3, L"ms-winsoundevent:Notification.Looping.Alarm3"},
- {AudioSystemFile::Alarm4, L"ms-winsoundevent:Notification.Looping.Alarm4"},
- {AudioSystemFile::Alarm5, L"ms-winsoundevent:Notification.Looping.Alarm5"},
- {AudioSystemFile::Alarm6, L"ms-winsoundevent:Notification.Looping.Alarm6"},
- {AudioSystemFile::Alarm7, L"ms-winsoundevent:Notification.Looping.Alarm7"},
- {AudioSystemFile::Alarm8, L"ms-winsoundevent:Notification.Looping.Alarm8"},
- {AudioSystemFile::Alarm9, L"ms-winsoundevent:Notification.Looping.Alarm9"},
- {AudioSystemFile::Alarm10, L"ms-winsoundevent:Notification.Looping.Alarm10"},
- {AudioSystemFile::Call, L"ms-winsoundevent:Notification.Looping.Call"},
- {AudioSystemFile::Call1, L"ms-winsoundevent:Notification.Looping.Call1"},
- {AudioSystemFile::Call2, L"ms-winsoundevent:Notification.Looping.Call2"},
- {AudioSystemFile::Call3, L"ms-winsoundevent:Notification.Looping.Call3"},
- {AudioSystemFile::Call4, L"ms-winsoundevent:Notification.Looping.Call4"},
- {AudioSystemFile::Call5, L"ms-winsoundevent:Notification.Looping.Call5"},
- {AudioSystemFile::Call6, L"ms-winsoundevent:Notification.Looping.Call6"},
- {AudioSystemFile::Call7, L"ms-winsoundevent:Notification.Looping.Call7"},
- {AudioSystemFile::Call8, L"ms-winsoundevent:Notification.Looping.Call8"},
- {AudioSystemFile::Call9, L"ms-winsoundevent:Notification.Looping.Call9"},
- {AudioSystemFile::Call10, L"ms-winsoundevent:Notification.Looping.Call10"},
- };
- const auto iter = Files.find(file);
- assert(iter != Files.end());
- _audioPath = iter->second;
-}
-
-void WinToastTemplate::setAudioOption(_In_ WinToastTemplate::AudioOption audioOption) {
- _audioOption = audioOption;
-}
-
-void WinToastTemplate::setFirstLine(const std::wstring &text) {
- setTextField(text, WinToastTemplate::FirstLine);
-}
-
-void WinToastTemplate::setSecondLine(const std::wstring &text) {
- setTextField(text, WinToastTemplate::SecondLine);
-}
-
-void WinToastTemplate::setThirdLine(const std::wstring &text) {
- setTextField(text, WinToastTemplate::ThirdLine);
-}
-
-void WinToastTemplate::setDuration(_In_ Duration duration) {
- _duration = duration;
-}
-
-void WinToastTemplate::setExpiration(_In_ INT64 millisecondsFromNow) {
- _expiration = millisecondsFromNow;
-}
-
-void WinToastTemplate::setAttributionText(_In_ const std::wstring& attributionText) {
- _attributionText = attributionText;
-}
-
-void WinToastTemplate::addAction(_In_ const std::wstring & label) {
- _actions.push_back(label);
-}
-
-std::size_t WinToastTemplate::textFieldsCount() const {
- return _textFields.size();
-}
-
-std::size_t WinToastTemplate::actionsCount() const {
- return _actions.size();
-}
-
-bool WinToastTemplate::hasImage() const {
- return _type < WinToastTemplateType::Text01;
-}
-
-const std::vector& WinToastTemplate::textFields() const {
- return _textFields;
-}
-
-const std::wstring& WinToastTemplate::textField(_In_ TextField pos) const {
- const auto position = static_cast(pos);
- assert(position < _textFields.size());
- return _textFields[position];
-}
-
-const std::wstring& WinToastTemplate::actionLabel(_In_ std::size_t position) const {
- assert(position < _actions.size());
- return _actions[position];
-}
-
-const std::wstring& WinToastTemplate::imagePath() const {
- return _imagePath;
-}
-
-const std::wstring& WinToastTemplate::audioPath() const {
- return _audioPath;
-}
-
-const std::wstring& WinToastTemplate::attributionText() const {
- return _attributionText;
-}
-
-INT64 WinToastTemplate::expiration() const {
- return _expiration;
-}
-
-WinToastTemplate::WinToastTemplateType WinToastTemplate::type() const {
- return _type;
-}
-
-WinToastTemplate::AudioOption WinToastTemplate::audioOption() const {
- return _audioOption;
-}
-
-WinToastTemplate::Duration WinToastTemplate::duration() const {
- return _duration;
-}
diff --git a/DFAssist.WinToast/wintoastlib.h b/DFAssist.WinToast/wintoastlib.h
deleted file mode 100644
index f226e5f..0000000
--- a/DFAssist.WinToast/wintoastlib.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/* * Copyright (C) 2016-2019 Mohammed Boujemaoui
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef WINTOASTLIB_H
-#define WINTOASTLIB_H
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include