1 /** 2 Microsoft Excel Developer's Toolkit 3 Version 14.0 4 5 File: SRC\XLCALL.CPP 6 Description: Code file for Excel callbacks 7 Platform: Microsoft Windows 8 9 This file defines the entry points 10 which are used in the Microsoft Excel C API. 11 12 */ 13 module xlld.xlcallcpp; 14 15 import xlld.xlcall: LPXLOPER12; 16 17 /** 18 Excel 12 entry points backwards compatible with Excel 11 19 20 Excel12 and Excel12v ensure backwards compatibility with Excel 11 21 and earlier versions. These functions will return xlretFailed when 22 used to callback into Excel 11 and earlier versions 23 */ 24 25 26 // PASCAL 27 alias EXCEL12PROC=extern(Windows) int function (int xlfn, int coper, LPXLOPER12 *rgpxloper12, LPXLOPER12 xloper12Res) nothrow @nogc; 28 29 EXCEL12PROC gExcel12; 30 31 void FetchExcel12EntryPt() nothrow @nogc 32 { 33 version(Windows) { 34 import core.sys.windows.windows: GetModuleHandleW, GetProcAddress; 35 if (gExcel12 is null) 36 { 37 auto hmodule = GetModuleHandleW(null); 38 if (hmodule !is null) 39 { 40 enum EXCEL12ENTRYPT="MdCallBack12"; 41 gExcel12 = cast(EXCEL12PROC) GetProcAddress(hmodule, EXCEL12ENTRYPT); 42 } 43 assert(gExcel12 !is null, "No entry point fetched"); 44 } 45 } 46 } 47 48 /** 49 This function explicitly sets EXCEL12ENTRYPT. 50 51 If the XLL is loaded not by Excel.exe, but by a HPC cluster container DLL, 52 then GetModuleHandle(null) would return the process EXE module handle. 53 In that case GetProcAddress would fail, since the process EXE doesn't 54 export EXCEL12ENTRYPT ( since it's not Excel.exe). 55 56 First try to fetch the known good entry point, 57 then set the passed in address. 58 */ 59 60 //pascal 61 extern(Windows) void SetExcel12EntryPt(EXCEL12PROC gExcel12New) 62 { 63 if (gExcel12 is null) 64 { 65 gExcel12 = gExcel12New; 66 } 67 } 68 69 //_cdecl 70 int Excel12(int xlfn, LPXLOPER12 operRes, LPXLOPER12[] args ...) 71 { 72 import core.vararg: va_list; 73 import xlld.xlcall: xlretFailed, xlretInvCount; 74 75 enum cxloper12Max=255; 76 LPXLOPER12[cxloper12Max] rgxloper12; 77 va_list ap; 78 int ioper; 79 int mdRet; 80 81 FetchExcel12EntryPt(); 82 if (gExcel12 is null) 83 { 84 mdRet = xlretFailed; 85 } 86 else 87 { 88 mdRet = xlretInvCount; 89 if ((args.length >= 0) && (args.length<= cxloper12Max)) 90 { 91 foreach(i,arg;args) 92 rgxloper12[ioper] = arg; 93 // original line was mdRet = (gExcel12)(xlfn, count, &rgxloper12[0], operRes); 94 mdRet = (*gExcel12)(xlfn, cast(int)args.length, rgxloper12.ptr, operRes); 95 } 96 } 97 return(mdRet); 98 99 } 100 101 extern(Windows) int Excel12v(int xlfn, LPXLOPER12 operRes, int count, LPXLOPER12* opers) nothrow @nogc 102 { 103 import xlld.xlcall: xlretFailed; 104 105 int mdRet; 106 FetchExcel12EntryPt(); 107 if (gExcel12 is null) 108 { 109 mdRet = xlretFailed; 110 } 111 else 112 { 113 // original line was mdRet = (gExcel12)(xlfn, count, &rgxloper12[0], operRes); 114 mdRet = (*gExcel12)(xlfn, count, opers, operRes); 115 } 116 return(mdRet); 117 118 }