Ruby 2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)

win32ole_method.c
Go to the documentation of this file.
1 #include "win32ole.h"
2
3 static void olemethod_free(void *ptr);
4 static size_t olemethod_size(const void *ptr);
5 static VALUE ole_method_sub(VALUE self, ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE name);
6 static VALUE olemethod_from_typeinfo(VALUE self, ITypeInfo *pTypeInfo, VALUE name);
7 static VALUE ole_methods_sub(ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE methods, int mask);
8 static VALUE olemethod_set_member(VALUE self, ITypeInfo *pTypeInfo, ITypeInfo *pOwnerTypeInfo, int index, VALUE name);
9 static VALUE folemethod_initialize(VALUE self, VALUE oletype, VALUE method);
10 static VALUE folemethod_name(VALUE self);
11 static VALUE ole_method_return_type(ITypeInfo *pTypeInfo, UINT method_index);
12 static VALUE folemethod_return_type(VALUE self);
13 static VALUE ole_method_return_vtype(ITypeInfo *pTypeInfo, UINT method_index);
14 static VALUE folemethod_return_vtype(VALUE self);
15 static VALUE ole_method_return_type_detail(ITypeInfo *pTypeInfo, UINT method_index);
16 static VALUE folemethod_return_type_detail(VALUE self);
17 static VALUE ole_method_invkind(ITypeInfo *pTypeInfo, UINT method_index);
18 static VALUE ole_method_invoke_kind(ITypeInfo *pTypeInfo, UINT method_index);
19 static VALUE folemethod_invkind(VALUE self);
20 static VALUE folemethod_invoke_kind(VALUE self);
21 static VALUE ole_method_visible(ITypeInfo *pTypeInfo, UINT method_index);
22 static VALUE folemethod_visible(VALUE self);
23 static VALUE ole_method_event(ITypeInfo *pTypeInfo, UINT method_index, VALUE method_name);
24 static VALUE folemethod_event(VALUE self);
25 static VALUE folemethod_event_interface(VALUE self);
26 static HRESULT ole_method_docinfo_from_type(ITypeInfo *pTypeInfo, UINT method_index, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile);
27 static VALUE ole_method_helpstring(ITypeInfo *pTypeInfo, UINT method_index);
28 static VALUE folemethod_helpstring(VALUE self);
29 static VALUE ole_method_helpfile(ITypeInfo *pTypeInfo, UINT method_index);
30 static VALUE folemethod_helpfile(VALUE self);
31 static VALUE ole_method_helpcontext(ITypeInfo *pTypeInfo, UINT method_index);
32 static VALUE folemethod_helpcontext(VALUE self);
33 static VALUE ole_method_dispid(ITypeInfo *pTypeInfo, UINT method_index);
34 static VALUE folemethod_dispid(VALUE self);
35 static VALUE ole_method_offset_vtbl(ITypeInfo *pTypeInfo, UINT method_index);
36 static VALUE folemethod_offset_vtbl(VALUE self);
37 static VALUE ole_method_size_params(ITypeInfo *pTypeInfo, UINT method_index);
38 static VALUE folemethod_size_params(VALUE self);
39 static VALUE ole_method_size_opt_params(ITypeInfo *pTypeInfo, UINT method_index);
40 static VALUE folemethod_size_opt_params(VALUE self);
41 static VALUE ole_method_params(ITypeInfo *pTypeInfo, UINT method_index);
42 static VALUE folemethod_params(VALUE self);
43 static VALUE folemethod_inspect(VALUE self);
44
45 static const rb_data_type_t olemethod_datatype = {
46 "win32ole_method",
47 {NULL, olemethod_free, olemethod_size,},
48 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
49 };
50
51 static void
52 olemethod_free(void *ptr)
53 {
54 struct olemethoddata *polemethod = ptr;
55 OLE_FREE(polemethod->pTypeInfo);
56 OLE_FREE(polemethod->pOwnerTypeInfo);
57 free(polemethod);
58 }
59
60 static size_t
61 olemethod_size(const void *ptr)
62 {
63 return ptr ? sizeof(struct olemethoddata) : 0;
64 }
65
66 struct olemethoddata *
67 olemethod_data_get_struct(VALUE obj)
68 {
69 struct olemethoddata *pmethod;
70 TypedData_Get_Struct(obj, struct olemethoddata, &olemethod_datatype, pmethod);
71 return pmethod;
72 }
73
74 static VALUE
75 ole_method_sub(VALUE self, ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE name)
76 {
77 HRESULT hr;
78 TYPEATTR *pTypeAttr;
79 BSTR bstr;
80 FUNCDESC *pFuncDesc;
81 WORD i;
82 VALUE fname;
83 VALUE method = Qnil;
84 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
85 if (FAILED(hr)) {
86 ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeAttr");
87 }
88 for(i = 0; i < pTypeAttr->cFuncs && method == Qnil; i++) {
89 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc);
90 if (FAILED(hr))
91 continue;
92
93 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
94 &bstr, NULL, NULL, NULL);
95 if (FAILED(hr)) {
96 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
97 continue;
98 }
99 fname = WC2VSTR(bstr);
100 if (strcasecmp(StringValuePtr(name), StringValuePtr(fname)) == 0) {
101 olemethod_set_member(self, pTypeInfo, pOwnerTypeInfo, i, fname);
102 method = self;
103 }
104 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
105 pFuncDesc=NULL;
106 }
107 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
108 return method;
109 }
110
111 VALUE
112 ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask)
113 {
114 HRESULT hr;
115 TYPEATTR *pTypeAttr;
116 WORD i;
117 HREFTYPE href;
118 ITypeInfo *pRefTypeInfo;
119 VALUE methods = rb_ary_new();
120 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
121 if (FAILED(hr)) {
122 ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeAttr");
123 }
124
125 ole_methods_sub(0, pTypeInfo, methods, mask);
126 for(i=0; i < pTypeAttr->cImplTypes; i++){
127 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
128 if(FAILED(hr))
129 continue;
130 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
131 if (FAILED(hr))
132 continue;
133 ole_methods_sub(pTypeInfo, pRefTypeInfo, methods, mask);
134 OLE_RELEASE(pRefTypeInfo);
135 }
136 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
137 return methods;
138 }
139
140 static VALUE
141 olemethod_from_typeinfo(VALUE self, ITypeInfo *pTypeInfo, VALUE name)
142 {
143 HRESULT hr;
144 TYPEATTR *pTypeAttr;
145 WORD i;
146 HREFTYPE href;
147 ITypeInfo *pRefTypeInfo;
148 VALUE method = Qnil;
149 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
150 if (FAILED(hr)) {
151 ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeAttr");
152 }
153 method = ole_method_sub(self, 0, pTypeInfo, name);
154 if (method != Qnil) {
155 return method;
156 }
157 for(i=0; i < pTypeAttr->cImplTypes && method == Qnil; i++){
158 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
159 if(FAILED(hr))
160 continue;
161 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
162 if (FAILED(hr))
163 continue;
164 method = ole_method_sub(self, pTypeInfo, pRefTypeInfo, name);
165 OLE_RELEASE(pRefTypeInfo);
166 }
167 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
168 return method;
169 }
170
171 static VALUE
172 ole_methods_sub(ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE methods, int mask)
173 {
174 HRESULT hr;
175 TYPEATTR *pTypeAttr;
176 BSTR bstr;
177 FUNCDESC *pFuncDesc;
178 VALUE method;
179 WORD i;
180 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
181 if (FAILED(hr)) {
182 ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeAttr");
183 }
184 for(i = 0; i < pTypeAttr->cFuncs; i++) {
185 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc);
186 if (FAILED(hr))
187 continue;
188
189 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
190 &bstr, NULL, NULL, NULL);
191 if (FAILED(hr)) {
192 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
193 continue;
194 }
195 if(pFuncDesc->invkind & mask) {
196 method = folemethod_s_allocate(cWIN32OLE_METHOD);
197 olemethod_set_member(method, pTypeInfo, pOwnerTypeInfo,
198 i, WC2VSTR(bstr));
199 rb_ary_push(methods, method);
200 }
201 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
202 pFuncDesc=NULL;
203 }
204 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
205
206 return methods;
207 }
208
209 VALUE
210 create_win32ole_method(ITypeInfo *pTypeInfo, VALUE name)
211 {
212
213 VALUE method = folemethod_s_allocate(cWIN32OLE_METHOD);
214 VALUE obj = olemethod_from_typeinfo(method, pTypeInfo, name);
215 return obj;
216 }
217
218 /*
219 * Document-class: WIN32OLE_METHOD
220 *
221 * <code>WIN32OLE_METHOD</code> objects represent OLE method information.
222 */
223
224 static VALUE
225 olemethod_set_member(VALUE self, ITypeInfo *pTypeInfo, ITypeInfo *pOwnerTypeInfo, int index, VALUE name)
226 {
227 struct olemethoddata *pmethod;
228 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
229 pmethod->pTypeInfo = pTypeInfo;
230 OLE_ADDREF(pTypeInfo);
231 pmethod->pOwnerTypeInfo = pOwnerTypeInfo;
232 OLE_ADDREF(pOwnerTypeInfo);
233 pmethod->index = index;
234 rb_ivar_set(self, rb_intern("name"), name);
235 return self;
236 }
237
238 VALUE
239 folemethod_s_allocate(VALUE klass)
240 {
241 struct olemethoddata *pmethod;
242 VALUE obj;
243 obj = TypedData_Make_Struct(klass,
244 struct olemethoddata,
245 &olemethod_datatype, pmethod);
246 pmethod->pTypeInfo = NULL;
247 pmethod->pOwnerTypeInfo = NULL;
248 pmethod->index = 0;
249 return obj;
250 }
251
252 /*
253 * call-seq:
254 * WIN32OLE_METHOD.new(ole_type, method) -> WIN32OLE_METHOD object
255 *
256 * Returns a new WIN32OLE_METHOD object which represents the information
257 * about OLE method.
258 * The first argument <i>ole_type</i> specifies WIN32OLE_TYPE object.
259 * The second argument <i>method</i> specifies OLE method name defined OLE class
260 * which represents WIN32OLE_TYPE object.
261 *
262 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
263 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
264 */
265 static VALUE
266 folemethod_initialize(VALUE self, VALUE oletype, VALUE method)
267 {
268 VALUE obj = Qnil;
269 ITypeInfo *pTypeInfo;
270 if (rb_obj_is_kind_of(oletype, cWIN32OLE_TYPE)) {
271 SafeStringValue(method);
272 pTypeInfo = itypeinfo(oletype);
273 obj = olemethod_from_typeinfo(self, pTypeInfo, method);
274 if (obj == Qnil) {
275 rb_raise(eWIN32OLERuntimeError, "not found %s",
276 StringValuePtr(method));
277 }
278 }
279 else {
280 rb_raise(rb_eTypeError, "1st argument should be WIN32OLE_TYPE object");
281 }
282 return obj;
283 }
284
285 /*
286 * call-seq:
287 * WIN32OLE_METHOD#name
288 *
289 * Returns the name of the method.
290 *
291 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
292 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
293 * puts method.name # => SaveAs
294 *
295 */
296 static VALUE
297 folemethod_name(VALUE self)
298 {
299 return rb_ivar_get(self, rb_intern("name"));
300 }
301
302 static VALUE
303 ole_method_return_type(ITypeInfo *pTypeInfo, UINT method_index)
304 {
305 FUNCDESC *pFuncDesc;
306 HRESULT hr;
307 VALUE type;
308
309 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
310 if (FAILED(hr))
311 ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetFuncDesc");
312
313 type = ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), Qnil);
314 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
315 return type;
316 }
317
318 /*
319 * call-seq:
320 * WIN32OLE_METHOD#return_type
321 *
322 * Returns string of return value type of method.
323 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
324 * method = WIN32OLE_METHOD.new(tobj, 'Add')
325 * puts method.return_type # => Workbook
326 *
327 */
328 static VALUE
329 folemethod_return_type(VALUE self)
330 {
331 struct olemethoddata *pmethod;
332 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
333 return ole_method_return_type(pmethod->pTypeInfo, pmethod->index);
334 }
335
336 static VALUE
337 ole_method_return_vtype(ITypeInfo *pTypeInfo, UINT method_index)
338 {
339 FUNCDESC *pFuncDesc;
340 HRESULT hr;
341 VALUE vvt;
342
343 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
344 if (FAILED(hr))
345 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc");
346
347 vvt = RB_INT2FIX(pFuncDesc->elemdescFunc.tdesc.vt);
348 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
349 return vvt;
350 }
351
352 /*
353 * call-seq:
354 * WIN32OLE_METHOD#return_vtype
355 *
356 * Returns number of return value type of method.
357 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
358 * method = WIN32OLE_METHOD.new(tobj, 'Add')
359 * puts method.return_vtype # => 26
360 *
361 */
362 static VALUE
363 folemethod_return_vtype(VALUE self)
364 {
365 struct olemethoddata *pmethod;
366 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
367 return ole_method_return_vtype(pmethod->pTypeInfo, pmethod->index);
368 }
369
370 static VALUE
371 ole_method_return_type_detail(ITypeInfo *pTypeInfo, UINT method_index)
372 {
373 FUNCDESC *pFuncDesc;
374 HRESULT hr;
375 VALUE type = rb_ary_new();
376
377 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
378 if (FAILED(hr))
379 return type;
380
381 ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), type);
382 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
383 return type;
384 }
385
386 /*
387 * call-seq:
388 * WIN32OLE_METHOD#return_type_detail
389 *
390 * Returns detail information of return value type of method.
391 * The information is array.
392 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
393 * method = WIN32OLE_METHOD.new(tobj, 'Add')
394 * p method.return_type_detail # => ["PTR", "USERDEFINED", "Workbook"]
395 */
396 static VALUE
397 folemethod_return_type_detail(VALUE self)
398 {
399 struct olemethoddata *pmethod;
400 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
401 return ole_method_return_type_detail(pmethod->pTypeInfo, pmethod->index);
402 }
403
404 static VALUE
405 ole_method_invkind(ITypeInfo *pTypeInfo, UINT method_index)
406 {
407 FUNCDESC *pFuncDesc;
408 HRESULT hr;
409 VALUE invkind;
410 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
411 if(FAILED(hr))
412 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc");
413 invkind = RB_INT2FIX(pFuncDesc->invkind);
414 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
415 return invkind;
416 }
417
418 static VALUE
419 ole_method_invoke_kind(ITypeInfo *pTypeInfo, UINT method_index)
420 {
421 VALUE type = rb_str_new2("UNKNOWN");
422 VALUE invkind = ole_method_invkind(pTypeInfo, method_index);
423 if((RB_FIX2INT(invkind) & INVOKE_PROPERTYGET) &&
424 (RB_FIX2INT(invkind) & INVOKE_PROPERTYPUT) ) {
425 type = rb_str_new2("PROPERTY");
426 } else if(RB_FIX2INT(invkind) & INVOKE_PROPERTYGET) {
427 type = rb_str_new2("PROPERTYGET");
428 } else if(RB_FIX2INT(invkind) & INVOKE_PROPERTYPUT) {
429 type = rb_str_new2("PROPERTYPUT");
430 } else if(RB_FIX2INT(invkind) & INVOKE_PROPERTYPUTREF) {
431 type = rb_str_new2("PROPERTYPUTREF");
432 } else if(RB_FIX2INT(invkind) & INVOKE_FUNC) {
433 type = rb_str_new2("FUNC");
434 }
435 return type;
436 }
437
438 /*
439 * call-seq:
440 * WIN32OLE_MTHOD#invkind
441 *
442 * Returns the method invoke kind.
443 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
444 * method = WIN32OLE_METHOD.new(tobj, 'Add')
445 * puts method.invkind # => 1
446 *
447 */
448 static VALUE
449 folemethod_invkind(VALUE self)
450 {
451 struct olemethoddata *pmethod;
452 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
453 return ole_method_invkind(pmethod->pTypeInfo, pmethod->index);
454 }
455
456 /*
457 * call-seq:
458 * WIN32OLE_METHOD#invoke_kind
459 *
460 * Returns the method kind string. The string is "UNKNOWN" or "PROPERTY"
461 * or "PROPERTY" or "PROPERTYGET" or "PROPERTYPUT" or "PROPERTYPPUTREF"
462 * or "FUNC".
463 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
464 * method = WIN32OLE_METHOD.new(tobj, 'Add')
465 * puts method.invoke_kind # => "FUNC"
466 */
467 static VALUE
468 folemethod_invoke_kind(VALUE self)
469 {
470 struct olemethoddata *pmethod;
471 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
472 return ole_method_invoke_kind(pmethod->pTypeInfo, pmethod->index);
473 }
474
475 static VALUE
476 ole_method_visible(ITypeInfo *pTypeInfo, UINT method_index)
477 {
478 FUNCDESC *pFuncDesc;
479 HRESULT hr;
480 VALUE visible;
481 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
482 if(FAILED(hr))
483 return Qfalse;
484 if (pFuncDesc->wFuncFlags & (FUNCFLAG_FRESTRICTED |
485 FUNCFLAG_FHIDDEN |
486 FUNCFLAG_FNONBROWSABLE)) {
487 visible = Qfalse;
488 } else {
489 visible = Qtrue;
490 }
491 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
492 return visible;
493 }
494
495 /*
496 * call-seq:
497 * WIN32OLE_METHOD#visible?
498 *
499 * Returns true if the method is public.
500 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
501 * method = WIN32OLE_METHOD.new(tobj, 'Add')
502 * puts method.visible? # => true
503 */
504 static VALUE
505 folemethod_visible(VALUE self)
506 {
507 struct olemethoddata *pmethod;
508 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
509 return ole_method_visible(pmethod->pTypeInfo, pmethod->index);
510 }
511
512 static VALUE
513 ole_method_event(ITypeInfo *pTypeInfo, UINT method_index, VALUE method_name)
514 {
515 TYPEATTR *pTypeAttr;
516 HRESULT hr;
517 WORD i;
518 int flags;
519 HREFTYPE href;
520 ITypeInfo *pRefTypeInfo;
521 FUNCDESC *pFuncDesc;
522 BSTR bstr;
523 VALUE name;
524 VALUE event = Qfalse;
525
526 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
527 if (FAILED(hr))
528 return event;
529 if(pTypeAttr->typekind != TKIND_COCLASS) {
530 pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr);
531 return event;
532 }
533 for (i = 0; i < pTypeAttr->cImplTypes; i++) {
534 hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags);
535 if (FAILED(hr))
536 continue;
537
538 if (flags & IMPLTYPEFLAG_FSOURCE) {
539 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,
540 i, &href);
541 if (FAILED(hr))
542 continue;
543 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
544 href, &pRefTypeInfo);
545 if (FAILED(hr))
546 continue;
547 hr = pRefTypeInfo->lpVtbl->GetFuncDesc(pRefTypeInfo, method_index,
548 &pFuncDesc);
549 if (FAILED(hr)) {
550 OLE_RELEASE(pRefTypeInfo);
551 continue;
552 }
553
554 hr = pRefTypeInfo->lpVtbl->GetDocumentation(pRefTypeInfo,
555 pFuncDesc->memid,
556 &bstr, NULL, NULL, NULL);
557 if (FAILED(hr)) {
558 pRefTypeInfo->lpVtbl->ReleaseFuncDesc(pRefTypeInfo, pFuncDesc);
559 OLE_RELEASE(pRefTypeInfo);
560 continue;
561 }
562
563 name = WC2VSTR(bstr);
564 pRefTypeInfo->lpVtbl->ReleaseFuncDesc(pRefTypeInfo, pFuncDesc);
565 OLE_RELEASE(pRefTypeInfo);
566 if (rb_str_cmp(method_name, name) == 0) {
567 event = Qtrue;
568 break;
569 }
570 }
571 }
572 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
573 return event;
574 }
575
576 /*
577 * call-seq:
578 * WIN32OLE_METHOD#event?
579 *
580 * Returns true if the method is event.
581 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
582 * method = WIN32OLE_METHOD.new(tobj, 'SheetActivate')
583 * puts method.event? # => true
584 *
585 */
586 static VALUE
587 folemethod_event(VALUE self)
588 {
589 struct olemethoddata *pmethod;
590 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
591 if (!pmethod->pOwnerTypeInfo)
592 return Qfalse;
593 return ole_method_event(pmethod->pOwnerTypeInfo,
594 pmethod->index,
595 rb_ivar_get(self, rb_intern("name")));
596 }
597
598 /*
599 * call-seq:
600 * WIN32OLE_METHOD#event_interface
601 *
602 * Returns event interface name if the method is event.
603 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
604 * method = WIN32OLE_METHOD.new(tobj, 'SheetActivate')
605 * puts method.event_interface # => WorkbookEvents
606 */
607 static VALUE
608 folemethod_event_interface(VALUE self)
609 {
610 BSTR name;
611 struct olemethoddata *pmethod;
612 HRESULT hr;
613 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
614 if(folemethod_event(self) == Qtrue) {
615 hr = ole_docinfo_from_type(pmethod->pTypeInfo, &name, NULL, NULL, NULL);
616 if(SUCCEEDED(hr))
617 return WC2VSTR(name);
618 }
619 return Qnil;
620 }
621
622 static HRESULT
623 ole_method_docinfo_from_type(
624 ITypeInfo *pTypeInfo,
625 UINT method_index,
626 BSTR *name,
627 BSTR *helpstr,
628 DWORD *helpcontext,
629 BSTR *helpfile
630 )
631 {
632 FUNCDESC *pFuncDesc;
633 HRESULT hr;
634 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
635 if (FAILED(hr))
636 return hr;
637 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
638 name, helpstr,
639 helpcontext, helpfile);
640 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
641 return hr;
642 }
643
644 static VALUE
645 ole_method_helpstring(ITypeInfo *pTypeInfo, UINT method_index)
646 {
647 HRESULT hr;
648 BSTR bhelpstring;
649 hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, &bhelpstring,
650 NULL, NULL);
651 if (FAILED(hr))
652 return Qnil;
653 return WC2VSTR(bhelpstring);
654 }
655
656 /*
657 * call-seq:
658 * WIN32OLE_METHOD#helpstring
659 *
660 * Returns help string of OLE method. If the help string is not found,
661 * then the method returns nil.
662 * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'IWebBrowser')
663 * method = WIN32OLE_METHOD.new(tobj, 'Navigate')
664 * puts method.helpstring # => Navigates to a URL or file.
665 *
666 */
667 static VALUE
668 folemethod_helpstring(VALUE self)
669 {
670 struct olemethoddata *pmethod;
671 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
672 return ole_method_helpstring(pmethod->pTypeInfo, pmethod->index);
673 }
674
675 static VALUE
676 ole_method_helpfile(ITypeInfo *pTypeInfo, UINT method_index)
677 {
678 HRESULT hr;
679 BSTR bhelpfile;
680 hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, NULL,
681 NULL, &bhelpfile);
682 if (FAILED(hr))
683 return Qnil;
684 return WC2VSTR(bhelpfile);
685 }
686
687 /*
688 * call-seq:
689 * WIN32OLE_METHOD#helpfile
690 *
691 * Returns help file. If help file is not found, then
692 * the method returns nil.
693 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
694 * method = WIN32OLE_METHOD.new(tobj, 'Add')
695 * puts method.helpfile # => C:\...\VBAXL9.CHM
696 */
697 static VALUE
698 folemethod_helpfile(VALUE self)
699 {
700 struct olemethoddata *pmethod;
701 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
702
703 return ole_method_helpfile(pmethod->pTypeInfo, pmethod->index);
704 }
705
706 static VALUE
707 ole_method_helpcontext(ITypeInfo *pTypeInfo, UINT method_index)
708 {
709 HRESULT hr;
710 DWORD helpcontext = 0;
711 hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, NULL,
712 &helpcontext, NULL);
713 if (FAILED(hr))
714 return Qnil;
715 return RB_INT2FIX(helpcontext);
716 }
717
718 /*
719 * call-seq:
720 * WIN32OLE_METHOD#helpcontext
721 *
722 * Returns help context.
723 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
724 * method = WIN32OLE_METHOD.new(tobj, 'Add')
725 * puts method.helpcontext # => 65717
726 */
727 static VALUE
728 folemethod_helpcontext(VALUE self)
729 {
730 struct olemethoddata *pmethod;
731 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
732 return ole_method_helpcontext(pmethod->pTypeInfo, pmethod->index);
733 }
734
735 static VALUE
736 ole_method_dispid(ITypeInfo *pTypeInfo, UINT method_index)
737 {
738 FUNCDESC *pFuncDesc;
739 HRESULT hr;
740 VALUE dispid = Qnil;
741 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
742 if (FAILED(hr))
743 return dispid;
744 dispid = RB_INT2NUM(pFuncDesc->memid);
745 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
746 return dispid;
747 }
748
749 /*
750 * call-seq:
751 * WIN32OLE_METHOD#dispid
752 *
753 * Returns dispatch ID.
754 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
755 * method = WIN32OLE_METHOD.new(tobj, 'Add')
756 * puts method.dispid # => 181
757 */
758 static VALUE
759 folemethod_dispid(VALUE self)
760 {
761 struct olemethoddata *pmethod;
762 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
763 return ole_method_dispid(pmethod->pTypeInfo, pmethod->index);
764 }
765
766 static VALUE
767 ole_method_offset_vtbl(ITypeInfo *pTypeInfo, UINT method_index)
768 {
769 FUNCDESC *pFuncDesc;
770 HRESULT hr;
771 VALUE offset_vtbl = Qnil;
772 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
773 if (FAILED(hr))
774 return offset_vtbl;
775 offset_vtbl = RB_INT2FIX(pFuncDesc->oVft);
776 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
777 return offset_vtbl;
778 }
779
780 /*
781 * call-seq:
782 * WIN32OLE_METHOD#offset_vtbl
783 *
784 * Returns the offset ov VTBL.
785 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
786 * method = WIN32OLE_METHOD.new(tobj, 'Add')
787 * puts method.offset_vtbl # => 40
788 */
789 static VALUE
790 folemethod_offset_vtbl(VALUE self)
791 {
792 struct olemethoddata *pmethod;
793 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
794 return ole_method_offset_vtbl(pmethod->pTypeInfo, pmethod->index);
795 }
796
797 static VALUE
798 ole_method_size_params(ITypeInfo *pTypeInfo, UINT method_index)
799 {
800 FUNCDESC *pFuncDesc;
801 HRESULT hr;
802 VALUE size_params = Qnil;
803 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
804 if (FAILED(hr))
805 return size_params;
806 size_params = RB_INT2FIX(pFuncDesc->cParams);
807 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
808 return size_params;
809 }
810
811 /*
812 * call-seq:
813 * WIN32OLE_METHOD#size_params
814 *
815 * Returns the size of arguments of the method.
816 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
817 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
818 * puts method.size_params # => 11
819 *
820 */
821 static VALUE
822 folemethod_size_params(VALUE self)
823 {
824 struct olemethoddata *pmethod;
825 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
826 return ole_method_size_params(pmethod->pTypeInfo, pmethod->index);
827 }
828
829 static VALUE
830 ole_method_size_opt_params(ITypeInfo *pTypeInfo, UINT method_index)
831 {
832 FUNCDESC *pFuncDesc;
833 HRESULT hr;
834 VALUE size_opt_params = Qnil;
835 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
836 if (FAILED(hr))
837 return size_opt_params;
838 size_opt_params = RB_INT2FIX(pFuncDesc->cParamsOpt);
839 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
840 return size_opt_params;
841 }
842
843 /*
844 * call-seq:
845 * WIN32OLE_METHOD#size_opt_params
846 *
847 * Returns the size of optional parameters.
848 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
849 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
850 * puts method.size_opt_params # => 4
851 */
852 static VALUE
853 folemethod_size_opt_params(VALUE self)
854 {
855 struct olemethoddata *pmethod;
856 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
857 return ole_method_size_opt_params(pmethod->pTypeInfo, pmethod->index);
858 }
859
860 static VALUE
861 ole_method_params(ITypeInfo *pTypeInfo, UINT method_index)
862 {
863 FUNCDESC *pFuncDesc;
864 HRESULT hr;
865 BSTR *bstrs;
866 UINT len, i;
867 VALUE param;
868 VALUE params = rb_ary_new();
869 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
870 if (FAILED(hr))
871 return params;
872
873 len = 0;
874 bstrs = ALLOCA_N(BSTR, pFuncDesc->cParams + 1);
875 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pFuncDesc->memid,
876 bstrs, pFuncDesc->cParams + 1,
877 &len);
878 if (FAILED(hr)) {
879 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
880 return params;
881 }
882 SysFreeString(bstrs[0]);
883 if (pFuncDesc->cParams > 0) {
884 for(i = 1; i < len; i++) {
885 param = create_win32ole_param(pTypeInfo, method_index, i-1, WC2VSTR(bstrs[i]));
886 rb_ary_push(params, param);
887 }
888 }
889 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
890 return params;
891 }
892
893 /*
894 * call-seq:
895 * WIN32OLE_METHOD#params
896 *
897 * returns array of WIN32OLE_PARAM object corresponding with method parameters.
898 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
899 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
900 * p method.params # => [Filename, FileFormat, Password, WriteResPassword,
901 * ReadOnlyRecommended, CreateBackup, AccessMode,
902 * ConflictResolution, AddToMru, TextCodepage,
903 * TextVisualLayout]
904 */
905 static VALUE
906 folemethod_params(VALUE self)
907 {
908 struct olemethoddata *pmethod;
909 TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
910 return ole_method_params(pmethod->pTypeInfo, pmethod->index);
911 }
912
913 /*
914 * call-seq:
915 * WIN32OLE_METHOD#inspect -> String
916 *
917 * Returns the method name with class name.
918 *
919 */
920 static VALUE
921 folemethod_inspect(VALUE self)
922 {
923 return default_inspect(self, "WIN32OLE_METHOD");
924 }
925
926 void Init_win32ole_method(void)
927 {
928 cWIN32OLE_METHOD = rb_define_class("WIN32OLE_METHOD", rb_cObject);
929 rb_define_alloc_func(cWIN32OLE_METHOD, folemethod_s_allocate);
930 rb_define_method(cWIN32OLE_METHOD, "initialize", folemethod_initialize, 2);
931 rb_define_method(cWIN32OLE_METHOD, "name", folemethod_name, 0);
932 rb_define_method(cWIN32OLE_METHOD, "return_type", folemethod_return_type, 0);
933 rb_define_method(cWIN32OLE_METHOD, "return_vtype", folemethod_return_vtype, 0);
934 rb_define_method(cWIN32OLE_METHOD, "return_type_detail", folemethod_return_type_detail, 0);
935 rb_define_method(cWIN32OLE_METHOD, "invoke_kind", folemethod_invoke_kind, 0);
936 rb_define_method(cWIN32OLE_METHOD, "invkind", folemethod_invkind, 0);
937 rb_define_method(cWIN32OLE_METHOD, "visible?", folemethod_visible, 0);
938 rb_define_method(cWIN32OLE_METHOD, "event?", folemethod_event, 0);
939 rb_define_method(cWIN32OLE_METHOD, "event_interface", folemethod_event_interface, 0);
940 rb_define_method(cWIN32OLE_METHOD, "helpstring", folemethod_helpstring, 0);
941 rb_define_method(cWIN32OLE_METHOD, "helpfile", folemethod_helpfile, 0);
942 rb_define_method(cWIN32OLE_METHOD, "helpcontext", folemethod_helpcontext, 0);
943 rb_define_method(cWIN32OLE_METHOD, "dispid", folemethod_dispid, 0);
944 rb_define_method(cWIN32OLE_METHOD, "offset_vtbl", folemethod_offset_vtbl, 0);
945 rb_define_method(cWIN32OLE_METHOD, "size_params", folemethod_size_params, 0);
946 rb_define_method(cWIN32OLE_METHOD, "size_opt_params", folemethod_size_opt_params, 0);
947 rb_define_method(cWIN32OLE_METHOD, "params", folemethod_params, 0);
948 rb_define_alias(cWIN32OLE_METHOD, "to_s", "name");
949 rb_define_method(cWIN32OLE_METHOD, "inspect", folemethod_inspect, 0);
950 }
itypeinfo
ITypeInfo * itypeinfo(VALUE self)
Definition: win32ole_type.c:76
olemethoddata::pOwnerTypeInfo
ITypeInfo * pOwnerTypeInfo
Definition: win32ole_method.h:5
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
eWIN32OLEQueryInterfaceError
VALUE eWIN32OLEQueryInterfaceError
Definition: win32ole_error.h:5
olemethoddata::index
UINT index
Definition: win32ole_method.h:7
OLE_RELEASE_TYPEATTR
#define OLE_RELEASE_TYPEATTR(X, Y)
Definition: win32ole.h:109
create_win32ole_param
VALUE create_win32ole_param(ITypeInfo *pTypeInfo, UINT method_index, UINT index, VALUE name)
Definition: win32ole_param.c:52
VALUE
unsigned long VALUE
Definition: ruby.h:102
index
int index
Definition: rb_mjit_min_header-2.7.0.h:11246
rb_intern
#define rb_intern(str)
DWORD
IUnknown DWORD
Definition: win32ole.c:33
WC2VSTR
#define WC2VSTR(x)
Definition: win32ole.h:130
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
OLE_RELEASE
#define OLE_RELEASE(X)
Definition: win32ole.h:98
NULL
#define NULL
Definition: _sdbm.c:101
SafeStringValue
#define SafeStringValue(v)
Definition: ruby.h:607
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
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2669
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
ole_methods_from_typeinfo
VALUE ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask)
Definition: win32ole_method.c:112
create_win32ole_method
VALUE create_win32ole_method(ITypeInfo *pTypeInfo, VALUE name)
Definition: win32ole_method.c:210
RB_INT2NUM
#define RB_INT2NUM(x)
Definition: ruby.h:1597
i
uint32_t i
Definition: rb_mjit_min_header-2.7.0.h:5464
mask
enum @11::@13::@14 mask
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1195
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:922
ALLOCA_N
#define ALLOCA_N(type, n)
Definition: ruby.h:1684
StringValuePtr
#define StringValuePtr(v)
Definition: ruby.h:603
default_inspect
VALUE default_inspect(VALUE self, const char *class_name)
Definition: win32ole.c:1345
RB_FIX2INT
#define RB_FIX2INT(x)
Definition: ruby.h:712
olemethoddata::pTypeInfo
ITypeInfo * pTypeInfo
Definition: win32ole_method.h:6
cWIN32OLE_METHOD
VALUE cWIN32OLE_METHOD
Definition: win32ole_method.h:10
OLE_FREE
#define OLE_FREE(x)
Definition: win32ole.h:99
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:2010
TypedData_Get_Struct
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: ruby.h:1252
olemethoddata
Definition: win32ole_method.h:4
RB_INT2FIX
#define RB_INT2FIX(i)
Definition: ruby.h:262
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.0.h:13254
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
folemethod_s_allocate
VALUE folemethod_s_allocate(VALUE klass)
Definition: win32ole_method.c:239
ole_docinfo_from_type
HRESULT ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile)
Definition: win32ole.c:3647
free
#define free(x)
Definition: dln.c:52
rb_data_type_struct
Definition: ruby.h:1148
Qtrue
#define Qtrue
Definition: ruby.h:468
strcasecmp
int strcasecmp(const char *, const char *) __attribute__((__pure__))
len
uint8_t len
Definition: escape.c:17
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
Init_win32ole_method
void Init_win32ole_method(void)
Definition: win32ole_method.c:926
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:723
Qnil
#define Qnil
Definition: ruby.h:469
cWIN32OLE_TYPE
VALUE cWIN32OLE_TYPE
Definition: win32ole_type.h:3
OLE_GET_TYPEATTR
#define OLE_GET_TYPEATTR(X, Y)
Definition: win32ole.h:108
olemethod_data_get_struct
struct olemethoddata * olemethod_data_get_struct(VALUE obj)
Definition: win32ole_method.c:67
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
Definition: object.c:692
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
rb_str_cmp
int rb_str_cmp(VALUE, VALUE)
Definition: string.c:3228
name
const char * name
Definition: nkf.c:208