Ruby 2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)

win32ole_variable.c
Go to the documentation of this file.
1 #include "win32ole.h"
2
3 struct olevariabledata {
4 ITypeInfo *pTypeInfo;
5 UINT index;
6 };
7
8 static void olevariable_free(void *ptr);
9 static size_t olevariable_size(const void *ptr);
10 static VALUE folevariable_name(VALUE self);
11 static VALUE ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index);
12 static VALUE folevariable_ole_type(VALUE self);
13 static VALUE ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index);
14 static VALUE folevariable_ole_type_detail(VALUE self);
15 static VALUE ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index);
16 static VALUE folevariable_value(VALUE self);
17 static VALUE ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index);
18 static VALUE folevariable_visible(VALUE self);
19 static VALUE ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index);
20 static VALUE folevariable_variable_kind(VALUE self);
21 static VALUE ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index);
22 static VALUE folevariable_varkind(VALUE self);
23 static VALUE folevariable_inspect(VALUE self);
24
25 static const rb_data_type_t olevariable_datatype = {
26 "win32ole_variable",
27 {NULL, olevariable_free, olevariable_size,},
28 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
29 };
30
31 static void
32 olevariable_free(void *ptr)
33 {
34 struct olevariabledata *polevar = ptr;
35 OLE_FREE(polevar->pTypeInfo);
36 free(polevar);
37 }
38
39 static size_t
40 olevariable_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
51 VALUE
52 create_win32ole_variable(ITypeInfo *pTypeInfo, UINT index, VALUE name)
53 {
54 struct olevariabledata *pvar;
55 VALUE obj = TypedData_Make_Struct(cWIN32OLE_VARIABLE, struct olevariabledata,
56 &olevariable_datatype, pvar);
57 pvar->pTypeInfo = pTypeInfo;
58 OLE_ADDREF(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 */
84 static VALUE
85 folevariable_name(VALUE self)
86 {
87 return rb_ivar_get(self, rb_intern("name"));
88 }
89
90 static VALUE
91 ole_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 */
124 static VALUE
125 folevariable_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
132 static VALUE
133 ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index)
134 {
135 VARDESC *pVarDesc;
136 HRESULT hr;
137 VALUE type = rb_ary_new();
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 */
158 static VALUE
159 folevariable_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
166 static VALUE
167 ole_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 */
202 static VALUE
203 folevariable_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
210 static VALUE
211 ole_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 */
248 static VALUE
249 folevariable_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
256 static VALUE
257 ole_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 */
304 static VALUE
305 folevariable_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
312 static VALUE
313 ole_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 */
344 static VALUE
345 folevariable_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 */
359 static VALUE
360 folevariable_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
368 void Init_win32ole_variable(void)
369 {
370 cWIN32OLE_VARIABLE = rb_define_class("WIN32OLE_VARIABLE", rb_cObject);
371 rb_define_method(cWIN32OLE_VARIABLE, "name", folevariable_name, 0);
372 rb_define_method(cWIN32OLE_VARIABLE, "ole_type", folevariable_ole_type, 0);
373 rb_define_method(cWIN32OLE_VARIABLE, "ole_type_detail", folevariable_ole_type_detail, 0);
374 rb_define_method(cWIN32OLE_VARIABLE, "value", folevariable_value, 0);
375 rb_define_method(cWIN32OLE_VARIABLE, "visible?", folevariable_visible, 0);
376 rb_define_method(cWIN32OLE_VARIABLE, "variable_kind", folevariable_variable_kind, 0);
377 rb_define_method(cWIN32OLE_VARIABLE, "varkind", folevariable_varkind, 0);
378 rb_define_method(cWIN32OLE_VARIABLE, "inspect", folevariable_inspect, 0);
379 rb_define_alias(cWIN32OLE_VARIABLE, "to_s", "name");
380 }
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:649
TypedData_Make_Struct
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: ruby.h:1244
rb_str_new2
#define rb_str_new2
Definition: intern.h:903
win32ole.h
cWIN32OLE_VARIABLE
VALUE cWIN32OLE_VARIABLE
Definition: win32ole_variable.h:4
ole_variant2val
VALUE ole_variant2val(VARIANT *pvar)
Definition: win32ole.c:1418
create_win32ole_variable
VALUE create_win32ole_variable(ITypeInfo *pTypeInfo, UINT index, VALUE name)
Definition: win32ole_variable.c:52
VALUE
unsigned long VALUE
Definition: ruby.h:102
rb_intern
#define rb_intern(str)
rb_inspect
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
Definition: object.c:551
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1551
ptr
struct RIMemo * ptr
Definition: debug.c:74
Qfalse
#define Qfalse
Definition: ruby.h:467
NULL
#define NULL
Definition: _sdbm.c:101
PRIsVALUE
#define PRIsVALUE
Definition: ruby.h:166
eWIN32OLERuntimeError
VALUE eWIN32OLERuntimeError
Definition: win32ole_error.h:4
rb_define_alias
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1800
v
int VALUE v
Definition: rb_mjit_min_header-2.7.0.h:12332
rb_ivar_get
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1070
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.0.h:5742
ole_typedesc2val
VALUE ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
Definition: win32ole.c:3708
olevariabledata::pTypeInfo
ITypeInfo * pTypeInfo
Definition: win32ole_variable.c:4
V_UNION1
#define V_UNION1(X, Y)
Definition: win32ole.h:47
olevariabledata
Definition: win32ole_variable.c:3
OLE_FREE
#define OLE_FREE(x)
Definition: win32ole.h:99
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:2010
n
const char size_t n
Definition: rb_mjit_min_header-2.7.0.h:5456
TypedData_Get_Struct
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: ruby.h:1252
RB_INT2FIX
#define RB_INT2FIX(i)
Definition: ruby.h:262
rb_sprintf
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1197
HRESULT
typedef HRESULT(STDAPICALLTYPE FNCOCREATEINSTANCEEX)(REFCLSID
RUBY_TYPED_FREE_IMMEDIATELY
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1207
OLE_ADDREF
#define OLE_ADDREF(X)
Definition: win32ole.h:97
olevariabledata::index
UINT index
Definition: win32ole_variable.c:5
free
#define free(x)
Definition: dln.c:52
rb_data_type_struct
Definition: ruby.h:1148
Qtrue
#define Qtrue
Definition: ruby.h:468
rb_ivar_set
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1300
ole_raise
void ole_raise(HRESULT hr, VALUE ecs, const char *fmt,...)
Definition: win32ole_error.c:46
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:723
Qnil
#define Qnil
Definition: ruby.h:469
Init_win32ole_variable
void Init_win32ole_variable(void)
Definition: win32ole_variable.c:368
make_inspect
VALUE make_inspect(const char *class_name, VALUE detail)
Definition: win32ole.c:1333
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
name
const char * name
Definition: nkf.c:208