diff options
| -rw-r--r-- | 3rdParty/Snarl/SnarlInterface.cpp | 959 | ||||
| -rw-r--r-- | 3rdParty/Snarl/SnarlInterface.h | 412 | ||||
| -rw-r--r-- | SwifTools/Notifier/SnarlNotifier.cpp | 19 | ||||
| -rw-r--r-- | SwifTools/Notifier/SnarlNotifier.h | 2 | 
4 files changed, 580 insertions, 812 deletions
| diff --git a/3rdParty/Snarl/SnarlInterface.cpp b/3rdParty/Snarl/SnarlInterface.cpp index b780140..0ae0b37 100644 --- a/3rdParty/Snarl/SnarlInterface.cpp +++ b/3rdParty/Snarl/SnarlInterface.cpp @@ -1,484 +1,412 @@ -// About: -//   Snarl C++ interface implementation -//   To understand what the different functions do and what they return, please -//   have a look at the API on http://www.fullphat.net/dev/api.htm. -//   Also have a look at mSnarl_i.bas found in the CVS/SVN repository for Snarl. -// -//   The functions in SnarlInterface both have ANSI(UTF8) and UNICODE versions. -//   If the LPCWSTR (unicode) version of the functions are called, the strings -//   are converted to UTF8 by SnarlInterface before sent to Snarl. So using the -//   ANSI/UTF8/LPCSTR versions of the functions are faster! -//    -// -// Difference to VB implementation: -//   Please note that string functions return NULL when they fail and not an -//   empty string. So check for NULL... -//   Function names doesn't have the pre "sn". -// -//  -// Authors: -//   Written and maintained by Toke Noer Nøttrup -//   Original C++ version by "Whitman" -// -// License etc. : -//   Feel free to use this code and class as you see fit. -//   If you improve the code, it would be nice of you to take contact to the -//   authors, so all can get the benifit. -// -//   There is no guarantee that the code is correct or functional. -//   USE AT YOUR OWN RISK -//----------------------------------------------------------------------------- - -// History -//  2008/12/31 : Implemented V39 API -//             : Moved SnarlInterface into new Snarl namespace and moved enums etc. out of class -//             : Added WCHAR overloads for all functions -//  2008/08/27 : Fixed return value of IsMessageVisible and HideMessage (returns false on failure now) -//             : Fixed critical error in the new overloaded UpdateMessage() function -//  2008/08/27 : x64 compiler fix -//  2008/08/24 : Renamed all functions to not have prepended "sn". -//             : Memory allocation functions added. (Use FreeString to free strings returned by Snarl) -//             : Added m_nLastMessageId to the class. (Use GetLastMessageId() to get it) -//             : Overloaded a few functions, so one don't have include the message id. (UpdateMessage f.i.) - -//  2008/06/20 : Fixed snShowMessageEx so it actually sends the extended version - oops -//             : Fixed compiler warning C4800: forcing value to bool 'true' or 'false' (performance warning) - -//  2008/05/19 : uSend and uSendEx would always set return value to M_OK on successfull call -//  2008/04/14 : Updated to follow (what should be) the final Snarl 2.0 API -//  2008/03/28 : Few fixes for Snarl 2.0 -//  2007/05/23 : snGetGlobalMsg & snGetSnarlWindow made static -//  2007/03/25 : 1.6 RC1 fixup -//  2007/03/04 : Added - snGetAppPath, snGetIconsPath, snGetVersionEx,  -//                       snSetTimeout, uSendEx - +/// <summary> +///  Snarl C++ interface implementation +/// +///  Written and maintained by Toke Noer Nøttrup (toke@noer.it) +/// +///  Please note the following changes compared to the VB6 (official API) dokumentation: +///  - Function names doesn't have the prefix "sn". Naming of constants and variables are +///    generally changed to follow Microsoft C# standard. This naming convention is kept for +///    the C++ version, to keep them alike. +///  - Grouped variables like SNARL_LAUNCHED, SNARL_QUIT is enums in SnarlEnums namespace. +///  - Message events like SNARL_NOTIFICATION_CLICKED, is found in SnarlEnums::MessageEvent. +///  - Please note that string functions return NULL when they fail and not an empty string. +///  - Some functions in the VB API takes an appToken as first parameter. This token is a +///    member variable in C++ version, so it is omitted from the functions. +///    (Always call RegisterApp as first function!) +///  - Functions manipulating messages (Update, Hide etc.) still takes a message token as +///    parameter, but you can get the last message token calling GetLastMsgToken(); +///    Example: snarl.Hide(snarl.GetLastMsgToken()); +/// +///  The functions in SnarlInterface both have ANSI(UTF8) and UNICODE versions. +///  If the LPCWSTR (unicode) version of the functions are called, the strings +///  are converted to UTF8 by SnarlInterface before sent to Snarl. So using the +///  ANSI/UTF8/LPCSTR versions of the functions are faster! +/// +///  Funtions special to C++ V41 API compared to VB version: +///    GetLastMsgToken() +///    GetAppPath() +///    GetIconsPath() +/// </summary> +///---------------------------------------------------------------------------- +/// <example> +/// SnarlInterface snarl; +/// snarl.RegisterApp(_T("CppTest"), _T("C++ test app"), NULL); +/// snarl.AddClass(_T("Class1"), _T("Class 1")); +/// snarl.EZNotify(_T("Class1"), _T("C++ example 1"), _T("Some text"), 10); +/// snarl.UnregisterApp(); +/// +/// Please see the SimpleTest.cpp and SnarlV41Test.cpp for more example code. +/// </example> +///---------------------------------------------------------------------------- +/// <VersionHistory> +///  2010-08-13 : First release of V41 Snarl API implementation +/// </VersionHistory> + +#define _CRT_SECURE_NO_WARNINGS  #include "SnarlInterface.h" -using namespace Snarl; +namespace Snarl { +namespace V41 {  //-----------------------------------------------------------------------------  // Constructor/Destructor  //-----------------------------------------------------------------------------  SnarlInterface::SnarlInterface() -: m_hwndFrom(NULL), m_nLastMessageId(0) +	: appToken(0), lastMsgToken(0), localError(SnarlEnums::Success)  { -  }  SnarlInterface::~SnarlInterface()  { -  } +// ---------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// snShowMessage() - -/// Displays a message with Title and Text. Timeout controls how long the -/// message is displayed for (in seconds) (omitting this value means the message -/// is displayed indefinately). IconPath specifies the location of a PNG image -/// which will be displayed alongside the message text. -/// <returns>Message Id on success or M_RESULT on failure</returns> - -LONG32 SnarlInterface::ShowMessage(LPCSTR szTitle, LPCSTR szText, LONG32 timeout, LPCSTR szIconPath, HWND hWndReply, WPARAM uReplyMsg) +LONG32 SnarlInterface::RegisterApp(LPCSTR signature, LPCSTR title, LPCSTR icon, HWND hWndReply /* = NULL */, LONG32 msgReply /* = 0 */, SnarlEnums::AppFlags flags /* = SnarlEnums::AppDefault */)  { -	SNARLSTRUCT ss; -	ZeroMemory((void*)&ss, sizeof(ss)); - -	ss.Cmd = SNARL_SHOW; -	StringCbCopyA((LPSTR)&ss.Title, SNARL_STRING_LENGTH, szTitle); -	StringCbCopyA((LPSTR)&ss.Text,  SNARL_STRING_LENGTH, szText); -	StringCbCopyA((LPSTR)&ss.Icon,  SNARL_STRING_LENGTH, szIconPath); -	ss.Timeout = timeout; +	SnarlMessage msg; +	msg.Command = SnarlEnums::RegisterApp; +	msg.Token = 0; +	PackData(msg.PacketData,  +		"id::%s#?title::%s#?icon::%s#?hwnd::%d#?umsg::%d#?flags::%d",  +		signature, title, icon, hWndReply, msgReply, flags); -	ss.LngData2 = reinterpret_cast<LONG32>(hWndReply); -	ss.Id = static_cast<LONG32>(uReplyMsg); +	appToken = Send(msg); +	lastMsgToken = 0; -	m_nLastMessageId = Send(ss); -	return m_nLastMessageId; +	return appToken;  } -LONG32 SnarlInterface::ShowMessage(LPCWSTR szTitle, LPCWSTR szText, LONG32 timeout, LPCWSTR szIconPath, HWND hWndReply, WPARAM uReplyMsg) +LONG32 SnarlInterface::RegisterApp(LPCWSTR signature, LPCWSTR title, LPCWSTR icon, HWND hWndReply /* = NULL */, LONG32 msgReply /* = 0 */, SnarlEnums::AppFlags flags /* = SnarlEnums::AppDefault */)  { -	LPSTR szUTF8Title = WideToUTF8(szTitle); -	LPSTR szUTF8Text  = WideToUTF8(szText); -	LPSTR szUFT8IconPath = WideToUTF8(szIconPath); +	LPCSTR szParam1 = WideToUTF8(signature); +	LPCSTR szParam2 = WideToUTF8(title); +	LPCSTR szParam3 = WideToUTF8(icon); -	LONG32 result = ShowMessage(szUTF8Title, szUTF8Text, timeout, szUFT8IconPath, hWndReply, uReplyMsg); -	 -	delete [] szUTF8Title; -	delete [] szUTF8Text; -	delete [] szUFT8IconPath; +	LONG32 result = RegisterApp(szParam1, szParam2, szParam3, hWndReply, msgReply, flags); +	delete [] szParam1; +	delete [] szParam2; +	delete [] szParam3; +  	return result;  } -	 -//----------------------------------------------------------------------------- -// snShowMessageEx() - -/// Displays a notification. This function is identical to snShowMessage() -/// except that Class specifies an alert previously registered with -/// snRegisterAlert() and SoundFile can optionally specify a WAV sound to play -/// when the notification is displayed on screen. -/// <returns>Message Id on success or M_RESULT on failure</returns> - -LONG32 SnarlInterface::ShowMessageEx(LPCSTR szClass, LPCSTR szTitle, LPCSTR szText, LONG32 timeout, LPCSTR szIconPath, HWND hWndReply, WPARAM uReplyMsg, LPCSTR szSoundFile) +LONG32 SnarlInterface::UnregisterApp()  { -	SNARLSTRUCTEX ssex; -	ZeroMemory((void*)&ssex, sizeof(ssex)); - -	ssex.Cmd = SNARL_EX_SHOW; -	ssex.Timeout = timeout; -	ssex.LngData2 = reinterpret_cast<LONG32>(hWndReply); -	ssex.Id = static_cast<LONG32>(uReplyMsg); +	SnarlMessage msg; +	msg.Command = SnarlEnums::UnregisterApp; +	msg.Token = appToken; +	PackData(msg.PacketData, NULL); -	StringCbCopyA((LPSTR)&ssex.Class, SNARL_STRING_LENGTH, szClass); -	StringCbCopyA((LPSTR)&ssex.Title, SNARL_STRING_LENGTH, szTitle); -	StringCbCopyA((LPSTR)&ssex.Text,  SNARL_STRING_LENGTH, szText); -	StringCbCopyA((LPSTR)&ssex.Icon,  SNARL_STRING_LENGTH, szIconPath); -	StringCbCopyA((LPSTR)&ssex.Extra, SNARL_STRING_LENGTH, szSoundFile); +	appToken = 0; +	lastMsgToken = 0; -	m_nLastMessageId = Send(ssex); -	return m_nLastMessageId; +	return Send(msg);  } -LONG32 SnarlInterface::ShowMessageEx(LPCWSTR szClass, LPCWSTR szTitle, LPCWSTR szText, LONG32 timeout, LPCWSTR szIconPath, HWND hWndReply, WPARAM uReplyMsg, LPCWSTR szSoundFile) +LONG32 SnarlInterface::UpdateApp(LPCSTR title /* = NULL */, LPCSTR icon /* = NULL */)  { -	LPSTR szUTF8Class = WideToUTF8(szClass); -	LPSTR szUTF8Title = WideToUTF8(szTitle); -	LPSTR szUTF8Text  = WideToUTF8(szText); -	LPSTR szUFT8IconPath = WideToUTF8(szIconPath); -	LPSTR szUFT8SoundFile = WideToUTF8(szSoundFile); -	 -	LONG32 result = ShowMessageEx(szUTF8Class, szUTF8Title, szUTF8Text, timeout, szUFT8IconPath, hWndReply, uReplyMsg, szUFT8SoundFile); +	if (title == NULL && icon == NULL) +		return 0; + +	SnarlMessage msg; +	msg.Command = SnarlEnums::UpdateApp; +	msg.Token = appToken; -	delete [] szUTF8Class; -	delete [] szUTF8Title; -	delete [] szUTF8Text; -	delete [] szUFT8IconPath; -	delete [] szUFT8SoundFile; +	// TODO: Uckly code ahead +	if (title != NULL && title[0] != 0 && icon != NULL && icon[0] != 0) +		PackData(msg.PacketData, "title::%s#?icon::%s", title, icon); +	else if (title != NULL && title[0] != 0) +		PackData(msg.PacketData, "title::%s", title); +	else if (icon != NULL && icon[0] != 0) +		PackData(msg.PacketData, "icon::%s", icon); -	return result; +	return Send(msg);  } -//----------------------------------------------------------------------------- -// snHideMessage() - -/// Hides the notification specified by Id. Id is the value returned by -/// snShowMessage() or snShowMessageEx() when the notification was initially -/// created. This function returns True if the notification was successfully -/// hidden or False otherwise (for example, the notification may no longer exist). - -BOOL SnarlInterface::HideMessage(LONG32 Id) +LONG32 SnarlInterface::UpdateApp(LPCWSTR title /* = NULL */, LPCWSTR icon /* = NULL */)  { -	SNARLSTRUCT ss; -	ss.Cmd = SNARL_HIDE; -	ss.Id = Id; +	LPCSTR szParam1 = WideToUTF8(title); +	LPCSTR szParam2 = WideToUTF8(icon); +	 +	LONG32 result = UpdateApp(szParam1, szParam2); +	 +	delete [] szParam1; +	delete [] szParam2; -	LONG32 n = Send(ss); -	return (n == -1 || n == 1) ? TRUE : FALSE; +	return result;  } -BOOL SnarlInterface::HideMessage() +LONG32 SnarlInterface::AddClass(LPCSTR className, LPCSTR description, bool enabled /* = true */)  { -	return HideMessage(m_nLastMessageId); -} - -//----------------------------------------------------------------------------- -// snIsMessageVisible() - -/// Returns True if the notification specified by Id is still visible, or -/// False if not. Id is the value returned by snShowMessage() or -/// snShowMessageEx() when the notification was initially created. +	SnarlMessage msg; +	msg.Command = SnarlEnums::AddClass; +	msg.Token = appToken; +	PackData(msg.PacketData, "id::%s#?name::%s#?enabled::%d", className, description, (enabled ? 1 : 0)); -BOOL SnarlInterface::IsMessageVisible(LONG32 Id) -{ -	SNARLSTRUCT ss; -	ss.Cmd = SNARL_IS_VISIBLE; -	ss.Id = Id; - -	// We are getting -1 when true, checking for 1 just in case. We don't want to return true for the other M_RESULT returns -	LONG32 n = Send(ss);	 -	return (n == -1 || n == 1) ? TRUE : FALSE; +	return Send(msg);  } -BOOL SnarlInterface::IsMessageVisible() +LONG32 SnarlInterface::AddClass(LPCWSTR className, LPCWSTR description, bool enabled /* = true */)  { -	if (m_nLastMessageId == 0) -		return FALSE; +	LPCSTR szParam1 = WideToUTF8(className); +	LPCSTR szParam2 = WideToUTF8(description); +	 +	LONG32 result = AddClass(szParam1, szParam2, enabled); +	 +	delete [] szParam1; +	delete [] szParam2; -	return IsMessageVisible(m_nLastMessageId); +	return result;  } -//----------------------------------------------------------------------------- -// snUpdateMessage() - -/// Changes the title and text in the message specified by Id to the values -/// specified by Title and Text respectively. Id is the value returned by  -/// snShowMessage() or snShowMessageEx() when the notification was originally -/// created. To change the timeout parameter of a notification, use snSetTimeout() - -M_RESULT SnarlInterface::UpdateMessage(LONG32 id, LPCSTR szTitle, LPCSTR szText, LPCSTR szIconPath) +LONG32 SnarlInterface::RemoveClass(LPCSTR className, bool forgetSettings /* = false */)  { -	SNARLSTRUCT ss; -	ZeroMemory((void*)&ss, sizeof(ss)); - -	ss.Cmd = SNARL_UPDATE; -	ss.Id = id; -	 -	StringCbCopyA((LPSTR)&ss.Title, SNARL_STRING_LENGTH, szTitle); -	StringCbCopyA((LPSTR)&ss.Text,  SNARL_STRING_LENGTH, szText); -	StringCbCopyA((LPSTR)&ss.Icon,  SNARL_STRING_LENGTH, szIconPath); +	SnarlMessage msg; +	msg.Command = SnarlEnums::RemoveClass; +	msg.Token = appToken; +	PackData(msg.PacketData, "id::%s#?forget::%d", className, (forgetSettings ? 1 : 0)); -	return static_cast<M_RESULT>(Send(ss)); +	return Send(msg);  } -M_RESULT SnarlInterface::UpdateMessage(LONG32 id, LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szIconPath) +LONG32 SnarlInterface::RemoveClass(LPCWSTR className, bool forgetSettings /* = false */)  { -	LPSTR szParam1 = WideToUTF8(szTitle); -	LPSTR szParam2 = WideToUTF8(szText); -	LPSTR szParam3 = WideToUTF8(szIconPath); +	LPCSTR szParam1 = WideToUTF8(className); -	M_RESULT result = UpdateMessage(id, szParam1, szParam2, szParam3); +	LONG32 result = RemoveClass(szParam1, forgetSettings);  	delete [] szParam1; -	delete [] szParam2; -	delete [] szParam3; -	 +  	return result;  } -M_RESULT SnarlInterface::UpdateMessage(LPCSTR szTitle, LPCSTR szText, LPCSTR szIconPath) +LONG32 SnarlInterface::RemoveAllClasses(bool forgetSettings /* = false */)  { -	return UpdateMessage(m_nLastMessageId, szTitle, szText, szIconPath); -} +	SnarlMessage msg; +	msg.Command = SnarlEnums::RemoveClass; +	msg.Token = appToken; +	PackData(msg.PacketData, "all::1#?forget::%d", (forgetSettings ? 1 : 0)); -M_RESULT SnarlInterface::UpdateMessage(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szIconPath) -{ -	return UpdateMessage(m_nLastMessageId, szTitle, szText, szIconPath); +	return Send(msg);  } -//----------------------------------------------------------------------------- -// snRegisterConfig - -/// Registers an application's configuration interface with Snarl. -/// AppName is the text that's displayed in the Applications list so it should -/// be people friendly ("My cool app" rather than "my_cool_app"). - -M_RESULT SnarlInterface::RegisterConfig(HWND hWnd, LPCSTR szAppName, LONG32 replyMsg) +LONG32 SnarlInterface::EZNotify(LPCSTR className, LPCSTR title, LPCSTR text, LONG32 timeout /* = -1 */, LPCSTR icon /* = NULL */, LONG32 priority /* = 0 */, LPCSTR acknowledge /* = NULL */, LPCSTR value /* = NULL */)  { -	return RegisterConfig2(hWnd, szAppName, replyMsg, ""); -} +	SnarlMessage msg; +	msg.Command = SnarlEnums::Notify; +	msg.Token = appToken; +	PackData(msg.PacketData, +		"id::%s#?title::%s#?text::%s#?timeout::%d#?icon::%s#?priority::%d#?ack::%s#?value::%s", +		className, title, text, timeout, (icon ? icon : ""), priority, (acknowledge ? acknowledge : ""), (value ? value : "")); -M_RESULT SnarlInterface::RegisterConfig(HWND hWnd, LPCWSTR szAppName, LONG32 replyMsg) -{ -	return RegisterConfig2(hWnd, szAppName, replyMsg, L""); +	lastMsgToken = Send(msg); +	return lastMsgToken;  } -//----------------------------------------------------------------------------- -// snRegisterConfig2 - -/// Registers an application's configuration interface with Snarl. -/// This function is identical to snRegisterConfig() except that Icon can be -/// used to specify a PNG image which will be displayed against the -/// application's entry in Snarl's Preferences panel. - -M_RESULT SnarlInterface::RegisterConfig2(HWND hWnd, LPCSTR szAppName, LONG32 replyMsg, LPCSTR szIcon) +LONG32 SnarlInterface::EZNotify(LPCWSTR className, LPCWSTR title, LPCWSTR text, LONG32 timeout /* = -1 */, LPCWSTR icon /* = NULL */, LONG32 priority /* = 0 */, LPCWSTR acknowledge /* = NULL */, LPCWSTR value /* = NULL */)  { -	if (!szAppName || !szIcon) -		return M_BAD_POINTER; - -	SNARLSTRUCT ss; +	LPCSTR szParam1 = WideToUTF8(className); +	LPCSTR szParam2 = WideToUTF8(title); +	LPCSTR szParam3 = WideToUTF8(text); +	LPCSTR szParam4 = WideToUTF8(icon); +	LPCSTR szParam5 = WideToUTF8(acknowledge); +	LPCSTR szParam6 = WideToUTF8(value); +	 +	LONG32 result = EZNotify(szParam1, szParam2, szParam3, timeout, szParam4, priority, szParam5, szParam6); +	 +	delete [] szParam1; delete [] szParam2; delete [] szParam3; +	delete [] szParam4; delete [] szParam5; delete [] szParam6; -	m_hwndFrom = hWnd; +	return result; +} -	ss.Cmd = SNARL_REGISTER_CONFIG_WINDOW_2; -	ss.LngData2 = reinterpret_cast<LONG32>(hWnd); -	ss.Id = replyMsg; -	StringCbCopyA((LPSTR)&ss.Title, SNARL_STRING_LENGTH, szAppName); -	StringCbCopyA((LPSTR)&ss.Icon, SNARL_STRING_LENGTH, szIcon); +LONG32 SnarlInterface::Notify(LPCSTR className, LPCSTR packetData) +{ +	SnarlMessage msg; +	msg.Command = SnarlEnums::Notify; +	msg.Token = appToken; +	PackData(msg.PacketData, "id::%s#?%s", className, packetData); -	return static_cast<M_RESULT>(Send(ss)); +	lastMsgToken = Send(msg); +	return lastMsgToken;  } -M_RESULT SnarlInterface::RegisterConfig2(HWND hWnd, LPCWSTR szAppName, LONG32 replyMsg, LPCWSTR szIcon) +LONG32 SnarlInterface::Notify(LPCWSTR className, LPCWSTR packetData)  { -	LPSTR szParam1 = WideToUTF8(szAppName); -	LPSTR szParam2 = WideToUTF8(szIcon); -	 -	M_RESULT result = RegisterConfig2(hWnd, szParam1, replyMsg, szParam2); +	LPCSTR szParam1 = WideToUTF8(className); +	LPCSTR szParam2 = WideToUTF8(packetData); + +	LONG32 result = Notify(szParam1, szParam2); -	delete [] szParam1; -	delete [] szParam2; +	delete [] szParam1; delete [] szParam2;  	return result;  } - -//----------------------------------------------------------------------------- -// snRevokeConfig - -/// Removes the application previously registered using snRegisterConfig() or -/// snRegisterConfig2(). hWnd should be the same as that used during registration. - -M_RESULT SnarlInterface::RevokeConfig(HWND hWnd) +LONG32 SnarlInterface::EZUpdate(LONG32 msgToken, LPCSTR title /* = NULL */, LPCSTR text /* = NULL */, LONG32 timeout /* = -1 */, LPCSTR icon /* = NULL */)  { -	SNARLSTRUCT ss; +	SnarlMessage msg; +	msg.Command = SnarlEnums::UpdateNotification; +	msg.Token = msgToken; -	m_hwndFrom = NULL; +	// Create packed data +	errno_t err = 0; +	ZeroMemory(msg.PacketData, sizeof(msg.PacketData)); +	char* pData = reinterpret_cast<char*>(msg.PacketData); -	ss.Cmd = SNARL_REVOKE_CONFIG_WINDOW; -	ss.LngData2 = reinterpret_cast<LONG32>(hWnd); +	if (title != NULL) { +		err |= strncat_s(pData, SnarlPacketDataSize, (pData[0] != NULL) ? "#?title::" : "title::", _TRUNCATE); //StringCbCat(tmp, SnarlPacketDataSize, "title::%s"); +		err |= strncat_s(pData, SnarlPacketDataSize, title, _TRUNCATE); +	} +	if (text != NULL) { +		err |= strncat_s(pData, SnarlPacketDataSize, (pData[0] != NULL) ? "#?text::" : "text::", _TRUNCATE); +		err |= strncat_s(pData, SnarlPacketDataSize, text, _TRUNCATE); +	} +	if (icon != NULL) { +		err |= strncat_s(pData, SnarlPacketDataSize, (pData[0] != NULL) ? "#?icon::" : "icon::", _TRUNCATE); +		err |= strncat_s(pData, SnarlPacketDataSize, icon, _TRUNCATE); +	} +	if (timeout != -1) { +		char tmp[32]; +		_itoa_s(timeout, tmp, 10); +		 +		err |= strncat_s(pData, SnarlPacketDataSize, (pData[0] != NULL) ? "#?timeout::" : "timeout::", _TRUNCATE); +		err |= strncat_s(pData, SnarlPacketDataSize, tmp, _TRUNCATE); +	} +	 +	// Check for strcat errors and exit on error +	if (err != 0) { +		localError = SnarlEnums::ErrorFailed; +		return 0; +	} -	return static_cast<M_RESULT>(Send(ss)); +	return Send(msg);  } - -//----------------------------------------------------------------------------- -// snGetVersion() - -/// Checks if Snarl is currently running and, if it is, retrieves the major and -/// minor release version numbers in Major and Minor respectively. -/// Returns True if Snarl is running, False otherwise. - -BOOL SnarlInterface::GetVersion(WORD* Major, WORD* Minor) +LONG32 SnarlInterface::EZUpdate(LONG32 msgToken, LPCWSTR title /* = NULL */, LPCWSTR text /* = NULL */, LONG32 timeout /* = -1 */, LPCWSTR icon /* = NULL */)  { -	SNARLSTRUCT ss; -	ss.Cmd = SNARL_GET_VERSION; -	LONG32 versionInfo = Send(ss); -	if (versionInfo > 0 && versionInfo != M_FAILED && versionInfo != M_TIMED_OUT) { -		*Major = HIWORD(versionInfo); -		*Minor = LOWORD(versionInfo); -		return TRUE; -	} -	return FALSE; -} +	LPCSTR szParam1 = WideToUTF8(title); +	LPCSTR szParam2 = WideToUTF8(text); +	LPCSTR szParam3 = WideToUTF8(icon); +	LONG32 result = EZUpdate(msgToken, szParam1, szParam2, timeout, szParam3); +	 +	delete [] szParam1; delete [] szParam2; delete [] szParam3; +	 +	return result; +} -//----------------------------------------------------------------------------- -// snGetVersionEx +LONG32 SnarlInterface::Update(LONG32 msgToken, LPCSTR packetData) +{ +	SnarlMessage msg; +	msg.Command = SnarlEnums::UpdateNotification; +	msg.Token = msgToken; +	PackData(msg.PacketData, packetData); -/// Returns the Snarl system version number. This is an integer value which -/// represents the system build number and can be used to identify the specific -/// version of Snarl running +	return Send(msg); +} -LONG32 SnarlInterface::GetVersionEx() +LONG32 SnarlInterface::Update(LONG32 msgToken, LPCWSTR packetData)  { -	SNARLSTRUCT ss; -	ss.Cmd = SNARL_GET_VERSION_EX; -	return Send(ss); -} +	LPCSTR szParam1 = WideToUTF8(packetData); +	LONG32 result = Update(msgToken, szParam1); +	 +	delete [] szParam1; +	 +	return result; +} -//----------------------------------------------------------------------------- -// snSetTimeout() +LONG32 SnarlInterface::Hide(LONG32 msgToken) +{ +	SnarlMessage msg; +	msg.Command = SnarlEnums::HideNotification; +	msg.Token = msgToken; +	PackData(msg.PacketData, NULL); -/// Sets the timeout of existing notification Id to Timeout seconds. Id is the -/// value returned by snShowMessage() or snShowMessageEx() when the notification -/// was first created.  +	return Send(msg); +} -M_RESULT SnarlInterface::SetTimeout(LONG32 Id, LONG32 Timeout) +LONG32 SnarlInterface::IsVisible(LONG32 msgToken)  { -	SNARLSTRUCT ss; -	ss.Cmd = SNARL_SET_TIMEOUT; -	ss.Id = Id; -	ss.LngData2 = Timeout; +	SnarlMessage msg; +	msg.Command = SnarlEnums::IsNotificationVisible; +	msg.Token = msgToken; +	PackData(msg.PacketData, NULL); -	return static_cast<M_RESULT>(Send(ss)); +	return Send(msg);  } -M_RESULT SnarlInterface::SetTimeout(LONG32 Timeout) +SnarlEnums::SnarlStatus SnarlInterface::GetLastError()  { -	return SetTimeout(m_nLastMessageId, Timeout); +	return localError;  } -//----------------------------------------------------------------------------- -// snRegisterAlert() - -/// Registers an alert of Class for application AppName which must have previously -/// been registered with either snRegisterConfig() or snRegisterConfig2(). - -M_RESULT SnarlInterface::RegisterAlert(LPCSTR szAppName, LPCSTR szClass) +// static +BOOL SnarlInterface::IsSnarlRunning()  { -	SNARLSTRUCT ss; -	ss.Cmd = SNARL_REGISTER_ALERT; -	StringCbCopyA((LPSTR)&ss.Title, SNARL_STRING_LENGTH, szAppName); -	StringCbCopyA((LPSTR)&ss.Text, SNARL_STRING_LENGTH, szClass); - -	return static_cast<M_RESULT>(Send(ss)); +	return IsWindow(GetSnarlWindow());  } -M_RESULT SnarlInterface::RegisterAlert(LPCWSTR szAppName, LPCWSTR szClass) +LONG32 SnarlInterface::GetVersion()  { -	LPSTR szParam1 = WideToUTF8(szAppName); -	LPSTR szParam2 = WideToUTF8(szClass); -	 -	M_RESULT result = RegisterAlert(szParam1, szParam2); -	 -	delete [] szParam1; -	delete [] szParam2; -	 -	return result; -} +	localError = SnarlEnums::Success; -//----------------------------------------------------------------------------- -// snGetGlobalMsg() +	HWND hWnd = GetSnarlWindow(); +	if (!IsWindow(hWnd)) +	{ +		localError = SnarlEnums::ErrorNotRunning; +		return 0; +	} -/// Returns the atom that corresponds to the "SnarlGlobalEvent" registered -/// Windows message. This message is sent by Snarl when it is first starts and -/// when it shuts down. +	HANDLE hProp = GetProp(hWnd, _T("_version")); +	return reinterpret_cast<int>(hProp); +} -LONG32 SnarlInterface::GetGlobalMsg() +// static +UINT SnarlInterface::Broadcast()  { -	return RegisterWindowMessage(SNARL_GLOBAL_MSG); +	return RegisterWindowMessage(SnarlGlobalMsg);  } +// static +UINT SnarlInterface::AppMsg() +{ +	return RegisterWindowMessage(SnarlAppMsg); +} -//----------------------------------------------------------------------------- -// snGetSnarlWindow - +// static  HWND SnarlInterface::GetSnarlWindow()  { -	return FindWindow(NULL, _T("Snarl")); +	return FindWindow(SnarlWindowClass, SnarlWindowTitle);;  } - -//----------------------------------------------------------------------------- -// snGetAppPath() - -/// Returns a pointer to the path. -/// ** Remember to call FreeString -  LPCTSTR SnarlInterface::GetAppPath()  {  	HWND hWnd = GetSnarlWindow();  	if (hWnd)  	{ -		HWND hWndPath = FindWindowEx(hWnd, 0, _T("static"), NULL); +		HWND hWndPath = FindWindowEx(hWnd, NULL, _T("static"), NULL);  		if (hWndPath)  		{  			TCHAR strTmp[MAX_PATH] = {0}; -			int nReturn = GetWindowText(hWndPath, strTmp, MAX_PATH); +			int nReturn = GetWindowText(hWndPath, strTmp, MAX_PATH-1);  			if (nReturn > 0) {  				TCHAR* strReturn = AllocateString(nReturn + 1); -				StringCchCopy(strReturn, nReturn + 1, strTmp); +				_tcsncpy(strReturn, strTmp, nReturn + 1); +				strReturn[nReturn] = 0;  				return strReturn;  			}  		}  	} +  	return NULL;  } - -//----------------------------------------------------------------------------- -// snGetIconsPath() - -/// Returns a pointer to the iconpath. -/// ** Remember to call FreeString when done with the string -  LPCTSTR SnarlInterface::GetIconsPath()  {  	TCHAR* szIconPath = NULL; @@ -487,13 +415,14 @@ LPCTSTR SnarlInterface::GetIconsPath()  		return NULL;  	size_t nLen = 0; -	if (SUCCEEDED(StringCbLength(szPath, MAX_PATH, &nLen))) +	// TODO: _tcsnlen MAX_PATH +	if (nLen = _tcsnlen(szPath, MAX_PATH))  	{  		nLen += 10 + 1; // etc\\icons\\ + NULL  		szIconPath = AllocateString(nLen); -		StringCbCopy(szIconPath, nLen * sizeof(TCHAR), szPath); -		StringCbCat(szIconPath, nLen * sizeof(TCHAR), _T("etc\\icons\\")); +		_tcsncpy(szIconPath, szPath, nLen); +		_tcsncat(szIconPath, _T("etc\\icons\\"), nLen);  	}  	FreeString(szPath); @@ -501,312 +430,88 @@ LPCTSTR SnarlInterface::GetIconsPath()  	return szIconPath;  } - -//----------------------------------------------------------------------------- -// snSetAsSnarlApp() - -/// Identifies an application as a Snarl App.  (V39) - -void SnarlInterface::SetAsSnarlApp(HWND hWndOwner, SNARL_APP_FLAGS Flags) +LONG32 SnarlInterface::GetLastMsgToken() const  { -	if (IsWindow(hWndOwner)) { -		SetProp(hWndOwner, _T("snarl_app"), reinterpret_cast<HANDLE>(1)); -		SetProp(hWndOwner, _T("snarl_app_flags"), reinterpret_cast<HANDLE>(Flags)); -	} +	return lastMsgToken;  }  //----------------------------------------------------------------------------- -// snGetAppMsg() - -/// Returns the global Snarl Application message  (V39) - -LONG32 SnarlInterface::GetAppMsg() -{ -	return RegisterWindowMessage(SNARL_APP_MSG); -} - - -//----------------------------------------------------------------------------- -// snRegisterApp() - -/// Registers an application with Snarl  (V39) - -M_RESULT SnarlInterface::RegisterApp(LPCSTR Application, LPCSTR SmallIcon, LPCSTR LargeIcon, HWND hWnd, LONG32 ReplyMsg) -{ -	m_hwndFrom = hWnd; -	   -    SNARLSTRUCT ss; -	ss.Cmd = SNARL_REGISTER_APP; -	 -	StringCbCopyA((LPSTR)&ss.Title, SNARL_STRING_LENGTH, Application); -	StringCbCopyA((LPSTR)&ss.Icon,  SNARL_STRING_LENGTH, SmallIcon); -	StringCbCopyA((LPSTR)&ss.Text,  SNARL_STRING_LENGTH, LargeIcon); - -	ss.LngData2 = reinterpret_cast<LONG32>(hWnd); -	ss.Id = ReplyMsg; -	ss.Timeout = GetCurrentProcessId(); - -	return static_cast<M_RESULT>(Send(ss)); -} - -M_RESULT SnarlInterface::RegisterApp(LPCWSTR Application, LPCWSTR SmallIcon, LPCWSTR LargeIcon, HWND hWnd, LONG32 ReplyMsg) -{ -	LPSTR szParam1 = WideToUTF8(Application); -	LPSTR szParam2 = WideToUTF8(SmallIcon); -	LPSTR szParam3 = WideToUTF8(LargeIcon); -	 -	M_RESULT result = RegisterApp(szParam1, szParam2, szParam3, hWnd, ReplyMsg); -	 -	delete [] szParam1; -	delete [] szParam2; -	delete [] szParam3; -	 -	return result; -} - - +// Private functions   //----------------------------------------------------------------------------- -// snUnregisterApp() - -/// Unregisters an application with Snarl  (V39) -M_RESULT SnarlInterface::UnregisterApp() +LONG32 SnarlInterface::Send(SnarlMessage msg)  { -	SNARLSTRUCT ss; -	ss.Cmd = SNARL_UNREGISTER_APP; -	ss.LngData2 = GetCurrentProcessId(); -	 -	m_hwndFrom = NULL; -	 -	return static_cast<M_RESULT>(Send(ss)); -} - +	DWORD_PTR nReturn = 0; // Failure -//----------------------------------------------------------------------------- -// snShowNotification() - -/// Displays a Snarl notification using registered class  (V39) -/// <returns>Message Id on success or M_RESULT on failure</returns> - -LONG32 SnarlInterface::ShowNotification(LPCSTR Class, LPCSTR Title, LPCSTR Text, LONG32 Timeout, LPCSTR Icon, HWND hWndReply, LONG32 uReplyMsg, LPCSTR Sound) -{ -	SNARLSTRUCTEX ssex; -	ssex.Cmd = SNARL_SHOW_NOTIFICATION; -	 -	StringCbCopyExA((LPSTR)&ssex.Title, SNARL_STRING_LENGTH, Title, NULL, NULL, STRSAFE_IGNORE_NULLS); -	StringCbCopyExA((LPSTR)&ssex.Text,  SNARL_STRING_LENGTH, Text,  NULL, NULL, STRSAFE_IGNORE_NULLS); -	StringCbCopyExA((LPSTR)&ssex.Icon,  SNARL_STRING_LENGTH, Icon,  NULL, NULL, STRSAFE_IGNORE_NULLS); - -	ssex.Timeout = Timeout; -	ssex.LngData2 = reinterpret_cast<LONG32>(hWndReply); -	ssex.Id = uReplyMsg; - -	StringCbCopyExA((LPSTR)&ssex.Extra, SNARL_STRING_LENGTH, Sound, NULL, NULL, STRSAFE_IGNORE_NULLS); -	StringCbCopyA((LPSTR)&ssex.Class,  SNARL_STRING_LENGTH, Class); -     -	ssex.Reserved1 = GetCurrentProcessId(); -	 -	m_nLastMessageId = Send(ssex); -	return m_nLastMessageId; -} - -LONG32 SnarlInterface::ShowNotification(LPCWSTR Class, LPCWSTR Title, LPCWSTR Text, LONG32 Timeout, LPCWSTR Icon, HWND hWndReply, LONG32 uReplyMsg, LPCWSTR Sound) -{ -	LPSTR szParam1 = WideToUTF8(Class); -	LPSTR szParam2 = WideToUTF8(Title); -	LPSTR szParam3 = WideToUTF8(Text); -	LPSTR szParam4 = WideToUTF8(Icon); -	LPSTR szParam5 = WideToUTF8(Sound); -	 -	LONG32 result = ShowNotification(szParam1, szParam2, szParam3, Timeout, szParam4, hWndReply, uReplyMsg, szParam5); -	 -	delete [] szParam1; -	delete [] szParam2; -	delete [] szParam3; -	delete [] szParam4; -	delete [] szParam5; -	 -	return result; -} - - -//----------------------------------------------------------------------------- -// snChangeAttribute() - -/// (V39) +	HWND hWnd = GetSnarlWindow(); +	if (!IsWindow(hWnd)) +	{ +		localError = SnarlEnums::ErrorNotRunning; +		return 0; +	} -M_RESULT SnarlInterface::ChangeAttribute(LONG32 Id, SNARL_ATTRIBUTES Attr, LPCSTR Value) -{ -	SNARLSTRUCT ss; -	ss.Cmd = SNARL_CHANGE_ATTR; -	ss.Id = Id; -	ss.LngData2 = Attr; -	 -	StringCbCopyExA((LPSTR)&ss.Text, SNARL_STRING_LENGTH, Value, NULL, NULL, STRSAFE_IGNORE_NULLS); -	 -	return static_cast<M_RESULT>(Send(ss)); -} +	COPYDATASTRUCT cds; +	cds.dwData = 0x534E4C02; // "SNL",2; +	cds.cbData = sizeof(SnarlMessage); +	cds.lpData = &msg; -M_RESULT SnarlInterface::ChangeAttribute(LONG32 Id, SNARL_ATTRIBUTES Attr, LPCWSTR Value) -{ -	LPSTR szParam1 = WideToUTF8(Value); -	 -	M_RESULT result = ChangeAttribute(Id, Attr, szParam1); -	 -	delete [] szParam1; -	 -	return result; -} +	if (SendMessageTimeout(hWnd, WM_COPYDATA, (WPARAM)GetCurrentProcessId(), (LPARAM)&cds, SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG, 500, &nReturn) == 0) +	{ +		// return zero on failure +		if (GetLastError() == ERROR_TIMEOUT) +			localError = SnarlEnums::ErrorTimedOut; +		else +			localError = SnarlEnums::ErrorFailed; +		 +		return 0; +	} -M_RESULT SnarlInterface::ChangeAttribute(SNARL_ATTRIBUTES Attr, LPCSTR Value) -{ -	return ChangeAttribute(m_nLastMessageId, Attr, Value); -} +	// return result and cache LastError +	HANDLE hProp = GetProp(hWnd, _T("last_error")); +	localError = static_cast<SnarlEnums::SnarlStatus>(reinterpret_cast<int>(hProp)); -M_RESULT SnarlInterface::ChangeAttribute(SNARL_ATTRIBUTES Attr, LPCWSTR Value) -{ -	return ChangeAttribute(m_nLastMessageId, Attr, Value); +	return nReturn;  } -  //----------------------------------------------------------------------------- -// snSetClassDefault() -/// Sets the default value for an alert class  (V39) - -M_RESULT SnarlInterface::SetClassDefault(LPCSTR Class, SNARL_ATTRIBUTES Attr, LPCSTR Value) +// Remember to delete [] returned string +inline +LPSTR SnarlInterface::WideToUTF8(LPCWSTR szWideStr)  { -	SNARLSTRUCT ss; -	ss.Cmd = SNARL_SET_CLASS_DEFAULT; -	ss.LngData2 = Attr; -	ss.Timeout = GetCurrentProcessId(); -	 -	StringCbCopyExA((LPSTR)&ss.Text, SNARL_STRING_LENGTH, Class, NULL, NULL, STRSAFE_IGNORE_NULLS); -	StringCbCopyExA((LPSTR)&ss.Icon, SNARL_STRING_LENGTH, Value, NULL, NULL, STRSAFE_IGNORE_NULLS); - -	return static_cast<M_RESULT>(Send(ss)); -} +	if (szWideStr == NULL) +		return NULL; -M_RESULT SnarlInterface::SetClassDefault(LPCWSTR Class, SNARL_ATTRIBUTES Attr, LPCWSTR Value) -{ -	LPSTR szParam1 = WideToUTF8(Class); -	LPSTR szParam2 = WideToUTF8(Value); +	int nSize = WideCharToMultiByte(CP_UTF8, 0, szWideStr, -1, NULL, 0, NULL, NULL); +	LPSTR szUTF8 = new char[nSize]; +	WideCharToMultiByte(CP_UTF8, 0, szWideStr, -1, szUTF8, nSize, NULL, NULL); -	M_RESULT result = SetClassDefault(szParam1, Attr, szParam2); -	 -	delete [] szParam1; -	delete [] szParam2; -	 -	return result; -} - - -//----------------------------------------------------------------------------- -// snGetRevision() - -/// Gets the current Snarl revision (build) number  (V39) -/// Returns the build version number, or M_RESULT on failure. - -LONG32 SnarlInterface::GetRevision() -{ -	SNARLSTRUCT ss; -	ss.Cmd = SNARL_GET_REVISION; -	ss.LngData2 = 0xFFFE; - -	return Send(ss); +	return szUTF8;  } - -//----------------------------------------------------------------------------- -// snAddClass() - -/// (V39) - -M_RESULT SnarlInterface::AddClass(LPCSTR Class, LPCSTR Description, SNARL_CLASS_FLAGS Flags, LPCSTR DefaultTitle, LPCSTR DefaultIcon, LONG32 DefaultTimeout) +void SnarlInterface::PackData(BYTE* data, LPCSTR format, ...)  { -	SNARLSTRUCT ss; -	ss.Cmd = SNARL_ADD_CLASS; -	ss.LngData2 = Flags; -	ss.Timeout = GetCurrentProcessId(); -	 -	StringCbCopyExA((LPSTR)&ss.Text,  SNARL_STRING_LENGTH, Class, NULL, NULL, STRSAFE_IGNORE_NULLS); -	StringCbCopyExA((LPSTR)&ss.Title, SNARL_STRING_LENGTH, Description, NULL, NULL, STRSAFE_IGNORE_NULLS); +	// Always zero array - Used to clear the array in member functions +	ZeroMemory(data, SnarlPacketDataSize); -	LONG32 result = Send(ss); +	// Return if format string is empty +	if (format == NULL || format[0] == 0) +		return; -	if (static_cast<M_RESULT>(result) == M_OK) -	{ -		SetClassDefault(Class, SNARL_ATTRIBUTE_TITLE, DefaultTitle); -		SetClassDefault(Class, SNARL_ATTRIBUTE_ICON, DefaultIcon); -		if (DefaultTimeout > 0) { -			char str[64] = {0}; -			StringCbPrintfA((LPSTR)&str, sizeof(str), "%d", DefaultTimeout); -			SetClassDefault(Class, SNARL_ATTRIBUTE_TIMEOUT, str); -		} -		 -		return M_OK; -	} -	else -		return M_FAILED; -} - -M_RESULT SnarlInterface::AddClass(LPCWSTR Class, LPCWSTR Description, SNARL_CLASS_FLAGS Flags, LPCWSTR DefaultTitle, LPCWSTR DefaultIcon, LONG32 DefaultTimeout) -{ -	LPCSTR szClass        = WideToUTF8(Class); -	LPCSTR szDescription  = WideToUTF8(Description); -	LPCSTR szDefaultTitle = WideToUTF8(DefaultTitle); -	LPCSTR szDefaultIcon  = WideToUTF8(DefaultIcon); +	int cchStrTextLen = 0; +	va_list args; +	va_start(args, format); -	M_RESULT result = AddClass(szClass, szDescription, Flags, szDefaultTitle, szDefaultIcon, DefaultTimeout); -	 -	delete [] szClass; -	delete [] szDescription; -	delete [] szDefaultTitle; -	delete [] szDefaultIcon; -	 -	return result; -} +	// Get size of buffer +	cchStrTextLen = _vscprintf(format, args) + 1; // + NULL +	if (cchStrTextLen <= 1) +		return; -//----------------------------------------------------------------------------- -// Private functions -//----------------------------------------------------------------------------- - -template <class T> -LONG32 SnarlInterface::Send(T ss) -{ -	DWORD_PTR nReturn = M_FAILED; +	// Create formated string - _TRUNCATE will ensure zero terminated +	_vsnprintf_s((char*)data, SnarlPacketDataSize, _TRUNCATE, format, args); -	HWND hWnd = GetSnarlWindow(); -	if (IsWindow(hWnd)) -	{ -		COPYDATASTRUCT cds; -		cds.dwData = 2; -		cds.cbData = sizeof(ss); -		cds.lpData = &ss; - -		if (SendMessageTimeout(hWnd, WM_COPYDATA, (WPARAM)m_hwndFrom, (LPARAM)&cds, SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG, 1000, &nReturn) == 0) -		{ -			if (GetLastError() == ERROR_TIMEOUT) -				nReturn = M_TIMED_OUT; -		} -	} - -	return static_cast<LONG32>(nReturn); +	va_end(args);  } -//----------------------------------------------------------------------------- - -// Remember to : delete [] returned string - -LPSTR SnarlInterface::WideToUTF8(LPCWSTR szWideStr) -{ -	if (szWideStr == NULL) -		return NULL; - -    int nSize = WideCharToMultiByte(CP_UTF8, 0, szWideStr, -1, NULL, 0, NULL, NULL); -    LPSTR szUTF8 = new char[nSize]; -    WideCharToMultiByte(CP_UTF8, 0, szWideStr, -1, szUTF8, nSize, NULL, NULL); -     -    return szUTF8; -} +}} // namespace Snarl::V41 diff --git a/3rdParty/Snarl/SnarlInterface.h b/3rdParty/Snarl/SnarlInterface.h index 137d597..9440451 100644 --- a/3rdParty/Snarl/SnarlInterface.h +++ b/3rdParty/Snarl/SnarlInterface.h @@ -1,218 +1,276 @@ -#ifndef SNARL_INTERFACE -#define SNARL_INTERFACE +#ifndef SNARL_INTERFACE_V41 +#define SNARL_INTERFACE_V41  #include <tchar.h>  #include <windows.h> -#include <strsafe.h> +#include <cstdio> + +#ifndef SMTO_NOTIMEOUTIFNOTHUNG +	#define SMTO_NOTIMEOUTIFNOTHUNG 8 +#endif  namespace Snarl { +	namespace V41 { -	static const LPCTSTR SNARL_GLOBAL_MSG = _T("SnarlGlobalEvent"); -	static const LPCTSTR SNARL_APP_MSG    = _T("SnarlAppMessage"); +	static const LPCTSTR SnarlWindowClass = _T("w>Snarl"); +	static const LPCTSTR SnarlWindowTitle = _T("Snarl"); -	static const int SNARL_STRING_LENGTH = 1024; -	static const int SNARL_UNICODE_LENGTH = SNARL_STRING_LENGTH / 2; +	static const LPCTSTR SnarlGlobalMsg = _T("SnarlGlobalEvent"); +	static const LPCTSTR SnarlAppMsg = _T("SnarlAppMessage"); -	static const LONG32 SNARL_LAUNCHED = 1;                // Snarl has just started running -	static const LONG32 SNARL_QUIT = 2;                    // Snarl is about to stop running -	static const LONG32 SNARL_ASK_APPLET_VER = 3;          // (R1.5) Reserved for future use -	static const LONG32 SNARL_SHOW_APP_UI = 4;             // (R1.6) Application should show its UI +	static const int SnarlPacketDataSize = 4096; -	static const LONG32 SNARL_NOTIFICATION_CLICKED = 32;   // notification was right-clicked by user -	static const LONG32 SNARL_NOTIFICATION_TIMED_OUT = 33; -	static const LONG32 SNARL_NOTIFICATION_ACK = 34;       // notification was left-clicked by user -	static const LONG32 SNARL_NOTIFICATION_MENU = 35;           // V39 - menu item selected -	static const LONG32 SNARL_NOTIFICATION_MIDDLE_BUTTON = 36;  // V39 - notification middle-clicked by user -	static const LONG32 SNARL_NOTIFICATION_CLOSED = 37;         // V39 - user clicked the close gadget +	// Enums put in own namespace, because ANSI C++ doesn't decorate enums with tagname :( +	namespace SnarlEnums { -	static const LONG32 SNARL_NOTIFICATION_CANCELLED = SNARL_NOTIFICATION_CLICKED;  // Added in R1.6 +		/// <summary> +		/// Global event identifiers. +		/// Identifiers marked with a '*' are sent by Snarl in two ways: +		///   1. As a broadcast message (uMsg = 'SNARL_GLOBAL_MSG') +		///   2. To the window registered in snRegisterConfig() or snRegisterConfig2() +		///      (uMsg = reply message specified at the time of registering) +		/// In both cases these values appear in wParam. +		///    +		/// Identifiers not marked are not broadcast; they are simply sent to the application's registered window. +		/// </summary> +		enum GlobalEvent +		{ +			SnarlLaunched = 1,      // Snarl has just started running* +			SnarlQuit = 2,          // Snarl is about to stop running* +			SnarlAskAppletVer = 3,  // (R1.5) Reserved for future use +			SnarlShowAppUi = 4      // (R1.6) Application should show its UI +		}; -	static const DWORD WM_SNARLTEST = WM_USER + 237;    // note hardcoded WM_USER value! +		/// <summary> +		/// Message event identifiers. +		/// These are sent by Snarl to the window specified in RegisterApp() when the +		/// Snarl Notification raised times out or the user clicks on it. +		/// </summary> +		enum MessageEvent +		{ +			NotificationClicked = 32,      // Notification was right-clicked by user +			NotificationCancelled = 32,    // Added in V37 (R1.6) -- same value, just improved the meaning of it +			NotificationTimedOut = 33,     //  +			NotificationAck = 34,          // Notification was left-clicked by user +			NotificationMenu = 35,         // Menu item selected (V39) +			NotificationMiddleButton = 36, // Notification middle-clicked by user (V39) +			NotificationClosed = 37        // User clicked the close gadget (V39) +		}; -	// -------------------------------------------------------------------- -	 -	typedef enum M_RESULT { -		M_ABORTED         = 0x80000007, -		M_ACCESS_DENIED   = 0x80000009, -		M_ALREADY_EXISTS  = 0x8000000C, -		M_BAD_HANDLE      = 0x80000006, -		M_BAD_POINTER     = 0x80000005, -		M_FAILED          = 0x80000008, -		M_INVALID_ARGS    = 0x80000003, -		M_NO_INTERFACE    = 0x80000004, -		M_NOT_FOUND       = 0x8000000B, -		M_NOT_IMPLEMENTED = 0x80000001, -		M_OK              = 0x00000000, -		M_OUT_OF_MEMORY   = 0x80000002, -		M_TIMED_OUT       = 0x8000000A -	}; +		/// <summary> +		/// Error values returned by calls to GetLastError(). +		/// </summary> +		enum SnarlStatus +		{ +			Success = 0, -	enum SNARL_COMMANDS { -		SNARL_SHOW = 1, -		SNARL_HIDE, -		SNARL_UPDATE, -		SNARL_IS_VISIBLE, -		SNARL_GET_VERSION, -		SNARL_REGISTER_CONFIG_WINDOW, -		SNARL_REVOKE_CONFIG_WINDOW, - -		/* R1.6 onwards */ -		SNARL_REGISTER_ALERT, -		SNARL_REVOKE_ALERT,   // for future use -		SNARL_REGISTER_CONFIG_WINDOW_2, -		SNARL_GET_VERSION_EX, -		SNARL_SET_TIMEOUT, -		 -		/* following introduced in Snarl V39 (R2.1) */ -		SNARL_SET_CLASS_DEFAULT, -		SNARL_CHANGE_ATTR, -		SNARL_REGISTER_APP, -		SNARL_UNREGISTER_APP, -		SNARL_ADD_CLASS, - -		/* extended commands (all use SNARLSTRUCTEX) */ -		SNARL_EX_SHOW = 0x20, -		SNARL_SHOW_NOTIFICATION                // V39 -	}; -	 -	static const SNARL_COMMANDS SNARL_GET_REVISION = SNARL_REVOKE_ALERT; -	 -	typedef enum SNARL_APP_FLAGS { -		SNARL_APP_HAS_PREFS = 1, -		SNARL_APP_HAS_ABOUT = 2 -	}; -	 -	static const LONG32 SNARL_APP_PREFS = 1; -	static const LONG32 SNARL_APP_ABOUT = 2; +			ErrorFailed = 101,        // miscellaneous failure +			ErrorUnknownCommand,      // specified command not recognised +			ErrorTimedOut,            // Snarl took too long to respond -	 -	/* --------------- V39 additions --------------- */ -	 -	/* snAddClass() flags */ -	enum SNARL_CLASS_FLAGS { -		SNARL_CLASS_ENABLED = 0, -		SNARL_CLASS_DISABLED = 1, -		SNARL_CLASS_NO_DUPLICATES = 2,         // means Snarl will suppress duplicate notifications -		SNARL_CLASS_DELAY_DUPLICATES = 4       // means Snarl will suppress duplicate notifications within a pre-set time period -	}; +			ErrorArgMissing = 109,    // required argument missing +			ErrorSystem,              // internal system error -	/* Class attributes */ -	typedef enum SNARL_ATTRIBUTES { -		SNARL_ATTRIBUTE_TITLE = 1, -		SNARL_ATTRIBUTE_TEXT, -		SNARL_ATTRIBUTE_ICON, -		SNARL_ATTRIBUTE_TIMEOUT, -		SNARL_ATTRIBUTE_SOUND, -		SNARL_ATTRIBUTE_ACK,               // file to run on ACK -		SNARL_ATTRIBUTE_MENU -	}; +			ErrorNotRunning = 201,    // Snarl handling window not found +			ErrorNotRegistered,       //  +			ErrorAlreadyRegistered,   // not used yet; RegisterApp() returns existing token +			ErrorClassAlreadyExists,  // not used yet; AddClass() returns existing token +			ErrorClassBlocked, +			ErrorClassNotFound, +			ErrorNotificationNotFound +		}; -	/* ------------------- end of V39 additions ------------------ */ -	 -	struct SNARLSTRUCT { -		SNARL_COMMANDS Cmd; -		LONG32 Id; -		LONG32 Timeout; -		LONG32 LngData2; -		char Title[SNARL_STRING_LENGTH]; -		char Text[SNARL_STRING_LENGTH]; -		char Icon[SNARL_STRING_LENGTH]; -	}; +		/// <summary> +		/// Application flags - features this app supports. +		/// </summary> +		enum AppFlags +		{ +			AppDefault = 0, +			AppHasPrefs = 1, +			AppHasAbout = 2, +			AppIsWindowless = 0x8000 +		}; -	struct SNARLSTRUCTEX { -		SNARL_COMMANDS Cmd; -		LONG32 Id; -		LONG32 Timeout; -		LONG32 LngData2; -		char Title[SNARL_STRING_LENGTH]; -		char Text[SNARL_STRING_LENGTH]; -		char Icon[SNARL_STRING_LENGTH]; - -		char Class[SNARL_STRING_LENGTH]; -		char Extra[SNARL_STRING_LENGTH]; -		char Extra2[SNARL_STRING_LENGTH]; -		LONG32 Reserved1; -		LONG32 Reserved2; +		enum SnarlCommand +		{ +			RegisterApp = 1, +			UnregisterApp, +			UpdateApp, +			SetCallback, +			AddClass, +			RemoveClass, +			Notify, +			UpdateNotification, +			HideNotification, +			IsNotificationVisible, +			LastError                  // deprecated but retained for backwards compatability +		}; +	} + +	struct SnarlMessage +	{ +		SnarlEnums::SnarlCommand Command; +		LONG32 Token; +		BYTE PacketData[SnarlPacketDataSize];  	}; +	static const DWORD WM_SNARLTEST = WM_USER + 237;  	// ------------------------------------------------------------------------ -	// SnarlInterface class definition +	/// SnarlInterface class definition  	// ------------------------------------------------------------------------ -	  	class SnarlInterface {  		public:  			SnarlInterface();  			~SnarlInterface(); - -			static HWND   GetSnarlWindow();		 -			static LONG32 GetGlobalMsg(); -  			LPTSTR AllocateString(size_t n) { return new TCHAR[n]; } -			void FreeString(LPCTSTR str)    { delete [] str; str = NULL; } +			void FreeString(LPTSTR str)     { delete [] str; str = NULL; } +			void FreeString(LPCTSTR str)    { delete [] str; } + +			/// <summary>Register application with Snarl.</summary> +			/// <returns>The application token or 0 on failure.</returns> +			/// <remarks>The application token is saved in SnarlInterface member variable, so just use return value to check for error.</remarks> +			LONG32 RegisterApp(LPCSTR signature, LPCSTR title, LPCSTR icon, HWND hWndReply = NULL, LONG32 msgReply = 0, SnarlEnums::AppFlags flags = SnarlEnums::AppDefault); +			LONG32 RegisterApp(LPCWSTR  signature, LPCWSTR title, LPCWSTR icon, HWND hWndReply = NULL, LONG32 msgReply = 0, SnarlEnums::AppFlags flags = SnarlEnums::AppDefault); + +			/// <summary>Unregister application with Snarl when application is closing.</summary> +			/// <returns>0 on failure.</returns> +			LONG32 UnregisterApp(); + +			/// <summary>Update information provided when calling RegisterApp.</summary> +			/// <returns>0 on failure.</returns> +			LONG32 UpdateApp(LPCSTR title = NULL, LPCSTR icon = NULL); +			LONG32 UpdateApp(LPCWSTR title = NULL, LPCWSTR icon = NULL); + +			/// <summary>Add a notification class to Snarl.</summary> +			/// <returns>0 on failure.</returns> +			LONG32 AddClass(LPCSTR className, LPCSTR description, bool enabled = true); +			LONG32 AddClass(LPCWSTR className, LPCWSTR description, bool enabled = true); +			/// <summary>Remove a notification class added with AddClass().</summary> +			/// <returns>0 on failure.</returns> +			LONG32 RemoveClass(LPCSTR className, bool forgetSettings = false); +			LONG32 RemoveClass(LPCWSTR className, bool forgetSettings = false); -			LONG32  ShowMessage(LPCSTR szTitle, LPCSTR szText, LONG32 timeout = 0, LPCSTR szIconPath = "", HWND hWndReply = NULL, WPARAM uReplyMsg = 0); -			LONG32  ShowMessage(LPCWSTR szTitle, LPCWSTR szText, LONG32 timeout = 0, LPCWSTR szIconPath = L"", HWND hWndReply = NULL, WPARAM uReplyMsg = 0); -			LONG32  ShowMessageEx(LPCSTR szClass, LPCSTR szTitle, LPCSTR szText, LONG32 timeout = 0, LPCSTR szIconPath = "", HWND hWndReply = NULL, WPARAM uReplyMsg = 0, LPCSTR szSoundFile = ""); -			LONG32  ShowMessageEx(LPCWSTR szClass, LPCWSTR szTitle, LPCWSTR szText, LONG32 timeout = 0, LPCWSTR szIconPath = L"", HWND hWndReply = NULL, WPARAM uReplyMsg = 0, LPCWSTR szSoundFile = L""); - -			LPCTSTR GetAppPath();    // ** Remember to FreeString when finished with the string ! -			LPCTSTR GetIconsPath();  // ** Remember to FreeString when finished with the string ! - -			BOOL      GetVersion(WORD* Major, WORD* Minor); -			LONG32    GetVersionEx(); -			BOOL      HideMessage(); -			BOOL      HideMessage(LONG32 Id); -			BOOL      IsMessageVisible(); -			BOOL      IsMessageVisible(LONG32 Id); -			M_RESULT  RegisterAlert(LPCSTR szAppName, LPCSTR szClass); -			M_RESULT  RegisterAlert(LPCWSTR szAppName, LPCWSTR szClass); -			M_RESULT  RegisterConfig(HWND hWnd, LPCSTR szAppName, LONG32 replyMsg); -			M_RESULT  RegisterConfig(HWND hWnd, LPCWSTR szAppName, LONG32 replyMsg); -			M_RESULT  RegisterConfig2(HWND hWnd, LPCSTR szAppName, LONG32 replyMsg, LPCSTR szIcon); -			M_RESULT  RegisterConfig2(HWND hWnd, LPCWSTR szAppName, LONG32 replyMsg, LPCWSTR szIcon); -			M_RESULT  RevokeConfig(HWND hWnd); -			M_RESULT  SetTimeout(LONG32 Timeout); -			M_RESULT  SetTimeout(LONG32 Id, LONG32 Timeout); -			M_RESULT  UpdateMessage(LPCSTR szTitle, LPCSTR szText, LPCSTR szIconPath = ""); -			M_RESULT  UpdateMessage(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szIconPath = L""); -			M_RESULT  UpdateMessage(LONG32 Id, LPCSTR szTitle, LPCSTR szText, LPCSTR szIconPath = ""); -			M_RESULT  UpdateMessage(LONG32 Id, LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szIconPath = L""); +			/// <summary>Remove all notification classes in one call.</summary> +			/// <returns>0 on failure.</returns> +			LONG32 RemoveAllClasses(bool forgetSettings = false); -			/* V39 */ -			M_RESULT  AddClass(LPCSTR Class, LPCSTR Description = NULL, SNARL_CLASS_FLAGS Flags = SNARL_CLASS_ENABLED, LPCSTR DefaultTitle = NULL, LPCSTR DefaultIcon = NULL, LONG32 DefaultTimeout = 0); -			M_RESULT  AddClass(LPCWSTR Class, LPCWSTR Description = NULL, SNARL_CLASS_FLAGS Flags = SNARL_CLASS_ENABLED, LPCWSTR DefaultTitle = NULL, LPCWSTR DefaultIcon = NULL, LONG32 DefaultTimeout = 0); -			M_RESULT  ChangeAttribute(SNARL_ATTRIBUTES Attr, LPCSTR Value); -			M_RESULT  ChangeAttribute(SNARL_ATTRIBUTES Attr, LPCWSTR Value); -			M_RESULT  ChangeAttribute(LONG32 Id, SNARL_ATTRIBUTES Attr, LPCSTR Value);			 -			M_RESULT  ChangeAttribute(LONG32 Id, SNARL_ATTRIBUTES Attr, LPCWSTR Value);			 -			LONG32    GetAppMsg(); -			LONG32    GetRevision(); +			/// <summary>Show a Snarl notification.</summary> +			/// <returns>Returns the notification token or 0 on failure.</returns> +			/// <remarks>You can use <see cref="GetLastMsgToken()" /> to get the last token.</remarks> +			LONG32 EZNotify(LPCSTR className, LPCSTR title, LPCSTR text, LONG32 timeout = -1, LPCSTR icon = NULL, LONG32 priority = 0, LPCSTR acknowledge = NULL, LPCSTR value = NULL); +			LONG32 EZNotify(LPCWSTR className, LPCWSTR title, LPCWSTR text, LONG32 timeout = -1, LPCWSTR icon = NULL, LONG32 priority = 0, LPCWSTR acknowledge = NULL, LPCWSTR value = NULL); + +			/// <summary> +			///     Show a Snarl notification. +			///     This function requires that you write your own packet data. +			/// </summary> +			/// <returns>Returns the notification token or 0 on failure.</returns> +			/// <remarks>You can use <see cref="GetLastMsgToken()" /> to get the last token.</remarks> +			LONG32 Notify(LPCSTR className, LPCSTR packetData); +			LONG32 Notify(LPCWSTR className, LPCWSTR packetData); + +			/// <summary>Update the text or other parameters of a visible Snarl notification.</summary> +			/// <returns>0 on failure.</returns> +			LONG32 EZUpdate(LONG32 msgToken, LPCSTR title = NULL, LPCSTR text = NULL, LONG32 timeout = -1, LPCSTR icon = NULL); +			LONG32 EZUpdate(LONG32 msgToken, LPCWSTR title = NULL, LPCWSTR text = NULL, LONG32 timeout = -1, LPCWSTR icon = NULL); -			M_RESULT  RegisterApp(LPCSTR Application, LPCSTR SmallIcon, LPCSTR LargeIcon, HWND hWnd = 0, LONG32 ReplyMsg = 0); -			M_RESULT  RegisterApp(LPCWSTR Application, LPCWSTR SmallIcon, LPCWSTR LargeIcon, HWND hWnd = 0, LONG32 ReplyMsg = 0); -			void      SetAsSnarlApp(HWND hWndOwner, SNARL_APP_FLAGS Flags = (SNARL_APP_FLAGS)(SNARL_APP_HAS_ABOUT | SNARL_APP_HAS_PREFS)); -			M_RESULT  SetClassDefault(LPCSTR Class, SNARL_ATTRIBUTES Attr, LPCSTR Value); -			M_RESULT  SetClassDefault(LPCWSTR Class, SNARL_ATTRIBUTES Attr, LPCWSTR Value); -			LONG32    ShowNotification(LPCSTR Class, LPCSTR Title = NULL, LPCSTR Text = NULL, LONG32 Timeout = 0, LPCSTR Icon = NULL, HWND hWndReply = NULL, LONG32 uReplyMsg = 0, LPCSTR Sound = NULL); -			LONG32    ShowNotification(LPCWSTR Class, LPCWSTR Title = NULL, LPCWSTR Text = NULL, LONG32 Timeout = 0, LPCWSTR Icon = NULL, HWND hWndReply = NULL, LONG32 uReplyMsg = 0, LPCWSTR Sound = NULL); -			M_RESULT  UnregisterApp(); +			/// <summary> +			///     Update the text or other parameters of a visible Snarl notification. +			///     This function requires that you write your own packet data. +			/// </summary> +			/// <returns>0 on failure.</returns> +			LONG32 Update(LONG32 msgToken, LPCSTR packetData); +			LONG32 Update(LONG32 msgToken, LPCWSTR packetData); + +			/// <summary>Hide a Snarl notification.</summary> +			/// <returns>0 on failure.</returns> +			LONG32 Hide(LONG32 msgToken); + +			/// <summary>Test if a Snarl notification is visible.</summary> +			/// <returns>Returns -1 if message is visible. 0 if not visible or if an error occured.</returns> +			LONG32 IsVisible(LONG32 msgToken); + +			/// <summary>Get the last error from Snarl. Call after other functions return 0 to know why it failed.</summary> +			/// <returns>Returns one of the SnarlEnums::SnarlStatus values.</returns> +			SnarlEnums::SnarlStatus GetLastError(); + +			/// <summary>Get Snarl version, if it is running.</summary> +			/// <returns>Returns a number indicating Snarl version.</returns> +			LONG32 GetVersion(); + +			/// <summary> +			///     Get the path to where Snarl is installed. +			///     ** Remember to call <see cref="FreeString(LPCTSTR)" /> on the returned string !!! +			/// </summary> +			/// <returns>Returns the path to where Snarl is installed.</returns> +			/// <remarks>This is a V39 API method.</remarks> +			LPCTSTR  GetAppPath(); + +			/// <summary> +			///     Get the path to where the default Snarl icons are located. +			///     <para>** Remember to call <see cref="FreeString(LPCTSTR)" /> on the returned string !!!</para> +			/// </summary> +			/// <returns>Returns the path to where the default Snarl icons are located.</returns> +			/// <remarks>This is a V39 API method.</remarks> +			LPCTSTR  GetIconsPath(); + +			/// <summary>GetLastMsgToken() returns token of the last message sent to Snarl.</summary> +			/// <returns>Returns message token of last message.</returns> +			/// <remarks>This function is not in the official API!</remarks> +			LONG32 GetLastMsgToken() const; -			LONG32    GetLastMessageId() { return m_nLastMessageId; } +			/// <summary>Check whether Snarl is running</summary> +			/// <returns>Returns true if Snarl system was found running.</returns> +			static BOOL IsSnarlRunning(); + +			/// <summary> +			///     Returns the value of Snarl's global registered message. +			///     Notes: +			///       Snarl registers SNARL_GLOBAL_MSG during startup which it then uses to communicate +			///       with all running applications through a Windows broadcast message. This function can +			///       only fail if for some reason the Windows RegisterWindowMessage() function fails +			///       - given this, this function *cannnot* be used to test for the presence of Snarl. +			/// </summary> +			/// <returns>A 16-bit value (translated to 32-bit) which is the registered Windows message for Snarl.</returns> +			static UINT Broadcast(); +			/// <summary>Returns the global Snarl Application message  (V39)</summary> +			/// <returns>Returns Snarl application registered message.</returns> +			static UINT AppMsg(); + +			/// <summary>Returns a handle to the Snarl Dispatcher window  (V37)</summary> +			/// <returns>Returns handle to Snarl Dispatcher window, or zero if it's not found.</returns> +			/// <remarks>This is now the preferred way to test if Snarl is actually running.</remarks> +			static HWND GetSnarlWindow(); +		  		private: -			template <class T> LONG32 Send(T ss); +			/// <summary>Send message to Snarl.</summary> +			/// <returns>Return zero on failure.</returns> +			LONG32 Send(SnarlMessage msg); + +			/// <summary>Convert a unicode string to UTF8</summary> +			/// <returns>Returns pointer to the new string - Remember to delete [] returned string !</returns> +			/// <remarks>Remember to delete [] returned string !!!</remarks>  			LPSTR  WideToUTF8(LPCWSTR szWideStr); -			 -			LONG32 m_nLastMessageId; -			HWND   m_hwndFrom; // set during snRegisterConfig() or snRegisterConfig2() -	}; +			/// <summary>Pack data into the PackedData member field.</summary> +			/// <param name="data">Should always be a pointer to the PackedData field</param> +			/// <param name="format">The format string. Can be NULL or "" to just zero PackedData!</param> +			/// <param name="...">Variable number of objects to convert</param> +			void   PackData(BYTE* data, LPCSTR format, ...); + +			LONG32 appToken; +			LONG32 lastMsgToken; +			SnarlEnums::SnarlStatus localError; + +	}; // class -} +	} // namespace V41 +} // namespace Snarl -#endif // SNARL_INTERFACE +#endif // SNARL_INTERFACE_V41 diff --git a/SwifTools/Notifier/SnarlNotifier.cpp b/SwifTools/Notifier/SnarlNotifier.cpp index eb4addc..9e82340 100644 --- a/SwifTools/Notifier/SnarlNotifier.cpp +++ b/SwifTools/Notifier/SnarlNotifier.cpp @@ -19,14 +19,14 @@ namespace Swift {  SnarlNotifier::SnarlNotifier(const String& name, Win32NotifierWindow* window, const boost::filesystem::path& icon) : window(window) {  	window->onMessageReceived.connect(boost::bind(&SnarlNotifier::handleMessageReceived, this, _1)); -	snarl.RegisterConfig2(window->getID(), name.getUTF8Data(), 0, icon.string().c_str()); +	snarl.RegisterApp(name.getUTF8Data(), name.getUTF8Data(), icon.string().c_str(), window->getID(), SWIFT_SNARLNOTIFIER_MESSAGE_ID);  	foreach(Notifier::Type type, getAllTypes()) { -		snarl.RegisterAlert(name.getUTF8Data(), typeToString(type).getUTF8Data()); +		snarl.AddClass(typeToString(type).getUTF8Data(), typeToString(type).getUTF8Data());  	}  }  SnarlNotifier::~SnarlNotifier() { -	snarl.RevokeConfig(window->getID()); +	snarl.UnregisterApp();  	window->onMessageReceived.disconnect(boost::bind(&SnarlNotifier::handleMessageReceived, this, _1));  	if (!notifications.empty()) {  		std::cerr << "Warning: " << notifications.size() << " Snarl notifications pending" << std::endl; @@ -34,8 +34,13 @@ SnarlNotifier::~SnarlNotifier() {  }  void SnarlNotifier::showMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picture, boost::function<void()> callback) { -	int timeout = (type == Type::IncomingMessage || type == Type::SystemMessage) ? DEFAULT_MESSAGE_NOTIFICATION_TIMEOUT_SECONDS : DEFAULT_STATUS_NOTIFICATION_TIMEOUT_SECONDS; -	int notificationID = snarl.ShowMessageEx(typeToString(type).getUTF8Data(), subject.getUTF8Data(), description.getUTF8Data(), timeout, picture.string().c_str(), window->getID(), SWIFT_SNARLNOTIFIER_MESSAGE_ID); +	int timeout = (type == IncomingMessage || type == SystemMessage) ? DEFAULT_MESSAGE_NOTIFICATION_TIMEOUT_SECONDS : DEFAULT_STATUS_NOTIFICATION_TIMEOUT_SECONDS; +	int notificationID = snarl.EZNotify( +			typeToString(type).getUTF8Data(), +			subject.getUTF8Data(), +			description.getUTF8Data(), +			timeout, +			picture.string().c_str());  	if (notificationID > 0) {  		notifications.insert(std::make_pair(notificationID, callback));  	} @@ -44,11 +49,11 @@ void SnarlNotifier::showMessage(Type type, const String& subject, const String&  void SnarlNotifier::handleMessageReceived(MSG* message) {  	if (message->message == SWIFT_SNARLNOTIFIER_MESSAGE_ID) {  		int action = message->wParam; -		if (action == Snarl::SNARL_NOTIFICATION_TIMED_OUT || action == Snarl::SNARL_NOTIFICATION_ACK || action == Snarl::SNARL_NOTIFICATION_CLOSED) { +		if (action == Snarl::V41::SnarlEnums::NotificationTimedOut || action == Snarl::V41::SnarlEnums::NotificationAck || action == Snarl::V41::SnarlEnums::NotificationClosed) {  			int notificationID = message->lParam;  			NotificationsMap::iterator i = notifications.find(notificationID);  			if (i != notifications.end()) { -				if (action == Snarl::SNARL_NOTIFICATION_ACK) { +				if (action == Snarl::V41::SnarlEnums::NotificationAck) {  					i->second();  				}  				notifications.erase(i); diff --git a/SwifTools/Notifier/SnarlNotifier.h b/SwifTools/Notifier/SnarlNotifier.h index 2350e29..8470326 100644 --- a/SwifTools/Notifier/SnarlNotifier.h +++ b/SwifTools/Notifier/SnarlNotifier.h @@ -25,7 +25,7 @@ namespace Swift {  			void handleMessageReceived(MSG* message);  		private: -			Snarl::SnarlInterface snarl; +			Snarl::V41::SnarlInterface snarl;  			Win32NotifierWindow* window;  			typedef std::map<int, boost::function<void()> > NotificationsMap;  			NotificationsMap notifications; | 
 Swift
 Swift