Ruby: ext/win32ole/win32ole_method.c Source File

Ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c52d4d35cc6a173c89eda98ceffa2dcf)

win32ole_method.c
Go to the documentation of this file.
1#include "win32ole.h"
2
3static void olemethod_free(void *ptr);
4static size_t olemethod_size(const void *ptr);
5static VALUE ole_method_sub(VALUE self, ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE name);
6static VALUE olemethod_from_typeinfo(VALUE self, ITypeInfo *pTypeInfo, VALUE name);
7static VALUE ole_methods_sub(ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE methods, int mask);
8static VALUE olemethod_set_member(VALUE self, ITypeInfo *pTypeInfo, ITypeInfo *pOwnerTypeInfo, int index, VALUE name);
9static VALUE folemethod_initialize(VALUE self, VALUE oletype, VALUE method);
10static VALUE folemethod_name(VALUE self);
11static VALUE ole_method_return_type(ITypeInfo *pTypeInfo, UINT method_index);
12static VALUE folemethod_return_type(VALUE self);
13static VALUE ole_method_return_vtype(ITypeInfo *pTypeInfo, UINT method_index);
14static VALUE folemethod_return_vtype(VALUE self);
15static VALUE ole_method_return_type_detail(ITypeInfo *pTypeInfo, UINT method_index);
16static VALUE folemethod_return_type_detail(VALUE self);
17static VALUE ole_method_invkind(ITypeInfo *pTypeInfo, UINT method_index);
18static VALUE ole_method_invoke_kind(ITypeInfo *pTypeInfo, UINT method_index);
19static VALUE folemethod_invkind(VALUE self);
20static VALUE folemethod_invoke_kind(VALUE self);
21static VALUE ole_method_visible(ITypeInfo *pTypeInfo, UINT method_index);
22static VALUE folemethod_visible(VALUE self);
23static VALUE ole_method_event(ITypeInfo *pTypeInfo, UINT method_index, VALUE method_name);
24static VALUE folemethod_event(VALUE self);
25static VALUE folemethod_event_interface(VALUE self);
26static HRESULT ole_method_docinfo_from_type(ITypeInfo *pTypeInfo, UINT method_index, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile);
27static VALUE ole_method_helpstring(ITypeInfo *pTypeInfo, UINT method_index);
28static VALUE folemethod_helpstring(VALUE self);
29static VALUE ole_method_helpfile(ITypeInfo *pTypeInfo, UINT method_index);
30static VALUE folemethod_helpfile(VALUE self);
31static VALUE ole_method_helpcontext(ITypeInfo *pTypeInfo, UINT method_index);
32static VALUE folemethod_helpcontext(VALUE self);
33static VALUE ole_method_dispid(ITypeInfo *pTypeInfo, UINT method_index);
34static VALUE folemethod_dispid(VALUE self);
35static VALUE ole_method_offset_vtbl(ITypeInfo *pTypeInfo, UINT method_index);
36static VALUE folemethod_offset_vtbl(VALUE self);
37static VALUE ole_method_size_params(ITypeInfo *pTypeInfo, UINT method_index);
38static VALUE folemethod_size_params(VALUE self);
39static VALUE ole_method_size_opt_params(ITypeInfo *pTypeInfo, UINT method_index);
40static VALUE folemethod_size_opt_params(VALUE self);
41static VALUE ole_method_params(ITypeInfo *pTypeInfo, UINT method_index);
42static VALUE folemethod_params(VALUE self);
43static VALUE folemethod_inspect(VALUE self);
44
45static 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
51static void
52olemethod_free(void *ptr)
53{
54 struct olemethoddata *polemethod = ptr;
55 OLE_FREE(polemethod->pTypeInfo);
56 OLE_FREE(polemethod->pOwnerTypeInfo);
57 free(polemethod);
58}
59
60static size_t
61olemethod_size(const void *ptr)
62{
63 return ptr ? sizeof(struct olemethoddata) : 0;
64}
65
66struct olemethoddata *
67olemethod_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
74static VALUE
75ole_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
112ole_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
140static VALUE
141olemethod_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
171static VALUE
172ole_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
210create_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
224static VALUE
225olemethod_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
239folemethod_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 */
265static VALUE
266folemethod_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 */
296static VALUE
297folemethod_name(VALUE self)
298{
299 return rb_ivar_get(self, rb_intern("name"));
300}
301
302static VALUE
303ole_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 */
328static VALUE
329folemethod_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
336static VALUE
337ole_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 */
362static VALUE
363folemethod_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
370static VALUE
371ole_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 */
396static VALUE
397folemethod_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
404static VALUE
405ole_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
418static VALUE
419ole_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 */
448static VALUE
449folemethod_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 */
467static VALUE
468folemethod_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
475static VALUE
476ole_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 */
504static VALUE
505folemethod_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
512static VALUE
513ole_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 */
586static VALUE
587folemethod_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 */
607static VALUE
608folemethod_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
622static HRESULT
623ole_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
644static VALUE
645ole_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 */
667static VALUE
668folemethod_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
675static VALUE
676ole_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 */
697static VALUE
698folemethod_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
706static VALUE
707ole_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 */
727static VALUE
728folemethod_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
735static VALUE
736ole_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 */
758static VALUE
759folemethod_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
766static VALUE
767ole_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 */
789static VALUE
790folemethod_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
797static VALUE
798ole_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 */
821static VALUE
822folemethod_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
829static VALUE
830ole_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 */
852static VALUE
853folemethod_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
860static VALUE
861ole_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 */
905static VALUE
906folemethod_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 */
920static VALUE
921folemethod_inspect(VALUE self)
922{
923 return default_inspect(self, "WIN32OLE_METHOD");
924}
925
926 VALUE cWIN32OLE_METHOD;
927
928 void Init_win32ole_method(void)
929{
930 cWIN32OLE_METHOD = rb_define_class("WIN32OLE_METHOD", rb_cObject);
931 rb_define_alloc_func(cWIN32OLE_METHOD, folemethod_s_allocate);
932 rb_define_method(cWIN32OLE_METHOD, "initialize", folemethod_initialize, 2);
933 rb_define_method(cWIN32OLE_METHOD, "name", folemethod_name, 0);
934 rb_define_method(cWIN32OLE_METHOD, "return_type", folemethod_return_type, 0);
935 rb_define_method(cWIN32OLE_METHOD, "return_vtype", folemethod_return_vtype, 0);
936 rb_define_method(cWIN32OLE_METHOD, "return_type_detail", folemethod_return_type_detail, 0);
937 rb_define_method(cWIN32OLE_METHOD, "invoke_kind", folemethod_invoke_kind, 0);
938 rb_define_method(cWIN32OLE_METHOD, "invkind", folemethod_invkind, 0);
939 rb_define_method(cWIN32OLE_METHOD, "visible?", folemethod_visible, 0);
940 rb_define_method(cWIN32OLE_METHOD, "event?", folemethod_event, 0);
941 rb_define_method(cWIN32OLE_METHOD, "event_interface", folemethod_event_interface, 0);
942 rb_define_method(cWIN32OLE_METHOD, "helpstring", folemethod_helpstring, 0);
943 rb_define_method(cWIN32OLE_METHOD, "helpfile", folemethod_helpfile, 0);
944 rb_define_method(cWIN32OLE_METHOD, "helpcontext", folemethod_helpcontext, 0);
945 rb_define_method(cWIN32OLE_METHOD, "dispid", folemethod_dispid, 0);
946 rb_define_method(cWIN32OLE_METHOD, "offset_vtbl", folemethod_offset_vtbl, 0);
947 rb_define_method(cWIN32OLE_METHOD, "size_params", folemethod_size_params, 0);
948 rb_define_method(cWIN32OLE_METHOD, "size_opt_params", folemethod_size_opt_params, 0);
949 rb_define_method(cWIN32OLE_METHOD, "params", folemethod_params, 0);
950 rb_define_alias(cWIN32OLE_METHOD, "to_s", "name");
951 rb_define_method(cWIN32OLE_METHOD, "inspect", folemethod_inspect, 0);
952}
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1301
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:749
rb_define_method
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
Definition: cxxanyargs.hpp:653
mask
enum @11::@13::@14 mask
ptr
struct RIMemo * ptr
Definition: debug.c:88
free
#define free(x)
Definition: dln.c:52
len
uint8_t len
Definition: escape.c:17
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:748
rb_define_alias
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1999
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2917
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:1057
rb_cObject
VALUE rb_cObject
Object class.
Definition: object.c:49
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
Definition: object.c:724
rb_str_new2
#define rb_str_new2
Definition: string.h:276
rb_str_cmp
int rb_str_cmp(VALUE, VALUE)
Definition: string.c:3378
rb_ivar_get
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1234
rb_ivar_set
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1493
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
rb_intern
ID rb_intern(const char *)
Definition: symbol.c:785
RB_INT2NUM
#define RB_INT2NUM
Definition: int.h:37
ALLOCA_N
#define ALLOCA_N(type, n)
Definition: memory.h:112
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:56
name
const char * name
Definition: nkf.c:208
NULL
#define NULL
Definition: regenc.h:69
SafeStringValue
#define SafeStringValue(v)
Definition: rstring.h:53
StringValuePtr
#define StringValuePtr(v)
Definition: rstring.h:51
TypedData_Get_Struct
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: rtypeddata.h:130
RUBY_TYPED_FREE_IMMEDIATELY
@ RUBY_TYPED_FREE_IMMEDIATELY
Definition: rtypeddata.h:62
TypedData_Make_Struct
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: rtypeddata.h:122
Qtrue
#define Qtrue
Definition: special_consts.h:52
Qnil
#define Qnil
Definition: special_consts.h:51
Qfalse
#define Qfalse
Definition: special_consts.h:50
olemethoddata
Definition: win32ole_method.h:4
olemethoddata::index
UINT index
Definition: win32ole_method.h:7
olemethoddata::pTypeInfo
ITypeInfo * pTypeInfo
Definition: win32ole_method.h:6
olemethoddata::pOwnerTypeInfo
ITypeInfo * pOwnerTypeInfo
Definition: win32ole_method.h:5
rb_data_type_struct
Definition: rtypeddata.h:70
VALUE
unsigned long VALUE
Definition: value.h:38
strcasecmp
#define strcasecmp
Definition: win32.h:207
ole_docinfo_from_type
HRESULT ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile)
Definition: win32ole.c:3648
ole_typedesc2val
VALUE ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
Definition: win32ole.c:3709
HRESULT
typedef HRESULT(STDAPICALLTYPE FNCOCREATEINSTANCEEX)(REFCLSID
default_inspect
VALUE default_inspect(VALUE self, const char *class_name)
Definition: win32ole.c:1346
DWORD
IUnknown DWORD
Definition: win32ole.c:33
win32ole.h
OLE_RELEASE
#define OLE_RELEASE(X)
Definition: win32ole.h:98
OLE_FREE
#define OLE_FREE(x)
Definition: win32ole.h:99
OLE_ADDREF
#define OLE_ADDREF(X)
Definition: win32ole.h:97
OLE_RELEASE_TYPEATTR
#define OLE_RELEASE_TYPEATTR(X, Y)
Definition: win32ole.h:109
WC2VSTR
#define WC2VSTR(x)
Definition: win32ole.h:130
OLE_GET_TYPEATTR
#define OLE_GET_TYPEATTR(X, Y)
Definition: win32ole.h:108
eWIN32OLERuntimeError
VALUE eWIN32OLERuntimeError
Definition: win32ole_error.c:63
eWIN32OLEQueryInterfaceError
VALUE eWIN32OLEQueryInterfaceError
Definition: win32ole_error.c:64
ole_raise
void ole_raise(HRESULT hr, VALUE ecs, const char *fmt,...)
Definition: win32ole_error.c:46
folemethod_s_allocate
VALUE folemethod_s_allocate(VALUE klass)
Definition: win32ole_method.c:239
cWIN32OLE_METHOD
VALUE cWIN32OLE_METHOD
Definition: win32ole_method.c:926
ole_methods_from_typeinfo
VALUE ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask)
Definition: win32ole_method.c:112
olemethod_data_get_struct
struct olemethoddata * olemethod_data_get_struct(VALUE obj)
Definition: win32ole_method.c:67
create_win32ole_method
VALUE create_win32ole_method(ITypeInfo *pTypeInfo, VALUE name)
Definition: win32ole_method.c:210
Init_win32ole_method
void Init_win32ole_method(void)
Definition: win32ole_method.c:928
create_win32ole_param
VALUE create_win32ole_param(ITypeInfo *pTypeInfo, UINT method_index, UINT index, VALUE name)
Definition: win32ole_param.c:52
cWIN32OLE_TYPE
VALUE cWIN32OLE_TYPE
Definition: win32ole_type.c:886
itypeinfo
ITypeInfo * itypeinfo(VALUE self)
Definition: win32ole_type.c:76