diff --git a/ChangeLog b/ChangeLog index 63416dc5d7..e74a39ef06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Fri Jan 26 23:55:56 2007 Masaki Suketa + + * ext/win32ole/win32ole.c: bug fix of WIN32OLE_VARIANT when variant + type is VT_BYREF|VT_VARIANT. + + * test/win32ole/test_win32ole_variant_with_ie.rb: ditto. + Fri Jan 26 12:03:39 2007 Hidetoshi NAGAI * ext/tk/lib/tk.rb (TkConfigMethod#__confinfo_cmd, diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c index 57f509a82e..7fb0710205 100644 --- a/ext/win32ole/win32ole.c +++ b/ext/win32ole/win32ole.c @@ -80,7 +80,7 @@ #define WC2VSTR(x) ole_wc2vstr((x), TRUE) -#define WIN32OLE_VERSION "0.8.7" +#define WIN32OLE_VERSION "0.8.8" typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX) (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*); @@ -1153,14 +1153,22 @@ ole_val2olevariantdata(VALUE val, VARTYPE vtype, struct olevariantdata *pvar) } } else { if (val == Qnil) { - V_VT(&(pvar->realvar)) = vtype & ~VT_BYREF; - V_VT(&(pvar->var)) = vtype; - if (vtype & VT_BYREF) { - ole_var2ptr_var(&(pvar->realvar), &(pvar->var)); + if (vtype == (VT_BYREF | VT_VARIANT)) { + V_VARIANTREF(&(pvar->var)) = &(pvar->realvar); + V_VT(&(pvar->var)) = vtype; + } else { + V_VT(&(pvar->realvar)) = vtype & ~VT_BYREF; + V_VT(&(pvar->var)) = vtype; + if (vtype & VT_BYREF) { + ole_var2ptr_var(&(pvar->realvar), &(pvar->var)); + } } } else { ole_val2variant(val, &(pvar->realvar)); - if (vtype & VT_BYREF) { + if (vtype == (VT_BYREF | VT_VARIANT)) { + V_VARIANTREF(&(pvar->var)) = &(pvar->realvar); + V_VT(&(pvar->var)) = vtype; + } else if (vtype & VT_BYREF) { if ( (vtype & ~VT_BYREF) == V_VT(&(pvar->realvar))) { ole_var2ptr_var(&(pvar->realvar), &(pvar->var)); } else { @@ -2536,6 +2544,13 @@ ole_invoke(int argc, VALUE *argv, VALUE self, USHORT wFlags, BOOL is_bracket) } /* clear dispatch parameter */ if(op.dp.cArgs > cNamedArgs) { + for(i = cNamedArgs; i < op.dp.cArgs; i++) { + n = op.dp.cArgs - i + cNamedArgs - 1; + param = rb_ary_entry(paramS, i-cNamedArgs); + if (rb_obj_is_kind_of(param, cWIN32OLE_VARIANT)) { + ole_val2variant(param, &realargs[n]); + } + } set_argv(realargs, cNamedArgs, op.dp.cArgs); } else { @@ -6956,14 +6971,15 @@ folevariant_value(VALUE self) struct olevariantdata *pvar; VALUE val = Qnil; VARTYPE vt; + int dim; + VALUE args; + SAFEARRAY *psa; Data_Get_Struct(self, struct olevariantdata, pvar); val = ole_variant2val(&(pvar->var)); vt = V_VT(&(pvar->var)); if ((vt & ~VT_BYREF) == (VT_UI1|VT_ARRAY)) { - SAFEARRAY *psa; - int dim; if (vt & VT_BYREF) { psa = *V_ARRAYREF(&(pvar->var)); } else { @@ -6971,7 +6987,7 @@ folevariant_value(VALUE self) } dim = SafeArrayGetDim(psa); if (dim == 1) { - VALUE args = rb_ary_new3(1, rb_str_new2("C*")); + args = rb_ary_new3(1, rb_str_new2("C*")); val = rb_apply(val, rb_intern("pack"), args); } } diff --git a/test/win32ole/test_win32ole_variant_with_ie.rb b/test/win32ole/test_win32ole_variant_with_ie.rb new file mode 100644 index 0000000000..680f17ff54 --- /dev/null +++ b/test/win32ole/test_win32ole_variant_with_ie.rb @@ -0,0 +1,53 @@ +# This is test script to check WIN32OLE_VARIANT using Internet Explorer +begin + require 'win32ole' +rescue LoadError +end +require 'test/unit' + +if defined?(WIN32OLE) + class TestWIN32OLE_VARIANT_WITH_IE < Test::Unit::TestCase + def create_temp_html + fso = WIN32OLE.new('Scripting.FileSystemObject') + dummy_file = fso.GetTempName + ".html" + cfolder = fso.getFolder(".") + f = cfolder.CreateTextFile(dummy_file) + f.writeLine("This is test HTML file for Win32OLE.") + f.close + dummy_path = cfolder.path + "\\" + dummy_file + dummy_path + end + def setup + @f = create_temp_html + @ie = WIN32OLE.new('InternetExplorer.Application') + @ie.visible = true + @ie.navigate("file:///#{@f}") + while @ie.busy + sleep 0.5 + end + end + def test_variant_ref_and_argv + @ie.execWB(19, 0, nil, -1) + size = WIN32OLE::ARGV[3] + assert(size >= 0) + + obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF) + @ie.execWb(19, 0, nil, obj) + assert_equal(size, obj.value) + assert_equal(size, WIN32OLE::ARGV[3]) + + obj = WIN32OLE_VARIANT.new(-1, WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF) + @ie.execWb(19, 0, nil, obj) + assert_equal(size, obj.value) + assert_equal(size, WIN32OLE::ARGV[3]) + end + + def teardown + File.unlink(@f) + if @ie + @ie.quit + @ie = nil + end + end + end +end