1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* ext/win32ole/win32ole.c(ole_val2olevariantdata): support VT_VARIANT in

WIN32OLE_VARIANT.new().

* ext/win32ole/tests/testOLEVARIANT.rb: ditto.

* ext/win32ole/tests/testOLEPARAM.rb: test method name should not be
  duplicated.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10032 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
suke 2006-03-12 08:09:48 +00:00
parent 7e69ffb1b6
commit 88ea87db21
4 changed files with 221 additions and 23 deletions

View file

@ -1,3 +1,13 @@
Sun Mar 12 17:02:10 2006 Masaki Suketa <masaki.suketa@nifty.ne.jp>
* ext/win32ole/win32ole.c(ole_val2olevariantdata): support VT_VARIANT in
WIN32OLE_VARIANT.new().
* ext/win32ole/tests/testOLEVARIANT.rb: ditto.
* ext/win32ole/tests/testOLEPARAM.rb: test method name should not be
duplicated.
Sun Mar 5 18:40:58 2006 Minero Aoki <aamine@loveruby.net>
* lib/fileutils.rb: do not repeat command options.

View file

@ -62,7 +62,7 @@ class TestOLEPARAM < RUNIT::TestCase
f = methods.find {|m| m.name == 'SaveAs'}
assert(f.params[0].optional?)
end
def test_ole_type_detail
def test_ole_type_detail2
classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)
methods = classes.find {|c| c.name == 'Worksheet'}.ole_methods
f = methods.find {|m| m.name == 'SaveAs'}

View file

@ -71,4 +71,9 @@ class TestWIN32OLE_VARIANT < Test::Unit::TestCase
assert_equal("10000", obj.value)
end
def test_create_vt_array
obj = WIN32OLE_VARIANT.new([1.2, 2.3], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_R8)
assert_equal([1.2, 2.3], obj.value)
end
end

View file

@ -79,7 +79,7 @@
#define WC2VSTR(x) ole_wc2vstr((x), TRUE)
#define WIN32OLE_VERSION "0.7.0"
#define WIN32OLE_VERSION "0.7.1"
typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
@ -743,12 +743,127 @@ ole_set_safe_array(n, psa, pid, pub, val, dim)
}
}
static void * get_ptr_of_variant(pvar)
VARIANT *pvar;
{
switch(V_VT(pvar)) {
case VT_UI1:
return &V_UI1(pvar);
break;
case VT_I2:
return &V_I2(pvar);
break;
case VT_I4:
return &V_I4(pvar);
break;
case VT_UI4:
return &V_UI4(pvar);
break;
/*
case VT_I8:
return &V_I8(pvar);
break;
*/
case VT_R4:
return &V_R4(pvar);
break;
case VT_R8:
return &V_R8(pvar);
break;
case VT_CY:
return &V_CY(pvar);
break;
case VT_DATE:
return &V_DATE(pvar);
break;
case VT_BSTR:
return &V_BSTR(pvar);
break;
case VT_DISPATCH:
return &V_DISPATCH(pvar);
break;
case VT_ERROR:
return &V_ERROR(pvar);
break;
case VT_BOOL:
return &V_BOOL(pvar);
break;
/*
case VT_VARIANT:
return &V_VARIANT(pvar);
break;
*/
case VT_UNKNOWN:
return &V_UNKNOWN(pvar);
break;
case VT_ARRAY:
return &V_ARRAY(pvar);
break;
default:
return NULL;
break;
}
}
static void
ole_set_safe_array_with_type(n, psa, pid, pub, val, dim, vtype)
long n;
SAFEARRAY *psa;
long *pid;
long *pub;
VALUE val;
long dim;
VARTYPE vtype;
{
VALUE val1;
HRESULT hr;
VARIANT var;
VARIANT vart;
VOID *p = NULL;
VariantInit(&var);
VariantInit(&vart);
if(n < 0) return;
if(n == dim) {
val1 = ole_ary_m_entry(val, pid);
ole_val2variant(val1, &var);
VariantInit(&vart);
if (vtype != V_VT(&var)) {
hr = VariantChangeTypeEx(&vart, &var,
LOCALE_SYSTEM_DEFAULT, 0, (VARTYPE)(vtype & ~VT_BYREF));
if (FAILED(hr)) {
ole_raise(hr, rb_eRuntimeError, "failed to change type");
}
p = get_ptr_of_variant(&vart);
}
else {
p = get_ptr_of_variant(&var);
}
if (p == NULL) {
rb_raise(rb_eRuntimeError, "failed to get ponter of variant");
}
hr = SafeArrayPutElement(psa, pid, p);
if (FAILED(hr)) {
ole_raise(hr, rb_eRuntimeError, "failed to SafeArrayPutElement");
}
}
pid[n] += 1;
if (pid[n] < pub[n]) {
ole_set_safe_array_with_type(dim, psa, pid, pub, val, dim, vtype);
}
else {
pid[n] = 0;
ole_set_safe_array_with_type(n-1, psa, pid, pub, val, dim, vtype);
}
}
static void
ole_val2variant(val, var)
VALUE val;
VARIANT *var;
{
struct oledata *pole;
struct olevariantdata *pvar;
if(rb_obj_is_kind_of(val, cWIN32OLE)) {
Data_Get_Struct(val, struct oledata, pole);
OLE_ADDREF(pole->pDispatch);
@ -756,6 +871,13 @@ ole_val2variant(val, var)
V_DISPATCH(var) = pole->pDispatch;
return;
}
if (rb_obj_is_kind_of(val, cWIN32OLE_VARIANT)) {
Data_Get_Struct(val, struct olevariantdata, pvar);
VariantCopy(var, &(pvar->var));
return;
}
if (rb_obj_is_kind_of(val, rb_cTime)) {
V_VT(var) = VT_DATE;
V_DATE(var) = time_object2date(val);
@ -1002,27 +1124,87 @@ ole_val2olevariantdata(val, vtype, pvar)
{
HRESULT hr = S_OK;
VARIANT var;
ole_val2variant(val, &(pvar->realvar));
if (vtype & VT_BYREF) {
if ( (vtype & ~VT_BYREF) == V_VT(&(pvar->realvar))) {
ole_var2ptr_var(&(pvar->realvar), &(pvar->var));
} else {
VariantInit(&var);
hr = VariantChangeTypeEx(&(var), &(pvar->realvar),
LOCALE_SYSTEM_DEFAULT, 0, (VARTYPE)(vtype & ~VT_BYREF));
if (SUCCEEDED(hr)) {
VariantClear(&(pvar->realvar));
hr = VariantCopy(&(pvar->realvar), &var);
VariantClear(&var);
ole_var2ptr_var(&(pvar->realvar), &(pvar->var));
}
if (vtype & VT_ARRAY) {
VALUE val1;
long dim = 0;
int i = 0;
HRESULT hr;
SAFEARRAYBOUND *psab = NULL;
SAFEARRAY *psa = NULL;
long *pub, *pid;
val1 = val;
while(TYPE(val1) == T_ARRAY) {
val1 = rb_ary_entry(val1, 0);
dim += 1;
}
psab = ALLOC_N(SAFEARRAYBOUND, dim);
pub = ALLOC_N(long, dim);
pid = ALLOC_N(long, dim);
if(!psab || !pub || !pid) {
if(pub) free(pub);
if(psab) free(psab);
if(pid) free(pid);
rb_raise(rb_eRuntimeError, "memory allocation error");
}
val1 = val;
i = 0;
while(TYPE(val1) == T_ARRAY) {
psab[i].cElements = RARRAY(val1)->len;
psab[i].lLbound = 0;
pub[i] = psab[i].cElements;
pid[i] = 0;
i ++;
val1 = rb_ary_entry(val1, 0);
}
/* Create and fill VARIANT array */
psa = SafeArrayCreate(vtype & VT_TYPEMASK, dim, psab);
if (psa == NULL)
hr = E_OUTOFMEMORY;
else
hr = SafeArrayLock(psa);
if (SUCCEEDED(hr)) {
ole_set_safe_array_with_type(dim-1, psa, pid, pub, val, dim-1, vtype& VT_TYPEMASK);
hr = SafeArrayUnlock(psa);
}
if(pub) free(pub);
if(psab) free(psab);
if(pid) free(pid);
if (SUCCEEDED(hr)) {
V_VT(&(pvar->realvar)) = vtype;
V_ARRAY(&(pvar->realvar)) = psa;
hr = VariantCopy(&(pvar->var), &(pvar->realvar));
}
else {
if (psa != NULL)
SafeArrayDestroy(psa);
}
} else {
if (vtype == V_VT(&(pvar->realvar))) {
hr = VariantCopy(&(pvar->var), &(pvar->realvar));
ole_val2variant(val, &(pvar->realvar));
if (vtype & VT_BYREF) {
if ( (vtype & ~VT_BYREF) == V_VT(&(pvar->realvar))) {
ole_var2ptr_var(&(pvar->realvar), &(pvar->var));
} else {
VariantInit(&var);
hr = VariantChangeTypeEx(&(var), &(pvar->realvar),
LOCALE_SYSTEM_DEFAULT, 0, (VARTYPE)(vtype & ~VT_BYREF));
if (SUCCEEDED(hr)) {
VariantClear(&(pvar->realvar));
hr = VariantCopy(&(pvar->realvar), &var);
VariantClear(&var);
ole_var2ptr_var(&(pvar->realvar), &(pvar->var));
}
}
} else {
hr = VariantChangeTypeEx(&(pvar->var), &(pvar->realvar),
LOCALE_SYSTEM_DEFAULT, 0, vtype);
if (vtype == V_VT(&(pvar->realvar))) {
hr = VariantCopy(&(pvar->var), &(pvar->realvar));
} else {
hr = VariantChangeTypeEx(&(pvar->var), &(pvar->realvar),
LOCALE_SYSTEM_DEFAULT, 0, vtype);
}
}
}
if (FAILED(hr)) {
@ -1030,7 +1212,6 @@ ole_val2olevariantdata(val, vtype, pvar)
}
}
static void
ole_val2variant2(val, var)
VALUE val;
@ -1120,7 +1301,6 @@ ole_variant2val(pvar)
SafeArrayGetLBound(psa, i+1, &pID[i]);
SafeArrayGetUBound(psa, i+1, &pUB[i]);
}
hr = SafeArrayLock(psa);
if (SUCCEEDED(hr)) {
val2 = rb_ary_new();
@ -1128,7 +1308,6 @@ ole_variant2val(pvar)
hr = SafeArrayPtrOfIndex(psa, pID, &V_BYREF(&variant));
if (FAILED(hr))
break;
val = ole_variant2val(&variant);
rb_ary_push(val2, val);
for (i = dim-1 ; i >= 0 ; --i) {
@ -6713,6 +6892,7 @@ fev_initialize(argc, argv, self)
IEVENTSINKOBJ *pIEV;
DWORD dwCookie;
struct oleeventdata *poleev;
VALUE events = Qnil;
rb_secure(4);
rb_scan_args(argc, argv, "11", &ole, &itf);
@ -6775,6 +6955,9 @@ fev_initialize(argc, argv, self)
poleev->freed = 0;
poleev->pEvent->ptr_freed = &(poleev->freed);
rb_ary_push(ary_ole_event, self);
events = rb_ary_new();
rb_ivar_set(self, id_events, events);
return self;
}