如何使用ToastGeneric在Delphi中创建Toast通知 [英] How to create toast notification in delphi with ToastGeneric

查看:189
本文介绍了如何使用ToastGeneric在Delphi中创建Toast通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用delphi在桌面上进行开发。我想用ToastGeneric类型通知
创建Toast通知LToastFactory.CreateToastNotification(LXMLTemplate);

I am developing on Desktop with delphi. I would like to create toast notification with ToastGeneric type notification LToastFactory.CreateToastNotification(LXMLTemplate);

此外,我在
https://docs.microsoft.com/zh-cn/windows/uwp/controls-and-patterns / tiles-and-notifications-adaptive-interactive-toasts

我的问题是我如何使delphi接受此xml,但我还没有找到将字符串转换为Xml_Dom_IXmlDocument类型的方法。

My question is how can i make delphi to accept this xml, i haven't found a way to convert that string into Xml_Dom_IXmlDocument type.

推荐答案

我遇到了同样的问题。

我的目标是从Delphi创建一个使用toastGeneric的Toast通知。但是,我找不到通过操纵xml来实现此目的的任何语言的任何示例-所有示例都使用无法从Delphi访问的类。

My objective was to create a Toast notification from Delphi that uses toastGeneric. However, I could not find any examples in any language that do this by manipulating the xml - all the examples use classes that do not appear to be accessible from Delphi.

我的解决方案是创建一个标准模板,然后用自定义模板所需的xml覆盖该标准模板中的xml。以下是一些应该让您想到的Delphi代码。这是一个完整的控制台应用程序。该代码在Delphi 10.2 Tokyo下编译。早期版本可能需要进行一些调整。您将对 OverwriteToastTemplateXML 函数感兴趣。

My solution was to create a standard template and then overwrite the xml in that standard template with the xml required for a custom template. Below is some Delphi code that should give you the idea. It is a complete console app. This code compiles under Delphi 10.2 Tokyo. There may be some tweaks required for earlier versions. You will be interested in the OverwriteToastTemplateXML function.

我的代码基于标准Toast模板示例中引用Marco Cantu的博客文章中的最终评论: http:/ /blog.marcocantu.com/blog/2015-june-windows10-notifications-vcl-winrt.html

My code was based around a standard toast template example referenced in the final comment in Marco Cantu's blog post here: http://blog.marcocantu.com/blog/2015-june-windows10-notifications-vcl-winrt.html

请注意,我在XML中对英雄图片jpg文件。为使通知正常工作,请确保在c:\notifications\hero.jpg处有一个jpg,或在xml中将该行注释掉。

Note the reference in my XML to a 'hero' image jpg file. For the notification to work fully, make sure you have a jpg at c:\notifications\hero.jpg, or comment out that line in the xml.

除了将XML字符串转换为自定义的Toast模板之外,该代码还将Toast模板转换回为字符串,这对于调试非常有用-这是 ToastTemplateToString 函数。这些是我对原始示例的主要功能修改。根据我自己的理解,我还更改了示例代码的结构,以使变量作用域以及每一行代码与其他代码之间的关系也更加明显。

As well as converting an XML string into a custom toast template, the code also converts a toast template back into a string, which is useful for debugging - this is the ToastTemplateToString function. These are my main functional modifications to the original example. For my own understanding, I have also changed the structure of the example code, so that variable scope and how each line of code relates to the others is also more apparent.

让我知道这是否对您有用-我发现敬酒通知是Delphi的一项艰巨工作!

Let me know if this works for you - I have found that toast notification are hard work from Delphi!

欢呼声

Steve

program ConsoleNotifier;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,

  // Required to create the Toast Notification
  WinAPI.WinRT,
  WinAPI.DataRT,
  WinAPI.UI.Notifications,
  WinAPI.ActiveX,
  WinAPI.CommonTypes,

  // Required for creating the Desktop Shell Link
  WinAPI.PropKey,
  WinAPI.PropSys,
  WinAPI.ShlObj,
  System.Win.ComObj,
  Windows
  ;

function CreateDesktopShellLink(const TargetName: string): Boolean;

  function GetStartMenuFolder: string;
  var
    Buffer: array [0 .. MAX_PATH - 1] of Char;
  begin
    Result := '';
    GetEnvironmentVariable(PChar('APPDATA'), Buffer, MAX_PATH - 1);
    Result := Buffer + '\Microsoft\Windows\Start Menu\Programs\Desktop Delphi Toasts App.lnk';
  end;

var
  IObject: IUnknown;
  ISLink: IShellLink;
  IPFile: IPersistFile;
  LinkName: string;

  LStore: WinAPI.PropSys.IPropertyStore;
  LValue: TPropVariant;
begin
  Result := False;

  IObject := CreateComObject(CLSID_ShellLink);
  ISLink := IObject as IShellLink;
  IPFile := IObject as IPersistFile;
  LStore := IObject as WinAPI.PropSys.IPropertyStore;

  with ISLink
  do begin
    SetPath(PChar( ParamStr(0) ));
  end;
  ISLink.SetArguments(PChar(''));

  if Succeeded(InitPropVariantFromStringAsVector(PWideChar('Delphi.DesktopNotification.Sample'), LValue))
  then begin
    if Succeeded(LStore.SetValue(PKEY_AppUserModel_ID, LValue))
    then LStore.Commit;
  end;

  LinkName := GetStartMenuFolder;

  if not FileExists(LinkName)
  then
    if IPFile.Save(PWideChar(LinkName), True) = S_OK
    then Result := True;
end;

function HStr( Value:String ): HString;
begin
  if NOT Succeeded(
    WindowsCreateString(PWideChar(Value), Length(Value), Result)
  )
  then raise Exception.CreateFmt('Unable to create HString for %s', [ Value ] );
end;

function ToastTemplateToString( Const Template:Xml_Dom_IXmlDocument ): String;

  function HStringToString(Src: HSTRING): String;
  var
    c: Cardinal;
  begin
    c := WindowsGetStringLen(Src);
    Result := WindowsGetStringRawBuffer(Src, @c);
  end;

begin
  Result := HStringToString(
    ( Template.DocumentElement as Xml_Dom_IXmlNodeSerializer ).GetXml
  );
end;

function GetFactory( Const Name:String; Const GUID:String ): IInspectable;
var
  FactoryHString : HString;
  FactoryGUID    : TGUID;
begin
  FactoryHString := HStr( Name );
  try
    FactoryGUID := TGUID.Create(GUID);

    if NOT Succeeded(
      RoGetActivationFactory(FactoryHString, FactoryGUID, Result)
    )
    then raise Exception.CreateFmt('Error creating factory: %s %s', [ Name, GUID ] );
  finally
    WindowsDeleteString( FactoryHString );
  end;
end;

procedure OverwriteToastTemplateXML( Const Template: Xml_Dom_IXmlDocument; Const XML:String );
var
  hXML: HSTRING;
begin
  hXML := HStr( XML );
  try
    (Template as Xml_Dom_IXmlDocumentIO).LoadXml( hXML );
  finally
    WindowsDeleteString( hXML );
  end;
end;

procedure SteveNotification( Const AppID:String; Const XML:String );
var
  ToastNotificationManagerStatics : IToastNotificationManagerStatics;
  ToastTemplate                   : Xml_Dom_IXmlDocument;
  LToastNotification              : IToastNotification;
  ToastNotificationManagerFactory : IInspectable;
  ToastNotificationFactory        : IInspectable;
  hAppID                          : HString;
begin
  ToastNotificationManagerFactory := GetFactory( sToastNotificationManager, '{50AC103F-D235-4598-BBEF-98FE4D1A3AD4}' );
  ToastNotificationManagerStatics := IToastNotificationManagerStatics(ToastNotificationManagerFactory);
  ToastTemplate := ToastNotificationManagerStatics.GetTemplateContent(ToastTemplateType.ToastText01);

  OverwriteToastTemplateXML( ToastTemplate, XML );

  WriteLn( 'XML: ', ToastTemplateToString( ToastTemplate ) );

  ToastNotificationFactory := GetFactory( SToastNotification, '{04124B20-82C6-4229-B109-FD9ED4662B53}' );

  LToastNotification := IToastNotificationFactory(ToastNotificationFactory).CreateToastNotification(ToastTemplate);

  hAppID := HStr( AppID );
  try
    ToastNotificationManagerStatics
    .CreateToastNotifier( hAppID )
    .Show(LToastNotification);
  finally
    WindowsDeleteString( hAppID );
  end;
end;

Const
  AppID = 'My Application ID';
  XML   = '<toast activationType="protocol" launch="http://www.ecutek.com" >'
        + '  <visual>'
        + '    <binding template="ToastGeneric">'
        + '      <text>Body Text ABC</text>'
        + '      <text>More Text</text>'
        + '      <image placement="hero" src="file:///c:\notifications\hero.jpg"/>'
        + '    </binding>'
        + '  </visual>'
        + '  <actions>'
        + '    <action content="Open Google" activationType="protocol" arguments="http://www.google.com" />'
        + '  </actions>'
        + '</toast>';

var
  c : char;
begin
  try
    if TOSVersion.Major < 10
    then raise Exception.Create('Windows 10 Required');

    RoInitialize(RO_INIT_MULTITHREADED);

    CreateDesktopShellLink( ParamStr(0) );

    SteveNotification( AppID, XML );

    // Wait for a KeyPress
    Read( c ); write( c );
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

这篇关于如何使用ToastGeneric在Delphi中创建Toast通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆