diff --git a/ChangeLog b/ChangeLog index 19e1fd9d18..8d40c79587 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Mon Aug 11 20:47:27 2014 Masaki Suketa + + * ext/win32ole/win32ole.c: seperate WIN32OLE_VARIABLE src from + win32ole.c + * ext/win32ole/win32ole.h: ditto. + * ext/win32ole/win32ole_variable.c: ditto. + * ext/win32ole/win32ole_variable.h: ditto. + * ext/win32ole/depend: ditto. + Mon Aug 11 16:17:21 2014 Tony Miller * dir.c (rb_dir_exists_p): [DOC] Document that Dir.exists? is diff --git a/ext/win32ole/depend b/ext/win32ole/depend index 4dd6be5b56..6682f3da5c 100644 --- a/ext/win32ole/depend +++ b/ext/win32ole/depend @@ -3,4 +3,5 @@ win32ole.o : win32ole.c $(WIN32OLE_HEADERS) win32ole_variant_m.o : win32ole_variant_m.c $(WIN32OLE_HEADERS) win32ole_typelib.o : win32ole_typelib.c $(WIN32OLE_HEADERS) win32ole_type.o : win32ole_type.c $(WIN32OLE_HEADERS) +win32ole_variable.o : win32ole_variable.c $(WIN32OLE_HEADERS) win32ole_error.o : win32ole_error.c $(WIN32OLE_HEADERS) diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c index 84f6642fa8..495d4698bc 100644 --- a/ext/win32ole/win32ole.c +++ b/ext/win32ole/win32ole.c @@ -157,18 +157,12 @@ struct oledata { IDispatch *pDispatch; }; -struct olevariabledata { - ITypeInfo *pTypeInfo; - UINT index; -}; - struct olemethoddata { ITypeInfo *pOwnerTypeInfo; ITypeInfo *pTypeInfo; UINT index; }; - struct oleparamdata { ITypeInfo *pTypeInfo; UINT method_index; @@ -219,7 +213,6 @@ static VALUE ole_excepinfo2msg(EXCEPINFO *pExInfo); static void ole_msg_loop(void); static void ole_free(struct oledata *pole); static void olemethod_free(struct olemethoddata *polemethod); -static void olevariable_free(struct olevariabledata *polevar); static void oleparam_free(struct oleparamdata *pole); static LPWSTR ole_mb2wc(char *pm, int len); static VALUE ole_ary_m_entry(VALUE val, LONG *pid); @@ -237,13 +230,11 @@ static void ole_val2ptr_variant(VALUE val, VARIANT *var); static void ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vt); static void ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar); static void ole_val2variant2(VALUE val, VARIANT *var); -static VALUE make_inspect(const char *class_name, VALUE detail); static VALUE ole_set_member(VALUE self, IDispatch *dispatch); static VALUE fole_s_allocate(VALUE klass); static VALUE create_win32ole_object(VALUE klass, IDispatch *pDispatch, int argc, VALUE *argv); static VALUE ary_new_dim(VALUE myary, LONG *pid, LONG *plb, LONG dim); static void ary_store_dim(VALUE myary, LONG *pid, LONG *plb, LONG dim, VALUE val); -static VALUE ole_variant2val(VARIANT *pvar); static void ole_const_load(ITypeLib *pTypeLib, VALUE klass, VALUE self); static HRESULT clsid_from_remote(VALUE host, VALUE com, CLSID *pclsid); static VALUE ole_create_dcom(int argc, VALUE *argv, VALUE self); @@ -301,20 +292,6 @@ static VALUE ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE t static VALUE ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails); static VALUE fole_method_help(VALUE self, VALUE cmdname); static VALUE fole_activex_initialize(VALUE self); -static VALUE folevariable_name(VALUE self); -static VALUE ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index); -static VALUE folevariable_ole_type(VALUE self); -static VALUE ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index); -static VALUE folevariable_ole_type_detail(VALUE self); -static VALUE ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index); -static VALUE folevariable_value(VALUE self); -static VALUE ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index); -static VALUE folevariable_visible(VALUE self); -static VALUE ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index); -static VALUE folevariable_variable_kind(VALUE self); -static VALUE ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index); -static VALUE folevariable_varkind(VALUE self); -static VALUE folevariable_inspect(VALUE self); static VALUE olemethod_set_member(VALUE self, ITypeInfo *pTypeInfo, ITypeInfo *pOwnerTypeInfo, int index, VALUE name); static VALUE folemethod_s_allocate(VALUE klass); static VALUE folemethod_initialize(VALUE self, VALUE oletype, VALUE method); @@ -1066,13 +1043,6 @@ olemethod_free(struct olemethoddata *polemethod) free(polemethod); } -static void -olevariable_free(struct olevariabledata *polevar) -{ - OLE_FREE(polevar->pTypeInfo); - free(polevar); -} - static void oleparam_free(struct oleparamdata *pole) { @@ -1080,7 +1050,6 @@ oleparam_free(struct oleparamdata *pole) free(pole); } - LPWSTR ole_vstr2wc(VALUE vstr) { @@ -1841,7 +1810,7 @@ ole_val2variant2(VALUE val, VARIANT *var) g_nil_to = VT_ERROR; } -static VALUE +VALUE make_inspect(const char *class_name, VALUE detail) { VALUE str; @@ -1926,7 +1895,7 @@ ary_store_dim(VALUE myary, LONG *pid, LONG *plb, LONG dim, VALUE val) { rb_ary_store(obj, id, val); } -static VALUE +VALUE ole_variant2val(VARIANT *pvar) { VALUE obj = Qnil; @@ -4545,330 +4514,6 @@ fole_activex_initialize(VALUE self) return Qnil; } - -/* - * Document-class: WIN32OLE_VARIABLE - * - * WIN32OLE_VARIABLE objects represent OLE variable information. - */ - -VALUE -create_win32ole_variable(ITypeInfo *pTypeInfo, UINT index, VALUE name) -{ - struct olevariabledata *pvar; - VALUE obj = Data_Make_Struct(cWIN32OLE_VARIABLE, struct olevariabledata, - 0,olevariable_free,pvar); - pvar->pTypeInfo = pTypeInfo; - OLE_ADDREF(pTypeInfo); - pvar->index = index; - rb_ivar_set(obj, rb_intern("name"), name); - return obj; -} - -/* - * call-seq: - * WIN32OLE_VARIABLE#name - * - * Returns the name of variable. - * - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') - * variables = tobj.variables - * variables.each do |variable| - * puts "#{variable.name}" - * end - * - * The result of above script is following: - * xlChart - * xlDialogSheet - * xlExcel4IntlMacroSheet - * xlExcel4MacroSheet - * xlWorksheet - * - */ -static VALUE -folevariable_name(VALUE self) -{ - return rb_ivar_get(self, rb_intern("name")); -} - -static VALUE -ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index) -{ - VARDESC *pVarDesc; - HRESULT hr; - VALUE type; - hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); - if (FAILED(hr)) - ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc"); - type = ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), Qnil); - pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); - return type; -} - -/* - * call-seq: - * WIN32OLE_VARIABLE#ole_type - * - * Returns OLE type string. - * - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') - * variables = tobj.variables - * variables.each do |variable| - * puts "#{variable.ole_type} #{variable.name}" - * end - * - * The result of above script is following: - * INT xlChart - * INT xlDialogSheet - * INT xlExcel4IntlMacroSheet - * INT xlExcel4MacroSheet - * INT xlWorksheet - * - */ -static VALUE -folevariable_ole_type(VALUE self) -{ - struct olevariabledata *pvar; - Data_Get_Struct(self, struct olevariabledata, pvar); - return ole_variable_ole_type(pvar->pTypeInfo, pvar->index); -} - -static VALUE -ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index) -{ - VARDESC *pVarDesc; - HRESULT hr; - VALUE type = rb_ary_new(); - hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); - if (FAILED(hr)) - ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc"); - ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), type); - pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); - return type; -} - -/* - * call-seq: - * WIN32OLE_VARIABLE#ole_type_detail - * - * Returns detail information of type. The information is array of type. - * - * tobj = WIN32OLE_TYPE.new('DirectX 7 for Visual Basic Type Library', 'D3DCLIPSTATUS') - * variable = tobj.variables.find {|variable| variable.name == 'lFlags'} - * tdetail = variable.ole_type_detail - * p tdetail # => ["USERDEFINED", "CONST_D3DCLIPSTATUSFLAGS"] - * - */ -static VALUE -folevariable_ole_type_detail(VALUE self) -{ - struct olevariabledata *pvar; - Data_Get_Struct(self, struct olevariabledata, pvar); - return ole_variable_ole_type_detail(pvar->pTypeInfo, pvar->index); -} - -static VALUE -ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index) -{ - VARDESC *pVarDesc; - HRESULT hr; - VALUE val = Qnil; - hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); - if (FAILED(hr)) - return Qnil; - if(pVarDesc->varkind == VAR_CONST) - val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue)); - pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); - return val; -} - -/* - * call-seq: - * WIN32OLE_VARIABLE#value - * - * Returns value if value is exists. If the value does not exist, - * this method returns nil. - * - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') - * variables = tobj.variables - * variables.each do |variable| - * puts "#{variable.name} #{variable.value}" - * end - * - * The result of above script is following: - * xlChart = -4109 - * xlDialogSheet = -4116 - * xlExcel4IntlMacroSheet = 4 - * xlExcel4MacroSheet = 3 - * xlWorksheet = -4167 - * - */ -static VALUE -folevariable_value(VALUE self) -{ - struct olevariabledata *pvar; - Data_Get_Struct(self, struct olevariabledata, pvar); - return ole_variable_value(pvar->pTypeInfo, pvar->index); -} - -static VALUE -ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index) -{ - VARDESC *pVarDesc; - HRESULT hr; - VALUE visible = Qfalse; - hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); - if (FAILED(hr)) - return visible; - if (!(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN | - VARFLAG_FRESTRICTED | - VARFLAG_FNONBROWSABLE))) { - visible = Qtrue; - } - pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); - return visible; -} - -/* - * call-seq: - * WIN32OLE_VARIABLE#visible? - * - * Returns true if the variable is public. - * - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') - * variables = tobj.variables - * variables.each do |variable| - * puts "#{variable.name} #{variable.visible?}" - * end - * - * The result of above script is following: - * xlChart true - * xlDialogSheet true - * xlExcel4IntlMacroSheet true - * xlExcel4MacroSheet true - * xlWorksheet true - * - */ -static VALUE -folevariable_visible(VALUE self) -{ - struct olevariabledata *pvar; - Data_Get_Struct(self, struct olevariabledata, pvar); - return ole_variable_visible(pvar->pTypeInfo, pvar->index); -} - -static VALUE -ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index) -{ - VARDESC *pVarDesc; - HRESULT hr; - VALUE kind = rb_str_new2("UNKNOWN"); - hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); - if (FAILED(hr)) - return kind; - switch(pVarDesc->varkind) { - case VAR_PERINSTANCE: - kind = rb_str_new2("PERINSTANCE"); - break; - case VAR_STATIC: - kind = rb_str_new2("STATIC"); - break; - case VAR_CONST: - kind = rb_str_new2("CONSTANT"); - break; - case VAR_DISPATCH: - kind = rb_str_new2("DISPATCH"); - break; - default: - break; - } - pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); - return kind; -} - -/* - * call-seq: - * WIN32OLE_VARIABLE#variable_kind - * - * Returns variable kind string. - * - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') - * variables = tobj.variables - * variables.each do |variable| - * puts "#{variable.name} #{variable.variable_kind}" - * end - * - * The result of above script is following: - * xlChart CONSTANT - * xlDialogSheet CONSTANT - * xlExcel4IntlMacroSheet CONSTANT - * xlExcel4MacroSheet CONSTANT - * xlWorksheet CONSTANT - */ -static VALUE -folevariable_variable_kind(VALUE self) -{ - struct olevariabledata *pvar; - Data_Get_Struct(self, struct olevariabledata, pvar); - return ole_variable_kind(pvar->pTypeInfo, pvar->index); -} - -static VALUE -ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index) -{ - VARDESC *pVarDesc; - HRESULT hr; - VALUE kind = Qnil; - hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); - if (FAILED(hr)) - return kind; - pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); - kind = INT2FIX(pVarDesc->varkind); - return kind; -} - -/* - * call-seq: - * WIN32OLE_VARIABLE#varkind - * - * Returns the number which represents variable kind. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') - * variables = tobj.variables - * variables.each do |variable| - * puts "#{variable.name} #{variable.varkind}" - * end - * - * The result of above script is following: - * xlChart 2 - * xlDialogSheet 2 - * xlExcel4IntlMacroSheet 2 - * xlExcel4MacroSheet 2 - * xlWorksheet 2 - */ -static VALUE -folevariable_varkind(VALUE self) -{ - struct olevariabledata *pvar; - Data_Get_Struct(self, struct olevariabledata, pvar); - return ole_variable_varkind(pvar->pTypeInfo, pvar->index); -} - -/* - * call-seq: - * WIN32OLE_VARIABLE#inspect -> String - * - * Returns the OLE variable name and the value with class name. - * - */ -static VALUE -folevariable_inspect(VALUE self) -{ - VALUE detail = rb_funcall(self, rb_intern("to_s"), 0); - rb_str_cat2(detail, "="); - rb_str_concat(detail, rb_funcall(rb_funcall(self, rb_intern("value"), 0), rb_intern("inspect"), 0)); - return make_inspect("WIN32OLE_VARIABLE", detail); -} - /* * Document-class: WIN32OLE_METHOD * @@ -8127,17 +7772,7 @@ Init_win32ole(void) Init_win32ole_variant_m(); Init_win32ole_typelib(); Init_win32ole_type(); - - cWIN32OLE_VARIABLE = rb_define_class("WIN32OLE_VARIABLE", rb_cObject); - rb_define_method(cWIN32OLE_VARIABLE, "name", folevariable_name, 0); - rb_define_method(cWIN32OLE_VARIABLE, "ole_type", folevariable_ole_type, 0); - rb_define_method(cWIN32OLE_VARIABLE, "ole_type_detail", folevariable_ole_type_detail, 0); - rb_define_method(cWIN32OLE_VARIABLE, "value", folevariable_value, 0); - rb_define_method(cWIN32OLE_VARIABLE, "visible?", folevariable_visible, 0); - rb_define_method(cWIN32OLE_VARIABLE, "variable_kind", folevariable_variable_kind, 0); - rb_define_method(cWIN32OLE_VARIABLE, "varkind", folevariable_varkind, 0); - rb_define_method(cWIN32OLE_VARIABLE, "inspect", folevariable_inspect, 0); - rb_define_alias(cWIN32OLE_VARIABLE, "to_s", "name"); + Init_win32ole_variable(); cWIN32OLE_METHOD = rb_define_class("WIN32OLE_METHOD", rb_cObject); rb_define_alloc_func(cWIN32OLE_METHOD, folemethod_s_allocate); diff --git a/ext/win32ole/win32ole.h b/ext/win32ole/win32ole.h index 8bd704a641..2a5af705af 100644 --- a/ext/win32ole/win32ole.h +++ b/ext/win32ole/win32ole.h @@ -97,7 +97,6 @@ #define OLE_RELEASE_TYPEATTR(X, Y) ((X)->lpVtbl->ReleaseTypeAttr((X), (Y))) VALUE cWIN32OLE; -VALUE cWIN32OLE_VARIABLE; LCID cWIN32OLE_lcid; @@ -119,12 +118,13 @@ HRESULT ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, D VALUE ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails); VALUE ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo); VALUE ole_type_from_itypeinfo(ITypeInfo *pTypeInfo); - -VALUE create_win32ole_variable(ITypeInfo *pTypeInfo, UINT index, VALUE name); +VALUE make_inspect(const char *class_name, VALUE detail); +VALUE ole_variant2val(VARIANT *pvar); #include "win32ole_variant_m.h" #include "win32ole_typelib.h" #include "win32ole_type.h" +#include "win32ole_variable.h" #include "win32ole_error.h" #endif diff --git a/ext/win32ole/win32ole_variable.c b/ext/win32ole/win32ole_variable.c new file mode 100644 index 0000000000..57a8115fb5 --- /dev/null +++ b/ext/win32ole/win32ole_variable.c @@ -0,0 +1,366 @@ +#include "win32ole.h" + +struct olevariabledata { + ITypeInfo *pTypeInfo; + UINT index; +}; + +static void olevariable_free(struct olevariabledata *polevar); +static VALUE folevariable_name(VALUE self); +static VALUE ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index); +static VALUE folevariable_ole_type(VALUE self); +static VALUE ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index); +static VALUE folevariable_ole_type_detail(VALUE self); +static VALUE ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index); +static VALUE folevariable_value(VALUE self); +static VALUE ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index); +static VALUE folevariable_visible(VALUE self); +static VALUE ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index); +static VALUE folevariable_variable_kind(VALUE self); +static VALUE ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index); +static VALUE folevariable_varkind(VALUE self); +static VALUE folevariable_inspect(VALUE self); + +static void +olevariable_free(struct olevariabledata *polevar) +{ + OLE_FREE(polevar->pTypeInfo); + free(polevar); +} + +/* + * Document-class: WIN32OLE_VARIABLE + * + * WIN32OLE_VARIABLE objects represent OLE variable information. + */ + +VALUE +create_win32ole_variable(ITypeInfo *pTypeInfo, UINT index, VALUE name) +{ + struct olevariabledata *pvar; + VALUE obj = Data_Make_Struct(cWIN32OLE_VARIABLE, struct olevariabledata, + 0,olevariable_free,pvar); + pvar->pTypeInfo = pTypeInfo; + OLE_ADDREF(pTypeInfo); + pvar->index = index; + rb_ivar_set(obj, rb_intern("name"), name); + return obj; +} + +/* + * call-seq: + * WIN32OLE_VARIABLE#name + * + * Returns the name of variable. + * + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') + * variables = tobj.variables + * variables.each do |variable| + * puts "#{variable.name}" + * end + * + * The result of above script is following: + * xlChart + * xlDialogSheet + * xlExcel4IntlMacroSheet + * xlExcel4MacroSheet + * xlWorksheet + * + */ +static VALUE +folevariable_name(VALUE self) +{ + return rb_ivar_get(self, rb_intern("name")); +} + +static VALUE +ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index) +{ + VARDESC *pVarDesc; + HRESULT hr; + VALUE type; + hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); + if (FAILED(hr)) + ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc"); + type = ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), Qnil); + pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); + return type; +} + +/* + * call-seq: + * WIN32OLE_VARIABLE#ole_type + * + * Returns OLE type string. + * + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') + * variables = tobj.variables + * variables.each do |variable| + * puts "#{variable.ole_type} #{variable.name}" + * end + * + * The result of above script is following: + * INT xlChart + * INT xlDialogSheet + * INT xlExcel4IntlMacroSheet + * INT xlExcel4MacroSheet + * INT xlWorksheet + * + */ +static VALUE +folevariable_ole_type(VALUE self) +{ + struct olevariabledata *pvar; + Data_Get_Struct(self, struct olevariabledata, pvar); + return ole_variable_ole_type(pvar->pTypeInfo, pvar->index); +} + +static VALUE +ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index) +{ + VARDESC *pVarDesc; + HRESULT hr; + VALUE type = rb_ary_new(); + hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); + if (FAILED(hr)) + ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc"); + ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), type); + pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); + return type; +} + +/* + * call-seq: + * WIN32OLE_VARIABLE#ole_type_detail + * + * Returns detail information of type. The information is array of type. + * + * tobj = WIN32OLE_TYPE.new('DirectX 7 for Visual Basic Type Library', 'D3DCLIPSTATUS') + * variable = tobj.variables.find {|variable| variable.name == 'lFlags'} + * tdetail = variable.ole_type_detail + * p tdetail # => ["USERDEFINED", "CONST_D3DCLIPSTATUSFLAGS"] + * + */ +static VALUE +folevariable_ole_type_detail(VALUE self) +{ + struct olevariabledata *pvar; + Data_Get_Struct(self, struct olevariabledata, pvar); + return ole_variable_ole_type_detail(pvar->pTypeInfo, pvar->index); +} + +static VALUE +ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index) +{ + VARDESC *pVarDesc; + HRESULT hr; + VALUE val = Qnil; + hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); + if (FAILED(hr)) + return Qnil; + if(pVarDesc->varkind == VAR_CONST) + val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue)); + pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); + return val; +} + +/* + * call-seq: + * WIN32OLE_VARIABLE#value + * + * Returns value if value is exists. If the value does not exist, + * this method returns nil. + * + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') + * variables = tobj.variables + * variables.each do |variable| + * puts "#{variable.name} #{variable.value}" + * end + * + * The result of above script is following: + * xlChart = -4109 + * xlDialogSheet = -4116 + * xlExcel4IntlMacroSheet = 4 + * xlExcel4MacroSheet = 3 + * xlWorksheet = -4167 + * + */ +static VALUE +folevariable_value(VALUE self) +{ + struct olevariabledata *pvar; + Data_Get_Struct(self, struct olevariabledata, pvar); + return ole_variable_value(pvar->pTypeInfo, pvar->index); +} + +static VALUE +ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index) +{ + VARDESC *pVarDesc; + HRESULT hr; + VALUE visible = Qfalse; + hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); + if (FAILED(hr)) + return visible; + if (!(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN | + VARFLAG_FRESTRICTED | + VARFLAG_FNONBROWSABLE))) { + visible = Qtrue; + } + pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); + return visible; +} + +/* + * call-seq: + * WIN32OLE_VARIABLE#visible? + * + * Returns true if the variable is public. + * + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') + * variables = tobj.variables + * variables.each do |variable| + * puts "#{variable.name} #{variable.visible?}" + * end + * + * The result of above script is following: + * xlChart true + * xlDialogSheet true + * xlExcel4IntlMacroSheet true + * xlExcel4MacroSheet true + * xlWorksheet true + * + */ +static VALUE +folevariable_visible(VALUE self) +{ + struct olevariabledata *pvar; + Data_Get_Struct(self, struct olevariabledata, pvar); + return ole_variable_visible(pvar->pTypeInfo, pvar->index); +} + +static VALUE +ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index) +{ + VARDESC *pVarDesc; + HRESULT hr; + VALUE kind = rb_str_new2("UNKNOWN"); + hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); + if (FAILED(hr)) + return kind; + switch(pVarDesc->varkind) { + case VAR_PERINSTANCE: + kind = rb_str_new2("PERINSTANCE"); + break; + case VAR_STATIC: + kind = rb_str_new2("STATIC"); + break; + case VAR_CONST: + kind = rb_str_new2("CONSTANT"); + break; + case VAR_DISPATCH: + kind = rb_str_new2("DISPATCH"); + break; + default: + break; + } + pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); + return kind; +} + +/* + * call-seq: + * WIN32OLE_VARIABLE#variable_kind + * + * Returns variable kind string. + * + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') + * variables = tobj.variables + * variables.each do |variable| + * puts "#{variable.name} #{variable.variable_kind}" + * end + * + * The result of above script is following: + * xlChart CONSTANT + * xlDialogSheet CONSTANT + * xlExcel4IntlMacroSheet CONSTANT + * xlExcel4MacroSheet CONSTANT + * xlWorksheet CONSTANT + */ +static VALUE +folevariable_variable_kind(VALUE self) +{ + struct olevariabledata *pvar; + Data_Get_Struct(self, struct olevariabledata, pvar); + return ole_variable_kind(pvar->pTypeInfo, pvar->index); +} + +static VALUE +ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index) +{ + VARDESC *pVarDesc; + HRESULT hr; + VALUE kind = Qnil; + hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc); + if (FAILED(hr)) + return kind; + pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); + kind = INT2FIX(pVarDesc->varkind); + return kind; +} + +/* + * call-seq: + * WIN32OLE_VARIABLE#varkind + * + * Returns the number which represents variable kind. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') + * variables = tobj.variables + * variables.each do |variable| + * puts "#{variable.name} #{variable.varkind}" + * end + * + * The result of above script is following: + * xlChart 2 + * xlDialogSheet 2 + * xlExcel4IntlMacroSheet 2 + * xlExcel4MacroSheet 2 + * xlWorksheet 2 + */ +static VALUE +folevariable_varkind(VALUE self) +{ + struct olevariabledata *pvar; + Data_Get_Struct(self, struct olevariabledata, pvar); + return ole_variable_varkind(pvar->pTypeInfo, pvar->index); +} + +/* + * call-seq: + * WIN32OLE_VARIABLE#inspect -> String + * + * Returns the OLE variable name and the value with class name. + * + */ +static VALUE +folevariable_inspect(VALUE self) +{ + VALUE detail = rb_funcall(self, rb_intern("to_s"), 0); + rb_str_cat2(detail, "="); + rb_str_concat(detail, rb_funcall(rb_funcall(self, rb_intern("value"), 0), rb_intern("inspect"), 0)); + return make_inspect("WIN32OLE_VARIABLE", detail); +} + +void Init_win32ole_variable() +{ + cWIN32OLE_VARIABLE = rb_define_class("WIN32OLE_VARIABLE", rb_cObject); + rb_define_method(cWIN32OLE_VARIABLE, "name", folevariable_name, 0); + rb_define_method(cWIN32OLE_VARIABLE, "ole_type", folevariable_ole_type, 0); + rb_define_method(cWIN32OLE_VARIABLE, "ole_type_detail", folevariable_ole_type_detail, 0); + rb_define_method(cWIN32OLE_VARIABLE, "value", folevariable_value, 0); + rb_define_method(cWIN32OLE_VARIABLE, "visible?", folevariable_visible, 0); + rb_define_method(cWIN32OLE_VARIABLE, "variable_kind", folevariable_variable_kind, 0); + rb_define_method(cWIN32OLE_VARIABLE, "varkind", folevariable_varkind, 0); + rb_define_method(cWIN32OLE_VARIABLE, "inspect", folevariable_inspect, 0); + rb_define_alias(cWIN32OLE_VARIABLE, "to_s", "name"); +} diff --git a/ext/win32ole/win32ole_variable.h b/ext/win32ole/win32ole_variable.h new file mode 100644 index 0000000000..dbb27acf9b --- /dev/null +++ b/ext/win32ole/win32ole_variable.h @@ -0,0 +1,8 @@ +#ifndef WIN32OLE_VARIABLE_H +#define WIN32OLE_VARIABLE_H 1 + +VALUE cWIN32OLE_VARIABLE; +VALUE create_win32ole_variable(ITypeInfo *pTypeInfo, UINT index, VALUE name); +void Init_win32ole_variable(); + +#endif