diff options
author | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-16 18:49:26 +0900 |
---|---|---|
committer | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-30 00:39:06 +0900 |
commit | fcbf63e62c627deae76c1b8cb8c0876c536ed811 (patch) | |
tree | 64cb17de3f41a2b6fef2368028fbd00349946994 /jni/ruby/ext/win32ole/win32ole_type.c |
Fresh start
Diffstat (limited to 'jni/ruby/ext/win32ole/win32ole_type.c')
-rw-r--r-- | jni/ruby/ext/win32ole/win32ole_type.c | 915 |
1 files changed, 915 insertions, 0 deletions
diff --git a/jni/ruby/ext/win32ole/win32ole_type.c b/jni/ruby/ext/win32ole/win32ole_type.c new file mode 100644 index 0000000..efcac88 --- /dev/null +++ b/jni/ruby/ext/win32ole/win32ole_type.c @@ -0,0 +1,915 @@ +#include "win32ole.h" + +struct oletypedata { + ITypeInfo *pTypeInfo; +}; + +static void oletype_free(void *ptr); +static size_t oletype_size(const void *ptr); +static VALUE foletype_s_ole_classes(VALUE self, VALUE typelib); +static VALUE foletype_s_typelibs(VALUE self); +static VALUE foletype_s_progids(VALUE self); +static VALUE oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name); +static VALUE foletype_s_allocate(VALUE klass); +static VALUE oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass); +static VALUE foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass); +static VALUE foletype_name(VALUE self); +static VALUE ole_ole_type(ITypeInfo *pTypeInfo); +static VALUE foletype_ole_type(VALUE self); +static VALUE ole_type_guid(ITypeInfo *pTypeInfo); +static VALUE foletype_guid(VALUE self); +static VALUE ole_type_progid(ITypeInfo *pTypeInfo); +static VALUE foletype_progid(VALUE self); +static VALUE ole_type_visible(ITypeInfo *pTypeInfo); +static VALUE foletype_visible(VALUE self); +static VALUE ole_type_major_version(ITypeInfo *pTypeInfo); +static VALUE foletype_major_version(VALUE self); +static VALUE ole_type_minor_version(ITypeInfo *pTypeInfo); +static VALUE foletype_minor_version(VALUE self); +static VALUE ole_type_typekind(ITypeInfo *pTypeInfo); +static VALUE foletype_typekind(VALUE self); +static VALUE ole_type_helpstring(ITypeInfo *pTypeInfo); +static VALUE foletype_helpstring(VALUE self); +static VALUE ole_type_src_type(ITypeInfo *pTypeInfo); +static VALUE foletype_src_type(VALUE self); +static VALUE ole_type_helpfile(ITypeInfo *pTypeInfo); +static VALUE foletype_helpfile(VALUE self); +static VALUE ole_type_helpcontext(ITypeInfo *pTypeInfo); +static VALUE foletype_helpcontext(VALUE self); +static VALUE ole_variables(ITypeInfo *pTypeInfo); +static VALUE foletype_variables(VALUE self); +static VALUE foletype_methods(VALUE self); +static VALUE foletype_ole_typelib(VALUE self); +static VALUE ole_type_impl_ole_types(ITypeInfo *pTypeInfo, int implflags); +static VALUE foletype_impl_ole_types(VALUE self); +static VALUE foletype_source_ole_types(VALUE self); +static VALUE foletype_default_event_sources(VALUE self); +static VALUE foletype_default_ole_types(VALUE self); +static VALUE foletype_inspect(VALUE self); + +static const rb_data_type_t oletype_datatype = { + "win32ole_type", + {NULL, oletype_free, oletype_size,}, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY +}; + +/* + * Document-class: WIN32OLE_TYPE + * + * <code>WIN32OLE_TYPE</code> objects represent OLE type libarary information. + */ + +static void +oletype_free(void *ptr) +{ + struct oletypedata *poletype = ptr; + OLE_FREE(poletype->pTypeInfo); + free(poletype); +} + +static size_t +oletype_size(const void *ptr) +{ + return ptr ? sizeof(struct oletypedata) : 0; +} + +ITypeInfo *itypeinfo(VALUE self) +{ + struct oletypedata *ptype; + TypedData_Get_Struct(self, struct oletypedata, &oletype_datatype, ptype); + return ptype->pTypeInfo; +} + +VALUE +ole_type_from_itypeinfo(ITypeInfo *pTypeInfo) +{ + ITypeLib *pTypeLib; + VALUE type = Qnil; + HRESULT hr; + unsigned int index; + BSTR bstr; + + hr = pTypeInfo->lpVtbl->GetContainingTypeLib( pTypeInfo, &pTypeLib, &index ); + if(FAILED(hr)) { + return Qnil; + } + hr = pTypeLib->lpVtbl->GetDocumentation( pTypeLib, index, + &bstr, NULL, NULL, NULL); + OLE_RELEASE(pTypeLib); + if (FAILED(hr)) { + return Qnil; + } + type = create_win32ole_type(pTypeInfo, WC2VSTR(bstr)); + return type; +} + + +/* + * call-seq: + * WIN32OLE_TYPE.ole_classes(typelib) + * + * Returns array of WIN32OLE_TYPE objects defined by the <i>typelib</i> type library. + * This method will be OBSOLETE. Use WIN32OLE_TYPELIB.new(typelib).ole_classes instead. + */ +static VALUE +foletype_s_ole_classes(VALUE self, VALUE typelib) +{ + VALUE obj; + + /* + rb_warn("%s is obsolete; use %s instead.", + "WIN32OLE_TYPE.ole_classes", + "WIN32OLE_TYPELIB.new(typelib).ole_types"); + */ + obj = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("new"), 1, typelib); + return rb_funcall(obj, rb_intern("ole_types"), 0); +} + +/* + * call-seq: + * WIN32OLE_TYPE.typelibs + * + * Returns array of type libraries. + * This method will be OBSOLETE. Use WIN32OLE_TYPELIB.typelibs.collect{|t| t.name} instead. + * + */ +static VALUE +foletype_s_typelibs(VALUE self) +{ + /* + rb_warn("%s is obsolete. use %s instead.", + "WIN32OLE_TYPE.typelibs", + "WIN32OLE_TYPELIB.typelibs.collect{t|t.name}"); + */ + return rb_eval_string("WIN32OLE_TYPELIB.typelibs.collect{|t|t.name}"); +} + +/* + * call-seq: + * WIN32OLE_TYPE.progids + * + * Returns array of ProgID. + */ +static VALUE +foletype_s_progids(VALUE self) +{ + HKEY hclsids, hclsid; + DWORD i; + LONG err; + VALUE clsid; + VALUE v = rb_str_new2(""); + VALUE progids = rb_ary_new(); + + err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hclsids); + if(err != ERROR_SUCCESS) { + return progids; + } + for(i = 0; ; i++) { + clsid = reg_enum_key(hclsids, i); + if (clsid == Qnil) + break; + err = reg_open_vkey(hclsids, clsid, &hclsid); + if (err != ERROR_SUCCESS) + continue; + if ((v = reg_get_val2(hclsid, "ProgID")) != Qnil) + rb_ary_push(progids, v); + if ((v = reg_get_val2(hclsid, "VersionIndependentProgID")) != Qnil) + rb_ary_push(progids, v); + RegCloseKey(hclsid); + } + RegCloseKey(hclsids); + return progids; +} + +static VALUE +oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name) +{ + struct oletypedata *ptype; + TypedData_Get_Struct(self, struct oletypedata, &oletype_datatype, ptype); + rb_ivar_set(self, rb_intern("name"), name); + ptype->pTypeInfo = pTypeInfo; + OLE_ADDREF(pTypeInfo); + return self; +} + +static VALUE +foletype_s_allocate(VALUE klass) +{ + struct oletypedata *poletype; + VALUE obj; + ole_initialize(); + obj = TypedData_Make_Struct(klass,struct oletypedata, &oletype_datatype, poletype); + poletype->pTypeInfo = NULL; + return obj; +} + +VALUE +create_win32ole_type(ITypeInfo *pTypeInfo, VALUE name) +{ + VALUE obj = foletype_s_allocate(cWIN32OLE_TYPE); + oletype_set_member(obj, pTypeInfo, name); + return obj; +} + +static VALUE +oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass) +{ + + long count; + int i; + HRESULT hr; + BSTR bstr; + VALUE typelib; + ITypeInfo *pTypeInfo; + + VALUE found = Qfalse; + + count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib); + for (i = 0; i < count && found == Qfalse; i++) { + hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo); + if (FAILED(hr)) + continue; + hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i, + &bstr, NULL, NULL, NULL); + if (FAILED(hr)) + continue; + typelib = WC2VSTR(bstr); + if (rb_str_cmp(oleclass, typelib) == 0) { + oletype_set_member(self, pTypeInfo, typelib); + found = Qtrue; + } + OLE_RELEASE(pTypeInfo); + } + return found; +} + +/* + * call-seq: + * WIN32OLE_TYPE.new(typelib, ole_class) -> WIN32OLE_TYPE object + * + * Returns a new WIN32OLE_TYPE object. + * The first argument <i>typelib</i> specifies OLE type library name. + * The second argument specifies OLE class name. + * + * WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application') + * # => WIN32OLE_TYPE object of Application class of Excel. + */ +static VALUE +foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass) +{ + VALUE file; + OLECHAR * pbuf; + ITypeLib *pTypeLib; + HRESULT hr; + + SafeStringValue(oleclass); + SafeStringValue(typelib); + file = typelib_file(typelib); + if (file == Qnil) { + file = typelib; + } + pbuf = ole_vstr2wc(file); + hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib); + if (FAILED(hr)) + ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx"); + SysFreeString(pbuf); + if (oleclass_from_typelib(self, pTypeLib, oleclass) == Qfalse) { + OLE_RELEASE(pTypeLib); + rb_raise(eWIN32OLERuntimeError, "not found `%s` in `%s`", + StringValuePtr(oleclass), StringValuePtr(typelib)); + } + OLE_RELEASE(pTypeLib); + return self; +} + +/* + * call-seq: + * WIN32OLE_TYPE#name #=> OLE type name + * + * Returns OLE type name. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application') + * puts tobj.name # => Application + */ +static VALUE +foletype_name(VALUE self) +{ + return rb_ivar_get(self, rb_intern("name")); +} + +static VALUE +ole_ole_type(ITypeInfo *pTypeInfo) +{ + HRESULT hr; + TYPEATTR *pTypeAttr; + VALUE type = Qnil; + hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); + if(FAILED(hr)){ + return type; + } + switch(pTypeAttr->typekind) { + case TKIND_ENUM: + type = rb_str_new2("Enum"); + break; + case TKIND_RECORD: + type = rb_str_new2("Record"); + break; + case TKIND_MODULE: + type = rb_str_new2("Module"); + break; + case TKIND_INTERFACE: + type = rb_str_new2("Interface"); + break; + case TKIND_DISPATCH: + type = rb_str_new2("Dispatch"); + break; + case TKIND_COCLASS: + type = rb_str_new2("Class"); + break; + case TKIND_ALIAS: + type = rb_str_new2("Alias"); + break; + case TKIND_UNION: + type = rb_str_new2("Union"); + break; + case TKIND_MAX: + type = rb_str_new2("Max"); + break; + default: + type = Qnil; + break; + } + OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); + return type; +} + +/* + * call-seq: + * WIN32OLE_TYPE#ole_type #=> OLE type string. + * + * returns type of OLE class. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application') + * puts tobj.ole_type # => Class + */ +static VALUE +foletype_ole_type(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_ole_type(pTypeInfo); +} + +static VALUE +ole_type_guid(ITypeInfo *pTypeInfo) +{ + HRESULT hr; + TYPEATTR *pTypeAttr; + int len; + OLECHAR bstr[80]; + VALUE guid = Qnil; + hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); + if (FAILED(hr)) + return guid; + len = StringFromGUID2(&pTypeAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR)); + if (len > 3) { + guid = ole_wc2vstr(bstr, FALSE); + } + OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); + return guid; +} + +/* + * call-seq: + * WIN32OLE_TYPE#guid #=> GUID + * + * Returns GUID. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application') + * puts tobj.guid # => {00024500-0000-0000-C000-000000000046} + */ +static VALUE +foletype_guid(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_type_guid(pTypeInfo); +} + +static VALUE +ole_type_progid(ITypeInfo *pTypeInfo) +{ + HRESULT hr; + TYPEATTR *pTypeAttr; + OLECHAR *pbuf; + VALUE progid = Qnil; + hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); + if (FAILED(hr)) + return progid; + hr = ProgIDFromCLSID(&pTypeAttr->guid, &pbuf); + if (SUCCEEDED(hr)) { + progid = ole_wc2vstr(pbuf, FALSE); + CoTaskMemFree(pbuf); + } + OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); + return progid; +} + +/* + * call-seq: + * WIN32OLE_TYPE#progid #=> ProgID + * + * Returns ProgID if it exists. If not found, then returns nil. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application') + * puts tobj.progid # => Excel.Application.9 + */ +static VALUE +foletype_progid(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_type_progid(pTypeInfo); +} + + +static VALUE +ole_type_visible(ITypeInfo *pTypeInfo) +{ + HRESULT hr; + TYPEATTR *pTypeAttr; + VALUE visible; + hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); + if (FAILED(hr)) + return Qtrue; + if (pTypeAttr->wTypeFlags & (TYPEFLAG_FHIDDEN | TYPEFLAG_FRESTRICTED)) { + visible = Qfalse; + } else { + visible = Qtrue; + } + OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); + return visible; +} + +/* + * call-seq: + * WIN32OLE_TYPE#visible? #=> true or false + * + * Returns true if the OLE class is public. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application') + * puts tobj.visible # => true + */ +static VALUE +foletype_visible(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_type_visible(pTypeInfo); +} + +static VALUE +ole_type_major_version(ITypeInfo *pTypeInfo) +{ + VALUE ver; + TYPEATTR *pTypeAttr; + HRESULT hr; + hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); + if (FAILED(hr)) + ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr"); + ver = INT2FIX(pTypeAttr->wMajorVerNum); + OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); + return ver; +} + +/* + * call-seq: + * WIN32OLE_TYPE#major_version + * + * Returns major version. + * tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents') + * puts tobj.major_version # => 8 + */ +static VALUE +foletype_major_version(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_type_major_version(pTypeInfo); +} + +static VALUE +ole_type_minor_version(ITypeInfo *pTypeInfo) +{ + VALUE ver; + TYPEATTR *pTypeAttr; + HRESULT hr; + hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); + if (FAILED(hr)) + ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr"); + ver = INT2FIX(pTypeAttr->wMinorVerNum); + OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); + return ver; +} + +/* + * call-seq: + * WIN32OLE_TYPE#minor_version #=> OLE minor version + * + * Returns minor version. + * tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents') + * puts tobj.minor_version # => 2 + */ +static VALUE +foletype_minor_version(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_type_minor_version(pTypeInfo); +} + +static VALUE +ole_type_typekind(ITypeInfo *pTypeInfo) +{ + VALUE typekind; + TYPEATTR *pTypeAttr; + HRESULT hr; + hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); + if (FAILED(hr)) + ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr"); + typekind = INT2FIX(pTypeAttr->typekind); + OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); + return typekind; +} + +/* + * call-seq: + * WIN32OLE_TYPE#typekind #=> number of type. + * + * Returns number which represents type. + * tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents') + * puts tobj.typekind # => 4 + * + */ +static VALUE +foletype_typekind(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_type_typekind(pTypeInfo); +} + +static VALUE +ole_type_helpstring(ITypeInfo *pTypeInfo) +{ + HRESULT hr; + BSTR bhelpstr; + hr = ole_docinfo_from_type(pTypeInfo, NULL, &bhelpstr, NULL, NULL); + if(FAILED(hr)) { + return Qnil; + } + return WC2VSTR(bhelpstr); +} + +/* + * call-seq: + * WIN32OLE_TYPE#helpstring #=> help string. + * + * Returns help string. + * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'IWebBrowser') + * puts tobj.helpstring # => Web Browser interface + */ +static VALUE +foletype_helpstring(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_type_helpstring(pTypeInfo); +} + +static VALUE +ole_type_src_type(ITypeInfo *pTypeInfo) +{ + HRESULT hr; + TYPEATTR *pTypeAttr; + VALUE alias = Qnil; + hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); + if (FAILED(hr)) + return alias; + if(pTypeAttr->typekind != TKIND_ALIAS) { + OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); + return alias; + } + alias = ole_typedesc2val(pTypeInfo, &(pTypeAttr->tdescAlias), Qnil); + OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); + return alias; +} + +/* + * call-seq: + * WIN32OLE_TYPE#src_type #=> OLE source class + * + * Returns source class when the OLE class is 'Alias'. + * tobj = WIN32OLE_TYPE.new('Microsoft Office 9.0 Object Library', 'MsoRGBType') + * puts tobj.src_type # => I4 + * + */ +static VALUE +foletype_src_type(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_type_src_type(pTypeInfo); +} + +static VALUE +ole_type_helpfile(ITypeInfo *pTypeInfo) +{ + HRESULT hr; + BSTR bhelpfile; + hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL, NULL, &bhelpfile); + if(FAILED(hr)) { + return Qnil; + } + return WC2VSTR(bhelpfile); +} + +/* + * call-seq: + * WIN32OLE_TYPE#helpfile + * + * Returns helpfile path. If helpfile is not found, then returns nil. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet') + * puts tobj.helpfile # => C:\...\VBAXL9.CHM + * + */ +static VALUE +foletype_helpfile(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_type_helpfile(pTypeInfo); +} + +static VALUE +ole_type_helpcontext(ITypeInfo *pTypeInfo) +{ + HRESULT hr; + DWORD helpcontext; + hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL, + &helpcontext, NULL); + if(FAILED(hr)) + return Qnil; + return INT2FIX(helpcontext); +} + +/* + * call-seq: + * WIN32OLE_TYPE#helpcontext + * + * Returns helpcontext. If helpcontext is not found, then returns nil. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet') + * puts tobj.helpfile # => 131185 + */ +static VALUE +foletype_helpcontext(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_type_helpcontext(pTypeInfo); +} + +static VALUE +ole_variables(ITypeInfo *pTypeInfo) +{ + HRESULT hr; + TYPEATTR *pTypeAttr; + WORD i; + UINT len; + BSTR bstr; + VARDESC *pVarDesc; + VALUE var; + VALUE variables = rb_ary_new(); + hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); + if (FAILED(hr)) { + ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr"); + } + + for(i = 0; i < pTypeAttr->cVars; i++) { + hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, i, &pVarDesc); + if(FAILED(hr)) + continue; + len = 0; + hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr, + 1, &len); + if(FAILED(hr) || len == 0 || !bstr) + continue; + + var = create_win32ole_variable(pTypeInfo, i, WC2VSTR(bstr)); + rb_ary_push(variables, var); + + pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); + pVarDesc = NULL; + } + OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); + return variables; +} + +/* + * call-seq: + * WIN32OLE_TYPE#variables + * + * Returns array of WIN32OLE_VARIABLE objects which represent variables + * defined in OLE class. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') + * vars = tobj.variables + * vars.each do |v| + * puts "#{v.name} = #{v.value}" + * end + * + * The result of above sample script is follows: + * xlChart = -4109 + * xlDialogSheet = -4116 + * xlExcel4IntlMacroSheet = 4 + * xlExcel4MacroSheet = 3 + * xlWorksheet = -4167 + * + */ +static VALUE +foletype_variables(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_variables(pTypeInfo); +} + +/* + * call-seq: + * WIN32OLE_TYPE#ole_methods # the array of WIN32OLE_METHOD objects. + * + * Returns array of WIN32OLE_METHOD objects which represent OLE method defined in + * OLE type library. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet') + * methods = tobj.ole_methods.collect{|m| + * m.name + * } + * # => ['Activate', 'Copy', 'Delete',....] + */ +static VALUE +foletype_methods(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_methods_from_typeinfo(pTypeInfo, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF); +} + +/* + * call-seq: + * WIN32OLE_TYPE#ole_typelib + * + * Returns the WIN32OLE_TYPELIB object which is including the WIN32OLE_TYPE + * object. If it is not found, then returns nil. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet') + * puts tobj.ole_typelib # => 'Microsoft Excel 9.0 Object Library' + */ +static VALUE +foletype_ole_typelib(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_typelib_from_itypeinfo(pTypeInfo); +} + +static VALUE +ole_type_impl_ole_types(ITypeInfo *pTypeInfo, int implflags) +{ + HRESULT hr; + ITypeInfo *pRefTypeInfo; + HREFTYPE href; + WORD i; + VALUE type; + TYPEATTR *pTypeAttr; + int flags; + + VALUE types = rb_ary_new(); + hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); + if (FAILED(hr)) { + return types; + } + for (i = 0; i < pTypeAttr->cImplTypes; i++) { + hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags); + if (FAILED(hr)) + continue; + + hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href); + if (FAILED(hr)) + continue; + hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo); + if (FAILED(hr)) + continue; + + if ((flags & implflags) == implflags) { + type = ole_type_from_itypeinfo(pRefTypeInfo); + if (type != Qnil) { + rb_ary_push(types, type); + } + } + + OLE_RELEASE(pRefTypeInfo); + } + OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); + return types; +} + +/* + * call-seq: + * WIN32OLE_TYPE#implemented_ole_types + * + * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE + * object. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet') + * p tobj.implemented_ole_types # => [_Worksheet, DocEvents] + */ +static VALUE +foletype_impl_ole_types(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_type_impl_ole_types(pTypeInfo, 0); +} + +/* + * call-seq: + * WIN32OLE_TYPE#source_ole_types + * + * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE + * object and having IMPLTYPEFLAG_FSOURCE. + * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer") + * p tobj.source_ole_types + * # => [#<WIN32OLE_TYPE:DWebBrowserEvents2>, #<WIN32OLE_TYPE:DWebBrowserEvents>] + */ +static VALUE +foletype_source_ole_types(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_type_impl_ole_types(pTypeInfo, IMPLTYPEFLAG_FSOURCE); +} + +/* + * call-seq: + * WIN32OLE_TYPE#default_event_sources + * + * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE + * object and having IMPLTYPEFLAG_FSOURCE and IMPLTYPEFLAG_FDEFAULT. + * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer") + * p tobj.default_event_sources # => [#<WIN32OLE_TYPE:DWebBrowserEvents2>] + */ +static VALUE +foletype_default_event_sources(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_type_impl_ole_types(pTypeInfo, IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT); +} + +/* + * call-seq: + * WIN32OLE_TYPE#default_ole_types + * + * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE + * object and having IMPLTYPEFLAG_FDEFAULT. + * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer") + * p tobj.default_ole_types + * # => [#<WIN32OLE_TYPE:IWebBrowser2>, #<WIN32OLE_TYPE:DWebBrowserEvents2>] + */ +static VALUE +foletype_default_ole_types(VALUE self) +{ + ITypeInfo *pTypeInfo = itypeinfo(self); + return ole_type_impl_ole_types(pTypeInfo, IMPLTYPEFLAG_FDEFAULT); +} + +/* + * call-seq: + * WIN32OLE_TYPE#inspect -> String + * + * Returns the type name with class name. + * + * ie = WIN32OLE.new('InternetExplorer.Application') + * ie.ole_type.inspect => #<WIN32OLE_TYPE:IWebBrowser2> + */ +static VALUE +foletype_inspect(VALUE self) +{ + return default_inspect(self, "WIN32OLE_TYPE"); +} + +void Init_win32ole_type(void) +{ + cWIN32OLE_TYPE = rb_define_class("WIN32OLE_TYPE", rb_cObject); + rb_define_singleton_method(cWIN32OLE_TYPE, "ole_classes", foletype_s_ole_classes, 1); + rb_define_singleton_method(cWIN32OLE_TYPE, "typelibs", foletype_s_typelibs, 0); + rb_define_singleton_method(cWIN32OLE_TYPE, "progids", foletype_s_progids, 0); + rb_define_alloc_func(cWIN32OLE_TYPE, foletype_s_allocate); + rb_define_method(cWIN32OLE_TYPE, "initialize", foletype_initialize, 2); + rb_define_method(cWIN32OLE_TYPE, "name", foletype_name, 0); + rb_define_method(cWIN32OLE_TYPE, "ole_type", foletype_ole_type, 0); + rb_define_method(cWIN32OLE_TYPE, "guid", foletype_guid, 0); + rb_define_method(cWIN32OLE_TYPE, "progid", foletype_progid, 0); + rb_define_method(cWIN32OLE_TYPE, "visible?", foletype_visible, 0); + rb_define_alias(cWIN32OLE_TYPE, "to_s", "name"); + rb_define_method(cWIN32OLE_TYPE, "major_version", foletype_major_version, 0); + rb_define_method(cWIN32OLE_TYPE, "minor_version", foletype_minor_version, 0); + rb_define_method(cWIN32OLE_TYPE, "typekind", foletype_typekind, 0); + rb_define_method(cWIN32OLE_TYPE, "helpstring", foletype_helpstring, 0); + rb_define_method(cWIN32OLE_TYPE, "src_type", foletype_src_type, 0); + rb_define_method(cWIN32OLE_TYPE, "helpfile", foletype_helpfile, 0); + rb_define_method(cWIN32OLE_TYPE, "helpcontext", foletype_helpcontext, 0); + rb_define_method(cWIN32OLE_TYPE, "variables", foletype_variables, 0); + rb_define_method(cWIN32OLE_TYPE, "ole_methods", foletype_methods, 0); + rb_define_method(cWIN32OLE_TYPE, "ole_typelib", foletype_ole_typelib, 0); + rb_define_method(cWIN32OLE_TYPE, "implemented_ole_types", foletype_impl_ole_types, 0); + rb_define_method(cWIN32OLE_TYPE, "source_ole_types", foletype_source_ole_types, 0); + rb_define_method(cWIN32OLE_TYPE, "default_event_sources", foletype_default_event_sources, 0); + rb_define_method(cWIN32OLE_TYPE, "default_ole_types", foletype_default_ole_types, 0); + rb_define_method(cWIN32OLE_TYPE, "inspect", foletype_inspect, 0); +} |