The demo application MfcTutorial contains an example of an MFC dialog, CLanguageDialog. The example code below shows how to call this dialog when the add-in is opened.
BOOL CMfcTutorialApp::OnXllOpenEx() { // Create an instance of CExcelWnd CExcelWnd wndParent; // Create a dialog whose parent is Excel's application window CLanguageDialog lang(&wndParent); // Show the dialog and fail if the user cancels if (lang.DoModal() != IDOK) return FALSE; // Read the user's input from the dialog m_nLanguage = lang.m_nLanguage; return TRUE; }
Whenever you use application-level data in an add-in function built using MFC, you must remember to use XLL_FIX_STATE. The example function below (also in MfcTutorial.cpp) demonstrates the use of application data in an add-in function.
// Function: DigitName // Purpose: Return the text of a digit, in the current language //{{XLP_SRC(DigitName) // NOTE - the FunctionWizard will add and remove mapping code here. // DO NOT EDIT what you see in these blocks of generated code! IMPLEMENT_XLLFN2(DigitName, "RH", "DigitName", "Digit", "User Defined", "Return the text of a digit, in the current" " language", "A number whose least significant digit will be" " named", "\0", 1) extern "C" __declspec( dllexport ) LPXLOPER DigitName(USHORT Digit) { CXlOper xloResult; //}}XLP_SRC // Ensure MFC variables are in scope XLL_FIX_STATE // Delegate to the application object xloResult = ((CMfcTutorialApp*)XllGetApp())->GetDigitName(Digit); return xloResult.Ret(); }
Note: If you fail to declare XLL_FIX_STATE, then XllGetApp() will assert. In the Debug build, a message will be written to the Output Window of DevStudio, describing the problem.
You can save yourself some effort by using the Uses Application-level Data command on the Function menu of the XLL+ Function Wizard, as shown below:
This ensures the XLL_FIX_STATE statement is generated as part of the function header, thus:
extern "C" __declspec( dllexport ) LPXLOPER DigitName(USHORT Digit) { XLL_FIX_STATE; CXlOper xloResult; //}}XLP_SRC
You can change the default value of the setting to true, using the second tab of the Function Extended Attributes dialog. Then the setting will be true for every new function.