git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8984 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
suke 2005-08-13 12:22:12 +00:00
Родитель 31c063eac3
Коммит ba30d87a36
2 изменённых файлов: 268 добавлений и 77 удалений

Просмотреть файл

@ -1,3 +1,11 @@
Sat Aug 13 21:11:05 2005 Masaki Suketa <masaki.suketa@nifty.ne.jp>
* ext/win32ole/win32ole.c: add WIN32OLE_VARIANT class.
* ext/win32ole/tests/testall.rb: ditto.
* ext/win32ole/tests/testOLEVARIANT.rb: ditto.
Sat Aug 13 18:51:26 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
* eval.c (rb_block_pass): distinguish current block from others.

Просмотреть файл

@ -79,7 +79,7 @@
#define WC2VSTR(x) ole_wc2vstr((x), TRUE)
#define WIN32OLE_VERSION "0.6.7"
#define WIN32OLE_VERSION "0.6.8"
typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
@ -144,6 +144,7 @@ VALUE cWIN32OLE_VARIABLE;
VALUE cWIN32OLE_METHOD;
VALUE cWIN32OLE_PARAM;
VALUE cWIN32OLE_EVENT;
VALUE cWIN32OLE_VARIANT;
VALUE eWIN32OLE_RUNTIME_ERROR;
VALUE mWIN32OLE_VARIANT;
@ -192,6 +193,11 @@ struct oleparam {
OLECHAR** pNamedArgs;
};
struct olevariantdata {
VARIANT realvar;
VARIANT var;
};
static VALUE folemethod_s_allocate _((VALUE));
static VALUE olemethod_set_member _((VALUE, ITypeInfo *, ITypeInfo *, int, VALUE));
static VALUE foletype_s_allocate _((VALUE));
@ -270,7 +276,9 @@ static HRESULT ( STDMETHODCALLTYPE GetIDsOfNames )(
/* [in] */ LCID lcid,
/* [size_is][out] */ DISPID __RPC_FAR *rgDispId)
{
/*
Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
*/
char* psz = ole_wc2mb(*rgszNames); // support only one method
*rgDispId = rb_intern(psz);
free(psz);
@ -496,7 +504,7 @@ ole_hresult2msg(hr)
DWORD dwCount;
char strhr[100];
sprintf(strhr, " HRESULT error code:0x%08x\n ", hr);
sprintf(strhr, " HRESULT error code:0x%08x\n ", (unsigned)hr);
msg = rb_str_new2(strhr);
dwCount = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
@ -849,6 +857,178 @@ ole_val2variant(val, var)
}
}
static void
ole_val2ptr_variant(val, var)
VALUE val;
VARIANT *var;
{
switch (TYPE(val)) {
case T_STRING:
if (V_VT(var) == (VT_BSTR | VT_BYREF)) {
*V_BSTRREF(var) = ole_mb2wc(StringValuePtr(val), -1);
}
break;
case T_FIXNUM:
switch(V_VT(var)) {
case (VT_UI1 | VT_BYREF) :
*V_UI1REF(var) = NUM2CHR(val);
break;
case (VT_I2 | VT_BYREF) :
*V_I2REF(var) = (short)NUM2INT(val);
break;
case (VT_I4 | VT_BYREF) :
*V_I4REF(var) = NUM2INT(val);
break;
case (VT_R4 | VT_BYREF) :
*V_R4REF(var) = (float)NUM2INT(val);
break;
case (VT_R8 | VT_BYREF) :
*V_R8REF(var) = NUM2INT(val);
break;
default:
break;
}
break;
case T_FLOAT:
switch(V_VT(var)) {
case (VT_I2 | VT_BYREF) :
*V_I2REF(var) = (short)NUM2INT(val);
break;
case (VT_I4 | VT_BYREF) :
*V_I4REF(var) = NUM2INT(val);
break;
case (VT_R4 | VT_BYREF) :
*V_R4REF(var) = (float)NUM2DBL(val);
break;
case (VT_R8 | VT_BYREF) :
*V_R8REF(var) = NUM2DBL(val);
break;
default:
break;
}
break;
case T_BIGNUM:
if (V_VT(var) == (VT_R8 | VT_BYREF)) {
*V_R8REF(var) = rb_big2dbl(val);
}
break;
case T_TRUE:
if (V_VT(var) == (VT_BOOL | VT_BYREF)) {
*V_BOOLREF(var) = VARIANT_TRUE;
}
break;
case T_FALSE:
if (V_VT(var) == (VT_BOOL | VT_BYREF)) {
*V_BOOLREF(var) = VARIANT_FALSE;
}
break;
default:
break;
}
}
static void
ole_var2ptr_var(var, pvar)
VARIANT *var;
VARIANT *pvar;
{
VARTYPE vt = V_VT(var);
V_VT(pvar) = V_VT(var) | VT_BYREF;
switch(vt) {
case VT_UI1:
V_UI1REF(pvar) = &V_UI1(var);
break;
case VT_I2:
V_I2REF(pvar) = &V_I2(var);
break;
case VT_I4:
V_I4REF(pvar) = &V_I4(var);
break;
case VT_UI4:
V_UI4REF(pvar) = &V_UI4(var);
break;
/*
case VT_I8:
V_I8REF(pvar) = &V_I8(var);
break;
*/
case VT_R4:
V_R4REF(pvar) = &V_R4(var);
break;
case VT_R8:
V_R8REF(pvar) = &V_R8(var);
break;
case VT_CY:
V_CYREF(pvar) = &V_CY(var);
break;
case VT_DATE:
V_DATEREF(pvar) = &V_DATE(var);
break;
case VT_BSTR:
V_BSTRREF(pvar) = &V_BSTR(var);
break;
case VT_DISPATCH:
V_DISPATCHREF(pvar) = &V_DISPATCH(var);
break;
case VT_ERROR:
V_ERRORREF(pvar) = &V_ERROR(var);
break;
case VT_BOOL:
V_BOOLREF(pvar) = &V_BOOL(var);
break;
/*
case VT_VARIANT:
V_VARIANTREF(pvar) = &V_VARIANT(var);
break;
*/
case VT_UNKNOWN:
V_UNKNOWNREF(pvar) = &V_UNKNOWN(var);
break;
case VT_ARRAY:
V_ARRAYREF(pvar) = &V_ARRAY(var);
break;
default:
break;
}
}
static void
ole_val2olevariantdata(val, vtype, pvar)
VALUE val;
VARTYPE vtype;
struct olevariantdata *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, vtype & ~VT_BYREF);
if (SUCCEEDED(hr)) {
VariantClear(&(pvar->realvar));
hr = VariantCopy(&(pvar->realvar), &var);
VariantClear(&var);
ole_var2ptr_var(&(pvar->realvar), &(pvar->var));
}
}
} else {
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)) {
ole_raise(hr, rb_eRuntimeError, "failed to change type");
}
}
static void
ole_val2variant2(val, var)
VALUE val;
@ -1997,6 +2177,7 @@ ole_invoke(argc, argv, self, wFlags)
unsigned int cNamedArgs;
int n;
struct oleparam op;
struct olevariantdata *pvar;
memset(&excepinfo, 0, sizeof(EXCEPINFO));
VariantInit(&result);
@ -2077,11 +2258,14 @@ ole_invoke(argc, argv, self, wFlags)
VariantInit(&realargs[n]);
VariantInit(&op.dp.rgvarg[n]);
param = rb_ary_entry(paramS, i-cNamedArgs);
ole_val2variant(param, &realargs[n]);
V_VT(&op.dp.rgvarg[n]) = VT_VARIANT | VT_BYREF;
V_VARIANTREF(&op.dp.rgvarg[n]) = &realargs[n];
if (rb_obj_is_kind_of(param, cWIN32OLE_VARIANT)) {
Data_Get_Struct(param, struct olevariantdata, pvar);
VariantCopy(&op.dp.rgvarg[n], &(pvar->var));
} else {
ole_val2variant(param, &realargs[n]);
V_VT(&op.dp.rgvarg[n]) = VT_VARIANT | VT_BYREF;
V_VARIANTREF(&op.dp.rgvarg[n]) = &realargs[n];
}
}
}
/* apparent you need to call propput, you need this */
@ -6105,75 +6289,6 @@ ole_search_event(ary, ev, is_default)
return def_event;
}
static void
val2ptr_variant(val, var)
VALUE val;
VARIANT *var;
{
switch (TYPE(val)) {
case T_STRING:
if (V_VT(var) == (VT_BSTR | VT_BYREF)) {
*V_BSTRREF(var) = ole_mb2wc(StringValuePtr(val), -1);
}
break;
case T_FIXNUM:
switch(V_VT(var)) {
case (VT_UI1 | VT_BYREF) :
*V_UI1REF(var) = NUM2CHR(val);
break;
case (VT_I2 | VT_BYREF) :
*V_I2REF(var) = (short)NUM2INT(val);
break;
case (VT_I4 | VT_BYREF) :
*V_I4REF(var) = NUM2INT(val);
break;
case (VT_R4 | VT_BYREF) :
*V_R4REF(var) = (float)NUM2INT(val);
break;
case (VT_R8 | VT_BYREF) :
*V_R8REF(var) = NUM2INT(val);
break;
default:
break;
}
break;
case T_FLOAT:
switch(V_VT(var)) {
case (VT_I2 | VT_BYREF) :
*V_I2REF(var) = (short)NUM2INT(val);
break;
case (VT_I4 | VT_BYREF) :
*V_I4REF(var) = NUM2INT(val);
break;
case (VT_R4 | VT_BYREF) :
*V_R4REF(var) = (float)NUM2DBL(val);
break;
case (VT_R8 | VT_BYREF) :
*V_R8REF(var) = NUM2DBL(val);
break;
default:
break;
}
break;
case T_BIGNUM:
if (V_VT(var) == (VT_R8 | VT_BYREF)) {
*V_R8REF(var) = rb_big2dbl(val);
}
break;
case T_TRUE:
if (V_VT(var) == (VT_BOOL | VT_BYREF)) {
*V_BOOLREF(var) = VARIANT_TRUE;
}
break;
case T_FALSE:
if (V_VT(var) == (VT_BOOL | VT_BYREF)) {
*V_BOOLREF(var) = VARIANT_FALSE;
}
break;
default:
break;
}
}
static void
ary2ptr_dispparams(ary, pdispparams)
@ -6186,7 +6301,7 @@ ary2ptr_dispparams(ary, pdispparams)
for(i = 0; i < RARRAY(ary)->len && (unsigned int) i < pdispparams->cArgs; i++) {
v = rb_ary_entry(ary, i);
pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
val2ptr_variant(v, pvar);
ole_val2ptr_variant(v, pvar);
}
}
@ -6714,6 +6829,68 @@ fev_on_event_with_outargs(argc, argv, self)
return ev_on_event(argc, argv, self, Qtrue);
}
static void
olevariant_free(pvar)
struct olevariantdata *pvar;
{
VariantClear(&(pvar->realvar));
VariantClear(&(pvar->var));
}
static VALUE folevariant_s_allocate _((VALUE));
static VALUE
folevariant_s_allocate(klass)
VALUE klass;
{
struct olevariantdata *pvar;
VALUE obj;
ole_initialize();
obj = Data_Make_Struct(klass,struct olevariantdata,0,olevariant_free,pvar);
VariantInit(&(pvar->var));
VariantInit(&(pvar->realvar));
return obj;
}
static VALUE
folevariant_initialize(self, args)
VALUE self;
VALUE args;
{
long len = 0;
VARIANT var;
VALUE val;
VALUE vvt;
VARTYPE vt;
HRESULT hr;
struct olevariantdata *pvar;
len = RARRAY(args)->len;
if (len < 1 || len > 3) {
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..3)", len);
}
VariantInit(&var);
val = rb_ary_entry(args, 0);
Data_Get_Struct(self, struct olevariantdata, pvar);
if (len == 1) {
ole_val2variant(val, &(pvar->var));
} else {
vvt = rb_ary_entry(args, 1);
vt = NUM2INT(vvt);
ole_val2olevariantdata(val, vt, pvar);
}
return self;
}
static VALUE
folevariant_value(self)
VALUE self;
{
struct olevariantdata *pvar;
VALUE val = Qnil;
Data_Get_Struct(self, struct olevariantdata, pvar);
val = ole_variant2val(&(pvar->var));
return val;
}
void
Init_win32ole()
@ -6898,5 +7075,11 @@ Init_win32ole()
rb_define_method(cWIN32OLE_EVENT, "on_event", fev_on_event, -1);
rb_define_method(cWIN32OLE_EVENT, "on_event_with_outargs", fev_on_event_with_outargs, -1);
cWIN32OLE_VARIANT = rb_define_class("WIN32OLE_VARIANT", rb_cObject);
rb_define_alloc_func(cWIN32OLE_VARIANT, folevariant_s_allocate);
rb_define_method(cWIN32OLE_VARIANT, "initialize", folevariant_initialize, -2);
rb_define_method(cWIN32OLE_VARIANT, "value", folevariant_value, 0);
eWIN32OLE_RUNTIME_ERROR = rb_define_class("WIN32OLERuntimeError", rb_eRuntimeError);
}