summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Snarl/SnarlInterface.h')
-rw-r--r--3rdParty/Snarl/SnarlInterface.h412
1 files changed, 235 insertions, 177 deletions
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