Ruby 2.7.7p221 (2022-11-24 revision 168ec2b1e5ad0e4688e963d9de019557c78feed9)
win32ole_variable.c
Go to the documentation of this file.
1#include "win32ole.h"
2
4 ITypeInfo *pTypeInfo;
5 UINT index;
6};
7
8static void olevariable_free(void *ptr);
9static size_t olevariable_size(const void *ptr);
10static VALUE folevariable_name(VALUE self);
11static VALUE ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index);
12static VALUE folevariable_ole_type(VALUE self);
13static VALUE ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index);
14static VALUE folevariable_ole_type_detail(VALUE self);
15static VALUE ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index);
16static VALUE folevariable_value(VALUE self);
17static VALUE ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index);
18static VALUE folevariable_visible(VALUE self);
19static VALUE ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index);
20static VALUE folevariable_variable_kind(VALUE self);
21static VALUE ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index);
22static VALUE folevariable_varkind(VALUE self);
23static VALUE folevariable_inspect(VALUE self);
24
25static const rb_data_type_t olevariable_datatype = {
26 "win32ole_variable",
27 {NULL, olevariable_free, olevariable_size,},
29};
30
31static void
32olevariable_free(void *ptr)
33{
34 struct olevariabledata *polevar = ptr;
35 OLE_FREE(polevar->pTypeInfo);
36 free(polevar);
37}
38
39static size_t
40olevariable_size(const void *ptr)
41{
42 return ptr ? sizeof(struct olevariabledata) : 0;
43}
44
45/*
46 * Document-class: WIN32OLE_VARIABLE
47 *
48 * <code>WIN32OLE_VARIABLE</code> objects represent OLE variable information.
49 */
50
52create_win32ole_variable(ITypeInfo *pTypeInfo, UINT index, VALUE name)
53{
54 struct olevariabledata *pvar;
56 &olevariable_datatype, pvar);
57 pvar->pTypeInfo = pTypeInfo;
59 pvar->index = index;
60 rb_ivar_set(obj, rb_intern("name"), name);
61 return obj;
62}
63
64/*
65 * call-seq:
66 * WIN32OLE_VARIABLE#name
67 *
68 * Returns the name of variable.
69 *
70 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
71 * variables = tobj.variables
72 * variables.each do |variable|
73 * puts "#{variable.name}"
74 * end
75 *
76 * The result of above script is following:
77 * xlChart
78 * xlDialogSheet
79 * xlExcel4IntlMacroSheet
80 * xlExcel4MacroSheet
81 * xlWorksheet
82 *
83 */
84static VALUE
85folevariable_name(VALUE self)
86{
87 return rb_ivar_get(self, rb_intern("name"));
88}
89
90static VALUE
91ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index)
92{
93 VARDESC *pVarDesc;
94 HRESULT hr;
95 VALUE type;
96 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
97 if (FAILED(hr))
98 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc");
99 type = ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), Qnil);
100 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
101 return type;
102}
103
104/*
105 * call-seq:
106 * WIN32OLE_VARIABLE#ole_type
107 *
108 * Returns OLE type string.
109 *
110 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
111 * variables = tobj.variables
112 * variables.each do |variable|
113 * puts "#{variable.ole_type} #{variable.name}"
114 * end
115 *
116 * The result of above script is following:
117 * INT xlChart
118 * INT xlDialogSheet
119 * INT xlExcel4IntlMacroSheet
120 * INT xlExcel4MacroSheet
121 * INT xlWorksheet
122 *
123 */
124static VALUE
125folevariable_ole_type(VALUE self)
126{
127 struct olevariabledata *pvar;
128 TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar);
129 return ole_variable_ole_type(pvar->pTypeInfo, pvar->index);
130}
131
132static VALUE
133ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index)
134{
135 VARDESC *pVarDesc;
136 HRESULT hr;
138 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
139 if (FAILED(hr))
140 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc");
141 ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), type);
142 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
143 return type;
144}
145
146/*
147 * call-seq:
148 * WIN32OLE_VARIABLE#ole_type_detail
149 *
150 * Returns detail information of type. The information is array of type.
151 *
152 * tobj = WIN32OLE_TYPE.new('DirectX 7 for Visual Basic Type Library', 'D3DCLIPSTATUS')
153 * variable = tobj.variables.find {|variable| variable.name == 'lFlags'}
154 * tdetail = variable.ole_type_detail
155 * p tdetail # => ["USERDEFINED", "CONST_D3DCLIPSTATUSFLAGS"]
156 *
157 */
158static VALUE
159folevariable_ole_type_detail(VALUE self)
160{
161 struct olevariabledata *pvar;
162 TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar);
163 return ole_variable_ole_type_detail(pvar->pTypeInfo, pvar->index);
164}
165
166static VALUE
167ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index)
168{
169 VARDESC *pVarDesc;
170 HRESULT hr;
171 VALUE val = Qnil;
172 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
173 if (FAILED(hr))
174 return Qnil;
175 if(pVarDesc->varkind == VAR_CONST)
176 val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue));
177 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
178 return val;
179}
180
181/*
182 * call-seq:
183 * WIN32OLE_VARIABLE#value
184 *
185 * Returns value if value is exists. If the value does not exist,
186 * this method returns nil.
187 *
188 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
189 * variables = tobj.variables
190 * variables.each do |variable|
191 * puts "#{variable.name} #{variable.value}"
192 * end
193 *
194 * The result of above script is following:
195 * xlChart = -4109
196 * xlDialogSheet = -4116
197 * xlExcel4IntlMacroSheet = 4
198 * xlExcel4MacroSheet = 3
199 * xlWorksheet = -4167
200 *
201 */
202static VALUE
203folevariable_value(VALUE self)
204{
205 struct olevariabledata *pvar;
206 TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar);
207 return ole_variable_value(pvar->pTypeInfo, pvar->index);
208}
209
210static VALUE
211ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index)
212{
213 VARDESC *pVarDesc;
214 HRESULT hr;
215 VALUE visible = Qfalse;
216 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
217 if (FAILED(hr))
218 return visible;
219 if (!(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN |
220 VARFLAG_FRESTRICTED |
221 VARFLAG_FNONBROWSABLE))) {
222 visible = Qtrue;
223 }
224 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
225 return visible;
226}
227
228/*
229 * call-seq:
230 * WIN32OLE_VARIABLE#visible?
231 *
232 * Returns true if the variable is public.
233 *
234 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
235 * variables = tobj.variables
236 * variables.each do |variable|
237 * puts "#{variable.name} #{variable.visible?}"
238 * end
239 *
240 * The result of above script is following:
241 * xlChart true
242 * xlDialogSheet true
243 * xlExcel4IntlMacroSheet true
244 * xlExcel4MacroSheet true
245 * xlWorksheet true
246 *
247 */
248static VALUE
249folevariable_visible(VALUE self)
250{
251 struct olevariabledata *pvar;
252 TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar);
253 return ole_variable_visible(pvar->pTypeInfo, pvar->index);
254}
255
256static VALUE
257ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index)
258{
259 VARDESC *pVarDesc;
260 HRESULT hr;
261 VALUE kind = rb_str_new2("UNKNOWN");
262 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
263 if (FAILED(hr))
264 return kind;
265 switch(pVarDesc->varkind) {
266 case VAR_PERINSTANCE:
267 kind = rb_str_new2("PERINSTANCE");
268 break;
269 case VAR_STATIC:
270 kind = rb_str_new2("STATIC");
271 break;
272 case VAR_CONST:
273 kind = rb_str_new2("CONSTANT");
274 break;
275 case VAR_DISPATCH:
276 kind = rb_str_new2("DISPATCH");
277 break;
278 default:
279 break;
280 }
281 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
282 return kind;
283}
284
285/*
286 * call-seq:
287 * WIN32OLE_VARIABLE#variable_kind
288 *
289 * Returns variable kind string.
290 *
291 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
292 * variables = tobj.variables
293 * variables.each do |variable|
294 * puts "#{variable.name} #{variable.variable_kind}"
295 * end
296 *
297 * The result of above script is following:
298 * xlChart CONSTANT
299 * xlDialogSheet CONSTANT
300 * xlExcel4IntlMacroSheet CONSTANT
301 * xlExcel4MacroSheet CONSTANT
302 * xlWorksheet CONSTANT
303 */
304static VALUE
305folevariable_variable_kind(VALUE self)
306{
307 struct olevariabledata *pvar;
308 TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar);
309 return ole_variable_kind(pvar->pTypeInfo, pvar->index);
310}
311
312static VALUE
313ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index)
314{
315 VARDESC *pVarDesc;
316 HRESULT hr;
317 VALUE kind = Qnil;
318 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
319 if (FAILED(hr))
320 return kind;
321 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
322 kind = RB_INT2FIX(pVarDesc->varkind);
323 return kind;
324}
325
326/*
327 * call-seq:
328 * WIN32OLE_VARIABLE#varkind
329 *
330 * Returns the number which represents variable kind.
331 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
332 * variables = tobj.variables
333 * variables.each do |variable|
334 * puts "#{variable.name} #{variable.varkind}"
335 * end
336 *
337 * The result of above script is following:
338 * xlChart 2
339 * xlDialogSheet 2
340 * xlExcel4IntlMacroSheet 2
341 * xlExcel4MacroSheet 2
342 * xlWorksheet 2
343 */
344static VALUE
345folevariable_varkind(VALUE self)
346{
347 struct olevariabledata *pvar;
348 TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar);
349 return ole_variable_varkind(pvar->pTypeInfo, pvar->index);
350}
351
352/*
353 * call-seq:
354 * WIN32OLE_VARIABLE#inspect -> String
355 *
356 * Returns the OLE variable name and the value with class name.
357 *
358 */
359static VALUE
360folevariable_inspect(VALUE self)
361{
362 VALUE v = rb_inspect(folevariable_value(self));
363 VALUE n = folevariable_name(self);
364 VALUE detail = rb_sprintf("%"PRIsVALUE"=%"PRIsVALUE, n, v);
365 return make_inspect("WIN32OLE_VARIABLE", detail);
366}
367
369
371{
372 cWIN32OLE_VARIABLE = rb_define_class("WIN32OLE_VARIABLE", rb_cObject);
373 rb_define_method(cWIN32OLE_VARIABLE, "name", folevariable_name, 0);
374 rb_define_method(cWIN32OLE_VARIABLE, "ole_type", folevariable_ole_type, 0);
375 rb_define_method(cWIN32OLE_VARIABLE, "ole_type_detail", folevariable_ole_type_detail, 0);
376 rb_define_method(cWIN32OLE_VARIABLE, "value", folevariable_value, 0);
377 rb_define_method(cWIN32OLE_VARIABLE, "visible?", folevariable_visible, 0);
378 rb_define_method(cWIN32OLE_VARIABLE, "variable_kind", folevariable_variable_kind, 0);
379 rb_define_method(cWIN32OLE_VARIABLE, "varkind", folevariable_varkind, 0);
380 rb_define_method(cWIN32OLE_VARIABLE, "inspect", folevariable_inspect, 0);
381 rb_define_alias(cWIN32OLE_VARIABLE, "to_s", "name");
382}
struct RIMemo * ptr
Definition: debug.c:65
#define free(x)
Definition: dln.c:52
VALUE rb_define_class(const char *, VALUE)
Defines a top-level class.
Definition: class.c:662
void rb_define_alias(VALUE, const char *, const char *)
Defines an alias of a method.
Definition: class.c:1818
VALUE rb_cObject
Object class.
Definition: ruby.h:2012
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
Definition: object.c:551
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
const char * name
Definition: nkf.c:208
#define rb_str_new2
#define NULL
#define RB_INT2FIX(i)
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1070
const VALUE VALUE obj
const char size_t n
unsigned long VALUE
#define RUBY_TYPED_FREE_IMMEDIATELY
#define TypedData_Get_Struct(obj, type, data_type, sval)
#define PRIsVALUE
int VALUE v
VALUE rb_ary_new(void)
Definition: array.c:723
#define rb_intern(str)
#define Qtrue
#define Qnil
#define Qfalse
#define TypedData_Make_Struct(klass, type, data_type, sval)
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1300
VALUE rb_sprintf(const char *,...) __attribute__((format(printf
void rb_define_method(VALUE, const char *, VALUE(*)(), int)
ITypeInfo * pTypeInfo
VALUE ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
Definition: win32ole.c:3708
typedef HRESULT(STDAPICALLTYPE FNCOCREATEINSTANCEEX)(REFCLSID
VALUE ole_variant2val(VARIANT *pvar)
Definition: win32ole.c:1418
VALUE make_inspect(const char *class_name, VALUE detail)
Definition: win32ole.c:1333
#define OLE_FREE(x)
Definition: win32ole.h:99
#define OLE_ADDREF(X)
Definition: win32ole.h:97
#define V_UNION1(X, Y)
Definition: win32ole.h:47
VALUE eWIN32OLERuntimeError
void ole_raise(HRESULT hr, VALUE ecs, const char *fmt,...)
void Init_win32ole_variable(void)
VALUE create_win32ole_variable(ITypeInfo *pTypeInfo, UINT index, VALUE name)
VALUE cWIN32OLE_VARIABLE