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.