This toast notification works very well from the desktop with XE8 With Windows 10, but I can not figure out how to add a text line to the notification. iTitle is displayed but iMessage is not. This is all new to me so I do not know which direction to pursue.
Fifth edit....
Remy's excellent show toast procedure is a big improvement over the original Embaracdero code, but I don't think Remy actually tested the code because it would not compile as written. I had to change TWindowString to TWindowsString and IXmlNode to Xml_Dom_IXmlNode to get it to compile.
The following actually compiles but it generates an access violation in the GetActivationFactory function.
If we can get this to function correctly it will be a big improvement over the original Embarcadero code and should be of value to other developers.
procedure TForm1.ShowToast(const AMessage: String; const ATitle: String = '');
{ Send a Toast Notification }
var
LINotificationManagerStatics: IToastNotificationManagerStatics;
LToast: IToastNotification;
LToastFactory: IToastNotificationFactory;
LToastNotifier: IToastNotifier;
LToastTemplateType: ToastTemplateType;
LAccepted: TAcceptedEventHandler;
LXMLTemplate: Xml_Dom_IXmlDocument;
iTextNode: Xml_Dom_IXmlNode;
LTextNodeList: Xml_Dom_IXmlNodeList;
function GetActivationFactory(const ClassId: String; const Iid: String): IInspectable;
begin
OleCheck(RoGetActivationFactory(TWindowsString(ClassId), TGUID.Create(Iid), Result));
// This produces an access violation at run time
end;
begin
LINotificationManagerStatics := GetActivationFactory(SToastNotificationManager, '{50AC103F-D235-4598-BBEF-98FE4D1A3AD4}') as IToastNotificationManagerStatics;
LToastNotifier := LINotificationManagerStatics.CreateToastNotifier(TWindowsString(Edit1.Text));
if ATitle <> '' then begin
LToastTemplateType := ToastTemplateType.ToastText02;
end else begin
LToastTemplateType := ToastTemplateType.ToastText01;
end;
LXMLTemplate := LINotificationManagerStatics.GetTemplateContent(LToastTemplateType);
LTextNodeList := LXMLTemplate.getElementsByTagName(TWindowsString('text'));
if ATitle <> '' then
begin
LTextNodeList.Item(0).AppendChild(LXMLTemplate.CreateTextNode(TWindowsString(ATitle)) as Xml_Dom_IXmlNode);
iTextNode := LTextNodeList.Item(1);
end else begin
iTextNode := LTextNodeList.Item(0);
end;
iTextNode.AppendChild(LXMLTemplate.CreateTextNode(TWindowsString(AMessage)) as Xml_Dom_IXmlNode);
LToastFactory := GetActivationFactory(SToastNotification, '{04124B20-82C6-4229-B109-FD9ED4662B53}') as IToastNotificationFactory;
LToast := LToastFactory.CreateToastNotification(LXMLTemplate);
LAccepted := TAcceptedEventHandler.Create;
LToast.add_Activated(LAccepted);
LToastNotifier.Show(LToast);
end;
After much debugging I finally was successful getting the Toast Notification to display a Title and a message. It turns out I had to use a modified version of Remy's answer in combination with some of the Embaracdero's original demo code to get it to work.
Thank you Remy! I did not think I was going to get there but I finally did. To save others who are trying to do this a lot of grief my working code is shown below:
procedure TForm1.ShowToast(const AMessage: String; const ATitle: String = '');
{ Send a Toast Notification }
var
LINotificationManagerStatics: IToastNotificationManagerStatics;
LToast: IToastNotification;
LToastFactory: IToastNotificationFactory;
LToastNotifier: IToastNotifier;
LClassId: HString;
LAccepted: TAcceptedEventHandler;
LXMLTemplate: Xml_Dom_IXmlDocument;
iTextNode: Xml_Dom_IXmlNode;
LTextNodeList: Xml_Dom_IXmlNodeList;
LTagName: HString;
LTitle: HString;
LMessage: HString;
function GetActivationFactory(const ClassId: String; const Iid: String)
: IInspectable;
begin
if Succeeded(WindowsCreateString(PWideChar(ClassId), Length(ClassId),
LClassId)) then
OleCheck(RoGetActivationFactory(LClassId, TGUID.Create(Iid), Result));
end;
begin
LINotificationManagerStatics := GetActivationFactory
(SToastNotificationManager, '{50AC103F-D235-4598-BBEF-98FE4D1A3AD4}')
as IToastNotificationManagerStatics;
if Succeeded(WindowsCreateString(PWideChar(NotificationTitle1.Text),
Length(NotificationTitle1.Text), LClassId)) then
LToastNotifier := LINotificationManagerStatics.CreateToastNotifier
(LClassId);
LXMLTemplate := LINotificationManagerStatics.GetTemplateContent
(ToastTemplateType.ToastText02);
if Succeeded(WindowsCreateString(PWideChar('text'), Length('text'), LTagName))
then
LTextNodeList := LXMLTemplate.getElementsByTagName(LTagName);
if ATitle <> '' then
begin
if Succeeded(WindowsCreateString(PWideChar(ATitle), Length(ATitle), LTitle))
then
LTextNodeList.Item(0).AppendChild(LXMLTemplate.CreateTextNode(LTitle)
as Xml_Dom_IXmlNode);
iTextNode := LTextNodeList.Item(1);
end
else
begin
iTextNode := LTextNodeList.Item(0);
end;
if Succeeded(WindowsCreateString(PWideChar(AMessage), Length(AMessage),
LMessage)) then
iTextNode.AppendChild(LXMLTemplate.CreateTextNode(LMessage)
as Xml_Dom_IXmlNode);
LToastFactory := GetActivationFactory(SToastNotification,
'{04124B20-82C6-4229-B109-FD9ED4662B53}') as IToastNotificationFactory;
LToast := LToastFactory.CreateToastNotification(LXMLTemplate);
LAccepted := TAcceptedEventHandler.Create;
LToast.add_Activated(LAccepted);
LToastNotifier.Show(LToast);
end;
Usage:
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowToast(NotificationMessage1.Text, NotificationTitle1.Text);
end;