diff options
Diffstat (limited to '3rdParty/Snarl/SnarlInterface.h')
-rw-r--r-- | 3rdParty/Snarl/SnarlInterface.h | 412 |
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 |