forked from HemulGM/WindowsNotificationManager
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFMX.Win.NotificationManager.pas
More file actions
2693 lines (2354 loc) · 81.8 KB
/
FMX.Win.NotificationManager.pas
File metadata and controls
2693 lines (2354 loc) · 81.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
unit FMX.Win.NotificationManager;
interface
uses
System.SysUtils, System.Classes, System.Generics.Collections, System.DateUtils,
System.Win.Registry,
///
FMX.Win.Notification.XML,
// Windows RT (Runtime)
Win.WinRT, Winapi.DataRT, Winapi.Winrt, Winapi.Winrt.Utils, Winapi.UI.Notifications,
// Winapi
Winapi.Windows, Winapi.Messages, Winapi.CommonTypes, Winapi.Foundation;
{$SCOPEDENUMS ON}
type
ENotification = class(Exception);
ENotificationAlreadyPosted = class(ENotification);
ENotificationNotPosted = class(ENotification);
ENotificationTagNeeded = class(ENotification);
ENotificationUpdate = class(ENotification);
ENotificationNotInited = class(ENotification);
TNotification = class;
TUserInputMap = class;
NotificationMirroring = Winapi.UI.Notifications.NotificationMirroring;
ToastNotificationPriority = Winapi.UI.Notifications.ToastNotificationPriority;
// Cardinals
TSoundEventValue = ( //
Default, //
NotificationDefault, //
NotificationIM, //
NotificationMail, //
NotificationReminder, //
NotificationSMS, //
NotificationLoopingAlarm, //
NotificationLoopingAlarm2, //
NotificationLoopingAlarm3, //
NotificationLoopingAlarm4, //
NotificationLoopingAlarm5, //
NotificationLoopingAlarm6, //
NotificationLoopingAlarm7, //
NotificationLoopingAlarm8, //
NotificationLoopingAlarm9, //
NotificationLoopingAlarm10, //
NotificationLoopingCall, //
NotificationLoopingCall2, //
NotificationLoopingCall3, //
NotificationLoopingCall4, //
NotificationLoopingCall5, //
NotificationLoopingCall6, //
NotificationLoopingCall7, //
NotificationLoopingCall8, //
NotificationLoopingCall9, //
NotificationLoopingCall10); //
TSoundEventValueHelper = record helper for TSoundEventValue
function ToString: string; inline;
end;
TImagePlacement = (Default, Hero, LogoOverride);
TImageCrop = (Default, None, Circle);
TInputType = (Text, Selection);
TActivationType = (//
/// <summary>
/// Default
/// </summary>
Default,
/// <summary>
/// Default value. Your foreground app is launched.
/// </summary>
Foreground,
/// <summary>
/// Your corresponding background task is triggered, and you can execute code in the background without interrupting the user.
/// </summary>
Background,
/// <summary>
/// Launch a different app using protocol activation.
/// </summary>
Protocol,
/// <summary>
/// System
/// </summary>
System);
TActivationTypeHelper = record helper for TActivationType
function ToString: string; inline;
end;
/// <summary>
/// The amount of time the toast should display.
/// </summary>
TToastDuration = (
/// <summary>
/// Use default: short
/// </summary>
Default,
/// <summary>
/// Show for 7s
/// </summary>
Short,
/// <summary>
/// Show for 25s
/// </summary>
Long);
TToastDurationHelper = record helper for TToastDuration
function ToString: string; inline;
end;
/// <summary>
/// AudioMode
/// </summary>
TAudioMode = (
/// <summary>
/// The notification controls the audio
/// </summary>
Default,
/// <summary>
/// No audio
/// </summary>
Muted,
/// <summary>
/// Custom audio overrides all toast sounds
/// </summary>
Custom);
TNotificationRank = (Default, Normal, High, Topmost);
/// <summary>
/// The scenario your toast is used for, like an alarm or reminder.
/// </summary>
TToastScenario = (
/// <summary>
/// Default notification behaviour
/// </summary>
Default,
/// <summary>
/// An alarm notification. This will be displayed pre-expanded and stay on the user's screen till dismissed. Audio will loop by default and will use alarm audio.
/// </summary>
Alarm,
/// <summary>
/// A reminder notification. This will be displayed pre-expanded and stay on the user's screen till dismissed. Note that this will be silently ignored unless there's a toast button action that activates in background.
/// </summary>
Reminder,
/// <summary>
/// An incoming call notification. This will be displayed pre-expanded in a special call format and stay on the user's screen till dismissed. Audio will loop by default and will use ringtone audio.
/// </summary>
IncomingCall,
/// <summary>
/// An important notification. This allows users to have more control over what apps can send them high-priority toast notifications that can break through Focus Assist (Do not Disturb). This can be modified in the notifications settings.
/// </summary>
Urgent);
TToastScenarioHelper = record helper for TToastScenario
function ToString: string; inline;
end;
TToastDismissReason = ToastDismissalReason;
// Events
TOnToastActivated = procedure(Sender: TNotification; Arguments: string; UserInput: TUserInputMap) of object;
TOnToastDismissed = procedure(Sender: TNotification; Reason: TToastDismissReason) of object;
TOnToastFailed = procedure(Sender: TNotification; ErrorCode: HRESULT) of object;
INotificationEventHandler = interface
['{3E0F388D-6B7C-4FE7-A095-3E2822F84EB2}']
procedure Unscribe;
end;
// Events
TNotificationEventHandler = class(TInspectableObject, INotificationEventHandler)
private
FNotification: TNotification;
FToken: EventRegistrationToken;
public
constructor Create(const ANotification: TNotification); virtual;
procedure Unscribe; virtual; abstract;
destructor Destroy; override;
end;
TNotificationActivatedHandler = class(TNotificationEventHandler, TypedEventHandler_2__IToastNotification__IInspectable)
procedure Invoke(sender: IToastNotification; args: IInspectable); safecall;
constructor Create(const ANotification: TNotification); override;
procedure Unscribe; override;
end;
TNotificationDismissedHandler = class(TNotificationEventHandler, TypedEventHandler_2__IToastNotification__IToastDismissedEventArgs)
procedure Invoke(sender: IToastNotification; args: IToastDismissedEventArgs); safecall;
constructor Create(const ANotification: TNotification); override;
procedure Unscribe; override;
end;
TNotificationFailedHandler = class(TNotificationEventHandler, TypedEventHandler_2__IToastNotification__IToastFailedEventArgs)
procedure Invoke(sender: IToastNotification; args: IToastFailedEventArgs); safecall;
constructor Create(const ANotification: TNotification); override;
procedure Unscribe; override;
end;
// Notification data
TNotificationData = class
private
Data: INotificationData;
function GetValue(Key: string): string;
procedure SetValue(Key: string; const Value: string);
function GetSeq: Cardinal;
procedure SetSeq(const Value: Cardinal);
public
property InterfaceValue: INotificationData read Data;
// Seq
property SequenceNumber: Cardinal read GetSeq write SetSeq;
procedure IncreaseSequence;
// Proc
procedure Clear;
function ValueCount: Cardinal;
function ValueExists(Key: string): boolean;
// Manage
property Values[Key: string]: string read GetValue write SetValue; default;
constructor Create;
destructor Destroy; override;
end;
// User input parser
TUserInputMap = class
private
FMap: IMap_2__HSTRING__HSTRING;
public
function HasValue(ID: string): boolean;
function GetStringValue(ID: string): string;
function GetIntValue(ID: string): integer;
constructor Create(LookupMap: IMap_2__HSTRING__HSTRING); reintroduce;
destructor Destroy; override;
end;
TToastContentBuilder = class;
// Toast notification
TNotification = class(TComponent)
private
FPosted: Boolean;
FToast: IToastNotification;
FToast2: IToastNotification2;
FToast3: IToastNotification3;
FToast4: IToastNotification4;
FToast6: IToastNotification6;
FToastScheduled: IScheduledToastNotification;
FOnActivated: TOnToastActivated;
FOnDismissed: TOnToastDismissed;
FOnFailed: TOnToastFailed;
FHandleActivated: INotificationEventHandler;
FHandleDismissed: INotificationEventHandler;
FHandleFailed: INotificationEventHandler;
FData: TNotificationData;
procedure FreeEvents;
procedure Initiate(XML: Xml_Dom_IXmlDocument);
function GetExpiration: TDateTime;
procedure SetExpiration(const Value: TDateTime);
function GetSuppress: Boolean;
procedure SetSuppress(const Value: Boolean);
function GetGroup: string;
function GetTag: string;
procedure SetGroup(const Value: string);
procedure SetTag(const Value: string);
function GetMirroring: NotificationMirroring;
procedure SetMirroring(const Value: NotificationMirroring);
function GetRemoteID: string;
procedure SetRemoteID(const Value: string);
procedure SetData(const Value: TNotificationData);
function GetPriority: ToastNotificationPriority;
procedure SetPriority(const Value: ToastNotificationPriority);
function GetExireReboot: Boolean;
procedure SetExpireReboot(const Value: Boolean);
procedure SetEventActivated(const Value: TOnToastActivated);
procedure SetEventDismissed(const Value: TOnToastDismissed);
procedure SetEventFailed(const Value: TOnToastFailed);
public
/// <summary>
/// Defines the time at which the popup will dissapear.
/// </summary>
property ExpirationTime: TDateTime read GetExpiration write SetExpiration;
/// <summary>
/// Defines wheather the popup is shown to the user on the screen or of It's placed directly in the action center.
/// </summary>
property SuppressPopup: Boolean read GetSuppress write SetSuppress;
property Tag: string read GetTag write SetTag;
property Group: string read GetGroup write SetGroup;
property NotificationMirroring: NotificationMirroring read GetMirroring write SetMirroring;
property RemoteId: string read GetRemoteID write SetRemoteID;
property Data: TNotificationData read FData;
property Toast: IToastNotification read FToast;
/// <summary>
/// Notification priority
/// </summary>
property Priority: ToastNotificationPriority read GetPriority write SetPriority;
/// <summary>
/// Expire notification after reboot
/// </summary>
property ExpiresOnReboot: boolean read GetExireReboot write SetExpireReboot;
public
property Posted: Boolean read FPosted;
function Content: TXMLInterface;
/// <summary>
/// Reset the notification to It's default state before being posted.
/// </summary>
procedure Reset;
public
property OnActivated: TOnToastActivated read FOnActivated write SetEventActivated;
property OnDismissed: TOnToastDismissed read FOnDismissed write SetEventDismissed;
property OnFailed: TOnToastFailed read FOnFailed write SetEventFailed;
constructor Create(AOwner: TComponent; Content: TToastContentBuilder); reintroduce; virtual;
destructor Destroy; override;
end;
/// <summary>
/// The placement of the text.
/// </summary>
TToastTextPlacement = (
/// <summary>
/// An adaptive text element
/// </summary>
None,
/// <summary>
/// Attribution text displayed at the bottom of the toast notification.
/// </summary>
Attribution);
TToastTextPlacementHelper = record helper for TToastTextPlacement
function ToString: string; inline;
end;
TToastContentItem = class
protected
FNode: TWinXMLNode;
function GetNodeAndFree: TWinXMLNode;
public
constructor Create; virtual;
destructor Destroy; override;
end;
TToastContentItem<T> = class(TToastContentItem)
end;
TToastTextStyle = (
/// <summary>
/// Default value. Style is determined by the renderer.
/// </summary>
Default,
/// <summary>
/// Smaller than paragraph font size.
/// </summary>
Caption,
/// <summary>
/// Same as Caption but with subtle opacity.
/// </summary>
CaptionSubtle,
/// <summary>
/// Paragraph font size.
/// </summary>
Body,
/// <summary>
/// Same as Body but with subtle opacity.
/// </summary>
BodySubtle,
/// <summary>
/// Paragraph font size, bold weight. Essentially the bold version of Body.
/// </summary>
Base,
/// <summary>
/// Same as Base but with subtle opacity.
/// </summary>
BaseSubtle,
/// <summary>
/// H4 font size.
/// </summary>
Subtitle,
/// <summary>
/// Same as Subtitle but with subtle opacity.
/// </summary>
SubtitleSubtle,
/// <summary>
/// H3 font size.
/// </summary>
Title,
/// <summary>
/// Same as Title but with subtle opacity.
/// </summary>
TitleSubtle,
/// <summary>
/// Same as Title but with top/bottom padding removed.
/// </summary>
TitleNumeral,
/// <summary>
/// H2 font size.
/// </summary>
Subheader,
/// <summary>
/// Same as Subheader but with subtle opacity.
/// </summary>
SubheaderSubtle,
/// <summary>
/// Same as Subheader but with top/bottom padding removed.
/// </summary>
SubheaderNumeral,
/// <summary>
/// H1 font size.
/// </summary>
Header,
/// <summary>
/// Same as Header but with subtle opacity.
/// </summary>
HeaderSubtle,
/// <summary>
/// Same as Header but with top/bottom padding removed.
/// </summary>
HeaderNumeral);
TToastTextStyleHelper = record helper for TToastTextStyle
function ToString: string; inline;
end;
TToastTextAlign = (
/// <summary>
/// Default value. Alignment is automatically determined by the renderer.
/// </summary>
Default,
/// <summary>
/// Alignment determined by the current language and culture.
/// </summary>
Auto,
/// <summary>
/// Horizontally align the text to the left.
/// </summary>
Left,
/// <summary>
/// Horizontally align the text in the center.
/// </summary>
Center,
/// <summary>
/// Horizontally align the text to the right.
/// </summary>
Right);
TToastTextAlignHelper = record helper for TToastTextAlign
function ToString: string; inline;
end;
TToastText = class(TToastContentItem<TToastText>)
public
/// <summary>
/// The text to display. Data binding support added in Creators Update, but only works for top-level text elements.
/// </summary>
function Text(const Value: string): TToastText;
/// <summary>
/// The style controls the text's font size, weight, and opacity. Only works for text elements inside a group/subgroup.
/// </summary>
function HintStyle(const Value: TToastTextStyle): TToastText; overload;
/// <summary>
/// Set this to true to enable text wrapping. Top-level text elements ignore this property and always wrap (you can use HintMaxLines = 1 to disable wrapping for top-level text elements). Text elements inside groups/subgroups default to false for wrapping.
/// </summary>
function HintWrap(const Value: Boolean): TToastText; overload;
/// <summary>
/// The maximum number of lines the text element is allowed to display.
/// </summary>
function HintMaxLines(const Value: Integer): TToastText;
/// <summary>
/// The minimum number of lines the text element must display. Only works for text elements inside a group/subgroup.
/// </summary>
function HintMinLines(const Value: Integer): TToastText;
/// <summary>
/// The horizontal alignment of the text. Only works for text elements inside a group/subgroup.
/// </summary>
function HintAlign(const Value: TToastTextAlign): TToastText;
/// <summary>
/// The target locale of the XML payload, specified as a BCP-47 language tags such as "en-US" or "fr-FR". The locale specified here overrides any other specified locale, such as that in binding or visual. If this value is a literal string, this attribute defaults to the user's UI language. If this value is a string reference, this attribute defaults to the locale chosen by Windows Runtime in resolving the string.
/// </summary>
function Language(const Value: string): TToastText;
/// <summary>
/// The placement of the text. Introduced in Anniversary Update. If you specify the value "attribution", the text is always displayed at the bottom of your notification, along with your app's identity or the notification's timestamp. On older versions of Windows that don't support attribution text, the text will simply be displayed as another text element (assuming you don't already have the maximum of three text elements). For more information, see Toast content.
/// </summary>
function Placement(const Value: TToastTextPlacement): TToastText;
/// <summary>
/// Set to "true" to center the text for incoming call notifications. This value is only used for notifications with with a scenario value of "incomingCall"; otherwise, it is ignored. For more information, see Toast content.
/// </summary>
function HintСallScenarioCenterAlign(const Value: Boolean): TToastText;
end;
TToastProgressBar = class(TToastContentItem<TToastProgressBar>)
public
/// <summary>
/// Gets or sets an optional title string. Supports data binding.
/// </summary>
function Title(const Value: string): TToastProgressBar;
/// <summary>
/// Gets or sets the value of the progress bar. Supports data binding. Defaults to 0.
/// </summary>
function Value(const Value: Single): TToastProgressBar; overload;
/// <summary>
/// Gets or sets the name that maps to your binding data value.
/// </summary>
function Value(const Value: string): TToastProgressBar; overload;
/// <summary>
/// Gets or sets a value indicating whether the progress bar is indeterminate. If this is true, Value will be ignored.
/// </summary>
function ValueIndeterminate: TToastProgressBar;
/// <summary>
/// Gets or sets an optional string to be displayed instead of the default percentage string. If this isn't provided, something like "70%" will be displayed.
/// </summary>
function ValueStringOverride(const Value: string): TToastProgressBar;
/// <summary>
/// Gets or sets a status string (required), which is displayed underneath the progress bar on the left. This string should reflect the status of the operation, like "Downloading..." or "Installing..."
/// </summary>
function Status(const Value: string): TToastProgressBar;
constructor Create; override;
end;
/// <summary>
/// Specify audio to be played when the Toast notification is received.
/// </summary>
TToastAudio = class(TToastContentItem<TToastAudio>)
public
/// <summary>
/// The media file to play in place of the default sound. Only ms-appx and ms-resource are supported. All else (ms-appdata, http, C:, etc.) is not supported.
/// </summary>
function Src(const Uri: string): TToastAudio; overload;
/// <summary>
/// The "ms-winsoundevent" audio to play in place of the default sound.
/// </summary>
function Src(const WinSoundEvent: TSoundEventValue): TToastAudio; overload;
/// <summary>
/// Set to true if the sound should repeat as long as the Toast is shown; false to play only once (default).
/// </summary>
function Loop(const Value: Boolean): TToastAudio;
/// <summary>
/// True to mute the sound; false to allow the toast notification sound to play (default).
/// </summary>
function Silent(const Value: Boolean): TToastAudio;
end;
/// <summary>
/// A text box control that the user can type text into.
/// </summary>
TToastTextBox = class(TToastContentItem<TToastTextBox>)
protected
/// <summary>
/// The ID associated with the content.
/// </summary>
function InputType(const Value: string): TToastTextBox;
public
/// <summary>
/// The ID associated with the content.
/// </summary>
function Id(const Value: string): TToastTextBox;
/// <summary>
/// Title text to display above the text box.
/// </summary>
function Title(const Value: string): TToastTextBox;
/// <summary>
/// Placeholder text to be displayed on the text box when the user hasn't typed any text yet.
/// </summary>
function PlaceholderContent(const Value: string): TToastTextBox;
/// <summary>
/// The initial text to place in the text box. Leave this null for a blank text box.
/// </summary>
function DefaultInput(const Value: string): TToastTextBox;
/// <summary>
/// Add custom argument
/// </summary>
function AddArgument(const Name, Value: string): TToastTextBox;
end;
/// <summary>
/// Specifies the id and text of a selection item.
/// </summary>
TToastSelectionBoxItem = record
public
/// <summary>
/// The id of the selection item.
/// </summary>
Id: string;
/// <summary>
/// The content of the selection item.
/// </summary>
Content: string;
class function Create(const Id, Content: string): TToastSelectionBoxItem; static;
end;
/// <summary>
/// A selection box control, which lets users pick from a dropdown list of options.
/// </summary>
TToastSelectionBox = class(TToastContentItem<TToastSelectionBox>)
protected
/// <summary>
/// The ID associated with the content.
/// </summary>
function InputType(const Value: string): TToastSelectionBox;
public
/// <summary>
/// The ID associated with the content.
/// </summary>
function Id(const Value: string): TToastSelectionBox;
/// <summary>
/// Title text to display above the text box.
/// </summary>
function Title(const Value: string): TToastSelectionBox;
/// <summary>
/// Placeholder text to be displayed on the text box when the user hasn't typed any text yet.
/// </summary>
function PlaceholderContent(const Value: string): TToastSelectionBox;
/// <summary>
/// The initial text to place in the text box. Leave this null for a blank text box.
/// </summary>
function DefaultInput(const Value: string): TToastSelectionBox;
/// <summary>
/// Specifies the id and text of a selection item.
/// </summary>
function Items(const Values: TArray<TToastSelectionBoxItem>): TToastSelectionBox;
/// <summary>
/// Add custom argument
/// </summary>
function AddArgument(const Name, Value: string): TToastSelectionBox;
end;
/// <summary>
/// The button style. useButtonStyle must be set to true in the toast element.
/// </summary>
TToastActionButtonStyle = (
/// <summary>
/// The button is green.
/// </summary>
Success,
/// <summary>
/// The button is red.
/// </summary>
Critical);
TToastActionButtonStyleHelper = record helper for TToastActionButtonStyle
function ToString: string; inline;
end;
/// <summary>
/// Specifies the behavior that the toast should use when the user takes action on the toast.
/// </summary>
TToastActionActivationBehavior = (
/// <summary>
/// Default value. The toast will be dismissed when the user takes action on the toast.
/// </summary>
Default,
/// <summary>
/// After the user clicks a button on your toast, the notification will remain present, in a "pending update" visual state. You should immediately update your toast from a background task so that the user does not see this "pending update" visual state for too long.
/// </summary>
PendingUpdate);
TToastActionActivationBehaviorHelper = record helper for TToastActionActivationBehavior
function ToString: string; inline;
end;
/// <summary>
/// Specifies a button shown in a toast.
/// </summary>
TToastAction = class(TToastContentItem<TToastAction>)
public
/// <summary>
/// The content displayed on the button.
/// </summary>
function Content(const Value: string): TToastAction;
/// <summary>
/// App-defined string of arguments that the app will later receive if the user clicks this button.
/// For system activation: "snooze" , "dismiss" , "video" , "voice" , "decline"
/// </summary>
function Arguments(const Value: string): TToastAction;
/// <summary>
/// An argument string that can be passed to the associated app to provide specifics about the action that it should execute in response to the user action.
/// </summary>
function ActionType(const Value: string): TToastAction;
/// <summary>
/// Decides the type of activation that will be used when the user interacts with a specific action.
/// </summary>
function ActivationType(const Value: TActivationType): TToastAction;
/// <summary>
/// Specifies the behavior that the toast should use when the user takes action on the toast.
/// </summary>
function AfterActivationBehavior(const Value: TToastActionActivationBehavior): TToastAction;
/// <summary>
/// When set to "contextMenu", the action becomes a context menu action added to the toast notification's context menu rather than a traditional toast button.
/// </summary>
function Placement(const Value: string): TToastAction;
/// <summary>
/// The URI of the image source for a toast button icon. These icons are white transparent 16x16 pixel images at 100% scaling and should have no padding included in the image itself. If you choose to provide icons on a toast notification, you must provide icons for ALL of your buttons in the notification, as it transforms the style of your buttons into icon buttons.
/// Use one of the following protocol handlers:
/// - http:// or https:// - A web-based image.
/// - ms-appx:/// - An image included in the app package.
/// - ms-appdata:///local/ - An image saved to local storage.
/// - file:/// - A local image. (Supported only for desktop apps. This protocol cannot be used by UWP apps.)
/// </summary>
function ImageUri(const Value: string): TToastAction;
/// <summary>
/// Set to the Id of an input to position button beside the input.
/// </summary>
function HintInputId(const Value: string): TToastAction;
/// <summary>
/// The button style. useButtonStyle must be set to true in the toast element.
/// - "Success" - The button is green
/// - "Critical" - The button is red.
/// Note that these values are case-sensitive.
/// </summary>
function HintButtonStyle(const Value: TToastActionButtonStyle): TToastAction;
/// <summary>
/// The tooltip for a button, if the button has an empty content string.
/// </summary>
function HintToolTip(const Value: string): TToastAction;
/// <summary>
/// Add custom argument
/// </summary>
function AddArgument(const Name, Value: string): TToastAction;
end;
/// <summary>
/// The placement of the image.
/// </summary>
TToastImagePlacement = (
/// <summary>
/// The image replaces your app's logo in the toast notification.
/// </summary>
AppLogoOverride,
/// <summary>
/// The image is displayed as a hero image.
/// </summary>
Hero);
TToastImagePlacementHelper = record helper for TToastImagePlacement
function ToString: string; inline;
end;
/// <summary>
/// The cropping of the image.
/// </summary>
TToastImageHintCrop = (
/// <summary>
/// Unspecified - The image is not cropped and displayed as a square.
/// </summary>
None,
/// <summary>
/// The image is cropped into a circle.
/// </summary>
Circle);
TToastImageHintCropHelper = record helper for TToastImageHintCrop
function ToString: string; inline;
end;
/// <summary>
/// Specify audio to be played when the Toast notification is received.
/// </summary>
TToastImage = class(TToastContentItem<TToastAudio>)
public
/// <summary>
/// Set to "true" to allow Windows to append a query string to the image URI supplied in the toast notification. Use this attribute if your server hosts images and can handle query strings, either by retrieving an image variant based on the query strings or by ignoring the query string and returning the image as specified without the query string. This query string specifies scale, contrast setting, and language; for instance, a value of
/// "www.website.com/images/hello.png"
/// given in the notification becomes
/// "www.website.com/images/hello.png?ms-scale=100&ms-contrast=standard&ms-lang=en-us"
/// </summary>
function AddImageQuery(const Value: Boolean): TToastImage;
/// <summary>
/// A description of the image, for users of assistive technologies.
/// </summary>
function Alt(const Value: string): TToastImage;
/// <summary>
/// The image element in the toast template that this image is intended for. If a template has only one image, then this value is 1. The number of available image positions is based on the template definition.
/// </summary>
function Id(const Value: Integer): TToastImage;
/// <summary>
/// The URI of the image source, using one of these protocol handlers:
/// A web-based image: http:// or https://
/// An image included in the app package: ms-appx:///
/// An image saved to local storage: ms-appdata:///local/
/// A local image: file:///
/// (Supported only for desktop apps. This protocol cannot be used by UWP apps.)
/// </summary>
function Src(const Value: string): TToastImage;
/// <summary>
/// The placement of the image.
/// </summary>
function Placement(const Value: TToastImagePlacement): TToastImage;
/// <summary>
/// The cropping of the image.
/// Unspecified - The image is not cropped and displayed as a square.
/// </summary>
function HintCrop(const Value: TToastImageHintCrop): TToastImage;
/// <summary>
/// HintRemoveMargin
/// </summary>
function HintRemoveMargin(const Value: Boolean): TToastImage;
end;
/// <summary>
/// Specifies a custom header that groups multiple notifications together within Action Center.
/// </summary>
TToastHeader = class(TToastContentItem<TToastHeader>)
public
/// <summary>
/// A developer-created identifier that uniquely identifies this header. If two notifications have the same header id, they will be displayed underneath the same header in Action Center.
/// </summary>
function Id(const Value: string): TToastHeader;
/// <summary>
/// A title for the header.
/// </summary>
function Title(const Value: string): TToastHeader;
/// <summary>
/// A developer-defined string of arguments that is returned to the app when the user clicks this header. Cannot be null.
/// </summary>
function Arguments(const Value: string): TToastHeader;
/// <summary>
/// The type of activation this header will use when clicked.
/// </summary>
function ActivationType(const Value: TActivationType): TToastHeader;
end;
/// <summary>
/// Specifies vertical columns that can contain text and images.
/// </summary>
TToastSubGroup = class(TToastContentItem<TToastSubGroup>)
/// <summary>
/// Specifies text used in the toast template.
/// </summary>
function AddText(const Value: TToastText): TToastSubGroup;
/// <summary>
/// Specifies an image used in the toast template.
/// </summary>
function AddImage(const Value: TToastImage): TToastSubGroup;
/// <summary>
/// Specifies an image used in the toast template.
/// </summary>
function HintWeight(const Value: Integer): TToastSubGroup;
end;
/// <summary>
/// Semantically identifies that the content in the group must either be displayed as a whole, or not displayed if it cannot fit. Groups also allow creating multiple columns.
/// </summary>
TToastGroup = class(TToastContentItem<TToastGroup>)
public
/// <summary>
/// Specifies vertical columns that can contain text and images.
/// </summary>
function SubGroups(const Values: TArray<TToastSubGroup>): TToastGroup;
end;
// Builder
TToastContentBuilder = class
protected
FXML: TWinXMLDocument;
FXMLVisual, FXMLBinding, FXMLActions: TWinXMLNode;
function AddVisual(Item: TToastContentItem; const Name: string): TToastContentBuilder;
function AddAction(Item: TToastContentItem; const Name: string): TToastContentBuilder;
function AddGeneral(Item: TToastContentItem; const Name: string): TToastContentBuilder;
function AddBinding(Item: TToastContentItem; const Name: string): TToastContentBuilder;
public
function GenerateXML: TDomXMLDocument;
/// <summary>
/// Specifies a progress bar for a toast notification. Only supported on toasts on Desktop, build 15063 or later.
/// </summary>
function AddProgressBar(Item: TToastProgressBar): TToastContentBuilder;
/// <summary>
/// Specifies text used in the toast template.
/// </summary>
function AddText(Item: TToastText): TToastContentBuilder;
/// <summary>
/// Specifies an input, either text box or selection menu, shown in a toast notification.
/// </summary>
function AddInputBox(Item: TToastTextBox): TToastContentBuilder;
/// <summary>
/// Specifies the id and text of a selection item.
/// </summary>
function AddSelectionBox(Item: TToastSelectionBox): TToastContentBuilder;
/// <summary>
/// Specifies a button shown in a toast.
/// </summary>
function AddButton(Item: TToastAction): TToastContentBuilder;
/// <summary>
/// Specifies an image used in the toast template.
/// </summary>
function AddImage(Item: TToastImage): TToastContentBuilder;
/// <summary>
/// Specifies a custom header that groups multiple notifications together within Action Center.
/// </summary>
function AddHeader(Item: TToastHeader): TToastContentBuilder;
/// <summary>
/// Semantically identifies that the content in the group must either be displayed as a whole, or not displayed if it cannot fit. Groups also allow creating multiple columns.
/// </summary>
function AddGroup(Item: TToastGroup): TToastContentBuilder;
/// <summary>
/// Specifies a sound to play when a toast notification is displayed. This element also allows you to mute any toast notification audio.
/// </summary>
function Audio(Item: TToastAudio): TToastContentBuilder;
/// <summary>
/// The amount of time the toast should display.
/// </summary>
/// <seealso>https://learn.microsoft.com/en-us/dotnet/api/microsoft.toolkit.uwp.notifications.toastcontentbuilder.settoastduration</seealso>
function Duration(const Value: TToastDuration): TToastContentBuilder;
/// <summary>
/// The scenario your toast is used for, like an alarm or reminder.
/// </summary>
/// <seealso>https://learn.microsoft.com/en-us/dotnet/api/microsoft.toolkit.uwp.notifications.toastcontent.scenario</seealso>
function Scenario(const Value: TToastScenario): TToastContentBuilder;
/// <summary>
/// The type of activation this header will use when clicked.
/// </summary>
function ActivationType(const Value: TActivationType): TToastContentBuilder;
/// <summary>
/// A string that is passed to the application when it is activated by the toast. The format and contents of this string are defined by the app for its own use. When the user taps or clicks the toast to launch its associated app, the launch string provides the context to the app that allows it to show the user a view relevant to the toast content, rather than launching in its default way.
/// </summary>
function Launch(const Value: string): TToastContentBuilder;
/// <summary>
/// Introduced in Creators Update: Overrides the default timestamp with a custom timestamp representing when your notification content was actually delivered, rather than the time the notification was received by the Windows platform.
/// </summary>
function DisplayTimestamp(const Value: TDateTime): TToastContentBuilder;
/// <summary>
/// Specifies whether styled buttons should be used. The styling of the button is determined by the **hint-buttonStyle** attribute of the action element.
/// </summary>
function UseButtonStyle(const Value: Boolean): TToastContentBuilder;
/// <summary>
/// The version of the toast XML schema this particular payload was developed for.
/// </summary>
function Version(const Value: Integer): TToastContentBuilder;
/// <summary>
/// The target locale of the XML payload, specified as BCP-47 language tags such as "en-US" or "fr-FR". This locale is overridden by any locale specified in binding or text. If this value is a literal string, this attribute defaults to the user's UI language. If this value is a string reference, this attribute defaults to the locale chosen by Windows Runtime in resolving the string.
/// </summary>
function Lang(const Value: string): TToastContentBuilder;
/// <summary>
/// A default base URI that is combined with relative URIs in image source attributes.
/// </summary>
function BaseUri(const Value: string): TToastContentBuilder;
/// <summary>
/// Set to "true" to allow Windows to append a query string to the image URI supplied in the toast notification. Use this attribute if your server hosts images and can handle query strings, either by retrieving an image variant based on the query strings or by ignoring the query string and returning the image as specified without the query string. This query string specifies scale, contrast setting, and language; for instance, a value of
/// "www.website.com/images/hello.png"
/// given in the notification becomes
/// "www.website.com/images/hello.png?ms-scale=100&ms-contrast=standard&ms-lang=en-us"
/// </summary>
function AddImageQuery(const Value: Boolean): TToastContentBuilder;
constructor Create;
destructor Destroy; override;
end;
TNotificationManager = class(TComponent)
private
const
VALUE_NAME = 'DisplayName';
VALUE_ICON = 'IconUri';
VALUE_ACTIVATOR = 'CustomActivator';
VALUE_SETTINGS = 'ShowInSettings';
VALUE_LAUNCH = 'LaunchUri';
private
FNotifier: IToastNotifier;
FNotifier2: IToastNotifier2;
FNotifierCollectionManager: IToastCollectionManager;
FAppID: string;
FRegPath: string;
FRegistry: TRegistry;
FRegSettingsPath: string;
procedure RebuildNotifier;
function HasRegistryRecord: boolean;
function GetModuleName: string;
function GetAppIcon: string;
function GetAppName: string;
function GetAppLaunch: string;
function GetAppActivator: string;
function GetShowSettings: boolean;
function GetHideLockScreen: Boolean;
function GetShowBanner: Boolean;
function GetShowInActionCenter: Boolean;
function GetRank: TNotificationRank;
function GetStatusInteractionCount: integer;
function GetStatusNotificationCount: integer;
procedure SetAppID(const Value: string);
procedure SetAppIcon(const Value: string);
procedure SetAppName(const Value: string);
procedure SetAppLaunch(const Value: string);
procedure SetAppActivator(const Value: string);
procedure SetShowSettings(const Value: Boolean);
procedure SetHideLockScreen(const Value: Boolean);
procedure SetShowBanner(const Value: Boolean);
procedure SetShowInActionCenter(const Value: Boolean);
procedure SetRank(const Value: TNotificationRank);