1 /* * Copyright (C) 2016-2019 Mohammed Boujemaoui <mohabouje@gmail.com>
3 * Permission is hereby granted, free of charge, to any person obtaining a copy of
4 * this software and associated documentation files (the "Software"), to deal in
5 * the Software without restriction, including without limitation the rights to
6 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7 * the Software, and to permit persons to whom the Software is furnished to do so,
8 * subject to the following conditions:
10 * The above copyright notice and this permission notice shall be included in all
11 * copies or substantial portions of the Software.
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 #include <sdkddkver.h>
27 #include <wrl/implements.h>
28 #include <wrl/event.h>
29 #include <windows.ui.notifications.h>
34 #include <propvarutil.h>
35 #include <functiondiscoverykeys.h>
37 #include <winstring.h>
41 using namespace Microsoft::WRL
;
42 using namespace ABI::Windows::Data::Xml::Dom
;
43 using namespace ABI::Windows::Foundation
;
44 using namespace ABI::Windows::UI::Notifications
;
45 using namespace Windows::Foundation
;
48 namespace WinToastLib
{
50 class IWinToastHandler
{
52 enum WinToastDismissalReason
{
53 UserCanceled
= ToastDismissalReason::ToastDismissalReason_UserCanceled
,
54 ApplicationHidden
= ToastDismissalReason::ToastDismissalReason_ApplicationHidden
,
55 TimedOut
= ToastDismissalReason::ToastDismissalReason_TimedOut
57 virtual ~IWinToastHandler() = default;
58 virtual void toastActivated() const = 0;
59 virtual void toastActivated(int actionIndex
) const = 0;
60 virtual void toastDismissed(WinToastDismissalReason state
) const = 0;
61 virtual void toastFailed() const = 0;
64 class WinToastTemplate
{
66 enum class Scenario
{ Default
, Alarm
, IncomingCall
, Reminder
};
67 enum Duration
{ System
, Short
, Long
};
68 enum AudioOption
{ Default
= 0, Silent
, Loop
};
69 enum TextField
{ FirstLine
= 0, SecondLine
, ThirdLine
};
70 enum WinToastTemplateType
{
71 ImageAndText01
= ToastTemplateType::ToastTemplateType_ToastImageAndText01
,
72 ImageAndText02
= ToastTemplateType::ToastTemplateType_ToastImageAndText02
,
73 ImageAndText03
= ToastTemplateType::ToastTemplateType_ToastImageAndText03
,
74 ImageAndText04
= ToastTemplateType::ToastTemplateType_ToastImageAndText04
,
75 Text01
= ToastTemplateType::ToastTemplateType_ToastText01
,
76 Text02
= ToastTemplateType::ToastTemplateType_ToastText02
,
77 Text03
= ToastTemplateType::ToastTemplateType_ToastText03
,
78 Text04
= ToastTemplateType::ToastTemplateType_ToastText04
,
81 enum AudioSystemFile
{
111 WinToastTemplate(_In_ WinToastTemplateType type
= WinToastTemplateType::ImageAndText02
);
114 void setFirstLine(_In_
const std::wstring
& text
);
115 void setSecondLine(_In_
const std::wstring
& text
);
116 void setThirdLine(_In_
const std::wstring
& text
);
117 void setTextField(_In_
const std::wstring
& txt
, _In_ TextField pos
);
118 void setAttributionText(_In_
const std::wstring
& attributionText
);
119 void setImagePath(_In_
const std::wstring
& imgPath
);
120 void setAudioPath(_In_
WinToastTemplate::AudioSystemFile audio
);
121 void setAudioPath(_In_
const std::wstring
& audioPath
);
122 void setAudioOption(_In_
WinToastTemplate::AudioOption audioOption
);
123 void setDuration(_In_ Duration duration
);
124 void setExpiration(_In_ INT64 millisecondsFromNow
);
125 void setScenario(_In_ Scenario scenario
);
126 void addAction(_In_
const std::wstring
& label
);
128 std::size_t textFieldsCount() const;
129 std::size_t actionsCount() const;
130 bool hasImage() const;
131 const std::vector
<std::wstring
>& textFields() const;
132 const std::wstring
& textField(_In_ TextField pos
) const;
133 const std::wstring
& actionLabel(_In_
std::size_t pos
) const;
134 const std::wstring
& imagePath() const;
135 const std::wstring
& audioPath() const;
136 const std::wstring
& attributionText() const;
137 const std::wstring
& scenario() const;
138 INT64
expiration() const;
139 WinToastTemplateType
type() const;
140 WinToastTemplate::AudioOption
audioOption() const;
141 Duration
duration() const;
143 std::vector
<std::wstring
> _textFields
{};
144 std::vector
<std::wstring
> _actions
{};
145 std::wstring _imagePath
{};
146 std::wstring _audioPath
{};
147 std::wstring _attributionText
{};
148 std::wstring _scenario
{L
"Default"};
149 INT64 _expiration
{0};
150 AudioOption _audioOption
{WinToastTemplate::AudioOption::Default
};
151 WinToastTemplateType _type
{WinToastTemplateType::Text01
};
152 Duration _duration
{Duration::System
};
162 InvalidAppUserModelID
,
169 enum ShortcutResult
{
170 SHORTCUT_UNCHANGED
= 0,
171 SHORTCUT_WAS_CHANGED
= 1,
172 SHORTCUT_WAS_CREATED
= 2,
174 SHORTCUT_MISSING_PARAMETERS
= -1,
175 SHORTCUT_INCOMPATIBLE_OS
= -2,
176 SHORTCUT_COM_INIT_FAILURE
= -3,
177 SHORTCUT_CREATE_FAILED
= -4
180 enum ShortcutPolicy
{
181 /* Don't check, create, or modify a shortcut. */
182 SHORTCUT_POLICY_IGNORE
= 0,
183 /* Require a shortcut with matching AUMI, don't create or modify an existing one. */
184 SHORTCUT_POLICY_REQUIRE_NO_CREATE
= 1,
185 /* Require a shortcut with matching AUMI, create if missing, modify if not matching.
186 * This is the default. */
187 SHORTCUT_POLICY_REQUIRE_CREATE
= 2,
192 static WinToast
* instance();
193 static bool isCompatible();
194 static bool isSupportingModernFeatures();
195 static std::wstring
configureAUMI(_In_
const std::wstring
& companyName
,
196 _In_
const std::wstring
& productName
,
197 _In_
const std::wstring
& subProduct
= std::wstring(),
198 _In_
const std::wstring
& versionInformation
= std::wstring());
199 static const std::wstring
& strerror(_In_ WinToastError error
);
200 virtual bool initialize(_Out_ WinToastError
* error
= nullptr);
201 virtual bool isInitialized() const;
202 virtual bool hideToast(_In_ INT64 id
);
203 virtual INT64
showToast(_In_
const WinToastTemplate
& toast
, _In_ IWinToastHandler
* handler
, _Out_ WinToastError
* error
= nullptr);
204 virtual void clear();
205 virtual enum ShortcutResult
createShortcut();
207 const std::wstring
& appName() const;
208 const std::wstring
& appUserModelId() const;
209 void setAppUserModelId(_In_
const std::wstring
& aumi
);
210 void setAppName(_In_
const std::wstring
& appName
);
211 void setShortcutPolicy(_In_ ShortcutPolicy policy
);
214 bool _isInitialized
{false};
215 bool _hasCoInitialized
{false};
216 ShortcutPolicy _shortcutPolicy
{SHORTCUT_POLICY_REQUIRE_CREATE
};
217 std::wstring _appName
{};
218 std::wstring _aumi
{};
219 std::map
<INT64
, ComPtr
<IToastNotification
>> _buffer
{};
221 HRESULT
validateShellLinkHelper(_Out_
bool& wasChanged
);
222 HRESULT
createShellLinkHelper();
223 HRESULT
setImageFieldHelper(_In_ IXmlDocument
*xml
, _In_
const std::wstring
& path
);
224 HRESULT
setAudioFieldHelper(_In_ IXmlDocument
*xml
, _In_
const std::wstring
& path
, _In_opt_
WinToastTemplate::AudioOption option
= WinToastTemplate::AudioOption::Default
);
225 HRESULT
setTextFieldHelper(_In_ IXmlDocument
*xml
, _In_
const std::wstring
& text
, _In_ UINT32 pos
);
226 HRESULT
setAttributionTextFieldHelper(_In_ IXmlDocument
*xml
, _In_
const std::wstring
& text
);
227 HRESULT
addActionHelper(_In_ IXmlDocument
*xml
, _In_
const std::wstring
& action
, _In_
const std::wstring
& arguments
);
228 HRESULT
addDurationHelper(_In_ IXmlDocument
*xml
, _In_
const std::wstring
& duration
);
229 HRESULT
addScenarioHelper(_In_ IXmlDocument
*xml
, _In_
const std::wstring
& scenario
);
230 ComPtr
<IToastNotifier
> notifier(_In_
bool* succeded
) const;
231 void setError(_Out_ WinToastError
* error
, _In_ WinToastError value
);
234 #endif // WINTOASTLIB_H