XLL+ Class Library

Overriding OnXllOpenEx()

We are going to create a new function, STOCKNAME(), which will use application level data. It will look up a stock code in a database and, if successful, will return the company name. We will need to ensure that the database is initialised when the add-in opens.

Change the application class

Open the project header file Tutorial1.h. This contains the Wizard-generated definition of the application class CTutorial1App. Add the lines shown below.

Note: Depending on the options you selected when creating the project, the method OnXllOpenEx() may already exist.

#include <map>                                                                 

class CTutorial1App : public CXllApp
{
public:
    CTutorial1App();

// Names
public:
    static LPCSTR m_pszDefName;

// Data                                                                        
    std::map<CString, CString> m_mapStockNames;                                
    void InitMap();                                                            
    BOOL FindStockCode(const char* pszCode, CString& strCompanyName);          

// Overrides
    virtual BOOL OnXllOpenEx();                                                
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CTutorial1App)
    public:
    virtual int ExitInstance();
    virtual BOOL InitInstance();
    //}}AFX_VIRTUAL

#ifdef XLL_LIB_MFC
    //{{AFX_MSG(CTutorial1App)
        // NOTE - the ClassWizard will add and remove member functions here.
        //    DO NOT EDIT what you see in these blocks of generated code !
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
#endif
};

Add some application data

Open Tutorial1.cpp and add the simple application level lookup functions shown below.

// Initialise an application-level in-memory database
void CTutorial1App::InitMap()
{
    // In a real application, these codes would be loaded from a database
    static const char* apszStockPairs[] = {
        "MSFT", "Microsoft",
        "ORCL", "Oracle",
        "IBM",  "International Business Machines",
        0
    };

    // Clear the map then add each pair
    m_mapStockNames.clear();
    for (int i = 0; apszStockPairs[i]; i += 2)
        m_mapStockNames[apszStockPairs[i]] = apszStockPairs[i + 1];
}

// Look up a stock code
// Returns FALSE if not found, TRUE if found
BOOL CTutorial1App::FindStockCode(const char* pszCode, CString& strCompanyName)
{
    std::map<CString, CString>::const_iterator itF = m_mapStockNames.find(pszCode);
    if (itF == m_mapStockNames.end())
        return FALSE;
    strCompanyName = itF->second;
    return TRUE;
}

Override OnXllOpenEx()

To ensure that the initialisation function InitMap() is called whenever the add-in is opened, we have to override OnXllOpenEx() in the application class. Add the code show below to Tutorial1.cpp.

BOOL CTutorial1App::OnXllOpenEx() 
{
    // Initialize application data
    InitMap();
    // Return TRUE to signal successful initialization
    return TRUE;
}
Note: It is essential to return TRUE to signal successful initialization. You should only return FALSE if a fatal error occurs, such as a failure to log on to a required database.

If you build and run the add-in now, you can put a break-point at OnXllOpenEx(), and see for yourself that the override is called once when the add-in is opened.

Next: Volatile functions >>