Page 2 of 6

Re: Windows Toast notifications - second try

PostPosted: Fri Apr 15, 2016 7:21 am
by Antonio Linares
Its working! :-)

Download the EXE and try it on your Windows 10:
https://bitbucket.org/fivetech/fivewin-contributions/downloads/toast.zip

Image

Image

toast.prg
Code: Select all  Expand view
#include "FiveWin.ch"

function Main()

   Toast()

return nil

#pragma BEGINDUMP

#include <Windows.h>
#include <psapi.h>
#include <Shobjidl.h>
#include <Propvarutil.h>
#include <propkey.h>
#include <wrl\client.h>
#include <windows.ui.notifications.h>
#include <hbapi.h>

using namespace Microsoft::WRL;
using namespace ABI::Windows::UI::Notifications;
using namespace ABI::Windows::Data::Xml::Dom;
using namespace Windows::Foundation;

static HRESULT InstallShortcut(_In_z_ wchar_t *shortcutPath)
{
    wchar_t exePath[MAX_PATH];
   
    DWORD charWritten = GetModuleFileNameEx(GetCurrentProcess(), nullptr, ( LPSTR ) exePath, ARRAYSIZE(exePath));

    HRESULT hr = charWritten > 0 ? S_OK : E_FAIL;
   
    if (SUCCEEDED(hr))
    {
        ComPtr<IShellLink> shellLink;
        hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shellLink));

        if (SUCCEEDED(hr))
        {
            hr = shellLink->SetPath((LPCSTR)exePath);
            if (SUCCEEDED(hr))
            {
                hr = shellLink->SetArguments((LPCSTR)L"");
                if (SUCCEEDED(hr))
                {
                    ComPtr<IPropertyStore> propertyStore;

                    hr = shellLink.As(&propertyStore);
                    if (SUCCEEDED(hr))
                    {
                        PROPVARIANT appIdPropVar;
                        hr = InitPropVariantFromString(L"FiveTech.FiveWin.samples", &appIdPropVar);
                        if (SUCCEEDED(hr))
                        {
                            hr = propertyStore->SetValue(PKEY_AppUserModel_ID, appIdPropVar);
                            if (SUCCEEDED(hr))
                            {
                                hr = propertyStore->Commit();
                                if (SUCCEEDED(hr))
                                {
                                    ComPtr<IPersistFile> persistFile;
                                    hr = shellLink.As(&persistFile);
                                    if (SUCCEEDED(hr))
                                    {
                                        hr = persistFile->Save(shortcutPath, TRUE);
                                    }
                                }
                            }
                            PropVariantClear(&appIdPropVar);
                        }
                    }
                }
            }
        }
    }
    return hr;
}

static HRESULT TryCreateShortcut( void )
{
   wchar_t shortcutPath[MAX_PATH];
   DWORD charWritten = GetEnvironmentVariableW( L"APPDATA", shortcutPath, MAX_PATH );
   HRESULT hr = charWritten > 0 ? S_OK : E_INVALIDARG;

    if (SUCCEEDED(hr))
    {
        errno_t concatError = wcscat_s(shortcutPath, ARRAYSIZE(shortcutPath), L"\\Microsoft\\Windows\\Start Menu\\Programs\\Desktop Toasts App.lnk");
 
        hr = concatError == 0 ? S_OK : E_INVALIDARG;
        if (SUCCEEDED(hr))
        {
            DWORD attributes = GetFileAttributes( ( LPCSTR ) shortcutPath );
            bool fileExists = attributes < 0xFFFFFFF;

            if (!fileExists)
            {
                hr = InstallShortcut(shortcutPath);  // See step 2.
            }
            else
            {
                hr = S_FALSE;
            }
        }
    }
    return hr;
}

HB_FUNC( TOAST )
{
   ComPtr<IToastNotificationManagerStatics> toastStatics;
   HSTRING hs = 0;
   HRESULT hr = WindowsCreateString( RuntimeClass_Windows_UI_Notifications_ToastNotificationManager,
                                     wcslen( RuntimeClass_Windows_UI_Notifications_ToastNotificationManager ), &hs );
                         
   CoInitialize( NULL );

   hr = TryCreateShortcut();

   hr = GetActivationFactory( hs, toastStatics.GetAddressOf() );

   if( toastStatics )
   {
      ComPtr<IXmlDocument> toastXml;
      ComPtr<IToastNotifier> notifier;
      ComPtr<IToastNotification> notification;
      ComPtr<IToastNotificationFactory> factory;
     
      hr = toastStatics->GetTemplateContent( ToastTemplateType::ToastTemplateType_ToastText01, &toastXml );
     
      ComPtr<IXmlNodeList> toastTextElements, toastImageElements;
      ComPtr<IXmlNode> titleTextNodeRoot, msgTextNodeRoot, imageNodeRoot, srcAttribute;

      // HSTRING title, msg, imagePath;
      HSTRING textNodeStr, imageNodeStr, srcNodeStr;
      HSTRING_HEADER textHeader, imageHeader, srcHeader;
 
      WindowsCreateStringReference( L"text", 4, &textHeader, &textNodeStr );
      WindowsCreateStringReference( L"image", 5, &imageHeader, &imageNodeStr );
      WindowsCreateStringReference( L"src", 3, &srcHeader, &srcNodeStr );
     
      toastXml->GetElementsByTagName( textNodeStr, &toastTextElements );
      toastXml->GetElementsByTagName( imageNodeStr, &toastImageElements );

      toastTextElements->Item( 0, &titleTextNodeRoot );
      toastTextElements->Item( 1, &msgTextNodeRoot );
      toastImageElements->Item( 0, &imageNodeRoot );

      ComPtr<IXmlNamedNodeMap> attributes;
      // imageNodeRoot->get_Attributes( &attributes );
      // attributes->GetNamedItem( srcNodeStr, &srcAttribute );

      // SetNodeValueString( title, titleTextNodeRoot.Get(), toastXml.Get());
      // SetNodeValueString( msg, msgTextNodeRoot.Get(), toastXml.Get());
      // SetNodeValueString( imagePath, srcAttribute.Get(), toastXml.Get());
 
      hr = WindowsCreateString( RuntimeClass_Windows_UI_Notifications_ToastNotification,
                                wcslen( RuntimeClass_Windows_UI_Notifications_ToastNotification ), &hs );  
                               
      hr = GetActivationFactory( hs, &factory );

      hr = factory->CreateToastNotification( toastXml.Get(), &notification );

      hr = WindowsCreateString( L"FiveWin", wcslen( L"FiveWin" ), &hs );  

      hr = toastStatics->CreateToastNotifierWithId( hs, &notifier );
     
      hr = notifier->Show( notification.Get() );
   }    
}

#pragma ENDDUMP

Re: Windows Toast notifications - second try

PostPosted: Fri Apr 15, 2016 7:39 am
by Baxajaun
Great !!!

Thanks !

Regards

Re: Windows Toast notifications - second try

PostPosted: Fri Apr 15, 2016 10:38 am
by Silvio.Falconi
Antonio,
but How it is compiled ? because here I have problems to compile it ?

Re: Windows Toast notifications - second try

PostPosted: Fri Apr 15, 2016 11:53 am
by richard-service
Antonio,

It's work.

Re: Windows Toast notifications - second try

PostPosted: Fri Apr 15, 2016 12:46 pm
by norberto
Antonio, your test work fine here, can i use with xharbour and bcc or only with VS?

thanks

Re: Windows Toast notifications - second try

PostPosted: Fri Apr 15, 2016 2:06 pm
by Antonio Linares
Norberto, Silvio,

I am using VSC2015 (Visual Studio Community 2015) to implement it.

later on, I will try to build it using Borland too

Re: Windows Toast notifications - second try

PostPosted: Fri Apr 15, 2016 2:29 pm
by James Bott
Congrats, Antonio!

I'm looking forward to trying it when you have a Borland version running.

James

Re: Windows Toast notifications - second try

PostPosted: Fri Apr 15, 2016 5:53 pm
by Antonio Linares
Enhanced version

toast.prg
Code: Select all  Expand view
#include "FiveWin.ch"

function Main()

   Toast( "Harbour and FWH power", "it is working", "three lines" )

return nil

#pragma BEGINDUMP

#include <Windows.h>
#include <psapi.h>
#include <Shobjidl.h>
#include <Propvarutil.h>
#include <propkey.h>
#include <wrl\client.h>
#include <windows.ui.notifications.h>
#include <hbapi.h>

using namespace Microsoft::WRL;
using namespace ABI::Windows::UI::Notifications;
using namespace ABI::Windows::Data::Xml::Dom;
using namespace Windows::Foundation;

extern "C" {
LPWSTR UTF8toUTF16( LPCSTR utf8 );
}

static void InstallShortcut( wchar_t * shortcutPath )
{
    wchar_t exePath[ MAX_PATH] ;
    ComPtr<IShellLink> shellLink;
    ComPtr<IPropertyStore> propertyStore;
    PROPVARIANT appIdPropVar;
    ComPtr<IPersistFile> persistFile;
   
    DWORD charWritten = GetModuleFileNameEx( GetCurrentProcess(), nullptr,
                                             ( LPSTR ) exePath, ARRAYSIZE( exePath ) );

    CoCreateInstance( CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &shellLink ) );
    shellLink->SetPath( ( LPCSTR ) exePath );
    shellLink->SetArguments( ( LPCSTR ) L"" );

    shellLink.As( &propertyStore );
    InitPropVariantFromString( L"FiveTech.FiveWin.samples", &appIdPropVar );
                       
    propertyStore->SetValue( PKEY_AppUserModel_ID, appIdPropVar);
    propertyStore->Commit();
                               
    shellLink.As( &persistFile );
    persistFile->Save( shortcutPath, TRUE );
    PropVariantClear( &appIdPropVar );
}

static void TryCreateShortcut( void )
{
   wchar_t shortcutPath[ MAX_PATH ];
   DWORD charWritten = GetEnvironmentVariableW( L"APPDATA", shortcutPath, MAX_PATH );

   errno_t concatError = wcscat_s( shortcutPath, ARRAYSIZE( shortcutPath ),
                                   L"\\Microsoft\\Windows\\Start Menu\\Programs\\Desktop Toasts App.lnk" );
 
   if( GetFileAttributes( ( LPCSTR ) shortcutPath ) >= 0xFFFFFFF )
      InstallShortcut( shortcutPath );
}

static void SetNodeValueString( const char * szText, IXmlNode * node, IXmlDocument * xml )
{
   LPWSTR pW = UTF8toUTF16( szText );
   HSTRING hs;
   ComPtr<IXmlText> inputText;
   ComPtr<IXmlNode> inputTextNode;
   ComPtr<IXmlNode> pAppendedChild;
   
   WindowsCreateString( pW, wcslen( pW ), &hs );  
   hb_xfree( pW );
   xml->CreateTextNode( hs, &inputText );
   WindowsDeleteString( hs );    
   inputText.As( &inputTextNode );
   node->AppendChild( inputTextNode.Get(), &pAppendedChild );
}

HB_FUNC( TOAST )
{
   ComPtr<IToastNotificationManagerStatics> toastStatics;
   HSTRING hs = 0; LPWSTR pW; int i;
       
   CoInitialize( NULL );

   TryCreateShortcut();

   WindowsCreateString( RuntimeClass_Windows_UI_Notifications_ToastNotificationManager,
                        wcslen( RuntimeClass_Windows_UI_Notifications_ToastNotificationManager ), &hs );
   GetActivationFactory( hs, toastStatics.GetAddressOf() );
   WindowsDeleteString( hs );

   ComPtr<IXmlDocument> toastXml;
   ComPtr<IToastNotifier> notifier;
   ComPtr<IToastNotification> notification;
   ComPtr<IToastNotificationFactory> factory;
     
   toastStatics->GetTemplateContent( ToastTemplateType::ToastTemplateType_ToastText04, &toastXml );
     
   ComPtr<IXmlNodeList> toastTextElements, toastImageElements;
   ComPtr<IXmlNode> xmlNode;

   WindowsCreateString( L"text", wcslen( L"text" ), &hs );
   toastXml->GetElementsByTagName( hs, &toastTextElements );
   WindowsDeleteString( hs );

   WindowsCreateString( L"image", wcslen( L"image" ), &hs );
   toastXml->GetElementsByTagName( hs, &toastImageElements );
   WindowsDeleteString( hs );

   for( i = 0; i < 3; i++ )
   {
      if( HB_ISCHAR( i + 1 ) )
      {
         toastTextElements->Item( i, &xmlNode );
         SetNodeValueString( hb_parc( i + 1 ), xmlNode.Get(), toastXml.Get() );
      }  
   }

   WindowsCreateString( RuntimeClass_Windows_UI_Notifications_ToastNotification,
                        wcslen( RuntimeClass_Windows_UI_Notifications_ToastNotification ), &hs );  
   GetActivationFactory( hs, &factory );
   WindowsDeleteString( hs );    

   factory->CreateToastNotification( toastXml.Get(), &notification );

   pW = UTF8toUTF16( "FiveTech" );
   WindowsCreateString( pW, wcslen( pW ), &hs );  
   hb_xfree( pW );
   toastStatics->CreateToastNotifierWithId( hs, &notifier );
   WindowsDeleteString( hs );
     
   notifier->Show( notification.Get() );
}

#pragma ENDDUMP

Re: Windows Toast notifications - second try

PostPosted: Fri Apr 15, 2016 7:03 pm
by Antonio Linares
Images working :-)

Image

toast.prg
Code: Select all  Expand view
#include "FiveWin.ch"

function Main()

   Toast( "Harbour and FWH power", "it is working", "three lines",;
          "file://c:\fwh\bitmaps\pngs\fivetech.png" )

return nil

#pragma BEGINDUMP

#include <Windows.h>
#include <psapi.h>
#include <Shobjidl.h>
#include <Propvarutil.h>
#include <propkey.h>
#include <wrl\client.h>
#include <windows.ui.notifications.h>
#include <hbapi.h>

using namespace Microsoft::WRL;
using namespace ABI::Windows::UI::Notifications;
using namespace ABI::Windows::Data::Xml::Dom;
using namespace Windows::Foundation;

extern "C" {
LPWSTR UTF8toUTF16( LPCSTR utf8 );
}

static void InstallShortcut( wchar_t * shortcutPath )
{
    wchar_t exePath[ MAX_PATH] ;
    ComPtr<IShellLink> shellLink;
    ComPtr<IPropertyStore> propertyStore;
    PROPVARIANT appIdPropVar;
    ComPtr<IPersistFile> persistFile;
   
    DWORD charWritten = GetModuleFileNameEx( GetCurrentProcess(), nullptr,
                                             ( LPSTR ) exePath, ARRAYSIZE( exePath ) );

    CoCreateInstance( CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &shellLink ) );
    shellLink->SetPath( ( LPCSTR ) exePath );
    shellLink->SetArguments( ( LPCSTR ) L"" );

    shellLink.As( &propertyStore );
    InitPropVariantFromString( L"FiveTech.FiveWin.samples", &appIdPropVar );
                       
    propertyStore->SetValue( PKEY_AppUserModel_ID, appIdPropVar);
    propertyStore->Commit();
                               
    shellLink.As( &persistFile );
    persistFile->Save( shortcutPath, TRUE );
    PropVariantClear( &appIdPropVar );
}

static void TryCreateShortcut( void )
{
   wchar_t shortcutPath[ MAX_PATH ];
   DWORD charWritten = GetEnvironmentVariableW( L"APPDATA", shortcutPath, MAX_PATH );

   errno_t concatError = wcscat_s( shortcutPath, ARRAYSIZE( shortcutPath ),
                                   L"\\Microsoft\\Windows\\Start Menu\\Programs\\Desktop Toasts App.lnk" );
 
   if( GetFileAttributes( ( LPCSTR ) shortcutPath ) >= 0xFFFFFFF )
      InstallShortcut( shortcutPath );
}

static void SetNodeValueString( const char * szText, IXmlNode * node, IXmlDocument * xml )
{
   LPWSTR pW = UTF8toUTF16( szText );
   HSTRING hs;
   ComPtr<IXmlText> inputText;
   ComPtr<IXmlNode> inputTextNode;
   ComPtr<IXmlNode> pAppendedChild;
   
   WindowsCreateString( pW, wcslen( pW ), &hs );  
   hb_xfree( pW );
   xml->CreateTextNode( hs, &inputText );
   WindowsDeleteString( hs );    
   inputText.As( &inputTextNode );
   node->AppendChild( inputTextNode.Get(), &pAppendedChild );
}

static void SetImageSrc( LPCSTR imagePath, IXmlDocument * toastXml )
{
   HSTRING hs;
   HRESULT hr;

   ComPtr<IXmlNodeList> nodeList;
   WindowsCreateString( L"image", wcslen( L"image" ), &hs );
   hr = toastXml->GetElementsByTagName( hs, &nodeList );
   WindowsDeleteString( hs );

   ComPtr<IXmlNode> imageNode;
   hr = nodeList->Item( 0, &imageNode );

   ComPtr<IXmlNamedNodeMap> attributes;
   hr = imageNode->get_Attributes( &attributes );

   ComPtr<IXmlNode> srcAttribute;
   WindowsCreateString( L"src", wcslen( L"src" ), &hs );
   attributes->GetNamedItem( hs, &srcAttribute );
   WindowsDeleteString( hs );

   SetNodeValueString( imagePath, srcAttribute.Get(), toastXml );
}

HB_FUNC( TOAST )
{
   ComPtr<IToastNotificationManagerStatics> toastStatics;
   HSTRING hs = 0; LPWSTR pW; int i;
       
   CoInitialize( NULL );

   TryCreateShortcut();

   WindowsCreateString( RuntimeClass_Windows_UI_Notifications_ToastNotificationManager,
                        wcslen( RuntimeClass_Windows_UI_Notifications_ToastNotificationManager ), &hs );
   GetActivationFactory( hs, toastStatics.GetAddressOf() );
   WindowsDeleteString( hs );

   ComPtr<IXmlDocument> toastXml;
   ComPtr<IToastNotifier> notifier;
   ComPtr<IToastNotification> notification;
   ComPtr<IToastNotificationFactory> factory;
     
   toastStatics->GetTemplateContent( ToastTemplateType::ToastTemplateType_ToastImageAndText04, &toastXml );
     
   ComPtr<IXmlNodeList> toastTextElements;
   ComPtr<IXmlNode> xmlNode;

   WindowsCreateString( L"text", wcslen( L"text" ), &hs );
   toastXml->GetElementsByTagName( hs, &toastTextElements );
   WindowsDeleteString( hs );

   for( i = 0; i < 3; i++ )
   {
      if( HB_ISCHAR( i + 1 ) )
      {
         toastTextElements->Item( i, &xmlNode );
         SetNodeValueString( hb_parc( i + 1 ), xmlNode.Get(), toastXml.Get() );
      }  
   }

   if( HB_ISCHAR( 4 ) )
      SetImageSrc( hb_parc( 4 ), toastXml.Get() );

   WindowsCreateString( RuntimeClass_Windows_UI_Notifications_ToastNotification,
                        wcslen( RuntimeClass_Windows_UI_Notifications_ToastNotification ), &hs );  
   GetActivationFactory( hs, &factory );
   WindowsDeleteString( hs );    

   factory->CreateToastNotification( toastXml.Get(), &notification );

   pW = UTF8toUTF16( "FiveTech" );
   WindowsCreateString( pW, wcslen( pW ), &hs );  
   hb_xfree( pW );
   toastStatics->CreateToastNotifierWithId( hs, &notifier );
   WindowsDeleteString( hs );
     
   notifier->Show( notification.Get() );
}

#pragma ENDDUMP

Re: Windows Toast notifications - second try

PostPosted: Sat Apr 16, 2016 10:32 am
by Silvio.Falconi
it need the possibility to insert a button for close the toast ( at right) and another ( at left ) to open a user function
I hope you make the borland version

Re: Windows Toast notifications - second try

PostPosted: Sat Apr 16, 2016 4:47 pm
by Silvio.Falconi
on win seven not run it need a api-ms.core-winrt-i1-1-0.dll

Re: Windows Toast notifications - second try

PostPosted: Sun Apr 17, 2016 4:39 am
by Antonio Linares
Silvio,

We are focused on Windows 10 now

This will be the code for Borland once it is ready:

viewtopic.php?p=189308#p189308

Re: Windows Toast notifications - second try

PostPosted: Sun Apr 17, 2016 10:06 am
by norberto
Antonio, it would be very interesting to do this also with email, calendar, people, translator, native and free Windows 10 applications, native interact with these applications to our programs in fwh. Thank you

Re: Windows Toast notifications - second try

PostPosted: Sun Apr 17, 2016 11:41 am
by Antonio Linares
Norberto,

We need to build a special WinRT support module

Lets see if we can build it

Re: Windows Toast notifications - second try

PostPosted: Sun Apr 17, 2016 4:28 pm
by Silvio.Falconi
Antonio Linares wrote:Silvio,

We are focused on Windows 10 now

This will be the code for Borland once it is ready:

viewtopic.php?p=189308#p189308


where I can download combase.dll ?