diff options
author | Alexander Lantsev <aunsane@gmail.com> | 2015-07-31 22:48:44 +0000 |
---|---|---|
committer | Alexander Lantsev <aunsane@gmail.com> | 2015-07-31 22:48:44 +0000 |
commit | a08e1cf9777b4a3766c91be2685aaf37c24fbd4e (patch) | |
tree | 76f00a6a8c26c04d84f1e259fcf4bdf4b984a0d1 /plugins/Toaster | |
parent | aa7b69500fc5ce34840076de537dbfab2c31ab81 (diff) |
Toaster: initial commit
git-svn-id: http://svn.miranda-ng.org/main/trunk@14775 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Toaster')
-rw-r--r-- | plugins/Toaster/Toaster.vcxproj | 58 | ||||
-rw-r--r-- | plugins/Toaster/Toaster.vcxproj.filters | 4 | ||||
-rw-r--r-- | plugins/Toaster/res/resource.rc | 61 | ||||
-rw-r--r-- | plugins/Toaster/res/version.rc | 38 | ||||
-rw-r--r-- | plugins/Toaster/src/main.cpp | 124 | ||||
-rw-r--r-- | plugins/Toaster/src/resource.h | 15 | ||||
-rw-r--r-- | plugins/Toaster/src/stdafx.cxx | 1 | ||||
-rw-r--r-- | plugins/Toaster/src/stdafx.h | 39 | ||||
-rw-r--r-- | plugins/Toaster/src/string_reference_wrapper.h | 54 | ||||
-rw-r--r-- | plugins/Toaster/src/toast_event_handler.cpp | 50 | ||||
-rw-r--r-- | plugins/Toaster/src/toast_event_handler.h | 26 | ||||
-rw-r--r-- | plugins/Toaster/src/toast_notification.cpp | 228 | ||||
-rw-r--r-- | plugins/Toaster/src/toast_notification.h | 33 | ||||
-rw-r--r-- | plugins/Toaster/src/version.h | 14 |
14 files changed, 745 insertions, 0 deletions
diff --git a/plugins/Toaster/Toaster.vcxproj b/plugins/Toaster/Toaster.vcxproj new file mode 100644 index 0000000000..3e26613e59 --- /dev/null +++ b/plugins/Toaster/Toaster.vcxproj @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>Toaster</ProjectName>
+ <ProjectGuid>{1FDBD8F0-3929-41BC-92D1-020779460769}</ProjectGuid>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <PlatformToolset>v140</PlatformToolset>
+ <WindowsAppContainer>
+ </WindowsAppContainer>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(ProjectDir)..\..\build\vc.common\plugin.props" />
+ </ImportGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <IncludePath>$(VC_IncludePath);$(WindowsSdk_IncludePath);</IncludePath>
+ <LibraryPath>$(VC_LibraryPath_x86);$(WindowsSdk_LibraryPath_x86);</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <IncludePath>$(VC_IncludePath);$(WindowsSdk_IncludePath);</IncludePath>
+ <LibraryPath>$(VC_LibraryPath_x64);$(WindowsSdk_LibraryPath_x64);</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <IncludePath>$(VC_IncludePath);$(WindowsSdk_IncludePath);</IncludePath>
+ <LibraryPath>$(VC_LibraryPath_x64);$(WindowsSdk_LibraryPath_x64);</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <IncludePath>$(VC_IncludePath);$(WindowsSdk_IncludePath);</IncludePath>
+ <LibraryPath>$(VC_LibraryPath_x86);$(WindowsSdk_LibraryPath_x86);</LibraryPath>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ <Link>
+ <AdditionalDependencies>runtimeobject.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <ClCompile>
+ <RuntimeLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ </ItemDefinitionGroup>
+</Project>
\ No newline at end of file diff --git a/plugins/Toaster/Toaster.vcxproj.filters b/plugins/Toaster/Toaster.vcxproj.filters new file mode 100644 index 0000000000..de5ad9f66c --- /dev/null +++ b/plugins/Toaster/Toaster.vcxproj.filters @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(ProjectDir)..\..\build\vc.common\common.filters" />
+</Project>
\ No newline at end of file diff --git a/plugins/Toaster/res/resource.rc b/plugins/Toaster/res/resource.rc new file mode 100644 index 0000000000..0bf3781247 --- /dev/null +++ b/plugins/Toaster/res/resource.rc @@ -0,0 +1,61 @@ +// Microsoft Visual C++ generated resource script.
+//
+#include "..\src\resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian (Russia) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "..\\src\\resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Russian (Russia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/Toaster/res/version.rc b/plugins/Toaster/res/version.rc new file mode 100644 index 0000000000..c969d635bf --- /dev/null +++ b/plugins/Toaster/res/version.rc @@ -0,0 +1,38 @@ +// Microsoft Visual C++ generated resource script.
+//
+#ifdef APSTUDIO_INVOKED
+#error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+#include "winres.h"
+#include "..\src\version.h"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION __FILEVERSION_STRING
+ PRODUCTVERSION __FILEVERSION_STRING
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x0L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "FileDescription", __DESCRIPTION
+ VALUE "InternalName", __PLUGIN_NAME
+ VALUE "LegalCopyright", __COPYRIGHT
+ VALUE "OriginalFilename", __FILENAME
+ VALUE "ProductName", __PLUGIN_NAME
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
diff --git a/plugins/Toaster/src/main.cpp b/plugins/Toaster/src/main.cpp new file mode 100644 index 0000000000..0f6265e293 --- /dev/null +++ b/plugins/Toaster/src/main.cpp @@ -0,0 +1,124 @@ +#include "stdafx.h"
+
+int hLangpack;
+
+HINSTANCE g_hInstance;
+
+PLUGININFOEX pluginInfo =
+{
+ sizeof(PLUGININFOEX),
+ __PLUGIN_NAME,
+ PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM),
+ __DESCRIPTION,
+ __AUTHOR,
+ __AUTHOREMAIL,
+ __COPYRIGHT,
+ __AUTHORWEB,
+ UNICODE_AWARE,
+ // {1FDBD8F0-3929-41BC-92D1-020779460769}
+ { 0x1fdbd8f0, 0x3929, 0x41bc, { 0x92, 0xd1, 0x2, 0x7, 0x79, 0x46, 0x7, 0x69 } }
+};
+
+DWORD WINAPI DllMain(HINSTANCE hInstance, DWORD, LPVOID)
+{
+ g_hInstance = hInstance;
+
+ return TRUE;
+}
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD)
+{
+ OSVERSIONINFO osvi = { sizeof(OSVERSIONINFO) };
+ //GetVersionEx(&osvi);
+ //if (osvi.dwMajorVersion >= 6 && osvi.dwMinorVersion >= 2)
+ return &pluginInfo;
+
+ //MessageBox(NULL, _T(MODULE" supports Windows 8 or higher"), _T(MODULE), MB_OK | MB_ICONERROR);
+ //return NULL;
+
+}
+
+static void __cdecl OnToastNotificationClicked(void* arg)
+{
+ MCONTACT hContact = (MCONTACT)arg;
+ if (hContact)
+ CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, (LPARAM)"");
+}
+
+static void ShowToastNotification(TCHAR* text, TCHAR* title, MCONTACT hContact)
+{
+ ptrT imagePath;
+ ToastEventHandler *eventHandler;
+ /*if (hContact)
+ {
+ eventHandler = new ToastEventHandler(OnToastNotificationClicked, (void*)hContact);
+
+ TCHAR avatarPath[MAX_PATH] = { 0 };
+ const char* szProto = GetContactProto(hContact);
+ if (ProtoServiceExists(szProto, PS_GETMYAVATAR))
+ if (!CallProtoService(szProto, PS_GETMYAVATAR, (WPARAM)avatarPath, (LPARAM)MAX_PATH))
+ imagePath = mir_tstrdup(avatarPath);
+ }
+ else*/
+ eventHandler = new ToastEventHandler(nullptr);
+
+ ToastNotification notification(text, title, imagePath);
+ notification.Show(eventHandler);
+}
+
+static INT_PTR CreatePopup(WPARAM wParam, LPARAM)
+{
+ POPUPDATA *ppd = (POPUPDATA*)wParam;
+ ptrW text(mir_a2u(ppd->lpzText));
+ ptrW contactName(mir_a2u(ppd->lpzContactName));
+
+ ShowToastNotification(text, contactName, ppd->lchContact);
+
+ return 0;
+}
+
+static INT_PTR CreatePopupW(WPARAM wParam, LPARAM)
+{
+ POPUPDATAW *ppd = (POPUPDATAW*)wParam;
+
+ ShowToastNotification(ppd->lpwzText, ppd->lpwzContactName, ppd->lchContact);
+
+ return 0;
+}
+
+static INT_PTR CreatePopup2(WPARAM wParam, LPARAM)
+{
+ POPUPDATA2 *ppd = (POPUPDATA2*)wParam;
+
+ ptrW text, title;
+ if (ppd->flags & PU2_UNICODE)
+ {
+ text = mir_wstrdup(ppd->lpwzText);
+ title = mir_wstrdup(ppd->lpwzTitle);
+ }
+ else
+ {
+ text = mir_a2u(ppd->lpzText);
+ title = mir_a2u(ppd->lpzTitle);
+ }
+
+ ShowToastNotification(text, title, ppd->lchContact);
+
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Load(void)
+{
+ mir_getLP(&pluginInfo);
+
+ CreateServiceFunction(MS_POPUP_ADDPOPUP, CreatePopup);
+ CreateServiceFunction(MS_POPUP_ADDPOPUPW, CreatePopupW);
+ CreateServiceFunction(MS_POPUP_ADDPOPUP2, CreatePopup2);
+
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Unload(void)
+{
+ return 0;
+}
diff --git a/plugins/Toaster/src/resource.h b/plugins/Toaster/src/resource.h new file mode 100644 index 0000000000..0f01763f97 --- /dev/null +++ b/plugins/Toaster/src/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by e:\Projects\C++\MirandaNG\plugins\Toaster\res\resource.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 107
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1013
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/Toaster/src/stdafx.cxx b/plugins/Toaster/src/stdafx.cxx new file mode 100644 index 0000000000..fd4f341c7b --- /dev/null +++ b/plugins/Toaster/src/stdafx.cxx @@ -0,0 +1 @@ +#include "stdafx.h" diff --git a/plugins/Toaster/src/stdafx.h b/plugins/Toaster/src/stdafx.h new file mode 100644 index 0000000000..f22ec15681 --- /dev/null +++ b/plugins/Toaster/src/stdafx.h @@ -0,0 +1,39 @@ +#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
+
+#include <Windows.h>
+#include <SDKDDKVer.h>
+#include <strsafe.h>
+#include <intsafe.h>
+
+#include <roapi.h>
+#include <wrl\client.h>
+#include <wrl\implements.h>
+#include <windows.ui.notifications.h>
+
+#include <newpluginapi.h>
+#include <m_core.h>
+#include <m_utils.h>
+#include <m_langpack.h>
+#include <m_avatars.h>
+#include <m_protocols.h>
+#include <m_popup.h>
+#include <m_message.h>
+
+#include "version.h"
+#include "resource.h"
+
+typedef void(__cdecl *pEventHandler)(void*);
+const wchar_t AppUserModelID[] = L"MirandaNG";
+
+#include "string_reference_wrapper.h"
+#include "toast_event_handler.h"
+#include "toast_notification.h"
+
+#define MODULE "Toaster"
+
+extern HINSTANCE g_hInstance;
+
+#endif //_COMMON_H_
diff --git a/plugins/Toaster/src/string_reference_wrapper.h b/plugins/Toaster/src/string_reference_wrapper.h new file mode 100644 index 0000000000..ca0f8afd9f --- /dev/null +++ b/plugins/Toaster/src/string_reference_wrapper.h @@ -0,0 +1,54 @@ +#ifndef _STRING_WRAPPER_H_
+#define _STRING_WRAPPER_H_
+
+class StringReferenceWrapper
+{
+public:
+ StringReferenceWrapper(_In_reads_(length) PCWSTR stringRef, _In_ UINT32 length) throw()
+ {
+ HRESULT hr = WindowsCreateStringReference(stringRef, length, &_header, &_hstring);
+
+ if (FAILED(hr))
+ RaiseException(static_cast<DWORD>(STATUS_INVALID_PARAMETER), EXCEPTION_NONCONTINUABLE, 0, nullptr);
+ }
+
+ template <size_t N>
+ StringReferenceWrapper(_In_reads_(N) wchar_t const (&stringRef)[N]) throw()
+ {
+ UINT32 length = N - 1;
+ HRESULT hr = WindowsCreateStringReference(stringRef, length, &_header, &_hstring);
+
+ if (FAILED(hr))
+ RaiseException(static_cast<DWORD>(STATUS_INVALID_PARAMETER), EXCEPTION_NONCONTINUABLE, 0, nullptr);
+ }
+
+ template <size_t _>
+ StringReferenceWrapper(_In_reads_(_) wchar_t(&stringRef)[_]) throw()
+ {
+ UINT32 length;
+ HRESULT hr = SizeTToUInt32(wcslen(stringRef), &length);
+
+ if (FAILED(hr))
+ {
+ RaiseException(static_cast<DWORD>(STATUS_INVALID_PARAMETER), EXCEPTION_NONCONTINUABLE, 0, nullptr);
+ }
+
+ WindowsCreateStringReference(stringRef, length, &_header, &_hstring);
+ }
+
+ ~StringReferenceWrapper()
+ {
+ WindowsDeleteString(_hstring);
+ }
+
+ HSTRING Get() const throw()
+ {
+ return _hstring;
+ }
+
+private:
+ HSTRING _hstring;
+ HSTRING_HEADER _header;
+};
+
+#endif //_STRING_WRAPPER_H_
\ No newline at end of file diff --git a/plugins/Toaster/src/toast_event_handler.cpp b/plugins/Toaster/src/toast_event_handler.cpp new file mode 100644 index 0000000000..e2ed29e165 --- /dev/null +++ b/plugins/Toaster/src/toast_event_handler.cpp @@ -0,0 +1,50 @@ +#include "stdafx.h"
+
+ToastEventHandler::ToastEventHandler() : _ref(1), _callback(nullptr), _arg(nullptr)
+{
+}
+
+ToastEventHandler::ToastEventHandler(_In_ pEventHandler callback, _In_ void* arg) : _ref(1), _callback(callback), _arg(arg)
+{
+}
+
+ToastEventHandler::~ToastEventHandler()
+{
+}
+
+IFACEMETHODIMP_(ULONG) ToastEventHandler::AddRef()
+{
+ return InterlockedIncrement(&_ref);
+}
+
+IFACEMETHODIMP_(ULONG) ToastEventHandler::Release()
+{
+ ULONG l = InterlockedDecrement(&_ref);
+ if (l == 0) delete this;
+ return l;
+}
+
+IFACEMETHODIMP ToastEventHandler::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void **ppv)
+{
+ if (IsEqualIID(riid, IID_IUnknown))
+ *ppv = static_cast<IUnknown*>(static_cast<DesktopToastActivatedEventHandler*>(this));
+ else if (IsEqualIID(riid, __uuidof(DesktopToastActivatedEventHandler)))
+ *ppv = static_cast<DesktopToastActivatedEventHandler*>(this);
+ else *ppv = nullptr;
+
+ if (*ppv)
+ {
+ reinterpret_cast<IUnknown*>(*ppv)->AddRef();
+ return S_OK;
+ }
+
+ return E_NOINTERFACE;
+}
+
+IFACEMETHODIMP ToastEventHandler::Invoke(_In_ ABI::Windows::UI::Notifications::IToastNotification* /* sender */, _In_::IInspectable* /* args */)
+{
+ if (_callback != nullptr)
+ _callback(_arg);
+
+ return S_OK;
+}
diff --git a/plugins/Toaster/src/toast_event_handler.h b/plugins/Toaster/src/toast_event_handler.h new file mode 100644 index 0000000000..10d2f1422f --- /dev/null +++ b/plugins/Toaster/src/toast_event_handler.h @@ -0,0 +1,26 @@ +#ifndef _TOAST_EVENT_HANDLER_H_
+#define _TOAST_EVENT_HANDLER_H_
+
+typedef ABI::Windows::Foundation::ITypedEventHandler<ABI::Windows::UI::Notifications::ToastNotification*, ::IInspectable*> DesktopToastActivatedEventHandler;
+
+class ToastEventHandler : public Microsoft::WRL::Implements<ABI::Windows::Foundation::ITypedEventHandler<ABI::Windows::UI::Notifications::ToastNotification*, ::IInspectable*>>
+{
+public:
+ ToastEventHandler::ToastEventHandler();
+ ToastEventHandler::ToastEventHandler(_In_ pEventHandler callback, _In_ void* arg = nullptr);
+ ~ToastEventHandler();
+
+ IFACEMETHODIMP_(ULONG) AddRef();
+ IFACEMETHODIMP_(ULONG) Release();
+
+ IFACEMETHODIMP QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppv);
+
+ IFACEMETHODIMP Invoke(_In_ ABI::Windows::UI::Notifications::IToastNotification* sender, _In_ IInspectable* args);
+
+private:
+ ULONG _ref;
+ void* _arg;
+ pEventHandler _callback;
+};
+
+#endif //_TOAST_EVENT_HANDLER_H_
\ No newline at end of file diff --git a/plugins/Toaster/src/toast_notification.cpp b/plugins/Toaster/src/toast_notification.cpp new file mode 100644 index 0000000000..856129f648 --- /dev/null +++ b/plugins/Toaster/src/toast_notification.cpp @@ -0,0 +1,228 @@ +#include "stdafx.h"
+
+ToastNotification::ToastNotification(_In_ wchar_t* text, _In_ wchar_t* caption, _In_ wchar_t* imagePath) throw()
+ : _text(text), _caption(caption), _imagePath(imagePath)
+{
+ HRESULT hr = Windows::Foundation::GetActivationFactory(StringReferenceWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(), &_notificationManager);
+
+ if (FAILED(hr))
+ RaiseException(static_cast<DWORD>(STATUS_INVALID_PARAMETER), EXCEPTION_NONCONTINUABLE, 0, nullptr);
+}
+
+ToastNotification::~ToastNotification()
+{
+}
+
+HRESULT ToastNotification::GetNodeByTag(_In_ HSTRING tagName, _Outptr_ ABI::Windows::Data::Xml::Dom::IXmlNode **node, _In_ ABI::Windows::Data::Xml::Dom::IXmlDocument* xml)
+{
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlNodeList> nodeList;
+ HRESULT hr = xml->GetElementsByTagName(tagName, &nodeList);
+ if (FAILED(hr))
+ return hr;
+
+ UINT32 length;
+ hr = nodeList->get_Length(&length);
+ if (FAILED(hr))
+ return hr;
+
+ if (length == 0)
+ return E_INVALIDARG;
+
+ return nodeList->Item(0, node);
+}
+
+HRESULT ToastNotification::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)
+{
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlElement> element;
+ HRESULT hr = xml->CreateElement(name, &element);
+ if (FAILED(hr))
+ return hr;
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlNode> tempNode;
+ hr = element.As(&tempNode);
+ if (FAILED(hr))
+ return hr;
+
+ return rootNode->AppendChild(tempNode.Get(), node);
+}
+
+HRESULT ToastNotification::SetNodeValueString(_In_ HSTRING inputString, _In_ ABI::Windows::Data::Xml::Dom::IXmlNode* node, _In_ ABI::Windows::Data::Xml::Dom::IXmlDocument* xml)
+{
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlText> inputText;
+ HRESULT hr = xml->CreateTextNode(inputString, &inputText);
+ if (FAILED(hr))
+ return hr;
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlNode> inputTextNode;
+ hr = inputText.As(&inputTextNode);
+ if (FAILED(hr))
+ return hr;
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlNode> pAppendedChild;
+ return hr = node->AppendChild(inputTextNode.Get(), &pAppendedChild);
+}
+
+HRESULT ToastNotification::SetTextValues(_In_reads_(textValuesCount) wchar_t** textValues, _In_ UINT32 textValuesCount, _In_ ABI::Windows::Data::Xml::Dom::IXmlDocument* xml)
+{
+ HRESULT hr = textValues != nullptr && textValuesCount > 0 ? S_OK : E_INVALIDARG;
+ if (FAILED(hr))
+ return hr;
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlNodeList> nodeList;
+ hr = xml->GetElementsByTagName(StringReferenceWrapper(L"text").Get(), &nodeList);
+ if (FAILED(hr))
+ return hr;
+
+ UINT32 nodeListLength;
+ hr = nodeList->get_Length(&nodeListLength);
+ if (FAILED(hr))
+ return hr;
+
+ hr = textValuesCount <= nodeListLength ? S_OK : E_INVALIDARG;
+ if (FAILED(hr))
+ return hr;
+
+ for (UINT32 i = 0; i < textValuesCount; i++)
+ {
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlNode> textNode;
+ hr = nodeList->Item(i, &textNode);
+ if (FAILED(hr))
+ return hr;
+
+ hr = SetNodeValueString(StringReferenceWrapper(textValues[i], (UINT32)wcslen(textValues[i])).Get(), textNode.Get(), xml);
+ if (FAILED(hr))
+ return hr;
+ }
+
+ return S_OK;
+}
+
+HRESULT ToastNotification::SetImageSrc(_In_z_ wchar_t* imagePath, _In_ ABI::Windows::Data::Xml::Dom::IXmlDocument* xml)
+{
+ wchar_t imageSrc[MAX_PATH] = L"file:///";
+ HRESULT hr = StringCchCat(imageSrc, ARRAYSIZE(imageSrc), imagePath);
+ if (FAILED(hr))
+ return hr;
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlNode> imageNode;
+ hr = GetNodeByTag(StringReferenceWrapper(L"image").Get(), &imageNode, xml);
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlNamedNodeMap> attributes;
+ hr = imageNode->get_Attributes(&attributes);
+ if (FAILED(hr))
+ return hr;
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlNode> srcAttribute;
+ hr = attributes->GetNamedItem(StringReferenceWrapper(L"src").Get(), &srcAttribute);
+ if (FAILED(hr))
+ return hr;
+
+ return hr = SetNodeValueString(StringReferenceWrapper(imageSrc).Get(), srcAttribute.Get(), xml);
+}
+
+HRESULT ToastNotification::Setup(_In_ ABI::Windows::Data::Xml::Dom::IXmlDocument* xml)
+{
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlNode> toastNode;
+ HRESULT hr = GetNodeByTag(StringReferenceWrapper(L"toast").Get(), &toastNode, xml);
+ if (FAILED(hr))
+ return hr;
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlNode> audioNode;
+ hr = AddNode(StringReferenceWrapper(L"audio").Get(), &audioNode, toastNode.Get(), xml);
+ if (FAILED(hr))
+ return hr;
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlNamedNodeMap> attributes;
+ hr = audioNode->get_Attributes(&attributes);
+ if (FAILED(hr))
+ return hr;
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlAttribute> silentAttribute;
+ hr = xml->CreateAttribute(StringReferenceWrapper(L"silent").Get(), &silentAttribute);
+ if (FAILED(hr))
+ return hr;
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlNode> silentAttributeNode;
+ hr = silentAttribute.As(&silentAttributeNode);
+ if (FAILED(hr))
+ return hr;
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlNode> tempNode;
+ hr = attributes->SetNamedItem(silentAttributeNode.Get(), &tempNode);
+ if (FAILED(hr))
+ return hr;
+
+ return SetNodeValueString(StringReferenceWrapper(L"true").Get(), silentAttributeNode.Get(), xml);
+}
+
+HRESULT ToastNotification::CreateXml(_Outptr_ ABI::Windows::Data::Xml::Dom::IXmlDocument** xml)
+{
+ ABI::Windows::UI::Notifications::ToastTemplateType templateId = _imagePath == nullptr
+ ? ABI::Windows::UI::Notifications::ToastTemplateType_ToastText02
+ : ABI::Windows::UI::Notifications::ToastTemplateType_ToastImageAndText02;
+ HRESULT hr = _notificationManager->GetTemplateContent(templateId, xml);
+ if (FAILED(hr))
+ return hr;
+
+ hr = Setup(*xml);
+ if (FAILED(hr))
+ return hr;
+
+ if (_imagePath)
+ {
+ hr = SetImageSrc(_imagePath, *xml);
+ if (FAILED(hr))
+ return hr;
+ }
+
+ wchar_t* textValues[] =
+ {
+ _caption == nullptr
+ ? L"Miranda NG"
+ : _caption,
+ _text
+ };
+
+ return SetTextValues(textValues, _countof(textValues), *xml);
+}
+
+HRESULT ToastNotification::Create(_Outptr_ ABI::Windows::UI::Notifications::IToastNotification** notification)
+{
+ Microsoft::WRL::ComPtr<ABI::Windows::Data::Xml::Dom::IXmlDocument> xml;
+ HRESULT hr = CreateXml(&xml);
+ if (FAILED(hr))
+ return hr;
+
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Notifications::IToastNotificationFactory> factory;
+ hr = Windows::Foundation::GetActivationFactory(StringReferenceWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(), &factory);
+ if (FAILED(hr))
+ return hr;
+
+ return hr = factory->CreateToastNotification(xml.Get(), notification);
+}
+
+HRESULT ToastNotification::Show()
+{
+ return Show(new ToastEventHandler(nullptr));
+}
+
+HRESULT ToastNotification::Show(_In_ ToastEventHandler* handler)
+{
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Notifications::IToastNotifier> notifier;
+ HRESULT 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;
+ Microsoft::WRL::ComPtr<ToastEventHandler> eventHandler(handler);
+ hr = notification->add_Activated(eventHandler.Get(), &activatedToken);
+ if (FAILED(hr))
+ return hr;
+
+ return notifier->Show(notification.Get());
+}
\ No newline at end of file diff --git a/plugins/Toaster/src/toast_notification.h b/plugins/Toaster/src/toast_notification.h new file mode 100644 index 0000000000..4a9c7e16f8 --- /dev/null +++ b/plugins/Toaster/src/toast_notification.h @@ -0,0 +1,33 @@ +#ifndef _TOAST_NOTIFICATION_H_
+#define _TOAST_NOTIFICATION_H_
+
+class ToastNotification
+{
+private:
+ wchar_t* _text;
+ wchar_t* _caption;
+ wchar_t* _imagePath;
+
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Notifications::IToastNotificationManagerStatics> _notificationManager;
+
+ 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);
+ HRESULT SetTextValues(_In_reads_(textValuesCount) wchar_t** textValues, _In_ UINT32 textValuesCount, _In_ ABI::Windows::Data::Xml::Dom::IXmlDocument* xml);
+ HRESULT SetImageSrc(_In_z_ wchar_t* imagePath, _In_ ABI::Windows::Data::Xml::Dom::IXmlDocument* xml);
+ HRESULT Setup(_In_ ABI::Windows::Data::Xml::Dom::IXmlDocument* xml);
+ HRESULT CreateXml(_Outptr_ ABI::Windows::Data::Xml::Dom::IXmlDocument** xml);
+ HRESULT Create(_Outptr_ ABI::Windows::UI::Notifications::IToastNotification** notification);
+
+public:
+ COLORREF background;
+ COLORREF foreground;
+
+ ToastNotification(_In_ wchar_t* text, _In_ wchar_t* caption = nullptr, _In_ wchar_t* imagePath = nullptr) throw();
+ ~ToastNotification();
+
+ HRESULT Show();
+ HRESULT Show(_In_ ToastEventHandler* handler);
+};
+
+#endif //_TOAST_NOTIFICATION_H_
\ No newline at end of file diff --git a/plugins/Toaster/src/version.h b/plugins/Toaster/src/version.h new file mode 100644 index 0000000000..15a4fa9c6e --- /dev/null +++ b/plugins/Toaster/src/version.h @@ -0,0 +1,14 @@ +#define __MAJOR_VERSION 0
+#define __MINOR_VERSION 11
+#define __RELEASE_NUM 0
+#define __BUILD_NUM 0
+
+#include <stdver.h>
+
+#define __PLUGIN_NAME "Toaster"
+#define __FILENAME "Toaster.dll"
+#define __DESCRIPTION "Provides popup services based on Windows toast notification for different plugins."
+#define __AUTHOR "Miranda NG team"
+#define __AUTHOREMAIL ""
+#define __AUTHORWEB "http://miranda-ng.org/p/Toaster/"
+#define __COPYRIGHT "© 2015 Miranda NG project"
|