Ruby  2.5.0dev(2017-10-22revision60238)
win32ole_type.c
Go to the documentation of this file.
1 #include "win32ole.h"
2 
3 struct oletypedata {
4  ITypeInfo *pTypeInfo;
5 };
6 
7 static void oletype_free(void *ptr);
8 static size_t oletype_size(const void *ptr);
9 static VALUE foletype_s_ole_classes(VALUE self, VALUE typelib);
10 static VALUE foletype_s_typelibs(VALUE self);
11 static VALUE foletype_s_progids(VALUE self);
12 static VALUE oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name);
13 static VALUE foletype_s_allocate(VALUE klass);
14 static VALUE oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass);
15 static VALUE foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass);
16 static VALUE foletype_name(VALUE self);
17 static VALUE ole_ole_type(ITypeInfo *pTypeInfo);
18 static VALUE foletype_ole_type(VALUE self);
19 static VALUE ole_type_guid(ITypeInfo *pTypeInfo);
20 static VALUE foletype_guid(VALUE self);
21 static VALUE ole_type_progid(ITypeInfo *pTypeInfo);
22 static VALUE foletype_progid(VALUE self);
23 static VALUE ole_type_visible(ITypeInfo *pTypeInfo);
24 static VALUE foletype_visible(VALUE self);
25 static VALUE ole_type_major_version(ITypeInfo *pTypeInfo);
26 static VALUE foletype_major_version(VALUE self);
27 static VALUE ole_type_minor_version(ITypeInfo *pTypeInfo);
28 static VALUE foletype_minor_version(VALUE self);
29 static VALUE ole_type_typekind(ITypeInfo *pTypeInfo);
30 static VALUE foletype_typekind(VALUE self);
31 static VALUE ole_type_helpstring(ITypeInfo *pTypeInfo);
32 static VALUE foletype_helpstring(VALUE self);
33 static VALUE ole_type_src_type(ITypeInfo *pTypeInfo);
34 static VALUE foletype_src_type(VALUE self);
35 static VALUE ole_type_helpfile(ITypeInfo *pTypeInfo);
36 static VALUE foletype_helpfile(VALUE self);
37 static VALUE ole_type_helpcontext(ITypeInfo *pTypeInfo);
38 static VALUE foletype_helpcontext(VALUE self);
39 static VALUE ole_variables(ITypeInfo *pTypeInfo);
40 static VALUE foletype_variables(VALUE self);
41 static VALUE foletype_methods(VALUE self);
42 static VALUE foletype_ole_typelib(VALUE self);
43 static VALUE ole_type_impl_ole_types(ITypeInfo *pTypeInfo, int implflags);
44 static VALUE foletype_impl_ole_types(VALUE self);
45 static VALUE foletype_source_ole_types(VALUE self);
46 static VALUE foletype_default_event_sources(VALUE self);
47 static VALUE foletype_default_ole_types(VALUE self);
48 static VALUE foletype_inspect(VALUE self);
49 
50 static const rb_data_type_t oletype_datatype = {
51  "win32ole_type",
52  {NULL, oletype_free, oletype_size,},
54 };
55 
56 /*
57  * Document-class: WIN32OLE_TYPE
58  *
59  * <code>WIN32OLE_TYPE</code> objects represent OLE type libarary information.
60  */
61 
62 static void
63 oletype_free(void *ptr)
64 {
65  struct oletypedata *poletype = ptr;
66  OLE_FREE(poletype->pTypeInfo);
67  free(poletype);
68 }
69 
70 static size_t
71 oletype_size(const void *ptr)
72 {
73  return ptr ? sizeof(struct oletypedata) : 0;
74 }
75 
76 ITypeInfo *itypeinfo(VALUE self)
77 {
78  struct oletypedata *ptype;
79  TypedData_Get_Struct(self, struct oletypedata, &oletype_datatype, ptype);
80  return ptype->pTypeInfo;
81 }
82 
83 VALUE
85 {
86  ITypeLib *pTypeLib;
87  VALUE type = Qnil;
88  HRESULT hr;
89  unsigned int index;
90  BSTR bstr;
91 
92  hr = pTypeInfo->lpVtbl->GetContainingTypeLib( pTypeInfo, &pTypeLib, &index );
93  if(FAILED(hr)) {
94  return Qnil;
95  }
96  hr = pTypeLib->lpVtbl->GetDocumentation( pTypeLib, index,
97  &bstr, NULL, NULL, NULL);
98  OLE_RELEASE(pTypeLib);
99  if (FAILED(hr)) {
100  return Qnil;
101  }
102  type = create_win32ole_type(pTypeInfo, WC2VSTR(bstr));
103  return type;
104 }
105 
106 
107 /*
108  * call-seq:
109  * WIN32OLE_TYPE.ole_classes(typelib)
110  *
111  * Returns array of WIN32OLE_TYPE objects defined by the <i>typelib</i> type library.
112  * This method will be OBSOLETE. Use WIN32OLE_TYPELIB.new(typelib).ole_classes instead.
113  */
114 static VALUE
115 foletype_s_ole_classes(VALUE self, VALUE typelib)
116 {
117  VALUE obj;
118 
119  /*
120  rb_warn("%s is obsolete; use %s instead.",
121  "WIN32OLE_TYPE.ole_classes",
122  "WIN32OLE_TYPELIB.new(typelib).ole_types");
123  */
124  obj = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("new"), 1, typelib);
125  return rb_funcall(obj, rb_intern("ole_types"), 0);
126 }
127 
128 /*
129  * call-seq:
130  * WIN32OLE_TYPE.typelibs
131  *
132  * Returns array of type libraries.
133  * This method will be OBSOLETE. Use WIN32OLE_TYPELIB.typelibs.collect{|t| t.name} instead.
134  *
135  */
136 static VALUE
137 foletype_s_typelibs(VALUE self)
138 {
139  /*
140  rb_warn("%s is obsolete. use %s instead.",
141  "WIN32OLE_TYPE.typelibs",
142  "WIN32OLE_TYPELIB.typelibs.collect{t|t.name}");
143  */
144  return rb_eval_string("WIN32OLE_TYPELIB.typelibs.collect{|t|t.name}");
145 }
146 
147 /*
148  * call-seq:
149  * WIN32OLE_TYPE.progids
150  *
151  * Returns array of ProgID.
152  */
153 static VALUE
154 foletype_s_progids(VALUE self)
155 {
156  HKEY hclsids, hclsid;
157  DWORD i;
158  LONG err;
159  VALUE clsid;
160  VALUE v = rb_str_new2("");
161  VALUE progids = rb_ary_new();
162 
163  err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hclsids);
164  if(err != ERROR_SUCCESS) {
165  return progids;
166  }
167  for(i = 0; ; i++) {
168  clsid = reg_enum_key(hclsids, i);
169  if (clsid == Qnil)
170  break;
171  err = reg_open_vkey(hclsids, clsid, &hclsid);
172  if (err != ERROR_SUCCESS)
173  continue;
174  if ((v = reg_get_val2(hclsid, "ProgID")) != Qnil)
175  rb_ary_push(progids, v);
176  if ((v = reg_get_val2(hclsid, "VersionIndependentProgID")) != Qnil)
177  rb_ary_push(progids, v);
178  RegCloseKey(hclsid);
179  }
180  RegCloseKey(hclsids);
181  return progids;
182 }
183 
184 static VALUE
185 oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name)
186 {
187  struct oletypedata *ptype;
188  TypedData_Get_Struct(self, struct oletypedata, &oletype_datatype, ptype);
189  rb_ivar_set(self, rb_intern("name"), name);
190  ptype->pTypeInfo = pTypeInfo;
191  OLE_ADDREF(pTypeInfo);
192  return self;
193 }
194 
195 static VALUE
196 foletype_s_allocate(VALUE klass)
197 {
198  struct oletypedata *poletype;
199  VALUE obj;
200  ole_initialize();
201  obj = TypedData_Make_Struct(klass,struct oletypedata, &oletype_datatype, poletype);
202  poletype->pTypeInfo = NULL;
203  return obj;
204 }
205 
206 VALUE
207 create_win32ole_type(ITypeInfo *pTypeInfo, VALUE name)
208 {
209  VALUE obj = foletype_s_allocate(cWIN32OLE_TYPE);
210  oletype_set_member(obj, pTypeInfo, name);
211  return obj;
212 }
213 
214 static VALUE
215 oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass)
216 {
217 
218  long count;
219  int i;
220  HRESULT hr;
221  BSTR bstr;
222  VALUE typelib;
223  ITypeInfo *pTypeInfo;
224 
225  VALUE found = Qfalse;
226 
227  count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
228  for (i = 0; i < count && found == Qfalse; i++) {
229  hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
230  if (FAILED(hr))
231  continue;
232  hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
233  &bstr, NULL, NULL, NULL);
234  if (FAILED(hr))
235  continue;
236  typelib = WC2VSTR(bstr);
237  if (rb_str_cmp(oleclass, typelib) == 0) {
238  oletype_set_member(self, pTypeInfo, typelib);
239  found = Qtrue;
240  }
241  OLE_RELEASE(pTypeInfo);
242  }
243  return found;
244 }
245 
246 /*
247  * call-seq:
248  * WIN32OLE_TYPE.new(typelib, ole_class) -> WIN32OLE_TYPE object
249  *
250  * Returns a new WIN32OLE_TYPE object.
251  * The first argument <i>typelib</i> specifies OLE type library name.
252  * The second argument specifies OLE class name.
253  *
254  * WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
255  * # => WIN32OLE_TYPE object of Application class of Excel.
256  */
257 static VALUE
258 foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass)
259 {
260  VALUE file;
261  OLECHAR * pbuf;
262  ITypeLib *pTypeLib;
263  HRESULT hr;
264 
265  SafeStringValue(oleclass);
266  SafeStringValue(typelib);
267  file = typelib_file(typelib);
268  if (file == Qnil) {
269  file = typelib;
270  }
271  pbuf = ole_vstr2wc(file);
272  hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);
273  if (FAILED(hr))
274  ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx");
275  SysFreeString(pbuf);
276  if (oleclass_from_typelib(self, pTypeLib, oleclass) == Qfalse) {
277  OLE_RELEASE(pTypeLib);
278  rb_raise(eWIN32OLERuntimeError, "not found `%s` in `%s`",
279  StringValuePtr(oleclass), StringValuePtr(typelib));
280  }
281  OLE_RELEASE(pTypeLib);
282  return self;
283 }
284 
285 /*
286  * call-seq:
287  * WIN32OLE_TYPE#name #=> OLE type name
288  *
289  * Returns OLE type name.
290  * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
291  * puts tobj.name # => Application
292  */
293 static VALUE
294 foletype_name(VALUE self)
295 {
296  return rb_ivar_get(self, rb_intern("name"));
297 }
298 
299 static VALUE
300 ole_ole_type(ITypeInfo *pTypeInfo)
301 {
302  HRESULT hr;
303  TYPEATTR *pTypeAttr;
304  VALUE type = Qnil;
305  hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
306  if(FAILED(hr)){
307  return type;
308  }
309  switch(pTypeAttr->typekind) {
310  case TKIND_ENUM:
311  type = rb_str_new2("Enum");
312  break;
313  case TKIND_RECORD:
314  type = rb_str_new2("Record");
315  break;
316  case TKIND_MODULE:
317  type = rb_str_new2("Module");
318  break;
319  case TKIND_INTERFACE:
320  type = rb_str_new2("Interface");
321  break;
322  case TKIND_DISPATCH:
323  type = rb_str_new2("Dispatch");
324  break;
325  case TKIND_COCLASS:
326  type = rb_str_new2("Class");
327  break;
328  case TKIND_ALIAS:
329  type = rb_str_new2("Alias");
330  break;
331  case TKIND_UNION:
332  type = rb_str_new2("Union");
333  break;
334  case TKIND_MAX:
335  type = rb_str_new2("Max");
336  break;
337  default:
338  type = Qnil;
339  break;
340  }
341  OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
342  return type;
343 }
344 
345 /*
346  * call-seq:
347  * WIN32OLE_TYPE#ole_type #=> OLE type string.
348  *
349  * returns type of OLE class.
350  * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
351  * puts tobj.ole_type # => Class
352  */
353 static VALUE
354 foletype_ole_type(VALUE self)
355 {
356  ITypeInfo *pTypeInfo = itypeinfo(self);
357  return ole_ole_type(pTypeInfo);
358 }
359 
360 static VALUE
361 ole_type_guid(ITypeInfo *pTypeInfo)
362 {
363  HRESULT hr;
364  TYPEATTR *pTypeAttr;
365  int len;
366  OLECHAR bstr[80];
367  VALUE guid = Qnil;
368  hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
369  if (FAILED(hr))
370  return guid;
371  len = StringFromGUID2(&pTypeAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
372  if (len > 3) {
373  guid = ole_wc2vstr(bstr, FALSE);
374  }
375  OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
376  return guid;
377 }
378 
379 /*
380  * call-seq:
381  * WIN32OLE_TYPE#guid #=> GUID
382  *
383  * Returns GUID.
384  * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
385  * puts tobj.guid # => {00024500-0000-0000-C000-000000000046}
386  */
387 static VALUE
388 foletype_guid(VALUE self)
389 {
390  ITypeInfo *pTypeInfo = itypeinfo(self);
391  return ole_type_guid(pTypeInfo);
392 }
393 
394 static VALUE
395 ole_type_progid(ITypeInfo *pTypeInfo)
396 {
397  HRESULT hr;
398  TYPEATTR *pTypeAttr;
399  OLECHAR *pbuf;
400  VALUE progid = Qnil;
401  hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
402  if (FAILED(hr))
403  return progid;
404  hr = ProgIDFromCLSID(&pTypeAttr->guid, &pbuf);
405  if (SUCCEEDED(hr)) {
406  progid = ole_wc2vstr(pbuf, FALSE);
407  CoTaskMemFree(pbuf);
408  }
409  OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
410  return progid;
411 }
412 
413 /*
414  * call-seq:
415  * WIN32OLE_TYPE#progid #=> ProgID
416  *
417  * Returns ProgID if it exists. If not found, then returns nil.
418  * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
419  * puts tobj.progid # => Excel.Application.9
420  */
421 static VALUE
422 foletype_progid(VALUE self)
423 {
424  ITypeInfo *pTypeInfo = itypeinfo(self);
425  return ole_type_progid(pTypeInfo);
426 }
427 
428 
429 static VALUE
430 ole_type_visible(ITypeInfo *pTypeInfo)
431 {
432  HRESULT hr;
433  TYPEATTR *pTypeAttr;
434  VALUE visible;
435  hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
436  if (FAILED(hr))
437  return Qtrue;
438  if (pTypeAttr->wTypeFlags & (TYPEFLAG_FHIDDEN | TYPEFLAG_FRESTRICTED)) {
439  visible = Qfalse;
440  } else {
441  visible = Qtrue;
442  }
443  OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
444  return visible;
445 }
446 
447 /*
448  * call-seq:
449  * WIN32OLE_TYPE#visible? #=> true or false
450  *
451  * Returns true if the OLE class is public.
452  * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
453  * puts tobj.visible # => true
454  */
455 static VALUE
456 foletype_visible(VALUE self)
457 {
458  ITypeInfo *pTypeInfo = itypeinfo(self);
459  return ole_type_visible(pTypeInfo);
460 }
461 
462 static VALUE
463 ole_type_major_version(ITypeInfo *pTypeInfo)
464 {
465  VALUE ver;
466  TYPEATTR *pTypeAttr;
467  HRESULT hr;
468  hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
469  if (FAILED(hr))
470  ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
471  ver = RB_INT2FIX(pTypeAttr->wMajorVerNum);
472  OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
473  return ver;
474 }
475 
476 /*
477  * call-seq:
478  * WIN32OLE_TYPE#major_version
479  *
480  * Returns major version.
481  * tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents')
482  * puts tobj.major_version # => 8
483  */
484 static VALUE
485 foletype_major_version(VALUE self)
486 {
487  ITypeInfo *pTypeInfo = itypeinfo(self);
488  return ole_type_major_version(pTypeInfo);
489 }
490 
491 static VALUE
492 ole_type_minor_version(ITypeInfo *pTypeInfo)
493 {
494  VALUE ver;
495  TYPEATTR *pTypeAttr;
496  HRESULT hr;
497  hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
498  if (FAILED(hr))
499  ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
500  ver = RB_INT2FIX(pTypeAttr->wMinorVerNum);
501  OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
502  return ver;
503 }
504 
505 /*
506  * call-seq:
507  * WIN32OLE_TYPE#minor_version #=> OLE minor version
508  *
509  * Returns minor version.
510  * tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents')
511  * puts tobj.minor_version # => 2
512  */
513 static VALUE
514 foletype_minor_version(VALUE self)
515 {
516  ITypeInfo *pTypeInfo = itypeinfo(self);
517  return ole_type_minor_version(pTypeInfo);
518 }
519 
520 static VALUE
521 ole_type_typekind(ITypeInfo *pTypeInfo)
522 {
523  VALUE typekind;
524  TYPEATTR *pTypeAttr;
525  HRESULT hr;
526  hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
527  if (FAILED(hr))
528  ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
529  typekind = RB_INT2FIX(pTypeAttr->typekind);
530  OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
531  return typekind;
532 }
533 
534 /*
535  * call-seq:
536  * WIN32OLE_TYPE#typekind #=> number of type.
537  *
538  * Returns number which represents type.
539  * tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents')
540  * puts tobj.typekind # => 4
541  *
542  */
543 static VALUE
544 foletype_typekind(VALUE self)
545 {
546  ITypeInfo *pTypeInfo = itypeinfo(self);
547  return ole_type_typekind(pTypeInfo);
548 }
549 
550 static VALUE
551 ole_type_helpstring(ITypeInfo *pTypeInfo)
552 {
553  HRESULT hr;
554  BSTR bhelpstr;
555  hr = ole_docinfo_from_type(pTypeInfo, NULL, &bhelpstr, NULL, NULL);
556  if(FAILED(hr)) {
557  return Qnil;
558  }
559  return WC2VSTR(bhelpstr);
560 }
561 
562 /*
563  * call-seq:
564  * WIN32OLE_TYPE#helpstring #=> help string.
565  *
566  * Returns help string.
567  * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'IWebBrowser')
568  * puts tobj.helpstring # => Web Browser interface
569  */
570 static VALUE
571 foletype_helpstring(VALUE self)
572 {
573  ITypeInfo *pTypeInfo = itypeinfo(self);
574  return ole_type_helpstring(pTypeInfo);
575 }
576 
577 static VALUE
578 ole_type_src_type(ITypeInfo *pTypeInfo)
579 {
580  HRESULT hr;
581  TYPEATTR *pTypeAttr;
582  VALUE alias = Qnil;
583  hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
584  if (FAILED(hr))
585  return alias;
586  if(pTypeAttr->typekind != TKIND_ALIAS) {
587  OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
588  return alias;
589  }
590  alias = ole_typedesc2val(pTypeInfo, &(pTypeAttr->tdescAlias), Qnil);
591  OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
592  return alias;
593 }
594 
595 /*
596  * call-seq:
597  * WIN32OLE_TYPE#src_type #=> OLE source class
598  *
599  * Returns source class when the OLE class is 'Alias'.
600  * tobj = WIN32OLE_TYPE.new('Microsoft Office 9.0 Object Library', 'MsoRGBType')
601  * puts tobj.src_type # => I4
602  *
603  */
604 static VALUE
605 foletype_src_type(VALUE self)
606 {
607  ITypeInfo *pTypeInfo = itypeinfo(self);
608  return ole_type_src_type(pTypeInfo);
609 }
610 
611 static VALUE
612 ole_type_helpfile(ITypeInfo *pTypeInfo)
613 {
614  HRESULT hr;
615  BSTR bhelpfile;
616  hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL, NULL, &bhelpfile);
617  if(FAILED(hr)) {
618  return Qnil;
619  }
620  return WC2VSTR(bhelpfile);
621 }
622 
623 /*
624  * call-seq:
625  * WIN32OLE_TYPE#helpfile
626  *
627  * Returns helpfile path. If helpfile is not found, then returns nil.
628  * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
629  * puts tobj.helpfile # => C:\...\VBAXL9.CHM
630  *
631  */
632 static VALUE
633 foletype_helpfile(VALUE self)
634 {
635  ITypeInfo *pTypeInfo = itypeinfo(self);
636  return ole_type_helpfile(pTypeInfo);
637 }
638 
639 static VALUE
640 ole_type_helpcontext(ITypeInfo *pTypeInfo)
641 {
642  HRESULT hr;
643  DWORD helpcontext;
644  hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL,
645  &helpcontext, NULL);
646  if(FAILED(hr))
647  return Qnil;
648  return RB_INT2FIX(helpcontext);
649 }
650 
651 /*
652  * call-seq:
653  * WIN32OLE_TYPE#helpcontext
654  *
655  * Returns helpcontext. If helpcontext is not found, then returns nil.
656  * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
657  * puts tobj.helpfile # => 131185
658  */
659 static VALUE
660 foletype_helpcontext(VALUE self)
661 {
662  ITypeInfo *pTypeInfo = itypeinfo(self);
663  return ole_type_helpcontext(pTypeInfo);
664 }
665 
666 static VALUE
667 ole_variables(ITypeInfo *pTypeInfo)
668 {
669  HRESULT hr;
670  TYPEATTR *pTypeAttr;
671  WORD i;
672  UINT len;
673  BSTR bstr;
674  VARDESC *pVarDesc;
675  VALUE var;
676  VALUE variables = rb_ary_new();
677  hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
678  if (FAILED(hr)) {
679  ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
680  }
681 
682  for(i = 0; i < pTypeAttr->cVars; i++) {
683  hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, i, &pVarDesc);
684  if(FAILED(hr))
685  continue;
686  len = 0;
687  hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr,
688  1, &len);
689  if(FAILED(hr) || len == 0 || !bstr)
690  continue;
691 
692  var = create_win32ole_variable(pTypeInfo, i, WC2VSTR(bstr));
693  rb_ary_push(variables, var);
694 
695  pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
696  pVarDesc = NULL;
697  }
698  OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
699  return variables;
700 }
701 
702 /*
703  * call-seq:
704  * WIN32OLE_TYPE#variables
705  *
706  * Returns array of WIN32OLE_VARIABLE objects which represent variables
707  * defined in OLE class.
708  * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
709  * vars = tobj.variables
710  * vars.each do |v|
711  * puts "#{v.name} = #{v.value}"
712  * end
713  *
714  * The result of above sample script is follows:
715  * xlChart = -4109
716  * xlDialogSheet = -4116
717  * xlExcel4IntlMacroSheet = 4
718  * xlExcel4MacroSheet = 3
719  * xlWorksheet = -4167
720  *
721  */
722 static VALUE
723 foletype_variables(VALUE self)
724 {
725  ITypeInfo *pTypeInfo = itypeinfo(self);
726  return ole_variables(pTypeInfo);
727 }
728 
729 /*
730  * call-seq:
731  * WIN32OLE_TYPE#ole_methods # the array of WIN32OLE_METHOD objects.
732  *
733  * Returns array of WIN32OLE_METHOD objects which represent OLE method defined in
734  * OLE type library.
735  * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
736  * methods = tobj.ole_methods.collect{|m|
737  * m.name
738  * }
739  * # => ['Activate', 'Copy', 'Delete',....]
740  */
741 static VALUE
742 foletype_methods(VALUE self)
743 {
744  ITypeInfo *pTypeInfo = itypeinfo(self);
745  return ole_methods_from_typeinfo(pTypeInfo, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);
746 }
747 
748 /*
749  * call-seq:
750  * WIN32OLE_TYPE#ole_typelib
751  *
752  * Returns the WIN32OLE_TYPELIB object which is including the WIN32OLE_TYPE
753  * object. If it is not found, then returns nil.
754  * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
755  * puts tobj.ole_typelib # => 'Microsoft Excel 9.0 Object Library'
756  */
757 static VALUE
758 foletype_ole_typelib(VALUE self)
759 {
760  ITypeInfo *pTypeInfo = itypeinfo(self);
761  return ole_typelib_from_itypeinfo(pTypeInfo);
762 }
763 
764 static VALUE
765 ole_type_impl_ole_types(ITypeInfo *pTypeInfo, int implflags)
766 {
767  HRESULT hr;
768  ITypeInfo *pRefTypeInfo;
769  HREFTYPE href;
770  WORD i;
771  VALUE type;
772  TYPEATTR *pTypeAttr;
773  int flags;
774 
775  VALUE types = rb_ary_new();
776  hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
777  if (FAILED(hr)) {
778  return types;
779  }
780  for (i = 0; i < pTypeAttr->cImplTypes; i++) {
781  hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags);
782  if (FAILED(hr))
783  continue;
784 
785  hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
786  if (FAILED(hr))
787  continue;
788  hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
789  if (FAILED(hr))
790  continue;
791 
792  if ((flags & implflags) == implflags) {
793  type = ole_type_from_itypeinfo(pRefTypeInfo);
794  if (type != Qnil) {
795  rb_ary_push(types, type);
796  }
797  }
798 
799  OLE_RELEASE(pRefTypeInfo);
800  }
801  OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
802  return types;
803 }
804 
805 /*
806  * call-seq:
807  * WIN32OLE_TYPE#implemented_ole_types
808  *
809  * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE
810  * object.
811  * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
812  * p tobj.implemented_ole_types # => [_Worksheet, DocEvents]
813  */
814 static VALUE
815 foletype_impl_ole_types(VALUE self)
816 {
817  ITypeInfo *pTypeInfo = itypeinfo(self);
818  return ole_type_impl_ole_types(pTypeInfo, 0);
819 }
820 
821 /*
822  * call-seq:
823  * WIN32OLE_TYPE#source_ole_types
824  *
825  * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE
826  * object and having IMPLTYPEFLAG_FSOURCE.
827  * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer")
828  * p tobj.source_ole_types
829  * # => [#<WIN32OLE_TYPE:DWebBrowserEvents2>, #<WIN32OLE_TYPE:DWebBrowserEvents>]
830  */
831 static VALUE
832 foletype_source_ole_types(VALUE self)
833 {
834  ITypeInfo *pTypeInfo = itypeinfo(self);
835  return ole_type_impl_ole_types(pTypeInfo, IMPLTYPEFLAG_FSOURCE);
836 }
837 
838 /*
839  * call-seq:
840  * WIN32OLE_TYPE#default_event_sources
841  *
842  * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE
843  * object and having IMPLTYPEFLAG_FSOURCE and IMPLTYPEFLAG_FDEFAULT.
844  * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer")
845  * p tobj.default_event_sources # => [#<WIN32OLE_TYPE:DWebBrowserEvents2>]
846  */
847 static VALUE
848 foletype_default_event_sources(VALUE self)
849 {
850  ITypeInfo *pTypeInfo = itypeinfo(self);
851  return ole_type_impl_ole_types(pTypeInfo, IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT);
852 }
853 
854 /*
855  * call-seq:
856  * WIN32OLE_TYPE#default_ole_types
857  *
858  * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE
859  * object and having IMPLTYPEFLAG_FDEFAULT.
860  * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer")
861  * p tobj.default_ole_types
862  * # => [#<WIN32OLE_TYPE:IWebBrowser2>, #<WIN32OLE_TYPE:DWebBrowserEvents2>]
863  */
864 static VALUE
865 foletype_default_ole_types(VALUE self)
866 {
867  ITypeInfo *pTypeInfo = itypeinfo(self);
868  return ole_type_impl_ole_types(pTypeInfo, IMPLTYPEFLAG_FDEFAULT);
869 }
870 
871 /*
872  * call-seq:
873  * WIN32OLE_TYPE#inspect -> String
874  *
875  * Returns the type name with class name.
876  *
877  * ie = WIN32OLE.new('InternetExplorer.Application')
878  * ie.ole_type.inspect => #<WIN32OLE_TYPE:IWebBrowser2>
879  */
880 static VALUE
881 foletype_inspect(VALUE self)
882 {
883  return default_inspect(self, "WIN32OLE_TYPE");
884 }
885 
887 {
888  cWIN32OLE_TYPE = rb_define_class("WIN32OLE_TYPE", rb_cObject);
889  rb_define_singleton_method(cWIN32OLE_TYPE, "ole_classes", foletype_s_ole_classes, 1);
890  rb_define_singleton_method(cWIN32OLE_TYPE, "typelibs", foletype_s_typelibs, 0);
891  rb_define_singleton_method(cWIN32OLE_TYPE, "progids", foletype_s_progids, 0);
892  rb_define_alloc_func(cWIN32OLE_TYPE, foletype_s_allocate);
893  rb_define_method(cWIN32OLE_TYPE, "initialize", foletype_initialize, 2);
894  rb_define_method(cWIN32OLE_TYPE, "name", foletype_name, 0);
895  rb_define_method(cWIN32OLE_TYPE, "ole_type", foletype_ole_type, 0);
896  rb_define_method(cWIN32OLE_TYPE, "guid", foletype_guid, 0);
897  rb_define_method(cWIN32OLE_TYPE, "progid", foletype_progid, 0);
898  rb_define_method(cWIN32OLE_TYPE, "visible?", foletype_visible, 0);
899  rb_define_alias(cWIN32OLE_TYPE, "to_s", "name");
900  rb_define_method(cWIN32OLE_TYPE, "major_version", foletype_major_version, 0);
901  rb_define_method(cWIN32OLE_TYPE, "minor_version", foletype_minor_version, 0);
902  rb_define_method(cWIN32OLE_TYPE, "typekind", foletype_typekind, 0);
903  rb_define_method(cWIN32OLE_TYPE, "helpstring", foletype_helpstring, 0);
904  rb_define_method(cWIN32OLE_TYPE, "src_type", foletype_src_type, 0);
905  rb_define_method(cWIN32OLE_TYPE, "helpfile", foletype_helpfile, 0);
906  rb_define_method(cWIN32OLE_TYPE, "helpcontext", foletype_helpcontext, 0);
907  rb_define_method(cWIN32OLE_TYPE, "variables", foletype_variables, 0);
908  rb_define_method(cWIN32OLE_TYPE, "ole_methods", foletype_methods, 0);
909  rb_define_method(cWIN32OLE_TYPE, "ole_typelib", foletype_ole_typelib, 0);
910  rb_define_method(cWIN32OLE_TYPE, "implemented_ole_types", foletype_impl_ole_types, 0);
911  rb_define_method(cWIN32OLE_TYPE, "source_ole_types", foletype_source_ole_types, 0);
912  rb_define_method(cWIN32OLE_TYPE, "default_event_sources", foletype_default_event_sources, 0);
913  rb_define_method(cWIN32OLE_TYPE, "default_ole_types", foletype_default_ole_types, 0);
914  rb_define_method(cWIN32OLE_TYPE, "inspect", foletype_inspect, 0);
915 }
VALUE eWIN32OLERuntimeError
Definition: win32ole_error.h:4
#define FALSE
Definition: nkf.h:174
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1138
int count
Definition: encoding.c:56
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1716
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2284
#define Qtrue
Definition: ruby.h:437
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: ruby.h:1183
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:924
LPWSTR ole_vstr2wc(VALUE vstr)
Definition: win32ole.c:864
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:774
VALUE cWIN32OLE_TYPELIB
#define OLE_GET_TYPEATTR(X, Y)
Definition: win32ole.h:108
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1210
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
void ole_initialize(void)
Definition: win32ole.c:812
void Init_win32ole_type(void)
const char * alias
Definition: nkf.c:1151
int rb_str_cmp(VALUE, VALUE)
Definition: string.c:3159
VALUE cWIN32OLE_TYPE
Definition: win32ole_type.h:3
void ole_raise(HRESULT hr, VALUE ecs, const char *fmt,...)
VALUE default_inspect(VALUE self, const char *class_name)
Definition: win32ole.c:1344
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1893
IUnknown DWORD
Definition: win32ole.c:32
VALUE ole_type_from_itypeinfo(ITypeInfo *pTypeInfo)
Definition: win32ole_type.c:84
VALUE reg_get_val2(HKEY hkey, const char *subkey)
Definition: win32ole.c:1752
VALUE rb_ary_new(void)
Definition: array.c:499
VALUE typelib_file(VALUE ole)
LONG reg_open_key(HKEY hkey, const char *name, HKEY *phkey)
Definition: win32ole.c:1697
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:646
#define WC2VSTR(x)
Definition: win32ole.h:130
VALUE rb_eval_string(const char *)
Evaluates the given string in an isolated binding.
Definition: vm_eval.c:1447
VALUE ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask)
#define Qfalse
Definition: ruby.h:436
#define rb_str_new2
Definition: intern.h:835
int err
Definition: win32.c:135
#define OLE_ADDREF(X)
Definition: win32ole.h:97
LONG reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey)
Definition: win32ole.c:1703
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1758
VALUE create_win32ole_variable(ITypeInfo *pTypeInfo, UINT index, VALUE name)
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1315
#define Qnil
Definition: ruby.h:438
unsigned long VALUE
Definition: ruby.h:85
register unsigned int len
Definition: zonetab.h:51
ITypeInfo * pTypeInfo
Definition: win32ole_type.c:4
#define OLE_RELEASE(X)
Definition: win32ole.h:98
VALUE ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
Definition: win32ole.c:3717
VALUE ole_wc2vstr(LPWSTR pw, BOOL isfree)
Definition: win32ole.c:945
typedef HRESULT(STDAPICALLTYPE FNCOCREATEINSTANCEEX)(REFCLSID
VALUE reg_enum_key(HKEY hkey, DWORD i)
Definition: win32ole.c:1709
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: ruby.h:1175
VALUE ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo)
#define OLE_RELEASE_TYPEATTR(X, Y)
Definition: win32ole.h:109
#define SafeStringValue(v)
Definition: ruby.h:574
const char * name
Definition: nkf.c:208
#define StringValuePtr(v)
Definition: ruby.h:570
ITypeInfo * itypeinfo(VALUE self)
Definition: win32ole_type.c:76
#define RB_INT2FIX(i)
Definition: ruby.h:231
#define rb_intern(str)
#define NULL
Definition: _sdbm.c:102
HRESULT ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile)
Definition: win32ole.c:3656
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
VALUE create_win32ole_type(ITypeInfo *pTypeInfo, VALUE name)
free(psz)
#define OLE_FREE(x)
Definition: win32ole.h:99