//================================================================
// Commonly used global variables
int err;
char buf[8192];
char txt[8192];
// Function registering table
int nFuncs;
// proc, type_text, function_text, arg, macro_type, category,
// shortcut_text, help_topic, function_help
static LPSTR func[][9] = {
{" MyFunc", " JJJ", " MyFunc", " ", " 1", " MyCat", " ", " ", " "},
{" MyMotd", " I", " MyMotd", " ", " 1", " MyCat", " ", " ", " "},
{0,0,0,0, 0, 0, 0}
};
// Menu table
int nMenuItems;
static LPSTR menu[][5] = {
{" &MyMenu", " ", " ", " Joe's Xll menu!!!", " "},
{" M.O.T.D."," MyMotd", " ", " Message of the Day!", " "},
{0, 0, 0, 0, 0}
};
// Initialization routine
BOOL __stdcall xlAutoOpen(void) {
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
// DEBUG output to indicate when called
AfxMessageBox("xlAutoOpen() called!", MB_SETFOREGROUND);
int i, j;
// Get XLL file name
static XLOPER xDll;
Excel(xlGetName, &xDll, 0);
// Prefix strengths with their length & count items
// Note the framework's TempStr() function prefixes the
// lengths anyway, but this is for other code that might
// use the arrays
for(nFuncs=0; func[nFuncs][0]; nFuncs++) {
for(i=0; i<9; i++) {
func[nFuncs][i][0] = (BYTE) strlen(func[nFuncs][i]+1);
}
}
for(nMenuItems=0; menu[nMenuItems][0]; nMenuItems++) {
for(i=0; i<5; i++) {
menu[nMenuItems][i][0] = (BYTE) strlen(menu[nMenuItems][i]+1);
}
}
// Loop through the function list, and register the functions
for(i=0; i<nFuncs; i++) {
// Register a function
err = Excel(xlfRegister, 0, 9, (LPXLOPER)&xDll,
(LPXLOPER)TempStr(func[i][0]),
(LPXLOPER)TempStr(func[i][1]),
(LPXLOPER)TempStr(func[i][2]),
(LPXLOPER)TempStr(func[i][3]),
(LPXLOPER)TempStr(func[i][4]),
(LPXLOPER)TempStr(func[i][5]),
(LPXLOPER)TempStr(func[i][6]),
(LPXLOPER)TempStr(func[i][7]),
(LPXLOPER)TempStr(func[i][8])
);
if(err != xlretSuccess) {
sprintf(buf, "xlfRegister for function %d, err = %d", i, err);
AfxMessageBox(buf, MB_SETFOREGROUND);
}
}
// Free XLL file name from the xlGetName call made earlier
Excel(xlFree, 0, 1, (LPXLOPER)&xDll);
// Menu support section
static XLOPER xMenu;
static XLOPER xMenuList[10*5];
ASSERT(nMenuItems< 10);
// Build menu
xMenu.xltype = xltypeMulti;
xMenu.val.array.lparray = &xMenuList[0];
xMenu.val.array.rows = nMenuItems;
xMenu.val.array.columns = 5;
for(i=0; i<nMenuItems; i++) {
for(j=0; j<5; j++) {
xMenuList[j+i*5].xltype = xltypeStr;
xMenuList[j+i*5].val.str = menu[i][j];
}
}
// Add menu
Excel(xlfAddMenu,0,3,TempNum(1),(LPXLOPER)&xMenu,TempStr(" Help"));
// Finished
return 1;
}
// Cleanup routine
BOOL __stdcall xlAutoClose(void) {
::MessageBox(NULL, "xlAutoClose()", "Debug", MB_SETFOREGROUND );
// Delete menu
Excel(xlfDeleteMenu, 0, 2, TempNum(1), TempStr(" MyMenu"));
return 1;
}
// Support for descriptive information about the add-in(s)
// You can add a new customized title for the user, but
// unfortunately, only an add-in written in Microsoft Visual Basic
// can add a description string.
LPXLOPER _stdcall xlAddInManagerInfo(LPXLOPER xAction) {
static XLOPER xInfo, xIntAction;
// Find out what action must be taken
Excel(xlCoerce, &xIntAction, 2, xAction, TempInt(xltypeInt));
// DEBUG output to indicate when called
sprintf(buf, "xlAddInManagerInfo(%ld)", (long)xIntAction.val.w);
::MessageBox(NULL, "xlAddInManagerInfo()", "Debug",
MB_SETFOREGROUND );
// Set title if asked
if(xIntAction.val.w == 1) {
xInfo.xltype = xltypeStr;
xInfo.val.str = " My Add-in!!!!";
xInfo.val.str[0] = (char)strlen(&xInfo.val.str[1]);
}
else {
xInfo.xltype = xltypeErr;
xInfo.val.err = xlerrValue;
}
return (LPXLOPER)&xInfo;
}
short __stdcall MyMotd(void) {
char *name[] = {
"Rebekah",
"Brent",
"John",
"Joseph",
"Robert",
"Sara",
0
};
char *quote[] = {
"An apple a day, keeps the doctor away!",
"Carpe Diem: Seize the Day!",
"What you dare to dream, dare to do!",
"I think, therefore I am.",
"A place for everything, and everything in its place.",
"Home is where the heart is.",
0
};
int nNames, nQuotes;
for(nNames=0; name[nNames]; nNames++);
for(nQuotes=0; quote[nQuotes]; nQuotes++);
sprintf(buf, "%s says '%s'", name[rand()%nNames],
quote[rand()%nQuotes]);
::MessageBox(NULL, buf, "XLL MOTD", MB_SETFOREGROUND );
return 0;
}
// Example function that returns the product of its two parameters
long __stdcall MyFunc(long parm1, long parm2) {
sprintf(buf, "You sent %ld and %ld to MyFunc()!", parm1, parm2);
::MessageBox(NULL, buf, "MyFunc() in Anewxll!!!", MB_SETFOREGROUND);
return parm1 * parm2;
}
//=================================================================