// Callback function that must be implemented and exported by every valid XLL. // The xlAutoOpen function is the recommended place from where to register XLL // functions and commands, initialize data structures, customize the user // interface, and so on. __declspec(dllexport) int WINAPI xlAutoOpen(void) { XLOPER12 xDLL; int i; // Get the name of the XLL Excel12f(xlGetName, &xDLL, 0); // Register each of the functions for (i = 0 ; i < rgFuncsRows ; i++) { Excel12f(xlfRegister, 0, 5, (LPXLOPER12)&xDLL, (LPXLOPER12)TempStr12(rgFuncs[i][0]), (LPXLOPER12)TempStr12(rgFuncs[i][1]), (LPXLOPER12)TempStr12(rgFuncs[i][2]), (LPXLOPER12)TempStr12(rgFuncs[i][3])); } // Free the XLL filename Excel12f(xlFree, 0, 1, (LPXLOPER12)&xDLL); // Return 1 => success return 1; }
int check_excel_array(const LPXLOPER12 excelArray, LPXLOPER12 coerced, const T&... args) { switch (excelArray->xltype) { case xltypeRef: case xltypeSRef: case xltypeMulti: break; default: Excel12f(xlcAlert, 0, 1, TempStr12(L"Expected a N-columns excel range")); return xlretInvXloper; } if (xlretUncalced == Excel12f(xlCoerce, coerced , 2, excelArray, TempInt12(xltypeMulti) ) ) return xlretUncalced; if (coerced->val.array.columns != sizeof...(args)) { //throw std::runtime_error("Wrong number of dimensions, expected:" + std::to_string(sizeof...(args))); Excel12f(xlcAlert, 0, 1, TempStr12(L"Wrong number of dimensions")); return xlretInvXloper; } return 0; }
// Called by Microsoft Office Excel whenever the user activates the XLL during // an Excel session by using the Add-In Manager. This function is not called // when Excel starts up and loads a pre-installed add-in. __declspec(dllexport) int WINAPI xlAutoAdd(void) { const size_t bufsize = 255; const size_t dllsize = 100; LPWSTR szBuf = (LPWSTR)malloc(bufsize * sizeof(WCHAR)); LPWSTR szDLL = (LPWSTR)malloc(dllsize * sizeof(WCHAR)); XLOPER12 xDLL; // Get the name of the XLL Excel12f(xlGetName, &xDLL, 0); wcsncpy_s(szDLL, dllsize, xDLL.val.str + 1, xDLL.val.str[0]); szDLL[xDLL.val.str[0]] = (WCHAR)NULL; // Display dialog swprintf_s((LPWSTR)szBuf, 255, L"Adding %s\nBuild %hs - %hs", szDLL, __DATE__, __TIME__); Excel12f(xlcAlert, 0, 2, TempStr12(szBuf), TempInt12(2)); // Free the XLL filename Excel12f(xlFree, 0, 1, (LPXLOPER12)&xDLL); free(szBuf); free(szDLL); return 1; }
// Called by Microsoft Office Excel whenever the XLL is deactivated. The add-in // is deactivated when an Excel session ends normally. The add-in can be // deactivated by the user during an Excel session, and this function will be // called in that case. __declspec(dllexport) int WINAPI xlAutoClose(void) { int i; // Delete all the registered functions for (i = 0 ; i < rgFuncsRows ; i++) Excel12f(xlfSetName, 0, 1, TempStr12(rgFuncs[i][2])); // Return 1 => success return 1; }
// Excel calls xlAutoClose when it unloads the XLL. __declspec(dllexport) int WINAPI xlAutoClose(void) { int i; // Delete all names added by xlAutoOpen or xlAutoRegister. for (i = 0; i < g_rgNumUDFs; i++) { Excel12f(xlfSetName, 0, 1, TempStr12(g_rgUDFs[i][2])); } return 1; }
// Excel calls xlAutoClose when it unloads the XLL. __declspec(dllexport) int WINAPI xlAutoClose(void) { int i; // Delete all names added by xlAutoOpen or xlAutoRegister. for (i = 0; i < rgWorksheetFuncsRows; i++) { Excel12f(xlfSetName, 0, 1, TempStr12(rgWorksheetFuncs[i][2])); } return 1; }
BOOL __stdcall xlAutoOpen(void) { if (++AutoOpenCount > 1) { //MessageBox(0, L"Test", L"Test", MB_OK); return TRUE; } static XLOPER12 xDLL; Excel12f(xlGetName, &xDLL, 0); int count = sizeof(rgFuncs) / (sizeof(rgFuncs[0][0]) * NumberOfParameters); for (int idx = 0; idx < count; idx++) { int macroType = wcscmp(rgFuncs[idx][4], L"0") == 0 ? 0 : 1; Excel12f ( xlfRegister, 0, 12, (LPXLOPER12) &xDLL, (LPXLOPER12) TempStr12(rgFuncs[idx][0]), (LPXLOPER12) TempStr12(rgFuncs[idx][1]), (LPXLOPER12) TempStr12(rgFuncs[idx][2]), (LPXLOPER12) TempStr12(rgFuncs[idx][3]), (LPXLOPER12) TempInt12(macroType), (LPXLOPER12) TempStr12(rgFuncs[idx][5]), (LPXLOPER12) TempStr12(rgFuncs[idx][6]), (LPXLOPER12) TempStr12(rgFuncs[idx][7]), (LPXLOPER12) TempStr12(rgFuncs[idx][8]), (LPXLOPER12) TempStr12(rgFuncs[idx][9]), (LPXLOPER12) TempStr12(rgFuncs[idx][10]) ); } Excel12f(xlFree, 0, 1, (LPXLOPER12) &xDLL); return StartAddinClrHost(); }
// Excel calls xlAutoRegister12 if a macro sheet tries to register // a function without specifying the type_text argument. __declspec(dllexport) LPXLOPER12 WINAPI xlAutoRegister12(LPXLOPER12 pxName) { static XLOPER12 xDLL, xRegId; int i; xRegId.xltype = xltypeErr; xRegId.val.err = xlerrValue; for (i = 0; i < g_rgNumUDFs; i++) { if (!lpwstricmp(g_rgUDFs[i][0], pxName->val.str)) { Excel12f(xlfRegister, 0, 1 + g_rgUDFdata, (LPXLOPER12) &xDLL, (LPXLOPER12) TempStr12(g_rgUDFs[i][0]), (LPXLOPER12) TempStr12(g_rgUDFs[i][1]), (LPXLOPER12) TempStr12(g_rgUDFs[i][2]), (LPXLOPER12) TempStr12(g_rgUDFs[i][3]), (LPXLOPER12) TempStr12(g_rgUDFs[i][4]), (LPXLOPER12) TempStr12(g_rgUDFs[i][5]), (LPXLOPER12) TempStr12(g_rgUDFs[i][6]), (LPXLOPER12) TempStr12(g_rgUDFs[i][7]), (LPXLOPER12) TempStr12(g_rgUDFs[i][8]), (LPXLOPER12) TempStr12(g_rgUDFs[i][9]), (LPXLOPER12) TempStr12(g_rgUDFs[i][10]) ); // Free the oper returned by Excel. Excel12f(xlFree, 0, 1, (LPXLOPER12) &xDLL); return(LPXLOPER12) &xRegId; } } return(LPXLOPER12) &xRegId; }
// Excel calls xlAutoOpen when it loads the XLL. __declspec(dllexport) int WINAPI xlAutoOpen(void) { static XLOPER12 xDLL; // The filename of this XLL. int i; // Fetch the name of this XLL. This is used as the first arg // to the REGISTER function to specify the name of the XLL. Excel12f(xlGetName, &xDLL, 0); // Loop through the g_rgUDFs[] table, registering each // function in the table using xlfRegister. for (i = 0; i < g_rgNumUDFs; i++) { Excel12f(xlfRegister, 0, 1 + g_rgUDFdata, (LPXLOPER12) &xDLL, (LPXLOPER12) TempStr12(g_rgUDFs[i][0]), (LPXLOPER12) TempStr12(g_rgUDFs[i][1]), (LPXLOPER12) TempStr12(g_rgUDFs[i][2]), (LPXLOPER12) TempStr12(g_rgUDFs[i][3]), (LPXLOPER12) TempStr12(g_rgUDFs[i][4]), (LPXLOPER12) TempStr12(g_rgUDFs[i][5]), (LPXLOPER12) TempStr12(g_rgUDFs[i][6]), (LPXLOPER12) TempStr12(g_rgUDFs[i][7]), (LPXLOPER12) TempStr12(g_rgUDFs[i][8]), (LPXLOPER12) TempStr12(g_rgUDFs[i][9]), (LPXLOPER12) TempStr12(g_rgUDFs[i][10]) ); } // Free the XLL filename. Excel12f(xlFree, 0, 1, (LPXLOPER12) &xDLL); return 1; }
// Excel calls xlAutoOpen when it loads the XLL. __declspec(dllexport) int WINAPI xlAutoOpen(void) { static XLOPER12 xDLL; /* name of this DLL */ int i; /* Loop index */ /* ** In the following block of code the name of the XLL is obtained by ** calling xlGetName. This name is used as the first argument to the ** REGISTER function to specify the name of the XLL. Next, the XLL loops ** through the rgFuncs[] table, registering each function in the table using ** xlfRegister. Functions must be registered before you can add a menu ** item. */ Excel12f(xlGetName, &xDLL, 0); for (i=0; i < rgWorksheetFuncsRows; i++) { Excel12f(xlfRegister, 0, 1 + rgWorksheetFuncsCols, (LPXLOPER12)&xDLL, (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][0]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][1]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][2]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][3]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][4]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][5]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][6]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][7]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][8]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][9]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][10]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][11]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][12]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][13])); } /* Free the XLL filename */ Excel12f(xlFree, 0, 1, (LPXLOPER12)&xDLL); return 1; }
// Excel calls xlAutoRegister12 if a macro sheet tries to register // a function without specifying the type_text argument. __declspec(dllexport) LPXLOPER12 WINAPI xlAutoRegister12(LPXLOPER12 pxName) { static XLOPER12 xDLL, xRegId; int i; /* ** This block initializes xRegId to a #VALUE! error first. This is done in ** case a function is not found to register. Next, the code loops through the ** functions in rgFuncs[] and uses lpstricmp to determine if the current ** row in rgFuncs[] represents the function that needs to be registered. ** When it finds the proper row, the function is registered and the ** register ID is returned to Microsoft Excel. If no matching function is ** found, an xRegId is returned containing a #VALUE! error. */ xRegId.xltype = xltypeErr; xRegId.val.err = xlerrValue; for (i = 0; i < rgWorksheetFuncsRows; i++) { if (!lpwstricmp(rgWorksheetFuncs[i][0], pxName->val.str)) { Excel12f(xlGetName, &xDLL, 0); Excel12f(xlfRegister, 0, 4, (LPXLOPER12)&xDLL, (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][0]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][1]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][2]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][3]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][4]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][5]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][6]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][7]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][8]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][9]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][10]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][11]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][12]), (LPXLOPER12)TempStr12(rgWorksheetFuncs[i][13])); /* Free the XLL filename */ Excel12f(xlFree, 0, 1, (LPXLOPER12)&xDLL); return (LPXLOPER12)&xRegId; } } //Word of caution - returning static XLOPERs/XLOPER12s is not thread safe //for UDFs declared as thread safe, use alternate memory allocation mechanisms return (LPXLOPER12)&xRegId; }