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.