view win/wintoast.cpp @ 2819:a2fc275fa9bb

iOS: Fix major memory leaks when destroying widgets and windows. More surely needs to be done regardig this, iOS doesn't destroy subviews as expected when the parent is removed. I was expecting it to bring the reference counts to 0 and starts destroying subviews... so I had to do this manually. Boxes, ScrollBoxes, Spinbuttons and Comboboxes all now destroy their subviews. Probably will need to do the same for splitbar, notebooks and possibly others. However this stops the memory leak in Interface Builder when recreating the interface. Also need to figure out why the reference count is lower for DWButtons.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Tue, 02 Aug 2022 06:17:09 +0000
parents 2e804b4db81e
children
line wrap: on
line source

/* Simple WinToast forwarder from Dynamic Windows APIs */

#include "dw.h"
#include "wintoastlib.h"

using namespace WinToastLib;

extern "C" {
   LRESULT CALLBACK _dw_wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2);
}

class DWHandler : public IWinToastHandler {
public:
    WinToastTemplate *templ;

    void toastActivated() const {
        // The user clicked in this toast
        _dw_wndproc((HWND)templ, WM_USER+102, 0, 0);
        dw_signal_disconnect_by_window((HWND)templ);
        delete templ;
    }

    void toastActivated(int actionIndex) const {
        // The user clicked on action
        _dw_wndproc((HWND)templ, WM_USER+102, 0, 0);
        dw_signal_disconnect_by_window((HWND)templ);
        delete templ;
    }

    void toastDismissed(WinToastDismissalReason state) const {
        switch (state) {
        case UserCanceled:
            // The user dismissed this toast
            dw_signal_disconnect_by_window((HWND)templ);
            delete templ;
            break;
        case TimedOut:
            // The toast has timed out
            break;
        case ApplicationHidden:
            // The application hid the toast using ToastNotifier.hide()
            break;
        default:
            // Toast not activated
            break;
        }
    }

    void toastFailed() const {
        // Error showing current toast
        delete templ;
    }
};


enum Results {
	ToastClicked,					// user clicked on the toast
	ToastDismissed,					// user dismissed the toast
	ToastTimeOut,					// toast timed out
	ToastHided,						// application hid the toast
	ToastNotActivated,				// toast was not activated
	ToastFailed,					// toast failed
	SystemNotSupported,				// system does not support toasts
	UnhandledOption,				// unhandled option
	MultipleTextNotSupported,		// multiple texts were provided
	InitializationFailure,			// toast notification manager initialization failure
	ToastNotLaunched				// toast could not be launched
};

extern "C" {
   
   void _dw_toast_init(LPWSTR AppName, LPWSTR AppID)
   {
      if(WinToast::isCompatible()) 
      {
         // Generate a Microsoft compatible Application User Model ID
         LPWSTR company = wcschr(AppID, '.');
         *company = 0;
         LPWSTR product = wcschr(++company, '.');
         *product = 0;
         LPWSTR subproduct = wcschr(++product, '.');
         if(subproduct)
                *subproduct = 0;
         LPWSTR version = subproduct ? wcschr(++subproduct, '.') : NULL;

         WinToast::instance()->setAppName(AppName);
         WinToast::instance()->setAppUserModelId(WinToast::instance()->configureAUMI(company, product, 
             subproduct ? subproduct : L"", (version && version++ && _wtoi(version) > 0) ? version : L""));
         WinToast::instance()->initialize();
      }
   }

   void *_dw_notification_new(LPWSTR title, LPWSTR image, LPWSTR description)
   {
      if(WinToast::isCompatible()) 
      {
         WinToastTemplate *templ = new WinToastTemplate(image ? WinToastTemplate::ImageAndText02 : WinToastTemplate::Text02);
         templ->setTextField(title, WinToastTemplate::FirstLine);
         templ->setAttributionText(description);
         if(image)
         {
            WCHAR fullpath[MAX_PATH+1] = {0};
            
            GetFullPathNameW(image, MAX_PATH, fullpath, NULL);
            templ->setImagePath(fullpath);
         }
         return (void *)templ;
      }
      return NULL;
   }

   int _dw_notification_send(void *notification)
   {
      if(WinToast::isCompatible()) 
      {
         WinToastTemplate *templ = (WinToastTemplate *)notification;
         DWHandler *handler = new DWHandler();
         handler->templ = templ;

         if(templ && WinToast::instance()->showToast(*templ, handler) >= 0)
            return DW_ERROR_NONE;
      }
      return DW_ERROR_UNKNOWN;
   }

   BOOL _dw_toast_is_compatible(void)
   {
       return WinToast::isCompatible();
   }
}