Windows Toast notifications - second try

Re: Windows Toast notifications - second try

Postby Antonio Linares » Fri Apr 15, 2016 7:21 am

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  RUN
#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
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42110
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Windows Toast notifications - second try

Postby Baxajaun » Fri Apr 15, 2016 7:39 am

Great !!!

Thanks !

Regards
User avatar
Baxajaun
 
Posts: 968
Joined: Wed Oct 19, 2005 2:17 pm
Location: Gatika. Bizkaia

Re: Windows Toast notifications - second try

Postby Silvio.Falconi » Fri Apr 15, 2016 10:38 am

Antonio,
but How it is compiled ? because here I have problems to compile it ?
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
 
Posts: 7063
Joined: Thu Oct 18, 2012 7:17 pm

Re: Windows Toast notifications - second try

Postby richard-service » Fri Apr 15, 2016 11:53 am

Antonio,

It's work.
Best Regards,

Richard

Harbour 3.2.0dev (r2402101027) => Borland C++ v7.7 32bit
MySQL v8.0 /ADS v10
Harbour 3.2.0dev (r2011030937) => Borland C++ v7.4 64bit
User avatar
richard-service
 
Posts: 803
Joined: Tue Oct 16, 2007 8:57 am
Location: New Taipei City, Taiwan

Re: Windows Toast notifications - second try

Postby norberto » Fri Apr 15, 2016 12:46 pm

Antonio, your test work fine here, can i use with xharbour and bcc or only with VS?

thanks
norberto
 
Posts: 566
Joined: Thu Aug 30, 2007 3:40 pm
Location: BR

Re: Windows Toast notifications - second try

Postby Antonio Linares » Fri Apr 15, 2016 2:06 pm

Norberto, Silvio,

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

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

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42110
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Windows Toast notifications - second try

Postby James Bott » Fri Apr 15, 2016 2:29 pm

Congrats, Antonio!

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

James
FWH 18.05/xHarbour 1.2.3/BCC7/Windows 10
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: Windows Toast notifications - second try

Postby Antonio Linares » Fri Apr 15, 2016 5:53 pm

Enhanced version

toast.prg
Code: Select all  Expand view  RUN
#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
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42110
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Windows Toast notifications - second try

Postby Antonio Linares » Fri Apr 15, 2016 7:03 pm

Images working :-)

Image

toast.prg
Code: Select all  Expand view  RUN
#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
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42110
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Windows Toast notifications - second try

Postby Silvio.Falconi » Sat Apr 16, 2016 10:32 am

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
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
 
Posts: 7063
Joined: Thu Oct 18, 2012 7:17 pm

Re: Windows Toast notifications - second try

Postby Silvio.Falconi » Sat Apr 16, 2016 4:47 pm

on win seven not run it need a api-ms.core-winrt-i1-1-0.dll
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
 
Posts: 7063
Joined: Thu Oct 18, 2012 7:17 pm

Re: Windows Toast notifications - second try

Postby Antonio Linares » Sun Apr 17, 2016 4:39 am

Silvio,

We are focused on Windows 10 now

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

viewtopic.php?p=189308#p189308
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42110
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Windows Toast notifications - second try

Postby norberto » Sun Apr 17, 2016 10:06 am

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
norberto
 
Posts: 566
Joined: Thu Aug 30, 2007 3:40 pm
Location: BR

Re: Windows Toast notifications - second try

Postby Antonio Linares » Sun Apr 17, 2016 11:41 am

Norberto,

We need to build a special WinRT support module

Lets see if we can build it
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42110
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Windows Toast notifications - second try

Postby Silvio.Falconi » Sun Apr 17, 2016 4:28 pm

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 ?
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
 
Posts: 7063
Joined: Thu Oct 18, 2012 7:17 pm

PreviousNext

Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 63 guests