1 |
francois |
283 |
#ifndef SMARTVARS_H |
2 |
|
|
#define SMARTVARS_H |
3 |
|
|
|
4 |
|
|
#include <assert.h> |
5 |
|
|
|
6 |
|
|
#ifdef __BORLANDC__ |
7 |
|
|
#include <Atl/atlbase.h> |
8 |
|
|
#endif |
9 |
|
|
|
10 |
|
|
#ifdef VC71 |
11 |
|
|
#include <atlbase.h> |
12 |
|
|
#endif |
13 |
|
|
|
14 |
|
|
/** |
15 |
|
|
* |
16 |
|
|
USAGE : |
17 |
|
|
SafeBSTRArray names(1); |
18 |
|
|
SafeLongArray types(1); |
19 |
|
|
SafeBSTRArray vals(1); |
20 |
|
|
|
21 |
|
|
names[0] = T2BSTR(_T("ReplaceFile")); |
22 |
|
|
types[0] = swMacroFeatureParamTypeString; |
23 |
|
|
vals[0] = m_replaceFile.AllocSysString(); |
24 |
|
|
|
25 |
|
|
CComVariant paramNames = names; |
26 |
|
|
CComVariant paramTypes = types; |
27 |
|
|
CComVariant paramValues = vals; |
28 |
|
|
|
29 |
|
|
LPDISPATCH outFeat = NULL; |
30 |
|
|
HRESULT hres = m_Part->InsertComFeature(T2BSTR(_T("{04B74DF2-ACBA-4218-887A-F42140F312E0}")), |
31 |
|
|
paramNames, paramTypes, paramValues, &outFeat); |
32 |
|
|
if (outFeat) |
33 |
|
|
outFeat->Release(); |
34 |
|
|
*/ |
35 |
|
|
template <class T,int type> class SafeArray |
36 |
|
|
{ |
37 |
|
|
public: |
38 |
|
|
SafeArray(VARIANT *input): |
39 |
|
|
m_input(input), |
40 |
|
|
m_access(false), |
41 |
|
|
m_bCreate(false), |
42 |
|
|
m_pSafeArray(NULL), |
43 |
|
|
m_arrayData(NULL), |
44 |
|
|
m_result(S_OK) |
45 |
|
|
|
46 |
|
|
{ |
47 |
|
|
if (m_input != NULL) |
48 |
|
|
{ |
49 |
|
|
if (V_VT(m_input) != VT_EMPTY) |
50 |
|
|
{ |
51 |
|
|
m_pSafeArray = V_ARRAY (m_input); |
52 |
|
|
m_result = SafeArrayAccessData ( m_pSafeArray, (void HUGEP**)&m_arrayData); |
53 |
|
|
m_access = m_result == S_OK ; |
54 |
|
|
} |
55 |
|
|
else |
56 |
|
|
m_access = true; |
57 |
|
|
} |
58 |
|
|
else |
59 |
|
|
{ |
60 |
|
|
assert(FALSE); |
61 |
|
|
m_input = &m_target; |
62 |
|
|
} |
63 |
|
|
} |
64 |
|
|
|
65 |
|
|
SafeArray(const VARIANT &input) : |
66 |
|
|
m_access(true), |
67 |
|
|
m_bCreate(false), |
68 |
|
|
m_pSafeArray(NULL), |
69 |
|
|
m_arrayData(NULL), |
70 |
|
|
m_result(S_OK) |
71 |
|
|
{ |
72 |
|
|
m_input = (VARIANT *) &input; |
73 |
|
|
if (V_VT(m_input) != VT_EMPTY) |
74 |
|
|
{ |
75 |
|
|
m_pSafeArray = V_ARRAY (m_input); |
76 |
|
|
m_result = SafeArrayAccessData ( m_pSafeArray, (void HUGEP**)&m_arrayData); |
77 |
|
|
m_access = m_result == S_OK ; |
78 |
|
|
} |
79 |
|
|
else |
80 |
|
|
m_access = true; |
81 |
|
|
} |
82 |
|
|
|
83 |
|
|
SafeArray(unsigned int size,unsigned int dims = 1): |
84 |
|
|
m_input(&m_target), |
85 |
|
|
m_access(false), |
86 |
|
|
m_bCreate(true), |
87 |
|
|
m_pSafeArray(NULL), |
88 |
|
|
m_arrayData(NULL), |
89 |
|
|
m_result(S_OK) |
90 |
|
|
{ |
91 |
|
|
assert(size >= 0); |
92 |
|
|
if (size > 0) |
93 |
|
|
{ |
94 |
|
|
m_rgsabound[0].lLbound = 0; |
95 |
|
|
m_rgsabound[0].cElements = (int) size; |
96 |
|
|
m_pSafeArray = SafeArrayCreate(type, (int)dims, m_rgsabound); |
97 |
|
|
V_VT(m_input) = VT_ARRAY | type; |
98 |
|
|
m_result = SafeArrayAccessData( m_pSafeArray, (void HUGEP**)&m_arrayData); |
99 |
|
|
m_access = m_result == S_OK ; |
100 |
|
|
if (!m_access) |
101 |
|
|
V_VT(m_input) = VT_EMPTY; |
102 |
|
|
} |
103 |
|
|
else |
104 |
|
|
{ |
105 |
|
|
V_VT(m_input) = VT_EMPTY; |
106 |
|
|
m_access = true; |
107 |
|
|
} |
108 |
|
|
} |
109 |
|
|
|
110 |
|
|
inline HRESULT status() { |
111 |
|
|
return m_result; |
112 |
|
|
} |
113 |
|
|
inline int getSize(int index = 0) { |
114 |
|
|
return (m_access&&m_pSafeArray)?m_pSafeArray->rgsabound[index].cElements:0; |
115 |
|
|
} |
116 |
|
|
|
117 |
|
|
~SafeArray() { |
118 |
|
|
UnaccessData(); |
119 |
|
|
} |
120 |
|
|
|
121 |
|
|
operator T* () { |
122 |
|
|
assert(m_access); |
123 |
|
|
return m_arrayData; |
124 |
|
|
} |
125 |
|
|
operator VARIANT () { |
126 |
|
|
assert(m_access); |
127 |
|
|
UnaccessData(); |
128 |
|
|
return *m_input; |
129 |
|
|
} |
130 |
|
|
T & operator[](int i) { |
131 |
|
|
assert(m_access&&m_arrayData); |
132 |
|
|
return m_arrayData[i]; |
133 |
|
|
} |
134 |
|
|
private: |
135 |
|
|
void UnaccessData() { |
136 |
|
|
if (m_access) { |
137 |
|
|
m_result = SafeArrayUnaccessData( m_pSafeArray ); |
138 |
|
|
if (m_bCreate && m_result == S_OK) |
139 |
|
|
V_ARRAY(m_input) = m_pSafeArray; |
140 |
|
|
m_access = false; |
141 |
|
|
} |
142 |
|
|
} |
143 |
|
|
|
144 |
|
|
bool m_bCreate; |
145 |
|
|
bool m_access; |
146 |
|
|
VARIANT *m_input; |
147 |
|
|
VARIANT m_target; |
148 |
|
|
T *m_arrayData ; |
149 |
|
|
SAFEARRAY *m_pSafeArray; |
150 |
|
|
SAFEARRAYBOUND m_rgsabound[1]; |
151 |
|
|
HRESULT m_result; |
152 |
|
|
}; |
153 |
|
|
|
154 |
|
|
typedef SafeArray<double, VT_R8> SafeDoubleArray ; |
155 |
|
|
typedef SafeArray<float, VT_R4> SafeFloatArray ; |
156 |
|
|
typedef SafeArray<long, VT_I4> SafeLongArray ; |
157 |
|
|
typedef SafeArray<BSTR, VT_BSTR> SafeBSTRArray ; |
158 |
|
|
typedef SafeArray<LPDISPATCH, VT_DISPATCH> SafeDISPATCHArray; |
159 |
|
|
typedef SafeArray<LPVARIANT, VT_VARIANT> SafeVARIANTArray; |
160 |
|
|
typedef SafeArray<short, VT_I2> SafeBooleanArray; |
161 |
|
|
|
162 |
|
|
|
163 |
|
|
|
164 |
|
|
/* |
165 |
|
|
|
166 |
|
|
assing SafeArrays in C++ |
167 |
|
|
Be careful when managing SafeArray memory. If you receive a SafeArray from the SolidWorks product, you are responsible for destroying it. Also, if you pass a SafeArray to the SolidWorks product, SolidWorks does not destroy the SafeArray; you are responsible for destroying it. |
168 |
|
|
|
169 |
|
|
See: |
170 |
|
|
|
171 |
|
|
Return Values for information and examples of handling SafeArray and VARIANT return values. |
172 |
|
|
|
173 |
|
|
A template class for VARIANT SafeArrays on the SolidWorks API Support Web site, http://www.solidworks.com/pages/services/APITips.html. |
174 |
|
|
|
175 |
|
|
|
176 |
|
|
|
177 |
|
|
*/ |
178 |
|
|
|
179 |
|
|
#endif//SMARTVARS_H |