During the development of the XLL+ run-time libraries, every effort has been made to preserve the behavior of code that uses older versions of XLL+. However, a few exceptions have proven impossible to avoid.
If you have existing code which uses string arguments, it will
in general continue working under XLL+ 6.
The old version of the function had an argument of type
const char*
; the upgraded version will have
const CXlStringArg&
.
The compiler will use the casting operator
CXlStringArg::operator const char*
and the code will work as before.
A problem arises if your code passes the string to a loosely-typed function
such as printf()
or CXlOper::Format.
The code will compile successfully,
but the compiler will not invoke the casting operator, and you must cast the value explicitly.
For example, an XLL+ 5 add-in function with a string argument might use it as follows:
extern "C" __declspec( dllexport ) LPXLOPER GetCustomerDetails(const char* customer) { //}}XLP_SRC char select[512]; sprintf(select, "SELECT * FROM CUSTOMER WHERE NAME='%s'", customer); ... }
Under XLL+ 6 the converted code will fail, and the argument to
sprintf
must be cast to const char*
:
CXlOper* GetCustomerDetails_Impl(CXlOper& xloResult, const CXlStringArg& customer) { // End of generated code //}}XLP_SRC char select[512]; sprintf(select, "SELECT * FROM CUSTOMER WHERE NAME='%s'", (const char*)customer); ... }
Under previous versions of XLL+ (5 and below), these methods returned a reference to a CXlOper type, which was contained within the outer CXlOper. In order to support both Excel 2007 and older versions of Excel, this functionality has had to be changed.
The methods now return a new class of object, CXlCell or CXlConstCell, which can be used to refer to the cell, but is not itself of type CXlOper.
If your code retained a copy of the return value, as in for instance:
const CXlOper& item = xloArray.VectorCell(i);
total += item.ToDouble();
then it must be changed. The code above becomes:
CXlConstCell item = xloArray.VectorCell(i); total += item.ToDouble();
If your code simply used the returned value without retaining a copy of it, then it will continue to compile. For example, the following code does not need to change:
xloArray.VectorCell(i) = 0.0;
A new model for implementing add-in functions has been introduced for
XLL+ 6.
There are two shell functions (generally
MyFunction_4
and MyFunction_12
) which
are called by Excel; each in turn calls a common implementation function
(generally MyFunction_Impl
).
If you have been calling an add-in function from another add-in function in the same project, using CXlOper::CallAddin, then you will need to change the way you call it.
The internal call should now be to MyFunction_Impl
instead of to MyFunction
, and it should have one extra argument,
which is the destination of the result.
For an example of the code change required, see the SimpOpt sample.
Under XLL+ version 5 and below, this method returned a reference to the actual CXlRef contained within the CXlOper, which could then be written to directly. In order to support Excel 2007 as well as earlier versions of Excel, this functionality has had to be changed.
The method now returns a copy of the CXlRef contained in the CXlOper; in order to change its value, you must call SetRef to apply any changes. Thus, if your existing code is:
xloRef.GetRef().MoveBy(0, 1);
You will need to change it to:
CXlRef xlr = xloRef.GetRef(); xlr.MoveBy(0, 1); xloRef.SetRef(xlr);
Alternatively, you can use one of the new short-hand functions CXlOper::MoveRefBy or CXlOper::SetRef, e.g.:
xloRef.MoveRefBy(0, 1); xloRef.SetRef(1, 2);
Earlier versions of XLL+ generated a VersionInfo add-in function that cannot be upgraded by the XLL+ Upgrade Wizard. To upgrade this function, the easiest solution is to generate a new VersionInfo function, using the Add VersionInfo Function command (on the Tools menu of the XLL Add-ins window). Then copy over any details you wish to retain from the old function, and delete it.
For XLL+ 6, the COper class has been merged into the CXlOper class. Some COper functions that have been deprecated for some time were not included in the merge:
For XLL+ 6, the mechanism for validation has been completely revised. Some COper functions that were used by the code generated by the Function Wizard are no longer used, and are not supported in XLL+ 6:
In earlier versions of XLL+, the CXlOper and COper classes were publicly
derived from their underlying C structures, XLOPER
and OPER
respectively.
This allowed developers to directly access the data members of the
underlying structure. In particular, the val
and xltype
data members could be read directly.
The CXlOper class is no longer directly derived from the
XLOPER
structure. It now holds a pointer to either a
XLOPER
or a XLOPER12
structure, depending
on the version of Excel under which the add-in is running.
Code that uses the xltype
member should call
CXlOper::IsOfType() to inspect
it.
Direct access to the val
data member is no longer supported.
Several of the data members of CXllFn have been removed, and replaced by Excel-version-dependent data members.
XLL+ 5.0 | XLL+ 6 - Excel 2003 & below | XLL+ 6 - Excel 2007 & above |
---|---|---|
m_stEntryPoint | m_stEntryPoint4 | m_stEntryPoint12 |
m_stArgTemplate | m_stArgTemplate4 | m_stArgTemplate12 |
m_stArgNames | m_stArgNames4 | m_stArgNames12 |
m_stCategory | m_stCategory4 | m_stCategory12 |
m_stHelpText | m_stHelpText4 | m_stHelpText12 |
m_astArgHelpText | m_astArgHelpText4 | m_astArgHelpText12 |
Where possible you should replace use of the data members above with calls to the following functions. Each of these functions returns the value appropriate for the version of Excel which is currently running. In addition, these calls handle any localization that is required if the strings contain resource IDs.
Data member | Function call |
---|---|
m_stEntryPoint | GetEntryPoint() |
m_stArgTemplate | GetArgumentTemplate() |
m_stArgNames | GetArgumentName(), GetArgumentNames() |
m_stCategory | GetCategory() |
m_stHelpText | GetHelpText() |
m_astArgHelpText | GetArgumentHelpText(), GetArgumentHelpTexts() |
The following data members are no longer supported.
Data member | Replacement |
---|---|
m_astArgExt | m_stDefinition |
m_stFnExt | m_stDefinition |
Finally, the data member m_stName has changed type from a CString to a Unicode CStringW type. In particular, code that compares the name to an ANSI string will fail to compile, e.g.:
if (strcmp(pfn->m_stName, "MyFunc") == 0)
This comparison would need to be changed to:
if (wcscmp(pfn->m_stName, L"MyFunc") == 0)
The method CXlHandleStore::ObjectFromHandle,
which is used to convert Excel handles to object pointers, is no longer const
.
The signature has been changed to non-const because the CXlHandleStore is now thread-safe,
and thus calls that were previously read-only now need to mutate the object in order
to lock it.
Projects that built perfectly with XLL+ 6.0 may fail to build with XLL+ 6.2, with the following linker errors.
xlllibsd.lib(WizardHook.obj) : error LNK2019: unresolved external symbol __imp__DeleteObject@4 referenced in function "public: void __thiscall CWizardHook::Uninstall(void)" (?Uninstall@CWizardHook@@QAEXXZ) xlllibsd.lib(WizardHook.obj) : error LNK2019: unresolved external symbol __imp__CreateFontIndirectA@4 referenced in function "private: struct HFONT__ * __thiscall CWizardHook::CreateButtonFont(void)" (?CreateButtonFont@CWizardHook@@AAEPAUHFONT__@@XZ) xlllibsd.lib(WizardHook.obj) : error LNK2019: unresolved external symbol __imp__SetBkMode@8 referenced in function "private: void __thiscall CWizardHook::DrawButton(int,struct tagDRAWITEMSTRUCT *)" (?DrawButton@CWizardHook@@AAEXHPAUtagDRAWITEMSTRUCT@@@Z) xlllibsd.lib(WizardHook.obj) : error LNK2019: unresolved external symbol __imp__SelectObject@8 referenced in function "private: void __thiscall CWizardHook::DrawButton(int,struct tagDRAWITEMSTRUCT *)" (?DrawButton@CWizardHook@@AAEXHPAUtagDRAWITEMSTRUCT@@@Z) xlllibsd.lib(WizardHook.obj) : error LNK2019: unresolved external symbol __imp__GetStockObject@4 referenced in function "private: void __thiscall CWizardHook::DrawButton(int,struct tagDRAWITEMSTRUCT *)" (?DrawButton@CWizardHook@@AAEXHPAUtagDRAWITEMSTRUCT@@@Z)
To resolve this problem add the library gdi32.lib
to the list of
Additional Dependencies in the Linker/Input page of the project's property pages.
For XLL+ 6.2, the Asynchronous function implementation model was improved. Asynchronous versions of functions no longer take an extra argument "RtdSignal". If you have released add-ins with asynchronous functions, you should use the UseAsyncHandleModel to ensure that existing spreadsheets still continue to work correctly.
See Upgrading asynchronous functions from XLL+ 6.0 for details.