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.sdk.xlcallcpp;
14 
15 import xlld.sdk.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 extern(Windows) void SetExcel12EntryPt(EXCEL12PROC gExcel12New) @nogc nothrow
60 {
61 	if (gExcel12 is null)
62 	{
63 		gExcel12 = gExcel12New;
64 	}
65 }
66 
67 //_cdecl
68 int Excel12(int xlfn, LPXLOPER12 operRes, LPXLOPER12[] args ...)
69 {
70 	import core.vararg: va_list;
71 	import xlld.sdk.xlcall: xlretFailed, xlretInvCount;
72 
73 	enum cxloper12Max=255;
74 	LPXLOPER12[cxloper12Max] rgxloper12;
75 	va_list ap;
76 	int ioper;
77 	int mdRet;
78 
79 	FetchExcel12EntryPt();
80 	if (gExcel12 is null)
81 	{
82 		mdRet = xlretFailed;
83 	}
84 	else
85 	{
86 		mdRet = xlretInvCount;
87 		if ((args.length >= 0)  && (args.length<= cxloper12Max))
88 		{
89 			foreach(i,arg;args)
90 				rgxloper12[ioper] = arg;
91 //			original line was mdRet = (gExcel12)(xlfn, count, &rgxloper12[0], operRes);
92 			mdRet = (*gExcel12)(xlfn, cast(int)args.length, rgxloper12.ptr, operRes);
93 		}
94 	}
95 	return(mdRet);
96 
97 }
98 
99 extern(Windows) int Excel12v(int xlfn, LPXLOPER12 operRes, int count, LPXLOPER12* opers)
100     nothrow @nogc
101 {
102 	import xlld.sdk.xlcall: xlretFailed;
103 
104 	int mdRet;
105 	FetchExcel12EntryPt();
106 	if (gExcel12 is null)
107 	{
108 		mdRet = xlretFailed;
109 	}
110 	else
111 	{
112 		// original line was mdRet = (gExcel12)(xlfn, count, &rgxloper12[0], operRes);
113 		mdRet = (*gExcel12)(xlfn, count, opers, operRes);
114 	}
115 	return(mdRet);
116 
117 }