As discussed above, the data received by the client consists of two strings: a topic string and a field list. The message class is therefore as follows:
class CMtFeedAddinMsg : public CXllMtMsg { public: CMtFeedAddinMsg(LPCSTR pszTopic, LPCSTR pszData) : m_strTopic(pszTopic), m_strData(pszData) { } CString m_strTopic; CString m_strData; };
The data cache is equally simple. It just maps topic strings to field lists.
class CMtFeedAddinDataCache { public: void Set(LPCSTR pszTopic, LPCSTR pszData) { m_map[pszTopic] = pszData; } BOOL Lookup(LPCSTR pszTopic, CString& strData) const { map_type::const_iterator itF = m_map.find(pszTopic); if (itF == m_map.end()) return FALSE; strData = itF->second; return TRUE; } protected: typedef std::map<CString, CString> map_type; map_type m_map; };
Most of the application class, CMtBackgroundApp, is shown below. The areas that have been changed from the AppWizard-produced original are shown in grey.
class CMtFeedAddinApp : public CXllPushApp { public: CMtFeedAddinApp(); // Names public: static LPCSTR m_pszDefName; // Implementation mtcHandle m_client; CMtFeedAddinDataCache m_cache; std::set<CString> m_advises; static BOOL ExtractField(LPCSTR pszData, LPCSTR pszField, double& dValue); BOOL Reconnect(); // Overrides virtual int OnXllOpenEx(); virtual void OnXllClose(); virtual void ProcessAsyncMessage(CXllMtMsg* msg); virtual void OnTopicAdd(LPCSTR pszTopic); virtual void OnTopicRemove(LPCSTR pszTopic); ... };
Let us examine each of these blocks in turn.
mtcHandle m_client; CMtFeedAddinDataCache m_cache; std::set<CString> m_advises;
The data member m_client is a handle to the communications channel. The data cache, m_cache is a data member of the application, and shares its lifetime. m_advises contains the list of topics currently being advised on.
static BOOL ExtractField(LPCSTR pszData, LPCSTR pszField, double& dValue);
ExtractField() is a utility function that extracts the value of a named field from a field list.
BOOL Reconnect();
Reconnect() closes and then reopens the channel to the server.
virtual int OnXllOpenEx(); virtual void OnXllClose(); virtual void ProcessAsyncMessage(CXllMtMsg* msg); virtual void OnTopicAdd(LPCSTR pszTopic); virtual void OnTopicRemove(LPCSTR pszTopic);
We have encountered the three standard overrides before, in the MtBackground sample. The two new event handlers are OnTopicAdd() and OnTopicRemove(). These are called by the push engine when a new topic is added to the list of connections (i.e. when the first connection to a particular topic is made) and when a topic is removed from the list (i.e. when the last connection to a topic is removed). The add-in handles these by sending Advise or Unadvise requests to the server.