diff options
author | MikalaiR <nikolay.romanovich@narod.ru> | 2015-08-28 11:32:10 +0000 |
---|---|---|
committer | MikalaiR <nikolay.romanovich@narod.ru> | 2015-08-28 11:32:10 +0000 |
commit | 4402f6924f14847c1570b22ef06ba54125a9c41c (patch) | |
tree | b474f5c3ef8660c0919474eb8c6e4a4dc15bb0a0 | |
parent | f056d6596882aa7cfecc21a61e8ef48f2b514460 (diff) |
Toaster: hiding toasts
git-svn-id: http://svn.miranda-ng.org/main/trunk@15053 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r-- | plugins/Toaster/src/main.cpp | 13 | ||||
-rw-r--r-- | plugins/Toaster/src/services.cpp | 42 | ||||
-rw-r--r-- | plugins/Toaster/src/stdafx.h | 13 | ||||
-rw-r--r-- | plugins/Toaster/src/toast_event_handler.cpp | 25 | ||||
-rw-r--r-- | plugins/Toaster/src/toast_event_handler.h | 9 | ||||
-rw-r--r-- | plugins/Toaster/src/toast_notification.cpp | 14 | ||||
-rw-r--r-- | plugins/Toaster/src/toast_notification.h | 4 |
7 files changed, 94 insertions, 26 deletions
diff --git a/plugins/Toaster/src/main.cpp b/plugins/Toaster/src/main.cpp index 6ce8fd69af..4f3515ffdf 100644 --- a/plugins/Toaster/src/main.cpp +++ b/plugins/Toaster/src/main.cpp @@ -39,7 +39,7 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD) extern "C" int __declspec(dllexport) Load(void)
{
mir_getLP(&pluginInfo);
-
+ HookEvent(ME_SYSTEM_SHUTDOWN, &OnPreShutdown);
InitServices();
return 0;
@@ -49,3 +49,14 @@ extern "C" int __declspec(dllexport) Unload(void) {
return 0;
}
+
+int OnPreShutdown(WPARAM, LPARAM)
+{
+ mir_cslock lck(csNotifications);
+ for (int i = 0; i < lstNotifications.getCount(); i++)
+ lstNotifications[0].Hide();
+
+ lstNotifications.destroy();
+
+ return 0;
+}
\ No newline at end of file diff --git a/plugins/Toaster/src/services.cpp b/plugins/Toaster/src/services.cpp index 79e8fba2b0..1168e8cc95 100644 --- a/plugins/Toaster/src/services.cpp +++ b/plugins/Toaster/src/services.cpp @@ -1,12 +1,16 @@ #include "stdafx.h"
+mir_cs csNotifications;
+OBJLIST<ToastNotification> lstNotifications(1);
+
__forceinline bool isChatRoom(MCONTACT hContact)
-{ return (bool)db_get_b(hContact, GetContactProto(hContact), "ChatRoom", 0);
+{ return (db_get_b(hContact, GetContactProto(hContact), "ChatRoom", 0) == 1);
}
static void __cdecl OnToastNotificationClicked(void* arg)
{
- MCONTACT hContact = (MCONTACT)arg;
+ callbackArg *cb = (callbackArg*)arg;
+ MCONTACT hContact = cb->hContact;
if (hContact)
{
if (!isChatRoom(hContact))
@@ -16,13 +20,13 @@ static void __cdecl OnToastNotificationClicked(void* arg) else
{
const char *szProto = GetContactProto(hContact);
- ptrT szChatRoom(db_get_tsa(hContact, szProto, "ChatRoomID"));
- GCDEST gcd = { szProto, szChatRoom, GC_EVENT_CONTROL };
+ ptrT tszChatRoom(db_get_tsa(hContact, szProto, "ChatRoomID"));
+ GCDEST gcd = { szProto, tszChatRoom, GC_EVENT_CONTROL };
GCEVENT gce = { sizeof(gce), &gcd };
- gce.time = time(NULL);
- CallServiceSync(MS_GC_EVENT, WINDOW_VISIBLE, reinterpret_cast<LPARAM>(&gce));
+ CallServiceSync(MS_GC_EVENT, WINDOW_VISIBLE, (LPARAM)&gce);
}
}
+ lstNotifications.remove(cb->notification);
}
static void ShowToastNotification(TCHAR* text, TCHAR* title, MCONTACT hContact)
@@ -31,25 +35,25 @@ static void ShowToastNotification(TCHAR* text, TCHAR* title, MCONTACT hContact) return;
ptrT imagePath;
- ToastEventHandler *eventHandler;
+ callbackArg *arg = (callbackArg*)mir_calloc(sizeof(callbackArg));
if (hContact)
{
- eventHandler = new ToastEventHandler(OnToastNotificationClicked, (void*)hContact);
-
+ arg->hContact = hContact;
const char* szProto = GetContactProto(hContact);
- PROTO_AVATAR_INFORMATION pai = { 0 };
- pai.hContact = hContact;
+
if (ProtoServiceExists(szProto, PS_GETAVATARINFO))
{
+ PROTO_AVATAR_INFORMATION pai = { 0 };
+ pai.hContact = hContact;
CallProtoService(szProto, PS_GETAVATARINFO, (WPARAM)0, (LPARAM)&pai);
imagePath = mir_tstrdup(pai.filename);
}
}
- else
- eventHandler = new ToastEventHandler(nullptr);
- ToastNotification notification(text, title, imagePath);
- notification.Show(eventHandler);
+ ToastNotification* notification = new ToastNotification (text, title, imagePath);
+ arg->notification = notification;
+ notification->Show(new ToastEventHandler(OnToastNotificationClicked, arg));
+ lstNotifications.insert(notification);
}
static INT_PTR CreatePopup(WPARAM wParam, LPARAM)
@@ -107,6 +111,14 @@ static INT_PTR PopupQuery(WPARAM wParam, LPARAM) {
bool enabled = db_get_b(0, "Popup", "ModuleIsEnabled", 1) != 0;
if (enabled) db_set_b(0, "Popup", "ModuleIsEnabled", 0);
+
+ while (lstNotifications.getCount())
+ {
+ mir_cslock lck(csNotifications);
+ lstNotifications[0].Hide();
+ lstNotifications.remove(0);
+ }
+
return enabled;
}
break;
diff --git a/plugins/Toaster/src/stdafx.h b/plugins/Toaster/src/stdafx.h index a113024828..8df66f4598 100644 --- a/plugins/Toaster/src/stdafx.h +++ b/plugins/Toaster/src/stdafx.h @@ -13,6 +13,8 @@ #include <windows.ui.notifications.h>
#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_system_cpp.h>
#include <m_core.h>
#include <m_utils.h>
#include <m_langpack.h>
@@ -33,10 +35,19 @@ const wchar_t AppUserModelID[] = _T("MirandaNG"); #include "toast_event_handler.h"
#include "toast_notification.h"
+extern mir_cs csNotifications;
+extern OBJLIST<ToastNotification> lstNotifications;
+
+struct callbackArg
+{
+ MCONTACT hContact;
+ ToastNotification* notification;
+};
+
#define MODULE "Toaster"
extern HINSTANCE g_hInstance;
void InitServices();
-
+int OnPreShutdown(WPARAM, LPARAM);
#endif //_COMMON_H_
diff --git a/plugins/Toaster/src/toast_event_handler.cpp b/plugins/Toaster/src/toast_event_handler.cpp index e2ed29e165..c7f43ad115 100644 --- a/plugins/Toaster/src/toast_event_handler.cpp +++ b/plugins/Toaster/src/toast_event_handler.cpp @@ -1,5 +1,7 @@ #include "stdafx.h"
+using namespace ABI::Windows::UI::Notifications;
+
ToastEventHandler::ToastEventHandler() : _ref(1), _callback(nullptr), _arg(nullptr)
{
}
@@ -30,10 +32,13 @@ IFACEMETHODIMP ToastEventHandler::QueryInterface(_In_ REFIID riid, _COM_Outptr_ *ppv = static_cast<IUnknown*>(static_cast<DesktopToastActivatedEventHandler*>(this));
else if (IsEqualIID(riid, __uuidof(DesktopToastActivatedEventHandler)))
*ppv = static_cast<DesktopToastActivatedEventHandler*>(this);
+ else if (IsEqualIID(riid, __uuidof(DesktopToastDismissedEventHandler)))
+ *ppv = static_cast<DesktopToastDismissedEventHandler*>(this);
+ else if (IsEqualIID(riid, __uuidof(DesktopToastFailedEventHandler)))
+ *ppv = static_cast<DesktopToastFailedEventHandler*>(this);
else *ppv = nullptr;
- if (*ppv)
- {
+ if (*ppv) {
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
@@ -41,10 +46,24 @@ IFACEMETHODIMP ToastEventHandler::QueryInterface(_In_ REFIID riid, _COM_Outptr_ return E_NOINTERFACE;
}
-IFACEMETHODIMP ToastEventHandler::Invoke(_In_ ABI::Windows::UI::Notifications::IToastNotification* /* sender */, _In_::IInspectable* /* args */)
+IFACEMETHODIMP ToastEventHandler::Invoke(_In_ IToastNotification* /* sender */, _In_ IInspectable* /* args */)
{
if (_callback != nullptr)
_callback(_arg);
return S_OK;
}
+
+IFACEMETHODIMP ToastEventHandler::Invoke(_In_ IToastNotification* /* sender */, _In_ IToastDismissedEventArgs* /* e */)
+{
+ callbackArg *cb = (callbackArg*)_arg;
+ lstNotifications.remove(cb->notification);
+ return S_OK;
+}
+
+IFACEMETHODIMP ToastEventHandler::Invoke(_In_ IToastNotification* /* sender */, _In_ IToastFailedEventArgs* /* e */)
+{
+ callbackArg *cb = (callbackArg*)_arg;
+ lstNotifications.remove(cb->notification);
+ return S_OK;
+}
\ No newline at end of file diff --git a/plugins/Toaster/src/toast_event_handler.h b/plugins/Toaster/src/toast_event_handler.h index 10d2f1422f..8cf82b3e21 100644 --- a/plugins/Toaster/src/toast_event_handler.h +++ b/plugins/Toaster/src/toast_event_handler.h @@ -1,9 +1,12 @@ #ifndef _TOAST_EVENT_HANDLER_H_
#define _TOAST_EVENT_HANDLER_H_
-typedef ABI::Windows::Foundation::ITypedEventHandler<ABI::Windows::UI::Notifications::ToastNotification*, ::IInspectable*> DesktopToastActivatedEventHandler;
+typedef ABI::Windows::Foundation::ITypedEventHandler<ABI::Windows::UI::Notifications::ToastNotification *, ::IInspectable *> DesktopToastActivatedEventHandler;
+typedef ABI::Windows::Foundation::ITypedEventHandler<ABI::Windows::UI::Notifications::ToastNotification *, ABI::Windows::UI::Notifications::ToastDismissedEventArgs *> DesktopToastDismissedEventHandler;
+typedef ABI::Windows::Foundation::ITypedEventHandler<ABI::Windows::UI::Notifications::ToastNotification *, ABI::Windows::UI::Notifications::ToastFailedEventArgs *> DesktopToastFailedEventHandler;
-class ToastEventHandler : public Microsoft::WRL::Implements<ABI::Windows::Foundation::ITypedEventHandler<ABI::Windows::UI::Notifications::ToastNotification*, ::IInspectable*>>
+
+class ToastEventHandler : public Microsoft::WRL::Implements<DesktopToastActivatedEventHandler, DesktopToastDismissedEventHandler, DesktopToastFailedEventHandler>
{
public:
ToastEventHandler::ToastEventHandler();
@@ -16,6 +19,8 @@ public: IFACEMETHODIMP QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppv);
IFACEMETHODIMP Invoke(_In_ ABI::Windows::UI::Notifications::IToastNotification* sender, _In_ IInspectable* args);
+ IFACEMETHODIMP Invoke(_In_ ABI::Windows::UI::Notifications::IToastNotification* /* sender */, _In_ ABI::Windows::UI::Notifications::IToastDismissedEventArgs* e);
+ IFACEMETHODIMP Invoke(_In_ ABI::Windows::UI::Notifications::IToastNotification* /* sender */, _In_ ABI::Windows::UI::Notifications::IToastFailedEventArgs* /* e */);
private:
ULONG _ref;
diff --git a/plugins/Toaster/src/toast_notification.cpp b/plugins/Toaster/src/toast_notification.cpp index 9e3ad1b915..7d11f9318e 100644 --- a/plugins/Toaster/src/toast_notification.cpp +++ b/plugins/Toaster/src/toast_notification.cpp @@ -215,21 +215,27 @@ HRESULT ToastNotification::Show(_In_ ToastEventHandler* handler) if (FAILED(hr))
RaiseException(static_cast<DWORD>(STATUS_INVALID_PARAMETER), EXCEPTION_NONCONTINUABLE, 0, nullptr);
- Microsoft::WRL::ComPtr<ABI::Windows::UI::Notifications::IToastNotifier> notifier;
hr = notificationManager->CreateToastNotifierWithId(StringReferenceWrapper(::AppUserModelID).Get(), ¬ifier);
if (FAILED(hr))
return hr;
-
- Microsoft::WRL::ComPtr<ABI::Windows::UI::Notifications::IToastNotification> notification;
hr = Create(¬ification);
if (FAILED(hr))
return hr;
- EventRegistrationToken activatedToken;
+ EventRegistrationToken activatedToken, dismissedToken, failedToken;
Microsoft::WRL::ComPtr<ToastEventHandler> eventHandler(handler);
hr = notification->add_Activated(eventHandler.Get(), &activatedToken);
if (FAILED(hr))
return hr;
+ notification->add_Activated(eventHandler.Get(), &activatedToken);
+ notification->add_Dismissed(eventHandler.Get(), &dismissedToken);
+ notification->add_Failed(eventHandler.Get(), &failedToken);
+
return notifier->Show(notification.Get());
+}
+
+HRESULT ToastNotification::Hide()
+{
+ return notifier->Hide(notification.Get());
}
\ No newline at end of file diff --git a/plugins/Toaster/src/toast_notification.h b/plugins/Toaster/src/toast_notification.h index 727966ac8f..0e4131b945 100644 --- a/plugins/Toaster/src/toast_notification.h +++ b/plugins/Toaster/src/toast_notification.h @@ -8,6 +8,9 @@ private: wchar_t* _caption;
wchar_t* _imagePath;
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Notifications::IToastNotifier> notifier;
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Notifications::IToastNotification> notification;
+
HRESULT GetNodeByTag(_In_ HSTRING tagName, _Outptr_ ABI::Windows::Data::Xml::Dom::IXmlNode **node, _In_ ABI::Windows::Data::Xml::Dom::IXmlDocument* xml);
HRESULT AddNode(_In_ HSTRING name, _Outptr_ ABI::Windows::Data::Xml::Dom::IXmlNode **node, _In_ ABI::Windows::Data::Xml::Dom::IXmlNode *rootNode, _In_ ABI::Windows::Data::Xml::Dom::IXmlDocument* xml);
HRESULT SetNodeValueString(_In_ HSTRING inputString, _In_ ABI::Windows::Data::Xml::Dom::IXmlNode* node, _In_ ABI::Windows::Data::Xml::Dom::IXmlDocument* xml);
@@ -26,6 +29,7 @@ public: HRESULT Show();
HRESULT Show(_In_ ToastEventHandler* handler);
+ HRESULT Hide();
};
#endif //_TOAST_NOTIFICATION_H_
\ No newline at end of file |