EXAMPLE.C

#include <ctype.h> 
#include <windows.h>
#include <xlcall.h>
#include <framewrk.h>

/*
** rgFuncs
**
** This is a table of all the functions exported by this module.
** These functions are all registered (in xlAutoOpen) when you
** open the XLL. Before every string, leave a space for the
** byte count. The format of this table is the same as
** the last seven arguments to the REGISTER function.
** rgFuncsRows define the number of rows in the table. The
** dimension [3] represents the number of columns in the table.
*/
#define rgFuncsRows 29


static LPWSTR rgFuncs[rgFuncsRows][7] = {
{L"CallerExample",
{L"debugPrintfExample",
{L"EvaluateExample",
{L"Excel12fExample",
{L"Excel12Example",
{L"InitFrameworkExample",
{L"TempActiveCellExample",
{L"TempActiveColumnExample",
{L"TempActiveRefExample",
{L"TempActiveRowExample",
{L"TempBoolExample",
{L"TempErrExample",
{L"TempIntExample",
{L"TempMissingExample",
{L"TempNumExample",
{L"TempStrExample",
{L"fArray",
{L"xlCoerceExample",
{L"xlFreeExample",
{L"xlGetInstExample",
{L"xlGetInstPtrExample",
{L"xlGetNameExample",
{L"xlSetExample",
{L"xlSheetIdExample",
{L"xlSheetNmExample",
{L"xlStackExample",
{L"xlUDFExample",
{L"InternationalExample",
{L"CalcCircum",
};


DllMain

This function is called by LibEntry which is called by Windows when the DLL is first loaded. LibEntry initializes the DLL's heap if a HEAPSIZE is specified in the DLL's .DEF file, and then calls DllMain. The following DllMain function satisfies that call. The DllMain function should perform additional initialization tasks required by the DLL. In this example, we byte-count all the strings in the preceding table. DllMain will be called will be called once per process. In Win32 DllMain replaces both the LibMain and WEP functions.
Returns 1 if initialization is successful.
In the following for loops, the strings in rgFuncs[] are byte-counted so that they won't need to be byte-counted later.

BOOL WINAPI DllMain(HANDLE hInstance, ULONG ul_reason_for_call, 
   LPVOID lpReserved)
{

   /*if(ul_reason_for_call == DLL_PROCESS_ATTACH)
   {
   int i,j;

   for (i = 0; i < rgFuncsRows; i++)
   {
   for (j = 0; j < 7; j++)
   {
   rgFuncs[i][j][0] = (BYTE)lstrlen (rgFuncs[i][j]+1);
   }
   }
   }*/

   return 1;
}

xlAutoOpen

This function is called by Microsoft Excel when the XLL file is loaded.
This is also called by the Add-in Manager when you add this XLL as an add-in. The Add-in Manager first calls xlAutoAdd, then calls REGISTER("EXAMPLE.XLL"), which in turn calls xlAutoOpen.
This should register all the functions you want to make available
It return 1 if successful, or return 0 if your XLL cannot be opened.

__declspec(dllexport) int WINAPI xlAutoOpen(void) 
{
   static XLOPER12 xDLL;
   int i;

   Excel12f(xlGetName, &xDLL, 0);

   for (i=0;i<rgFuncsRows;i++)
   {
      Excel12f(xlfRegister, 0, 4,
         (LPXLOPER12)&xDLL,
         (LPXLOPER12)TempStr12(rgFuncs[i][0]),
         (LPXLOPER12)TempStr12(rgFuncs[i][1]),
         (LPXLOPER12)TempStr12(rgFuncs[i][2]));
   }

   /* Free the XLL filename */
   Excel12f(xlFree, 0, 1, (LPXLOPER12)&xDLL);

   return 1;
}

xlAutoClose

This function is called by Microsoft Excel when the XLL file is unloaded.
The Add-in Manager first calls xlAutoRemove, then calls UNREGISTER("EXAMPLE.XLL"), which in turn calls xlAutoClose.
This function does not have to unregister the functions that were registered in xlAutoOpen. This is done automatically by Excel.
This function should return 1.

__declspec(dllexport) int WINAPI xlAutoClose(void) 
{
   int i;

   for (i = 0; i < rgFuncsRows; i++)
   {
      Excel12f(xlfSetName, 0, 1, TempStr12(rgFuncs[i][2]));
   }
   return 1;
}

lpwstricmp

Compares a pascal string and a null-terminated C-string to see if they are equal. Method is case insensitive
Unlike the usual string functions, lpwstricmp doesn't care about collating sequence.
This function returns 0 if they are equal and nonzero otherwise
LPWSTR s First string (null-terminated)
LPWSTR t Second string (byte counted)

int lpwstricmp(LPWSTR s, LPWSTR t) 
{
   int i;

   if (wcslen(s) != *t)
   {
      return 1;
   }

   for (i = 1; i <= s[0]; i++)
   {
      if (towlower(s[i-1]) != towlower(t[i]))
      {
         return 1;
      }
   }
   return 0;
}

xlAutoRegister

This function is called by Microsoft Excel if a macro sheet tries to register a function without specifying the type_text argument. If that happens, Microsoft Excel calls xlAutoRegister, passing the name of the function that the user tried to register. xlAutoRegister should use the normal REGISTER function to register the function, but this time it must specify the type_text argument. If xlAutoRegister does not recognize the function name, it should return a #VALUE! error. Otherwise, it should return whatever REGISTER returned.
LPXLOPER12 pxName xltypeStr containing the name of the function to be registered. This is not case sensitive, because Microsoft Excel uses Pascal calling convention.
This function returns LPXLOPER12 xltypeNum containing the result of registering the function, or xltypeErr containing #VALUE! if the function could not be registered.

__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 < rgFuncsRows; i++)
   {
      if (!lpwstricmp(rgFuncs[i][0], pxName->val.str))
      {
         Excel12f(xlGetName, &xDLL, 0);

         Excel12f(xlfRegister, 0, 4,
         (LPXLOPER12)&xDLL,
         (LPXLOPER12)TempStr12(rgFuncs[i][0]),
         (LPXLOPER12)TempStr12(rgFuncs[i][1]),
         (LPXLOPER12)TempStr12(rgFuncs[i][2]));

         /* 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;
}

xlAutoAdd

This function is called by the Add-in Manager only. When you add a DLL to the list of active add-ins, the Add-in Manager calls xlAutoAdd() and then opens the XLL, which in turn calls xlAutoOpen.

__declspec(dllexport) int WINAPI xlAutoAdd(void) 
{
   XCHAR szBuf[255];

   wsprintfW((LPWSTR)szBuf, L"Thank you for adding Example.XLL\n build date %hs, time %hs",__DATE__, __TIME__);

   /* Display a dialog box indicating that the XLL was successfully added */
   Excel12f(xlcAlert, 0, 2, TempStr12(szBuf), TempInt12(2));
   return 1;
}

xlAutoRemove

This function is called by the Add-in Manager only. When you remove an XLL from the list of active add-ins, the Add-in Manager calls xlAutoRemove() and then UNREGISTER("EXAMPLE.XLL").
You can use this function to perform any special tasks that need to be performed when you remove the XLL from the Add-in Manager's list of active add-ins. For example, you may want to delete an initialization file when the XLL is removed from the list.
This function display a dialog box indicating that the XLL was successfully removed */

__declspec(dllexport) int WINAPI xlAutoRemove(void) 
{
   Excel12f(xlcAlert, 0, 2, TempStr12(L"Thank you for removing Example.XLL!"), TempInt12(2));
   return 1;
}

xlAddInManagerInfo12

This function is called by the Add-in Manager to find the long name of the add-in. If xAction = 1, this function should return a string containing the long name of this XLL, which the Add-in Manager will use to describe this XLL. If xAction = 2 or 3, this function should return
** LPXLOPER12 xAction The information you want; either
** 1 = the long name of the
** add in, or
** 2 = reserved
** 3 = reserved
**
** Return value
** LPXLOPER12 The long name or #VALUE!.

__declspec(dllexport) LPXLOPER12 WINAPI xlAddInManagerInfo12(LPXLOPER12 xAction) 
{
   static XLOPER12 xInfo, xIntAction;

   ** This code coerces the passed-in value to an integer. This is how the
   ** code determines what is being requested. If it receives a 1, it returns a
   ** string representing the long name. If it receives anything else, it
   ** returns a #VALUE! error.

   Excel12f(xlCoerce, &xIntAction, 2, xAction, TempInt12(xltypeInt));

   if(xIntAction.val.w == 1)
   {
      xInfo.xltype = xltypeStr;
      xInfo.val.str = L"\026Example Standalone DLL";
   }
   else
   {
      xInfo.xltype = xltypeErr;
      xInfo.val.err = xlerrValue;
   }

   //Word of caution - returning static XLOPERs/XLOPER12s is not thread safe
   //for UDFs declared as thread safe, use alternate memory allocation mechanisms

   return (LPXLOPER12)&xInfo;
}

CallerExample

This function illustrates the xlfCaller function, which selects the cell from which it was called.

__declspec(dllexport) short WINAPI CallerExample(void) 
{
   XLOPER12 xRes;

   Excel12(xlfCaller, &xRes, 0);
   Excel12(xlcSelect, 0, 1, (LPXLOPER12)&xRes);
   Excel12(xlFree, 0, 1, (LPXLOPER12)&xRes);
   return 1;
}

debugPrintfExample

This function prints a string to show that control was passed to the function. The _DEBUG flag must be defined before compiling or else this function does nothing.

__declspec(dllexport) short WINAPI debugPrintfExample(void) 
{

   #ifdef _DEBUG
   debugPrintf("Made it!\r");
   #endif

   return 1;
}

EvaluateExample

This function demonstrates using evaluate to look up a cell reference. It uses xlfEvaluate to coerce the text "!B38" to the contents of cell B38.

__declspec(dllexport) short WINAPI EvaluateExample(void) 
{
   XLOPER12 xFormulaText, xRes, xRes2, xInt;

   xFormulaText.xltype = xltypeStr;
   xFormulaText.val.str = L"\004!B38";
   Excel12(xlfEvaluate, &xRes, 1, (LPXLOPER12)&xFormulaText);

   xInt.xltype = xltypeInt;
   xInt.val.w = 2;
   Excel12(xlcAlert, &xRes2, 2, (LPXLOPER12)&xRes, (LPXLOPER12)&xInt);
   Excel12(xlFree, 0, 1, (LPXLOPER12)&xRes);
   Excel12(xlFree, 0, 1, (LPXLOPER12)&xRes2);

   return 1;
}

Excel12fExample

This function demonstrates the debugging capability of Excel12f(). It passes a bad argument to the Excel12f() function, which outputs a debug message on the terminal attached to COM1.

__declspec(dllexport) short WINAPI Excel12fExample(void) 
{
   Excel12f(xlcDisplay, 0, 1, 0);
   return 1;
}

Excel12Example

This function illustrates the Excel12() function. It uses Excel12() to select the cell from which it was called.

__declspec(dllexport) short WINAPI Excel12Example(void) 
{
   XLOPER12 xRes;

   Excel12(xlfCaller, &xRes, 0);
   Excel12(xlcSelect, 0, 1, (LPXLOPER12)&xRes);
   Excel12(xlFree, 0, 1, (LPXLOPER12)&xRes);

   return 1;
}

InitFrameworkExample

This function uses InitFramework() to free all temporary memory.

__declspec(dllexport) short WINAPI InitFrameworkExample(void) 
{
   InitFramework();
   return 1;
}

TempActiveCellExample

This function uses TempActiveCell() to display the contents of cell B94 on the active sheet.

__declspec(dllexport) short WINAPI TempActiveCellExample(void) 
{
   Excel12f(xlcAlert, 0, 1, TempActiveCell12(93,1));
   return 1;
}

TempActiveColumnExample

This function uses TempActiveColumn() to select an entire column.

__declspec(dllexport) short WINAPI TempActiveColumnExample(void) 
{
   Excel12f(xlcSelect, 0, 1, TempActiveColumn12(1));
   return 1;
}

TempActiveRefExample

This function uses TempActiveRef() to select A105:C110.

__declspec(dllexport) short WINAPI TempActiveRefExample(void) 
{
   Excel12f(xlcSelect, 0, 1, TempActiveRef12(104, 109, 0, 2));
   return 1;
}

TempActiveRowExample

This function uses TempActiveRow() to select an entire row.

__declspec(dllexport) short WINAPI TempActiveRowExample(void) 
{
   Excel12f(xlcSelect, 0, 1, TempActiveRow12(112));
   return 1;
}

TempBoolExample

This function uses TempBool to clear the status bar. Temporary memory is freed when Excel12f() is called.

__declspec(dllexport) short WINAPI TempBoolExample(void) 
{
   Excel12f(xlcMessage, 0, 1, TempBool12(0));
   return 1;
}

TempErrExample

This function uses TempErr to return a #VALUE! error to Microsoft Excel.
This function can cause a memory leak as temp memory allocated by TempErr12 may never be freed.

__declspec(dllexport) LPXLOPER12 WINAPI TempErrExample(void) 
{
   return TempErr12(xlerrValue);
}

TempIntExample

This function uses TempInt() to pass an argument to xlfGetWorkspace.

__declspec(dllexport) short WINAPI TempIntExample(void) 
{
   XLOPER12 xRes;

   Excel12f(xlfGetWorkspace, &xRes, 1, TempInt12(44));
   Excel12f(xlFree, 0, 1, (LPXLOPER12)&xRes);
   return 1;
}

TempMissingExample

This example uses TempMissing12 to provide 3 missing arguments to xlcWorkspace followed by a Boolean FALSE to suppress the display of worksheet scroll-bars. The first 3 arguments correspond to other workspace settings which are unaffected

__declspec(dllexport) short WINAPI TempMissingExample(void) 
{
   XLOPER12 xBool;

   xBool.xltype = xltypeBool;
   xBool.val.xbool = 0;
   Excel12f(xlcWorkspace, 0, 4, TempMissing12(), TempMissing12(),
   TempMissing12(), (LPXLOPER12)&xBool);
   return 1;
}

TempNumExample

This function uses TempNum() to pass an argument to GET.WORKSPACE.

__declspec(dllexport) short WINAPI TempNumExample(void) 
{
   XLOPER12 xRes;

   Excel12f(xlfGetWorkspace, &xRes, 1, TempNum12(44));
   Excel12f(xlFree, 0, 1, (LPXLOPER12)&xRes);
   return 1;
}

TempStrExample

This function uses TempStrConst() to create a string for an alert message box.

__declspec(dllexport) short WINAPI TempStrExample(void) 
{
   Excel12f(xlcAlert, 0, 1, TempStr12(L"Made it!"));
   return 1;
}

fArray

This example consists of two routines: fArray and xlAutoFree().
This function creates an xltypeMulti containing eight values. It returns this array to Microsoft Excel with the xlbitDLLFree bit set. When Microsoft Excel is done with the values, it calls xlAutoFree(), which frees the memory that fArray() allocated.

HANDLE hArray; 

__declspec(dllexport) LPXLOPER12 WINAPI fArray(void)
{
   LPXLOPER12 pxArray;
   static XLOPER12 xMulti;
   int i;
   int rwcol;

   xMulti.xltype = xltypeMulti | xlbitDLLFree;
   xMulti.val.array.columns = 1;
   xMulti.val.array.rows = 8;

   //For large values of rows and columns, this would overflow
   //use __int64 in that case and return an error if rwcol
   //contains a number that won't fit in sizeof(int) bytes

   rwcol = xMulti.val.array.columns * xMulti.val.array.rows;

   pxArray = (LPXLOPER12)GlobalLock(hArray = GlobalAlloc(GMEM_ZEROINIT, rwcol * sizeof(XLOPER12)));

   xMulti.val.array.lparray = pxArray;

   for(i = 0; i < rwcol; i++)
   {
      pxArray[i].xltype = xltypeInt;
      pxArray[i].val.w = i;
   }

   //Word of caution - returning static XLOPERs/XLOPER12s is not thread safe
   //for UDFs declared as thread safe, use alternate memory allocation mechanisms

   return (LPXLOPER12)&xMulti;
}

xlAutoFree

Demonstrates the xlAutoFree callback. Frees the memory allocated by fArray as noted in the comment above.

__declspec(dllexport) void WINAPI xlAutoFree12(LPXLOPER12 pxFree) 
{
   GlobalUnlock(hArray);
   GlobalFree(hArray);
   return;
}

xlCoerceExample

This function takes a value and converts it to a string. Then, the function displays the string in an alert box.

__declspec(dllexport) short WINAPI xlCoerceExample(short iVal) 
{
   XLOPER12 xStr, xInt, xDestType;

   xInt.xltype = xltypeInt;
   xInt.val.w = iVal;

   xDestType.xltype = xltypeInt;
   xDestType.val.w = xltypeStr;

   Excel12f(xlCoerce, &xStr, 2, (LPXLOPER12)&xInt, (LPXLOPER12)&xDestType);

   Excel12f(xlcAlert, 0, 1, (LPXLOPER12)&xStr);
   Excel12f(xlFree, 0, 1, (LPXLOPER12)&xStr);

   return 1;
}

xlFreeExample

This example calls GET.WORKSPACE(1) to return (as a string) the platform on which Microsoft Excel is currently running. The code copies this returned string into a buffer for later use. The standard strcpy() function is not used to copy the string to the buffer because strcpy() expects a null-terminated string and the returned value is a byte-counted string. The code places the buffer back into the XLOPER12 for later use with Excel12f(). Finally, the code displays the string in an alert box.

__declspec(dllexport) short WINAPI xlFreeExample(void) 
{
   XLOPER12 xRes, xInt;
       XCHAR buffer[cchMaxStz];
       int i,len;

   // Create an XLOPER12 for the argument to Getworkspace
   xInt.xltype = xltypeInt;
   xInt.val.w = 1;
   // Call GetWorkspace
   Excel12f(xlfGetWorkspace, &xRes, 1, (LPXLOPER12)&xInt);

   // Get the length of the returned string
   len = (int)xRes.val.str[0];
   if (len > cchMaxStz - 2) //Take into account 1st char, which contains the length
           len = cchMaxStz - 2; //and the null terminator. Truncate if necessary to fit

   // Copy to buffer
   for(i = 1; i <= len; i++)
   {
      buffer[i] = xRes.val.str[i];
   }

   // Null terminate, Not necessary but a good idea
   buffer[len] = '\0';
   buffer[0] = len;

   // Free the string returned from Excel
   Excel12f(xlFree, 0, 1, &xRes);

   // Create a new string XLOPER12 for the alert
   xRes.xltype = xltypeStr;
   xRes.val.str = buffer;

   // Show the alert
   Excel12f(xlcAlert, 0, 1, (LPXLOPER12)&xRes);
   return 1;
}

xlGetInstExample

The following example compares the last instance of Microsoft Excel to the current instance of Microsoft Excel. If they are the same, the code returns 1; if they are not the same, it returns 0; if the function fails, it returns -1.

__declspec(dllexport) short WINAPI xlGetInstExample(void) 
{
   XLOPER12 xRes;
   static HANDLE hOld = 0;
   short iRet;

   if (Excel12f(xlGetInst, &xRes, 0) != xlretSuccess)
   {
      iRet = -1;
   }
   else
   {
      HANDLE hNew;

      hNew = (HANDLE)xRes.val.w;

      if (hNew != hOld)
         iRet = 0;
      else
         iRet = 1;

      hOld = hNew;
   }

   return iRet;
}

xlGetInstPtrExample

The following example compares the last instance of Microsoft Excel to the current instance of Microsoft Excel. If they are the same, the code returns 1; if they are not the same, it returns 0; if the function fails, it returns -1.

__declspec(dllexport) short WINAPI xlGetInstPtrExample(void) 
{
   XLOPER12 xRes;
   static HANDLE hOld = 0;
   short iRet;

   if (Excel12f(xlGetInstPtr, &xRes, 0) != xlretSuccess)
      iRet = -1;
   else
   {
      HANDLE hNew;

      hNew = xRes.val.bigdata.h.hdata;

      if (hNew != hOld)
         iRet = 0;
      else
         iRet = 1;
      hOld = hNew;
   }

   return iRet;
}

xlGetNameExample

The following code retrieves the name of the DLL that contains the code, and then displays it in an alert box.

__declspec(dllexport) short WINAPI xlGetNameExample(void) 
{
   XLOPER12 xRes;

   Excel12f(xlGetName, &xRes, 0);
   Excel12f(xlcAlert, 0, 1, (LPXLOPER12)&xRes);
   Excel12f(xlFree, 0, 1, (LPXLOPER12)&xRes);
   return 1;
}

xlSetExample

The following code places the passed-in value into B205:B206.

__declspec(dllexport) short WINAPI xlSetExample(short iVal) 
{
   XLOPER12 xRef, xValue;

   xRef.xltype = xltypeSRef;
   xRef.val.sref.count = 1;
   xRef.val.sref.ref.rwFirst = 204;
   xRef.val.sref.ref.rwLast = 205;
   xRef.val.sref.ref.colFirst = 1;
   xRef.val.sref.ref.colLast = 1;
   xValue.xltype = xltypeInt;
   xValue.val.w = iVal;
   Excel12(xlSet, 0, 2, (LPXLOPER12)&xRef, (LPXLOPER12)&xValue);
   return 1;
}

xlSheetIdExample

This function gets the sheet ID for Sheet1 in workbook BOOK1.XLSX.

__declspec(dllexport) short WINAPI xlSheetIdExample(void) 
{
   XLOPER12 xSheetName, xRes;
   XCHAR szBuf[sizeof(IDSHEET)*2+2+1];

   xSheetName.xltype = xltypeStr;
   xSheetName.val.str = L"\022[BOOK1.XLSX]Sheet1";
   Excel12(xlSheetId, &xRes, 1, (LPXLOPER12)&xSheetName);
   wsprintfW((LPWSTR)szBuf, L"0x%p",xRes.val.mref.idSheet);
   Excel12f(xlcAlert, 0, 1, TempStr12(szBuf));
   Excel12(xlFree, 0, 1, (LPXLOPER12)&xRes);
   return 1;
}

xlSheetNmExample

This function displays a message containing the name of the sheet that called it.

__declspec(dllexport) short WINAPI xlSheetNmExample(void) 
{
   XLOPER12 xRes, xSheetName;

   Excel12(xlfCaller, &xRes, 0);
   Excel12(xlSheetNm, &xSheetName, 1, (LPXLOPER12)&xRes);
   Excel12(xlcAlert, 0, 1, (LPXLOPER12)&xSheetName);
   Excel12(xlFree, 0, 1, (LPXLOPER12)&xSheetName);
   return 1;
}

xlStackExample

This function displays a message that indicates the amount of stack space remaining.

__declspec(dllexport) short WINAPI xlStackExample(void) 
{
   XLOPER12 xRes;

   Excel12(xlStack, &xRes, 0);
   Excel12(xlcAlert, 0, 1, (LPXLOPER12)&xRes);
   return 1;
}

xlUDFExample

This function demonstrates how to run a macro from an XLL. It runs a macro called TestMacro in a workbook called BOOK1.XLSX

__declspec(dllexport) short WINAPI xlUDFExample(void) 
{
   XLOPER12 xMacroName, xMacroRef, xRes;

   xMacroName.xltype = xltypeStr;
   xMacroName.val.str = L"\034[BOOK1.XLSX]Macro1!TestMacro";
   Excel12(xlfEvaluate, &xMacroRef, 1, (LPXLOPER12)&xMacroName);
   Excel12(xlUDF, &xRes, 1, (LPXLOPER12)&xMacroRef);
   return 1;
}

InternationalExample

This routine demonstrates how to set the xlIntl bit to allow function names to be intepreted correclty on international versions of Excel.

__declspec(dllexport) int WINAPI InternationalExample() 
{
   XLOPER12 xResult, xSum;

   xSum.xltype = xltypeStr;
   xSum.val.str = L"\011=SUM(1,2)";

   return Excel12f(xlcFormula | xlIntl, &xResult, 2, (LPXLOPER12) &xSum, TempActiveRef12(237,237,1,1));
}

CalcCircum

Calculates the circumference of a circle given the radius

__declspec(dllexport) double WINAPI CalcCircum(double pdRadius) 
{
   return pdRadius * 6.283185308;
}

© 2025 Better Solutions Limited. All Rights Reserved. © 2025 Better Solutions Limited TopPrevNext