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.
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 };
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; }
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.