如何将文本节点添加到 toast 通知
How to add a text node to a toast notification
此 Toast 通知在 XE8 和 Windows 10 的桌面上工作得很好,但我不知道如何向通知添加文本行。显示 iTitle 但不显示 iMessage。这对我来说都是新的,所以我不知道该往哪个方向走。
第五次编辑....
Remy 出色的 show toast 程序是对原始 Embaracdero 代码的重大改进,但我不认为 Remy 实际测试了代码,因为它不会像编写的那样编译。我必须将 TWindowString 更改为 TWindowsString 并将 IXmlNode 更改为 Xml_Dom_IXmlNode 才能编译。
以下内容实际编译但在 GetActivationFactory 函数中生成访问冲突。
如果我们能让它正常运行,这将是对原始 Embarcadero 代码的重大改进,应该对其他开发人员有价值。
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;
IXmlDocument.CreateTextNode()
创建并 returns 一个新的文本节点,但不会将其添加到 XML 文档中。您必须单独添加它。这甚至在 Toast 文档中得到了证明:
Quickstart: Sending a toast notification (HTML)
Quickstart: Sending a toast notification (XAML)
例如:
var
...
LTagName: HString;
...
if Succeeded(WindowsCreateString(PWideChar(iMessage), Length(iMessage), LString3)) then
try
if Succeeded(WindowsCreateString(PWideChar('text'), 4, LTagName)) then
try
LXMLTemplate.getElementsByTagName(LTagName).Item(0).AppendChild(LXMLTemplate.CreateTextNode(LString3) as IXmlNode);
...
finally
WindowsDeleteString(LTagName);
end;
...
finally
WindowsDeleteString(LString3);
end;
...
或者,使用 IXmlNode.InnerText
属性 而不是 IXmlDocument.CreateTextNode()
方法:
LXMLTemplate.getElementsByTagName(LTagName).Item(0).InnerText := LString3;
坦率地说,Embarcadero's example,您的代码基于它,有点乱。它可能需要一些认真的清理工作。
试试像这样的东西:
uses
...,
System.SysUtils,
System.Win.ComObj,
Winapi.Data,
System.WinrtHelpers; // see https://github.com/tgerdes/DelphiWinRT/blob/master/System.WinrtHelpers.pas
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowToast('The recycle bin is empty', 'Recycle Bin Is Empty');
end;
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));
end;
begin
LINotificationManagerStatics := GetActivationFactory(SToastNotificationManager, '{50AC103F-D235-4598-BBEF-98FE4D1A3AD4}') as IToastNotificationManagerStatics;
LToastNotifier := LINotificationManagerStatics.CreateToastNotifier(TWindowString(Edit1.Text));
if ATitle <> '' then begin
LToastTemplateType := ToastTemplateType.ToastText02;
end else begin
LToastTemplateType := ToastTemplateType.ToastText01;
end;
LXMLTemplate := LINotificationManagerStatics.GetTemplateContent(LToastTemplateType);
LTextNodeList := LXMLTemplate.getElementsByTagName(TWindowString('text'));
if ATitle <> '' then
begin
LTextNodeList.Item(0).AppendChild(LXMLTemplate.CreateTextNode(TWindowString(ATitle)) as IXmlNode);
iTextNode := LTextNodeList.Item(1);
end else begin
iTextNode := LTextNodeList.Item(0);
end;
iTextNode.AppendChild(LXMLTemplate.CreateTextNode(TWindowString(AMessage)) as 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;
经过多次调试,我终于成功地让 Toast 通知显示标题和消息。事实证明,我必须结合使用 Remy 答案的修改版本和 Embaracdero 的一些原始演示代码才能使其正常工作。
谢谢雷米!我不认为我会到达那里,但我终于做到了。
为了让其他尝试这样做的人免去很多痛苦,我的工作代码如下所示:
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;
用法:
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowToast(NotificationMessage1.Text, NotificationTitle1.Text);
end;
此 Toast 通知在 XE8 和 Windows 10 的桌面上工作得很好,但我不知道如何向通知添加文本行。显示 iTitle 但不显示 iMessage。这对我来说都是新的,所以我不知道该往哪个方向走。
第五次编辑....
Remy 出色的 show toast 程序是对原始 Embaracdero 代码的重大改进,但我不认为 Remy 实际测试了代码,因为它不会像编写的那样编译。我必须将 TWindowString 更改为 TWindowsString 并将 IXmlNode 更改为 Xml_Dom_IXmlNode 才能编译。
以下内容实际编译但在 GetActivationFactory 函数中生成访问冲突。
如果我们能让它正常运行,这将是对原始 Embarcadero 代码的重大改进,应该对其他开发人员有价值。
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;
IXmlDocument.CreateTextNode()
创建并 returns 一个新的文本节点,但不会将其添加到 XML 文档中。您必须单独添加它。这甚至在 Toast 文档中得到了证明:
Quickstart: Sending a toast notification (HTML)
Quickstart: Sending a toast notification (XAML)
例如:
var
...
LTagName: HString;
...
if Succeeded(WindowsCreateString(PWideChar(iMessage), Length(iMessage), LString3)) then
try
if Succeeded(WindowsCreateString(PWideChar('text'), 4, LTagName)) then
try
LXMLTemplate.getElementsByTagName(LTagName).Item(0).AppendChild(LXMLTemplate.CreateTextNode(LString3) as IXmlNode);
...
finally
WindowsDeleteString(LTagName);
end;
...
finally
WindowsDeleteString(LString3);
end;
...
或者,使用 IXmlNode.InnerText
属性 而不是 IXmlDocument.CreateTextNode()
方法:
LXMLTemplate.getElementsByTagName(LTagName).Item(0).InnerText := LString3;
坦率地说,Embarcadero's example,您的代码基于它,有点乱。它可能需要一些认真的清理工作。
试试像这样的东西:
uses
...,
System.SysUtils,
System.Win.ComObj,
Winapi.Data,
System.WinrtHelpers; // see https://github.com/tgerdes/DelphiWinRT/blob/master/System.WinrtHelpers.pas
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowToast('The recycle bin is empty', 'Recycle Bin Is Empty');
end;
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));
end;
begin
LINotificationManagerStatics := GetActivationFactory(SToastNotificationManager, '{50AC103F-D235-4598-BBEF-98FE4D1A3AD4}') as IToastNotificationManagerStatics;
LToastNotifier := LINotificationManagerStatics.CreateToastNotifier(TWindowString(Edit1.Text));
if ATitle <> '' then begin
LToastTemplateType := ToastTemplateType.ToastText02;
end else begin
LToastTemplateType := ToastTemplateType.ToastText01;
end;
LXMLTemplate := LINotificationManagerStatics.GetTemplateContent(LToastTemplateType);
LTextNodeList := LXMLTemplate.getElementsByTagName(TWindowString('text'));
if ATitle <> '' then
begin
LTextNodeList.Item(0).AppendChild(LXMLTemplate.CreateTextNode(TWindowString(ATitle)) as IXmlNode);
iTextNode := LTextNodeList.Item(1);
end else begin
iTextNode := LTextNodeList.Item(0);
end;
iTextNode.AppendChild(LXMLTemplate.CreateTextNode(TWindowString(AMessage)) as 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;
经过多次调试,我终于成功地让 Toast 通知显示标题和消息。事实证明,我必须结合使用 Remy 答案的修改版本和 Embaracdero 的一些原始演示代码才能使其正常工作。
谢谢雷米!我不认为我会到达那里,但我终于做到了。 为了让其他尝试这样做的人免去很多痛苦,我的工作代码如下所示:
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;
用法:
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowToast(NotificationMessage1.Text, NotificationTitle1.Text);
end;