#include "FiveWin.ch"
function Main()
MsgInfo( NumToHex( 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"FiveWin", &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;
// MessageBoxW( 0, L"path", shortcutPath, 0 );
if( ! SUCCEEDED( hr ) )
{
MessageBox( 0, "TryCreateShortcut", ( LPSTR ) shortcutPath, 0 );
hb_retni( hr );
return hr;
}
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 );
// RoInitialize( RO_INIT_MULTITHREADED );
hr = TryCreateShortcut();
if( ! SUCCEEDED( hr ) )
{
MessageBox( 0, "TryCreateShortcut", "error", 0 );
hb_retni( hr );
return;
}
hr = GetActivationFactory( hs, toastStatics.GetAddressOf() );
if( ! SUCCEEDED( hr ) )
{
MessageBox( 0, "GetActivationFactory", "&toastStatics", 0 );
return;
}
if( toastStatics )
{
ComPtr<IXmlDocument> toastXml;
ComPtr<IToastNotifier> notifier;
ComPtr<IToastNotification> notification;
ComPtr<IToastNotificationFactory> factory;
hr = toastStatics->GetTemplateContent( ToastTemplateType::ToastTemplateType_ToastText01, &toastXml );
if( ! SUCCEEDED( hr ) )
{
MessageBox( 0, "GetTemplateContent", "&toastXML", 0 );
return;
}
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 );
if( ! SUCCEEDED( hr ) )
{
MessageBox( 0, "GetActivationFactory", "&factory", 0 );
return;
}
hr = factory->CreateToastNotification( toastXml.Get(), ¬ification );
if( ! SUCCEEDED( hr ) )
{
MessageBox( 0, "CreateToastNotification", "¬ification", 0 );
return;
}
hr = toastStatics->CreateToastNotifier( ¬ifier );
if( ! SUCCEEDED( hr ) )
{
MessageBox( 0, "CreateToastNotifier", "¬ifier", 0 );
hb_retni( hr );
return;
}
hr = notifier->Show( notification.Get() );
if( ! SUCCEEDED( hr ) )
{
MessageBox( 0, "notifier->Show", "error", 0 );
hb_retni( hr );
return;
}
MessageBox( 0, "done", "ok", 0 );
}
}
#pragma ENDDUMP