From 47b2057a022f9aec1c064feb294a11013a10bf92 Mon Sep 17 00:00:00 2001 From: suke Date: Tue, 12 Aug 2014 15:09:29 +0000 Subject: * ext/win32ole/win32ole.c: seperate WIN32OLE_PARAM src from win32ole.c * ext/win32ole/win32ole.h: ditto. * ext/win32ole/win32ole_param.c: ditto. * ext/win32ole/win32ole_param.h: ditto. * ext/win32ole/depend: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47157 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/win32ole/depend | 1 + ext/win32ole/win32ole.c | 413 +---------------------------------------- ext/win32ole/win32ole.h | 2 +- ext/win32ole/win32ole_param.c | 418 ++++++++++++++++++++++++++++++++++++++++++ ext/win32ole/win32ole_param.h | 8 + 5 files changed, 430 insertions(+), 412 deletions(-) create mode 100644 ext/win32ole/win32ole_param.c create mode 100644 ext/win32ole/win32ole_param.h (limited to 'ext') diff --git a/ext/win32ole/depend b/ext/win32ole/depend index ce3fe96d33..8b7a655c99 100644 --- a/ext/win32ole/depend +++ b/ext/win32ole/depend @@ -5,4 +5,5 @@ 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_method.o : win32ole_method.c $(WIN32OLE_HEADERS) +win32ole_param.o : win32ole_param.c $(WIN32OLE_HEADERS) win32ole_error.o : win32ole_error.c $(WIN32OLE_HEADERS) diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c index d4886d1430..5a57813a75 100644 --- a/ext/win32ole/win32ole.c +++ b/ext/win32ole/win32ole.c @@ -103,7 +103,6 @@ typedef struct tagIEVENTSINKOBJ { }IEVENTSINKOBJ, *PIEVENTSINKOBJ; VALUE cWIN32OLE; -VALUE cWIN32OLE_PARAM; VALUE cWIN32OLE_EVENT; VALUE cWIN32OLE_VARIANT; VALUE cWIN32OLE_PROPERTY; @@ -152,11 +151,6 @@ struct oledata { IDispatch *pDispatch; }; -struct oleparamdata { - ITypeInfo *pTypeInfo; - UINT method_index; - UINT index; -}; struct oleeventdata { DWORD dwCookie; @@ -201,7 +195,6 @@ static void ole_freeexceptinfo(EXCEPINFO *pExInfo); static VALUE ole_excepinfo2msg(EXCEPINFO *pExInfo); static void ole_msg_loop(void); static void ole_free(struct oledata *pole); -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); static void * get_ptr_of_variant(VARIANT *pvar); @@ -278,23 +271,7 @@ static VALUE ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE ty static VALUE fole_method_help(VALUE self, VALUE cmdname); static VALUE fole_activex_initialize(VALUE self); -static VALUE foleparam_s_allocate(VALUE klass); -static VALUE oleparam_ole_param_from_index(VALUE self, ITypeInfo *pTypeInfo, UINT method_index, int param_index); -static VALUE oleparam_ole_param(VALUE self, VALUE olemethod, int n); -static VALUE foleparam_initialize(VALUE self, VALUE olemethod, VALUE n); -static VALUE foleparam_name(VALUE self); -static VALUE ole_param_ole_type(ITypeInfo *pTypeInfo, UINT method_index, UINT index); -static VALUE foleparam_ole_type(VALUE self); -static VALUE ole_param_ole_type_detail(ITypeInfo *pTypeInfo, UINT method_index, UINT index); -static VALUE foleparam_ole_type_detail(VALUE self); -static VALUE ole_param_flag_mask(ITypeInfo *pTypeInfo, UINT method_index, UINT index, USHORT mask); -static VALUE foleparam_input(VALUE self); -static VALUE foleparam_output(VALUE self); -static VALUE foleparam_optional(VALUE self); -static VALUE foleparam_retval(VALUE self); -static VALUE ole_param_default(ITypeInfo *pTypeInfo, UINT method_index, UINT index); -static VALUE foleparam_default(VALUE self); -static VALUE foleparam_inspect(VALUE self); + static long ole_search_event_at(VALUE ary, VALUE ev); static VALUE ole_search_event(VALUE ary, VALUE ev, BOOL *is_default); static VALUE ole_search_handler_method(VALUE handler, VALUE ev, BOOL *is_default_handler); @@ -984,13 +961,6 @@ ole_free(struct oledata *pole) free(pole); } -static void -oleparam_free(struct oleparamdata *pole) -{ - OLE_FREE(pole->pTypeInfo); - free(pole); -} - LPWSTR ole_vstr2wc(VALUE vstr) { @@ -4280,372 +4250,6 @@ fole_activex_initialize(VALUE self) return Qnil; } -VALUE -create_win32ole_param(ITypeInfo *pTypeInfo, UINT method_index, UINT index, VALUE name) -{ - struct oleparamdata *pparam; - VALUE obj = foleparam_s_allocate(cWIN32OLE_PARAM); - Data_Get_Struct(obj, struct oleparamdata, pparam); - - pparam->pTypeInfo = pTypeInfo; - OLE_ADDREF(pTypeInfo); - pparam->method_index = method_index; - pparam->index = index; - rb_ivar_set(obj, rb_intern("name"), name); - return obj; -} - - -/* - * Document-class: WIN32OLE_PARAM - * - * WIN32OLE_PARAM objects represent param information of - * the OLE method. - */ -static VALUE -foleparam_s_allocate(VALUE klass) -{ - struct oleparamdata *pparam; - VALUE obj; - obj = Data_Make_Struct(klass, - struct oleparamdata, - 0, oleparam_free, pparam); - pparam->pTypeInfo = NULL; - pparam->method_index = 0; - pparam->index = 0; - return obj; -} - -static VALUE -oleparam_ole_param_from_index(VALUE self, ITypeInfo *pTypeInfo, UINT method_index, int param_index) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - BSTR *bstrs; - UINT len; - struct oleparamdata *pparam; - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - ole_raise(hr, rb_eRuntimeError, "fail to ITypeInfo::GetFuncDesc"); - - len = 0; - bstrs = ALLOCA_N(BSTR, pFuncDesc->cParams + 1); - hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pFuncDesc->memid, - bstrs, pFuncDesc->cParams + 1, - &len); - if (FAILED(hr)) { - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - ole_raise(hr, rb_eRuntimeError, "fail to ITypeInfo::GetNames"); - } - SysFreeString(bstrs[0]); - if (param_index < 1 || len <= (UINT)param_index) - { - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - rb_raise(rb_eIndexError, "index of param must be in 1..%d", len); - } - - Data_Get_Struct(self, struct oleparamdata, pparam); - pparam->pTypeInfo = pTypeInfo; - OLE_ADDREF(pTypeInfo); - pparam->method_index = method_index; - pparam->index = param_index - 1; - rb_ivar_set(self, rb_intern("name"), WC2VSTR(bstrs[param_index])); - - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return self; -} - -static VALUE oleparam_ole_param(VALUE self, VALUE olemethod, int n) -{ - struct olemethoddata *pmethod; - Data_Get_Struct(olemethod, struct olemethoddata, pmethod); - return oleparam_ole_param_from_index(self, pmethod->pTypeInfo, pmethod->index, n); -} - -/* - * call-seq: - * WIN32OLE_PARAM.new(method, n) -> WIN32OLE_PARAM object - * - * Returns WIN32OLE_PARAM object which represents OLE parameter information. - * 1st argument should be WIN32OLE_METHOD object. - * 2nd argument `n' is n-th parameter of the method specified by 1st argument. - * - * tobj = WIN32OLE_TYPE.new('Microsoft Scripting Runtime', 'IFileSystem') - * method = WIN32OLE_METHOD.new(tobj, 'CreateTextFile') - * param = WIN32OLE_PARAM.new(method, 2) # => # - * - */ -static VALUE foleparam_initialize(VALUE self, VALUE olemethod, VALUE n) -{ - int idx; - if (!rb_obj_is_kind_of(olemethod, cWIN32OLE_METHOD)) { - rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE_METHOD object"); - } - idx = FIX2INT(n); - return oleparam_ole_param(self, olemethod, idx); -} - -/* - * call-seq: - * WIN32OLE_PARAM#name - * - * Returns name. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') - * param1 = method.params[0] - * puts param1.name # => Filename - */ -static VALUE -foleparam_name(VALUE self) -{ - return rb_ivar_get(self, rb_intern("name")); -} - -static VALUE -ole_param_ole_type(ITypeInfo *pTypeInfo, UINT method_index, UINT index) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - VALUE type = rb_str_new2("unknown type"); - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - return type; - type = ole_typedesc2val(pTypeInfo, - &(pFuncDesc->lprgelemdescParam[index].tdesc), Qnil); - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return type; -} - -/* - * call-seq: - * WIN32OLE_PARAM#ole_type - * - * Returns OLE type of WIN32OLE_PARAM object(parameter of OLE method). - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') - * param1 = method.params[0] - * puts param1.ole_type # => VARIANT - */ -static VALUE -foleparam_ole_type(VALUE self) -{ - struct oleparamdata *pparam; - Data_Get_Struct(self, struct oleparamdata, pparam); - return ole_param_ole_type(pparam->pTypeInfo, pparam->method_index, - pparam->index); -} - -static VALUE -ole_param_ole_type_detail(ITypeInfo *pTypeInfo, UINT method_index, UINT index) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - VALUE typedetail = rb_ary_new(); - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - return typedetail; - ole_typedesc2val(pTypeInfo, - &(pFuncDesc->lprgelemdescParam[index].tdesc), typedetail); - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return typedetail; -} - -/* - * call-seq: - * WIN32OLE_PARAM#ole_type_detail - * - * Returns detail information of type of argument. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'IWorksheetFunction') - * method = WIN32OLE_METHOD.new(tobj, 'SumIf') - * param1 = method.params[0] - * p param1.ole_type_detail # => ["PTR", "USERDEFINED", "Range"] - */ -static VALUE -foleparam_ole_type_detail(VALUE self) -{ - struct oleparamdata *pparam; - Data_Get_Struct(self, struct oleparamdata, pparam); - return ole_param_ole_type_detail(pparam->pTypeInfo, pparam->method_index, - pparam->index); -} - -static VALUE -ole_param_flag_mask(ITypeInfo *pTypeInfo, UINT method_index, UINT index, USHORT mask) -{ - FUNCDESC *pFuncDesc; - HRESULT hr; - VALUE ret = Qfalse; - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if(FAILED(hr)) - return ret; - if (V_UNION1((&(pFuncDesc->lprgelemdescParam[index])), paramdesc).wParamFlags &mask) - ret = Qtrue; - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return ret; -} - -/* - * call-seq: - * WIN32OLE_PARAM#input? - * - * Returns true if the parameter is input. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') - * param1 = method.params[0] - * puts param1.input? # => true - */ -static VALUE foleparam_input(VALUE self) -{ - struct oleparamdata *pparam; - Data_Get_Struct(self, struct oleparamdata, pparam); - return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index, - pparam->index, PARAMFLAG_FIN); -} - -/* - * call-seq: - * WIN32OLE#output? - * - * Returns true if argument is output. - * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'DWebBrowserEvents') - * method = WIN32OLE_METHOD.new(tobj, 'NewWindow') - * method.params.each do |param| - * puts "#{param.name} #{param.output?}" - * end - * - * The result of above script is following: - * URL false - * Flags false - * TargetFrameName false - * PostData false - * Headers false - * Processed true - */ -static VALUE foleparam_output(VALUE self) -{ - struct oleparamdata *pparam; - Data_Get_Struct(self, struct oleparamdata, pparam); - return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index, - pparam->index, PARAMFLAG_FOUT); -} - -/* - * call-seq: - * WIN32OLE_PARAM#optional? - * - * Returns true if argument is optional. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') - * param1 = method.params[0] - * puts "#{param1.name} #{param1.optional?}" # => Filename true - */ -static VALUE foleparam_optional(VALUE self) -{ - struct oleparamdata *pparam; - Data_Get_Struct(self, struct oleparamdata, pparam); - return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index, - pparam->index, PARAMFLAG_FOPT); -} - -/* - * call-seq: - * WIN32OLE_PARAM#retval? - * - * Returns true if argument is return value. - * tobj = WIN32OLE_TYPE.new('DirectX 7 for Visual Basic Type Library', - * 'DirectPlayLobbyConnection') - * method = WIN32OLE_METHOD.new(tobj, 'GetPlayerShortName') - * param = method.params[0] - * puts "#{param.name} #{param.retval?}" # => name true - */ -static VALUE foleparam_retval(VALUE self) -{ - struct oleparamdata *pparam; - Data_Get_Struct(self, struct oleparamdata, pparam); - return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index, - pparam->index, PARAMFLAG_FRETVAL); -} - -static VALUE -ole_param_default(ITypeInfo *pTypeInfo, UINT method_index, UINT index) -{ - FUNCDESC *pFuncDesc; - ELEMDESC *pElemDesc; - PARAMDESCEX * pParamDescEx; - HRESULT hr; - USHORT wParamFlags; - USHORT mask = PARAMFLAG_FOPT|PARAMFLAG_FHASDEFAULT; - VALUE defval = Qnil; - hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); - if (FAILED(hr)) - return defval; - pElemDesc = &pFuncDesc->lprgelemdescParam[index]; - wParamFlags = V_UNION1(pElemDesc, paramdesc).wParamFlags; - if ((wParamFlags & mask) == mask) { - pParamDescEx = V_UNION1(pElemDesc, paramdesc).pparamdescex; - defval = ole_variant2val(&pParamDescEx->varDefaultValue); - } - pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); - return defval; -} - -/* - * call-seq: - * WIN32OLE_PARAM#default - * - * Returns default value. If the default value does not exist, - * this method returns nil. - * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') - * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') - * method.params.each do |param| - * if param.default - * puts "#{param.name} (= #{param.default})" - * else - * puts "#{param}" - * end - * end - * - * The above script result is following: - * Filename - * FileFormat - * Password - * WriteResPassword - * ReadOnlyRecommended - * CreateBackup - * AccessMode (= 1) - * ConflictResolution - * AddToMru - * TextCodepage - * TextVisualLayout - */ -static VALUE foleparam_default(VALUE self) -{ - struct oleparamdata *pparam; - Data_Get_Struct(self, struct oleparamdata, pparam); - return ole_param_default(pparam->pTypeInfo, pparam->method_index, - pparam->index); -} - -/* - * call-seq: - * WIN32OLE_PARAM#inspect -> String - * - * Returns the parameter name with class name. If the parameter has default value, - * then returns name=value string with class name. - * - */ -static VALUE -foleparam_inspect(VALUE self) -{ - VALUE detail = foleparam_name(self); - VALUE defval = foleparam_default(self); - if (defval != Qnil) { - rb_str_cat2(detail, "="); - rb_str_concat(detail, rb_funcall(defval, rb_intern("inspect"), 0)); - } - return make_inspect("WIN32OLE_PARAM", detail); -} - /* * Document-class: WIN32OLE_EVENT * @@ -6841,20 +6445,7 @@ Init_win32ole(void) Init_win32ole_type(); Init_win32ole_variable(); Init_win32ole_method(); - - cWIN32OLE_PARAM = rb_define_class("WIN32OLE_PARAM", rb_cObject); - rb_define_alloc_func(cWIN32OLE_PARAM, foleparam_s_allocate); - rb_define_method(cWIN32OLE_PARAM, "initialize", foleparam_initialize, 2); - rb_define_method(cWIN32OLE_PARAM, "name", foleparam_name, 0); - rb_define_method(cWIN32OLE_PARAM, "ole_type", foleparam_ole_type, 0); - rb_define_method(cWIN32OLE_PARAM, "ole_type_detail", foleparam_ole_type_detail, 0); - rb_define_method(cWIN32OLE_PARAM, "input?", foleparam_input, 0); - rb_define_method(cWIN32OLE_PARAM, "output?", foleparam_output, 0); - rb_define_method(cWIN32OLE_PARAM, "optional?", foleparam_optional, 0); - rb_define_method(cWIN32OLE_PARAM, "retval?", foleparam_retval, 0); - rb_define_method(cWIN32OLE_PARAM, "default", foleparam_default, 0); - rb_define_alias(cWIN32OLE_PARAM, "to_s", "name"); - rb_define_method(cWIN32OLE_PARAM, "inspect", foleparam_inspect, 0); + Init_win32ole_param(); cWIN32OLE_EVENT = rb_define_class("WIN32OLE_EVENT", rb_cObject); rb_define_singleton_method(cWIN32OLE_EVENT, "message_loop", fev_s_msg_loop, 0); diff --git a/ext/win32ole/win32ole.h b/ext/win32ole/win32ole.h index 15c849293c..0508c654ec 100644 --- a/ext/win32ole/win32ole.h +++ b/ext/win32ole/win32ole.h @@ -117,13 +117,13 @@ HRESULT ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, D VALUE ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails); VALUE make_inspect(const char *class_name, VALUE detail); VALUE ole_variant2val(VARIANT *pvar); -VALUE create_win32ole_param(ITypeInfo *pTypeInfo, UINT method_index, UINT index, VALUE name); #include "win32ole_variant_m.h" #include "win32ole_typelib.h" #include "win32ole_type.h" #include "win32ole_variable.h" #include "win32ole_method.h" +#include "win32ole_param.h" #include "win32ole_error.h" #endif diff --git a/ext/win32ole/win32ole_param.c b/ext/win32ole/win32ole_param.c new file mode 100644 index 0000000000..5bec16895b --- /dev/null +++ b/ext/win32ole/win32ole_param.c @@ -0,0 +1,418 @@ +#include "win32ole.h" + +VALUE cWIN32OLE_PARAM; + +struct oleparamdata { + ITypeInfo *pTypeInfo; + UINT method_index; + UINT index; +}; + +static void oleparam_free(struct oleparamdata *pole); +static VALUE foleparam_s_allocate(VALUE klass); +static VALUE oleparam_ole_param_from_index(VALUE self, ITypeInfo *pTypeInfo, UINT method_index, int param_index); +static VALUE oleparam_ole_param(VALUE self, VALUE olemethod, int n); +static VALUE foleparam_initialize(VALUE self, VALUE olemethod, VALUE n); +static VALUE foleparam_name(VALUE self); +static VALUE ole_param_ole_type(ITypeInfo *pTypeInfo, UINT method_index, UINT index); +static VALUE foleparam_ole_type(VALUE self); +static VALUE ole_param_ole_type_detail(ITypeInfo *pTypeInfo, UINT method_index, UINT index); +static VALUE foleparam_ole_type_detail(VALUE self); +static VALUE ole_param_flag_mask(ITypeInfo *pTypeInfo, UINT method_index, UINT index, USHORT mask); +static VALUE foleparam_input(VALUE self); +static VALUE foleparam_output(VALUE self); +static VALUE foleparam_optional(VALUE self); +static VALUE foleparam_retval(VALUE self); +static VALUE ole_param_default(ITypeInfo *pTypeInfo, UINT method_index, UINT index); +static VALUE foleparam_default(VALUE self); +static VALUE foleparam_inspect(VALUE self); + +static void +oleparam_free(struct oleparamdata *pole) +{ + OLE_FREE(pole->pTypeInfo); + free(pole); +} + +VALUE +create_win32ole_param(ITypeInfo *pTypeInfo, UINT method_index, UINT index, VALUE name) +{ + struct oleparamdata *pparam; + VALUE obj = foleparam_s_allocate(cWIN32OLE_PARAM); + Data_Get_Struct(obj, struct oleparamdata, pparam); + + pparam->pTypeInfo = pTypeInfo; + OLE_ADDREF(pTypeInfo); + pparam->method_index = method_index; + pparam->index = index; + rb_ivar_set(obj, rb_intern("name"), name); + return obj; +} + +/* + * Document-class: WIN32OLE_PARAM + * + * WIN32OLE_PARAM objects represent param information of + * the OLE method. + */ +static VALUE +foleparam_s_allocate(VALUE klass) +{ + struct oleparamdata *pparam; + VALUE obj; + obj = Data_Make_Struct(klass, + struct oleparamdata, + 0, oleparam_free, pparam); + pparam->pTypeInfo = NULL; + pparam->method_index = 0; + pparam->index = 0; + return obj; +} + +static VALUE +oleparam_ole_param_from_index(VALUE self, ITypeInfo *pTypeInfo, UINT method_index, int param_index) +{ + FUNCDESC *pFuncDesc; + HRESULT hr; + BSTR *bstrs; + UINT len; + struct oleparamdata *pparam; + hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); + if (FAILED(hr)) + ole_raise(hr, rb_eRuntimeError, "fail to ITypeInfo::GetFuncDesc"); + + len = 0; + bstrs = ALLOCA_N(BSTR, pFuncDesc->cParams + 1); + hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pFuncDesc->memid, + bstrs, pFuncDesc->cParams + 1, + &len); + if (FAILED(hr)) { + pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); + ole_raise(hr, rb_eRuntimeError, "fail to ITypeInfo::GetNames"); + } + SysFreeString(bstrs[0]); + if (param_index < 1 || len <= (UINT)param_index) + { + pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); + rb_raise(rb_eIndexError, "index of param must be in 1..%d", len); + } + + Data_Get_Struct(self, struct oleparamdata, pparam); + pparam->pTypeInfo = pTypeInfo; + OLE_ADDREF(pTypeInfo); + pparam->method_index = method_index; + pparam->index = param_index - 1; + rb_ivar_set(self, rb_intern("name"), WC2VSTR(bstrs[param_index])); + + pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); + return self; +} + +static VALUE oleparam_ole_param(VALUE self, VALUE olemethod, int n) +{ + struct olemethoddata *pmethod; + Data_Get_Struct(olemethod, struct olemethoddata, pmethod); + return oleparam_ole_param_from_index(self, pmethod->pTypeInfo, pmethod->index, n); +} + +/* + * call-seq: + * WIN32OLE_PARAM.new(method, n) -> WIN32OLE_PARAM object + * + * Returns WIN32OLE_PARAM object which represents OLE parameter information. + * 1st argument should be WIN32OLE_METHOD object. + * 2nd argument `n' is n-th parameter of the method specified by 1st argument. + * + * tobj = WIN32OLE_TYPE.new('Microsoft Scripting Runtime', 'IFileSystem') + * method = WIN32OLE_METHOD.new(tobj, 'CreateTextFile') + * param = WIN32OLE_PARAM.new(method, 2) # => # + * + */ +static VALUE foleparam_initialize(VALUE self, VALUE olemethod, VALUE n) +{ + int idx; + if (!rb_obj_is_kind_of(olemethod, cWIN32OLE_METHOD)) { + rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE_METHOD object"); + } + idx = FIX2INT(n); + return oleparam_ole_param(self, olemethod, idx); +} + +/* + * call-seq: + * WIN32OLE_PARAM#name + * + * Returns name. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') + * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') + * param1 = method.params[0] + * puts param1.name # => Filename + */ +static VALUE +foleparam_name(VALUE self) +{ + return rb_ivar_get(self, rb_intern("name")); +} + +static VALUE +ole_param_ole_type(ITypeInfo *pTypeInfo, UINT method_index, UINT index) +{ + FUNCDESC *pFuncDesc; + HRESULT hr; + VALUE type = rb_str_new2("unknown type"); + hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); + if (FAILED(hr)) + return type; + type = ole_typedesc2val(pTypeInfo, + &(pFuncDesc->lprgelemdescParam[index].tdesc), Qnil); + pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); + return type; +} + +/* + * call-seq: + * WIN32OLE_PARAM#ole_type + * + * Returns OLE type of WIN32OLE_PARAM object(parameter of OLE method). + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') + * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') + * param1 = method.params[0] + * puts param1.ole_type # => VARIANT + */ +static VALUE +foleparam_ole_type(VALUE self) +{ + struct oleparamdata *pparam; + Data_Get_Struct(self, struct oleparamdata, pparam); + return ole_param_ole_type(pparam->pTypeInfo, pparam->method_index, + pparam->index); +} + +static VALUE +ole_param_ole_type_detail(ITypeInfo *pTypeInfo, UINT method_index, UINT index) +{ + FUNCDESC *pFuncDesc; + HRESULT hr; + VALUE typedetail = rb_ary_new(); + hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); + if (FAILED(hr)) + return typedetail; + ole_typedesc2val(pTypeInfo, + &(pFuncDesc->lprgelemdescParam[index].tdesc), typedetail); + pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); + return typedetail; +} + +/* + * call-seq: + * WIN32OLE_PARAM#ole_type_detail + * + * Returns detail information of type of argument. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'IWorksheetFunction') + * method = WIN32OLE_METHOD.new(tobj, 'SumIf') + * param1 = method.params[0] + * p param1.ole_type_detail # => ["PTR", "USERDEFINED", "Range"] + */ +static VALUE +foleparam_ole_type_detail(VALUE self) +{ + struct oleparamdata *pparam; + Data_Get_Struct(self, struct oleparamdata, pparam); + return ole_param_ole_type_detail(pparam->pTypeInfo, pparam->method_index, + pparam->index); +} + +static VALUE +ole_param_flag_mask(ITypeInfo *pTypeInfo, UINT method_index, UINT index, USHORT mask) +{ + FUNCDESC *pFuncDesc; + HRESULT hr; + VALUE ret = Qfalse; + hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); + if(FAILED(hr)) + return ret; + if (V_UNION1((&(pFuncDesc->lprgelemdescParam[index])), paramdesc).wParamFlags &mask) + ret = Qtrue; + pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); + return ret; +} + +/* + * call-seq: + * WIN32OLE_PARAM#input? + * + * Returns true if the parameter is input. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') + * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') + * param1 = method.params[0] + * puts param1.input? # => true + */ +static VALUE foleparam_input(VALUE self) +{ + struct oleparamdata *pparam; + Data_Get_Struct(self, struct oleparamdata, pparam); + return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index, + pparam->index, PARAMFLAG_FIN); +} + +/* + * call-seq: + * WIN32OLE#output? + * + * Returns true if argument is output. + * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'DWebBrowserEvents') + * method = WIN32OLE_METHOD.new(tobj, 'NewWindow') + * method.params.each do |param| + * puts "#{param.name} #{param.output?}" + * end + * + * The result of above script is following: + * URL false + * Flags false + * TargetFrameName false + * PostData false + * Headers false + * Processed true + */ +static VALUE foleparam_output(VALUE self) +{ + struct oleparamdata *pparam; + Data_Get_Struct(self, struct oleparamdata, pparam); + return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index, + pparam->index, PARAMFLAG_FOUT); +} + +/* + * call-seq: + * WIN32OLE_PARAM#optional? + * + * Returns true if argument is optional. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') + * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') + * param1 = method.params[0] + * puts "#{param1.name} #{param1.optional?}" # => Filename true + */ +static VALUE foleparam_optional(VALUE self) +{ + struct oleparamdata *pparam; + Data_Get_Struct(self, struct oleparamdata, pparam); + return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index, + pparam->index, PARAMFLAG_FOPT); +} + +/* + * call-seq: + * WIN32OLE_PARAM#retval? + * + * Returns true if argument is return value. + * tobj = WIN32OLE_TYPE.new('DirectX 7 for Visual Basic Type Library', + * 'DirectPlayLobbyConnection') + * method = WIN32OLE_METHOD.new(tobj, 'GetPlayerShortName') + * param = method.params[0] + * puts "#{param.name} #{param.retval?}" # => name true + */ +static VALUE foleparam_retval(VALUE self) +{ + struct oleparamdata *pparam; + Data_Get_Struct(self, struct oleparamdata, pparam); + return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index, + pparam->index, PARAMFLAG_FRETVAL); +} + +static VALUE +ole_param_default(ITypeInfo *pTypeInfo, UINT method_index, UINT index) +{ + FUNCDESC *pFuncDesc; + ELEMDESC *pElemDesc; + PARAMDESCEX * pParamDescEx; + HRESULT hr; + USHORT wParamFlags; + USHORT mask = PARAMFLAG_FOPT|PARAMFLAG_FHASDEFAULT; + VALUE defval = Qnil; + hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); + if (FAILED(hr)) + return defval; + pElemDesc = &pFuncDesc->lprgelemdescParam[index]; + wParamFlags = V_UNION1(pElemDesc, paramdesc).wParamFlags; + if ((wParamFlags & mask) == mask) { + pParamDescEx = V_UNION1(pElemDesc, paramdesc).pparamdescex; + defval = ole_variant2val(&pParamDescEx->varDefaultValue); + } + pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); + return defval; +} + +/* + * call-seq: + * WIN32OLE_PARAM#default + * + * Returns default value. If the default value does not exist, + * this method returns nil. + * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook') + * method = WIN32OLE_METHOD.new(tobj, 'SaveAs') + * method.params.each do |param| + * if param.default + * puts "#{param.name} (= #{param.default})" + * else + * puts "#{param}" + * end + * end + * + * The above script result is following: + * Filename + * FileFormat + * Password + * WriteResPassword + * ReadOnlyRecommended + * CreateBackup + * AccessMode (= 1) + * ConflictResolution + * AddToMru + * TextCodepage + * TextVisualLayout + */ +static VALUE foleparam_default(VALUE self) +{ + struct oleparamdata *pparam; + Data_Get_Struct(self, struct oleparamdata, pparam); + return ole_param_default(pparam->pTypeInfo, pparam->method_index, + pparam->index); +} + +/* + * call-seq: + * WIN32OLE_PARAM#inspect -> String + * + * Returns the parameter name with class name. If the parameter has default value, + * then returns name=value string with class name. + * + */ +static VALUE +foleparam_inspect(VALUE self) +{ + VALUE detail = foleparam_name(self); + VALUE defval = foleparam_default(self); + if (defval != Qnil) { + rb_str_cat2(detail, "="); + rb_str_concat(detail, rb_funcall(defval, rb_intern("inspect"), 0)); + } + return make_inspect("WIN32OLE_PARAM", detail); +} + +void +Init_win32ole_param() +{ + cWIN32OLE_PARAM = rb_define_class("WIN32OLE_PARAM", rb_cObject); + rb_define_alloc_func(cWIN32OLE_PARAM, foleparam_s_allocate); + rb_define_method(cWIN32OLE_PARAM, "initialize", foleparam_initialize, 2); + rb_define_method(cWIN32OLE_PARAM, "name", foleparam_name, 0); + rb_define_method(cWIN32OLE_PARAM, "ole_type", foleparam_ole_type, 0); + rb_define_method(cWIN32OLE_PARAM, "ole_type_detail", foleparam_ole_type_detail, 0); + rb_define_method(cWIN32OLE_PARAM, "input?", foleparam_input, 0); + rb_define_method(cWIN32OLE_PARAM, "output?", foleparam_output, 0); + rb_define_method(cWIN32OLE_PARAM, "optional?", foleparam_optional, 0); + rb_define_method(cWIN32OLE_PARAM, "retval?", foleparam_retval, 0); + rb_define_method(cWIN32OLE_PARAM, "default", foleparam_default, 0); + rb_define_alias(cWIN32OLE_PARAM, "to_s", "name"); + rb_define_method(cWIN32OLE_PARAM, "inspect", foleparam_inspect, 0); +} diff --git a/ext/win32ole/win32ole_param.h b/ext/win32ole/win32ole_param.h new file mode 100644 index 0000000000..24fcdc0fb2 --- /dev/null +++ b/ext/win32ole/win32ole_param.h @@ -0,0 +1,8 @@ +#ifndef WIN32OLE_PARAM_H +#define WIN32OLE_PARAM_H + +VALUE create_win32ole_param(ITypeInfo *pTypeInfo, UINT method_index, UINT index, VALUE name); +void Init_win32ole_param(); + +#endif + -- cgit v1.2.3