From 14f0a0d0bd25b02ced6d43c6335ecc9bf68fe605 Mon Sep 17 00:00:00 2001 From: suke Date: Sat, 30 Jul 2005 09:51:48 +0000 Subject: add WIN32OLE_TYPE#ole_typelib, WIN32OLE_TYPE#implemented_ole_types. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8867 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 7 ++ ext/win32ole/tests/testOLETYPE.rb | 15 +++ ext/win32ole/win32ole.c | 191 +++++++++++++++++++++++++++++--------- 3 files changed, 169 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7b367f9ff6..8212c8b9de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Sat Jul 30 18:49:44 2005 Masaki Suketa + + * ext/win32ole/win32ole.c: add WIN32OLE_TYPE#ole_typelib, + WIN32OLE_TYPE#implemented_ole_types. + + * ext/win32ole/tests/testOLETYPE.rb: ditto. + Fri Jul 29 16:12:02 005 Keiju Ishitsuka * lib/irb/context.rb: fix `irb --readline` option. [ruby-dev:40955] diff --git a/ext/win32ole/tests/testOLETYPE.rb b/ext/win32ole/tests/testOLETYPE.rb index d4eb1146e1..510691484f 100644 --- a/ext/win32ole/tests/testOLETYPE.rb +++ b/ext/win32ole/tests/testOLETYPE.rb @@ -93,4 +93,19 @@ class TestOLETYPE < RUNIT::TestCase type = WIN32OLE_TYPE.new(MS_EXCEL_TYPELIB, 'Application') assert_equal("Application", "#{type}"); end + def test_ole_typelib + type = WIN32OLE_TYPE.new(MS_EXCEL_TYPELIB, 'Application') + tlib = type.ole_typelib + assert_instance_of(WIN32OLE_TYPELIB, tlib); + assert_equal(MS_EXCEL_TYPELIB, tlib.name); + end + + def test_implemented_ole_types + type = WIN32OLE_TYPE.new(MS_EXCEL_TYPELIB, 'Application') + impltypes = type.implemented_ole_types + assert_instance_of(Array, impltypes); + assert_equal('_Application', impltypes[0].name) + assert_equal('AppEvents', impltypes[1].name) + end + end diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c index 61bc4d3e04..d5bba47fae 100644 --- a/ext/win32ole/win32ole.c +++ b/ext/win32ole/win32ole.c @@ -79,7 +79,7 @@ #define WC2VSTR(x) ole_wc2vstr((x), TRUE) -#define WIN32OLE_VERSION "0.6.5" +#define WIN32OLE_VERSION "0.6.6" typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX) (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*); @@ -2980,6 +2980,31 @@ fole_func_methods( self ) return ole_methods( self, INVOKE_FUNC); } +static VALUE +ole_type_from_itypeinfo(pTypeInfo) + 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 = foletype_s_allocate(cWIN32OLE_TYPE); + oletype_set_member(type, pTypeInfo, WC2VSTR(bstr)); + return type; +} + /* * call-seq: * WIN32OLE#ole_type @@ -2993,12 +3018,9 @@ static VALUE fole_type( self ) VALUE self; { - unsigned int index; ITypeInfo *pTypeInfo; - ITypeLib *pTypeLib; HRESULT hr; struct oledata *pole; - BSTR bstr; LCID lcid = LOCALE_SYSTEM_DEFAULT; VALUE type = Qnil; @@ -3008,20 +3030,11 @@ fole_type( self ) if(FAILED(hr)) { ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo"); } - hr = pTypeInfo->lpVtbl->GetContainingTypeLib( pTypeInfo, &pTypeLib, &index ); - if(FAILED(hr)) { - OLE_RELEASE(pTypeInfo); - ole_raise(hr, rb_eRuntimeError, "failed to GetContainingTypeLib"); - } - hr = pTypeLib->lpVtbl->GetDocumentation( pTypeLib, index, - &bstr, NULL, NULL, NULL); - if (SUCCEEDED(hr)) { - type = foletype_s_allocate(cWIN32OLE_TYPE); - oletype_set_member(type, pTypeInfo, WC2VSTR(bstr)); - } - OLE_RELEASE(pTypeLib); + type = ole_type_from_itypeinfo(pTypeInfo); OLE_RELEASE(pTypeInfo); - + if (type == Qnil) { + rb_raise(rb_eRuntimeError, "failed to create WIN32OLE_TYPE obj from ITypeInfo"); + } return type; } @@ -3038,46 +3051,24 @@ make_oletypelib_obj(guid, major_version, minor_version) return rb_apply(cWIN32OLE_TYPELIB, rb_intern("new"), args); } -/* - * call-seq: - * WIN32OLE#ole_typelib -> The WIN32OLE_TYPELIB object - * - * Returns the WIN32OLE_TYPELIB object. The object represents the - * type library which contains the WIN32OLE object. - * - * excel = WIN32OLE.new('Excel.Application') - * tlib = excel.ole_typelib - * puts tlib.name # -> 'Microsoft Excel 9.0 Object Library' - */ static VALUE -fole_typelib(self) - VALUE self; +ole_typelib_from_itypeinfo(pTypeInfo) + ITypeInfo *pTypeInfo; { - struct oledata *pole; HRESULT hr; - ITypeInfo *pTypeInfo; ITypeLib *pTypeLib; TLIBATTR *pTLibAttr; - unsigned int index; OLECHAR bstr[80]; int len; VALUE guid = Qnil; VALUE major; VALUE minor; - LCID lcid = LOCALE_SYSTEM_DEFAULT; + unsigned int index; - OLEData_Get_Struct(self, pole); - hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch, - 0, lcid, &pTypeInfo); - if(FAILED(hr)) { - ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo"); - } hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index); if(FAILED(hr)) { - OLE_RELEASE(pTypeInfo); - ole_raise(hr, rb_eRuntimeError, "failed to GetContainingTypeLib"); + return Qnil; } - OLE_RELEASE(pTypeInfo); hr = pTypeLib->lpVtbl->GetLibAttr(pTypeLib, &pTLibAttr); @@ -3090,11 +3081,46 @@ fole_typelib(self) pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr); OLE_RELEASE(pTypeLib); if (guid == Qnil) { - rb_raise(eWIN32OLE_RUNTIME_ERROR, "failed to get typelib"); + return Qnil; } return make_oletypelib_obj(guid, major, minor); } +/* + * call-seq: + * WIN32OLE#ole_typelib -> The WIN32OLE_TYPELIB object + * + * Returns the WIN32OLE_TYPELIB object. The object represents the + * type library which contains the WIN32OLE object. + * + * excel = WIN32OLE.new('Excel.Application') + * tlib = excel.ole_typelib + * puts tlib.name # -> 'Microsoft Excel 9.0 Object Library' + */ +static VALUE +fole_typelib(self) + VALUE self; +{ + struct oledata *pole; + HRESULT hr; + ITypeInfo *pTypeInfo; + LCID lcid = LOCALE_SYSTEM_DEFAULT; + VALUE vtlib = Qnil; + + OLEData_Get_Struct(self, pole); + hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch, + 0, lcid, &pTypeInfo); + if(FAILED(hr)) { + ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo"); + } + vtlib = ole_typelib_from_itypeinfo(pTypeInfo); + OLE_RELEASE(pTypeInfo); + if (vtlib == Qnil) { + rb_raise(rb_eRuntimeError, "failed to get type library info."); + } + return vtlib; +} + static HRESULT ole_docinfo_from_type(pTypeInfo, name, helpstr, helpcontext, helpfile) ITypeInfo *pTypeInfo; @@ -4431,6 +4457,81 @@ foletype_helpcontext(self) return ole_type_helpcontext(ptype->pTypeInfo); } +/* + * 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(self) + VALUE self; +{ + struct oletypedata *ptype; + Data_Get_Struct(self, struct oletypedata, ptype); + return ole_typelib_from_itypeinfo(ptype->pTypeInfo); +} + +static VALUE +ole_type_impl_ole_types(pTypeInfo) + ITypeInfo *pTypeInfo; +{ + 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; + 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(self) + VALUE self; +{ + struct oletypedata *ptype; + Data_Get_Struct(self, struct oletypedata, ptype); + return ole_type_impl_ole_types(ptype->pTypeInfo); +} + static VALUE ole_variables(pTypeInfo) ITypeInfo *pTypeInfo; @@ -6709,6 +6810,8 @@ Init_win32ole() 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, -1); + rb_define_method(cWIN32OLE_TYPE, "ole_typelib", foletype_ole_typelib, 0); + rb_define_method(cWIN32OLE_TYPE, "implemented_ole_types", foletype_impl_ole_types, 0); cWIN32OLE_VARIABLE = rb_define_class("WIN32OLE_VARIABLE", rb_cObject); rb_define_method(cWIN32OLE_VARIABLE, "name", folevariable_name, 0); -- cgit v1.2.3