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 }