XLL+ Class Library

MtBackground.h

Data

All the code for handling the (very simple) data used by the add-in is in MtBackground.h.

The data posted to the main thread is simply a topic string and a number. The message class is therefore as follows:

class CMtBackgroundMsg : public CXllMtMsg {
public:
    CMtBackgroundMsg(LPCSTR pszTopic, double dValue)
      : m_strTopic(pszTopic), m_dValue(dValue) {}
    // Framework requires a virtual destructor
    virtual ~CMtBackgroundMsg() {} 
    
    // Public data members
    CString m_strTopic;
    double m_dValue;
};

The data cache is equally simple. It just maps topic strings to values.

#include <map>
class MtBackgroundDataCache {
public:
    void Set(LPCSTR pszTopic, double dValue) {
        m_map[pszTopic] = dValue;
    }
    BOOL Lookup(LPCSTR pszTopic, double& value) const {
        map_type::const_iterator itF = m_map.find(pszTopic);
        if (itF == m_map.end()) 
            return FALSE;
        value = itF->second;
        return TRUE;
    }
protected:
    typedef std::map<CString, double> map_type;
    map_type m_map;
};

Application class

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 CMtBackgroundApp : public CXllPushApp
{
public:
    CMtBackgroundApp();

public:
// Data Members
    // Background thread
    HANDLE                  m_thread;                 
    long                    m_lTickPeriod;            
    // Data cache
    MtBackgroundDataCache   m_cache;                  

// Accessors
    long GetTickPeriod() const {                      
        return m_lTickPeriod;                         
    }                                                 
    void SetTickPeriod(long lTickPeriod) {            
        m_lTickPeriod = lTickPeriod;                  
    }                                                 

// Names
public:
    static LPCSTR m_pszDefName;

// Overrides
    virtual BOOL OnXllOpenEx();                       
    virtual void OnXllClose();                        
    virtual void ProcessAsyncMessage(CXllMtMsg* msg); 
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CMtBackgroundApp)
    public:
    virtual int ExitInstance();
    virtual BOOL InitInstance();
    //}}AFX_VIRTUAL

    ...
};

Let us examine each of these changes in turn.

    // Background thread                              
    HANDLE                  m_thread;                 
    long                    m_lTickPeriod;            

The data member m_thread is a handle to a background thread. It is set when the thread is started, and it used at closedown to kill the thread. m_lTickPeriod controls the period of the background thread events, in millisecs. It is set by the main thread and read by the background thread

    // Data cache                                     
    MtBackgroundDataCache   m_cache;                  

The data cache is a data member of the application, and shares its lifetime.

// Accessors                                          
    long GetTickPeriod() const {                      
        return m_lTickPeriod;                         
    }                                                 
    void SetTickPeriod(long lTickPeriod) {            
        m_lTickPeriod = lTickPeriod;                  
    }                                                 

These accessor functions are used to get and set the value of the background thread's tick period. In a more sophisticated implementation, these methods would be thread-safe, because they use data that is shared between both threads.

(In our implementation they are not thread-safe, to reduce complexity, and because the Set and Get methods are atomic in this case.)

// Overrides                                          
    virtual BOOL OnXllOpenEx();                       
    virtual void OnXllClose();                        
    virtual void ProcessAsyncMessage(CXllMtMsg* msg); 

These three overrides handle the three major events of the add-in's life: creation, destruction and the arrival of asynchronous data. We will examine them in detail later.

Next: MtBackgroundThread.cpp >>