From a08e1cf9777b4a3766c91be2685aaf37c24fbd4e Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Fri, 31 Jul 2015 22:48:44 +0000 Subject: Toaster: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@14775 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Toaster/src/main.cpp | 124 ++++++++++++++ plugins/Toaster/src/resource.h | 15 ++ plugins/Toaster/src/stdafx.cxx | 1 + plugins/Toaster/src/stdafx.h | 39 +++++ plugins/Toaster/src/string_reference_wrapper.h | 54 ++++++ plugins/Toaster/src/toast_event_handler.cpp | 50 ++++++ plugins/Toaster/src/toast_event_handler.h | 26 +++ plugins/Toaster/src/toast_notification.cpp | 228 +++++++++++++++++++++++++ plugins/Toaster/src/toast_notification.h | 33 ++++ plugins/Toaster/src/version.h | 14 ++ 10 files changed, 584 insertions(+) create mode 100644 plugins/Toaster/src/main.cpp create mode 100644 plugins/Toaster/src/resource.h create mode 100644 plugins/Toaster/src/stdafx.cxx create mode 100644 plugins/Toaster/src/stdafx.h create mode 100644 plugins/Toaster/src/string_reference_wrapper.h create mode 100644 plugins/Toaster/src/toast_event_handler.cpp create mode 100644 plugins/Toaster/src/toast_event_handler.h create mode 100644 plugins/Toaster/src/toast_notification.cpp create mode 100644 plugins/Toaster/src/toast_notification.h create mode 100644 plugins/Toaster/src/version.h (limited to 'plugins/Toaster/src') 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 +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#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(STATUS_INVALID_PARAMETER), EXCEPTION_NONCONTINUABLE, 0, nullptr); + } + + template + 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(STATUS_INVALID_PARAMETER), EXCEPTION_NONCONTINUABLE, 0, nullptr); + } + + template + StringReferenceWrapper(_In_reads_(_) wchar_t(&stringRef)[_]) throw() + { + UINT32 length; + HRESULT hr = SizeTToUInt32(wcslen(stringRef), &length); + + if (FAILED(hr)) + { + RaiseException(static_cast(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(static_cast(this)); + else if (IsEqualIID(riid, __uuidof(DesktopToastActivatedEventHandler))) + *ppv = static_cast(this); + else *ppv = nullptr; + + if (*ppv) + { + reinterpret_cast(*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 DesktopToastActivatedEventHandler; + +class ToastEventHandler : public Microsoft::WRL::Implements> +{ +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(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 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 element; + HRESULT hr = xml->CreateElement(name, &element); + if (FAILED(hr)) + return hr; + + Microsoft::WRL::ComPtr 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 inputText; + HRESULT hr = xml->CreateTextNode(inputString, &inputText); + if (FAILED(hr)) + return hr; + + Microsoft::WRL::ComPtr inputTextNode; + hr = inputText.As(&inputTextNode); + if (FAILED(hr)) + return hr; + + Microsoft::WRL::ComPtr 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 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 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 imageNode; + hr = GetNodeByTag(StringReferenceWrapper(L"image").Get(), &imageNode, xml); + + Microsoft::WRL::ComPtr attributes; + hr = imageNode->get_Attributes(&attributes); + if (FAILED(hr)) + return hr; + + Microsoft::WRL::ComPtr 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 toastNode; + HRESULT hr = GetNodeByTag(StringReferenceWrapper(L"toast").Get(), &toastNode, xml); + if (FAILED(hr)) + return hr; + + Microsoft::WRL::ComPtr audioNode; + hr = AddNode(StringReferenceWrapper(L"audio").Get(), &audioNode, toastNode.Get(), xml); + if (FAILED(hr)) + return hr; + + Microsoft::WRL::ComPtr attributes; + hr = audioNode->get_Attributes(&attributes); + if (FAILED(hr)) + return hr; + + Microsoft::WRL::ComPtr silentAttribute; + hr = xml->CreateAttribute(StringReferenceWrapper(L"silent").Get(), &silentAttribute); + if (FAILED(hr)) + return hr; + + Microsoft::WRL::ComPtr silentAttributeNode; + hr = silentAttribute.As(&silentAttributeNode); + if (FAILED(hr)) + return hr; + + Microsoft::WRL::ComPtr 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 xml; + HRESULT hr = CreateXml(&xml); + if (FAILED(hr)) + return hr; + + Microsoft::WRL::ComPtr 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 notifier; + HRESULT hr = _notificationManager->CreateToastNotifierWithId(StringReferenceWrapper(::AppUserModelID).Get(), ¬ifier); + if (FAILED(hr)) + return hr; + + Microsoft::WRL::ComPtr notification; + hr = Create(¬ification); + if (FAILED(hr)) + return hr; + + EventRegistrationToken activatedToken; + Microsoft::WRL::ComPtr 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 _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 + +#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" -- cgit v1.2.3