summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorsuke <suke@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-08-12 15:09:29 +0000
committersuke <suke@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-08-12 15:09:29 +0000
commit47b2057a022f9aec1c064feb294a11013a10bf92 (patch)
tree88c538452c84bc608e9a46e85eb65039c23dcc7c /ext
parentf4534ea38fbea2bb99fbfdbf136f74d85ef9ab12 (diff)
* 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
Diffstat (limited to 'ext')
-rw-r--r--ext/win32ole/depend1
-rw-r--r--ext/win32ole/win32ole.c413
-rw-r--r--ext/win32ole/win32ole.h2
-rw-r--r--ext/win32ole/win32ole_param.c418
-rw-r--r--ext/win32ole/win32ole_param.h8
5 files changed, 430 insertions, 412 deletions
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
- *
- * <code>WIN32OLE_PARAM</code> 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) # => #<WIN32OLE_PARAM:Overwrite=true>
- *
- */
-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
+ *
+ * <code>WIN32OLE_PARAM</code> 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) # => #<WIN32OLE_PARAM:Overwrite=true>
+ *
+ */
+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
+