Books
in black and white
Main menu
Share a book About us Home
Books
Biology Business Chemistry Computers Culture Economics Fiction Games Guide History Management Mathematical Medicine Mental Fitnes Physics Psychology Scince Sport Technics
Ads

Excel add in development in C++ Aplications in finance - Dalton S.

Dalton S. Excel add in development in C++ Aplications in finance - Wiley publishing , 2005. - 425 p.
ISBN 0-470-02469-0
Download (direct link): exceladdindevelopmentincand2005.pdf
Previous << 1 .. 77 78 79 80 81 82 < 83 > 84 85 86 87 88 89 .. 168 >> Next

xloper register_fnID[NUM_FUNCS];
int __stdcall xlAutoOpen(void)
{
for(int i = 0 ; i < NUM_FUNCS; i++)
Accessing Excel Functionality Using the C API
193
register_fnID[i] = register_function(i); return 1;
}
A bug prevents the function (and command) IDs from being used for their intended purpose of un-registering functions. (See the next two sections.) Therefore the above code can be replaced with this:
int stdcall xlAutoOpen(void)
{
for(int i = 0 ; i < NUM_FUNCS;) register_function(i++);
return 1;
}
The function register_function() registers the specified function using the above array. The function uses Excel4v() since the number of arguments is variable. The code uses the cpp_xloper class, described in section 6.4 on page 121, to simplify the handling of Excel4() and Excel4v() arguments and return values.
xloper *register_function(int index)
{
// Array of pointers to xloper that will be passed to Excel4v() xloper *ptr_array[MAX_EXCEL4_ARGS];
// Default to this value in case of a problem cpp_xloper RetVal((WORD)xlerrValue);
//------------------------------------------------------------
// Get the full path and name of the DLL.
// Passed as the first argument to xlfRegister, so need // to set first pointer in array to point to this.
//------------------------------------------------------------
cpp_xloper DllName;
if(Excel4(xlGetName, &DllName, 0) != xlretSuccess)
return NULL;
DllName.SetExceltoFree();
ptr_array[0] = &DllName; int num_args = 1;
//------------------------------------------------------------
// Set up the rest of the array of pointers.
//------------------------------------------------------------
cpp_xloper *fn_args = new cpp_xloper[MAX_EXCEL4_ARGS - 1];
char *p_arg;
int i = 0, num_args = 1;
do
{
194
Excel Add-in Development in C/C++
// get the next string from the char * array if((p_arg = FuncExports[fn_index][i]) == NULL)
break; // that was the last of the arguments for this fn
// Set the corresponding xlfRegister argument
fn_args[i] = p_arg; // convert the string to a cpp_xloper
ptr_array[num_args++] = &(fn_args[i++]); // address of xloper
}
while(num_args < MAX_EXCEL4_ARGS);
if(Excel4v(xlfRegister, &RetVal, num_args, ptr_array)
|| RetVal.IsType(xltypeErr))
{
char err[256];
sprintf(err, "Couldn't register %s", FuncExports[index][0]); cpp_xloper ErrMsg(err);
Excel4(xlcAlert, 0, 1, &ErrMsg);
}
delete[] fn_args;
// RetVal type is xltypeErr or xltypeNum, so no need to free return RetVal.ExtractXloper(false);
}
It would be a simple matter to alter the above code so that arrays of cpp_xlopers, or arrays of look-alike xlopers, are initialised with function information, instead of char * arrays.
8.5.11 Getting and using the function’s register ID
In the above section, code example register_function() registers a function and returns a pointer to an xloper. If the function was successful this xloper is of type xltypeNum and contains a unique register ID. This ID is intended to be used in calls to xlfUnregister. However, a bug in Excel prevents this from un-registering functions as intended - see next section.
If you did not record the ID that xlfRegister returned, you can get it at any time using the xlfRegisterld function. This takes 3 arguments:
1. DllName: The name of the DLL as returned by the function xlGetName.
2. FunctionName: The name of the function as exported and passed in the 2nd argument
to xlfRegister.
3. ArgRtnTypes: The string that encodes the return and argument types, the calling permission and volatile status of the function, as passed in the 3rd argument
to xlfRegister.
The macro sheet functions that take this ID as an argument are:
• xlfUnregister: (See next section.)
• xlfCall: Calls a DLL function. There is no point in calling this function where the caller is in the same DLL, but it does provide a means for inter-DLL calling. (The
Accessing Excel Functionality Using the C API
195
macro sheet version of this function, CALL(), used to be available on worksheets. This enabled a spreadsheet with no XLM or VB macros to access any DLL’s functionality without alerting the user to the potential misuse that this could be put to. This security chasm was closed in version 7.0.)
8.5.12 Un-registering a DLL function
Excel keeps an internal list of the functions that have been registered from a given DLL as well as the number of times each function has been registered. (You can interrogate Excel about the loaded DLL functions using the xlfGetWorkspace, argument 44. See section 8.9.11 Information about the workspace: xlfGetWorkspace on page 227 for details.) When registering a function, the xlfRegister function does two things.
1. Increments the count for the registered function.
2. Associates the function’s worksheet name, given as the 4th argument to
xlfRegister, with the DLL resource.
To un-register a function you therefore have to undo both of these actions in order to restore Excel to the pre-DLL state. The xlfUnregister function, which takes the register ID returned by the call to xlfRegister, decrements the usage count of the function. To disassociate the function’s worksheet name, you need to call the xlfSetName function, which usually associates a name with a resource, but without specifying a resource. This clears the existing associated resource - the DLL function. Sadly, a bug in Excel prevents even this two-pronged approach from successfully removing the reference to the function. In practice, not un-registering functions has no grave consequences.
Previous << 1 .. 77 78 79 80 81 82 < 83 > 84 85 86 87 88 89 .. 168 >> Next