类 WIN32OLE::Variant
常量
- Empty
表示 VT_EMPTY OLE 对象。
- NoParam
表示带有 DISP_E_PARAMNOTFOUND 的 VT_ERROR 变体。此常量用于未指定的参数。
fso = WIN32OLE.new("Scripting.FileSystemObject") fso.openTextFile(filename, WIN32OLE_VARIANT::NoParam, false)
- Nothing
表示 VB.NET 或 VB 中的
Nothing
。- Null
表示 VT_NULL OLE 对象。
公共类方法
array(ary, vt) 点击切换源代码
返回包装 OLE 变体的 Ruby 对象,其变体类型为 VT_ARRAY。第一个参数应该是 Array 对象,它指定 OLE 数组的维度和每个维度的尺寸。第二个参数指定 OLE 数组元素的变体类型。
以下创建 2 维 OLE 数组。第一个维度的尺寸为 3,第二个维度的尺寸为 4。
ole_ary = WIN32OLE_VARIANT.array([3,4], VT_I4) ruby_ary = ole_ary.value # => [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
static VALUE folevariant_s_array(VALUE klass, VALUE elems, VALUE vvt) { VALUE obj = Qnil; VARTYPE vt; struct olevariantdata *pvar; SAFEARRAYBOUND *psab = NULL; SAFEARRAY *psa = NULL; UINT dim = 0; UINT i = 0; ole_initialize(); vt = RB_NUM2UINT(vvt); vt = (vt | VT_ARRAY); Check_Type(elems, T_ARRAY); obj = folevariant_s_allocate(klass); TypedData_Get_Struct(obj, struct olevariantdata, &olevariant_datatype, pvar); dim = RARRAY_LEN(elems); psab = ALLOC_N(SAFEARRAYBOUND, dim); if(!psab) { rb_raise(rb_eRuntimeError, "memory allocation error"); } for (i = 0; i < dim; i++) { psab[i].cElements = RB_FIX2INT(rb_ary_entry(elems, i)); psab[i].lLbound = 0; } psa = SafeArrayCreate((VARTYPE)(vt & VT_TYPEMASK), dim, psab); if (psa == NULL) { if (psab) free(psab); rb_raise(rb_eRuntimeError, "memory allocation error(SafeArrayCreate)"); } V_VT(&(pvar->var)) = vt; if (vt & VT_BYREF) { V_VT(&(pvar->realvar)) = (vt & ~VT_BYREF); V_ARRAY(&(pvar->realvar)) = psa; V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar))); } else { V_ARRAY(&(pvar->var)) = psa; } if (psab) free(psab); return obj; }
new(val, vartype) #→ WIN32OLE_VARIANT 对象. 点击切换源代码
返回包装 OLE 变体的 Ruby 对象。第一个参数指定要转换为 OLE 变体变量的 Ruby 对象。第二个参数指定 VARIANT
类型。在某些情况下,您需要 WIN32OLE_VARIANT 对象才能传递给 OLE 方法
shell = WIN32OLE.new("Shell.Application") folder = shell.NameSpace("C:\\Windows") item = folder.ParseName("tmp.txt") # You can't use Ruby String object to call FolderItem.InvokeVerb. # Instead, you have to use WIN32OLE_VARIANT object to call the method. shortcut = WIN32OLE_VARIANT.new("Create Shortcut(\&S)") item.invokeVerb(shortcut)
static VALUE folevariant_initialize(VALUE self, VALUE args) { int len = 0; VARIANT var; VALUE val; VALUE vvt; VARTYPE vt; struct olevariantdata *pvar; len = RARRAY_LEN(args); rb_check_arity(len, 1, 3); VariantInit(&var); val = rb_ary_entry(args, 0); check_type_val2variant(val); TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar); if (len == 1) { ole_val2variant(val, &(pvar->var)); } else { vvt = rb_ary_entry(args, 1); vt = RB_NUM2INT(vvt); if ((vt & VT_TYPEMASK) == VT_RECORD) { rb_raise(rb_eArgError, "not supported VT_RECORD WIN32OLE_VARIANT object"); } ole_val2olevariantdata(val, vt, pvar); } return self; }
公共实例方法
WIN32OLE_VARIANT[i,j,...] #→ OLE 数组的元素. 点击切换源代码
返回 WIN32OLE_VARIANT 对象(OLE 数组)的元素。此方法仅在 WIN32OLE_VARIANT 对象的变体类型为 VT_ARRAY 时可用。
备注
The all indices should be 0 or natural number and lower than or equal to max indices. (This point is different with Ruby Array indices.) obj = WIN32OLE_VARIANT.new([[1,2,3],[4,5,6]]) p obj[0,0] # => 1 p obj[1,0] # => 4 p obj[2,0] # => WIN32OLERuntimeError p obj[0, -1] # => WIN32OLERuntimeError
static VALUE folevariant_ary_aref(int argc, VALUE *argv, VALUE self) { struct olevariantdata *pvar; SAFEARRAY *psa; VALUE val = Qnil; VARIANT variant; LONG *pid; HRESULT hr; TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar); if (!V_ISARRAY(&(pvar->var))) { rb_raise(eWIN32OLERuntimeError, "`[]' is not available for this variant type object"); } psa = get_locked_safe_array(self); if (psa == NULL) { return val; } pid = ary2safe_array_index(argc, argv, psa); VariantInit(&variant); V_VT(&variant) = (V_VT(&(pvar->var)) & ~VT_ARRAY) | VT_BYREF; hr = SafeArrayPtrOfIndex(psa, pid, &V_BYREF(&variant)); if (FAILED(hr)) { ole_raise(hr, eWIN32OLERuntimeError, "failed to SafeArrayPtrOfIndex"); } val = ole_variant2val(&variant); unlock_safe_array(psa); if (pid) free(pid); return val; }
WIN32OLE_VARIANT[i,j,...] = val #→ 设置 OLE 数组的元素 点击切换源代码
将 WIN32OLE_VARIANT 对象(OLE 数组)的元素设置为 val。此方法仅在 WIN32OLE_VARIANT 对象的变体类型为 VT_ARRAY 时可用。
备注
The all indices should be 0 or natural number and lower than or equal to max indices. (This point is different with Ruby Array indices.) obj = WIN32OLE_VARIANT.new([[1,2,3],[4,5,6]]) obj[0,0] = 7 obj[1,0] = 8 p obj.value # => [[7,2,3], [8,5,6]] obj[2,0] = 9 # => WIN32OLERuntimeError obj[0, -1] = 9 # => WIN32OLERuntimeError
static VALUE folevariant_ary_aset(int argc, VALUE *argv, VALUE self) { struct olevariantdata *pvar; SAFEARRAY *psa; VARIANT var; VARTYPE vt; LONG *pid; HRESULT hr; VOID *p = NULL; TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar); if (!V_ISARRAY(&(pvar->var))) { rb_raise(eWIN32OLERuntimeError, "`[]' is not available for this variant type object"); } psa = get_locked_safe_array(self); if (psa == NULL) { rb_raise(rb_eRuntimeError, "failed to get SafeArray pointer"); } pid = ary2safe_array_index(argc-1, argv, psa); VariantInit(&var); vt = (V_VT(&(pvar->var)) & ~VT_ARRAY); p = val2variant_ptr(argv[argc-1], &var, vt); if ((V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == NULL) || (V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) == NULL)) { rb_raise(eWIN32OLERuntimeError, "argument does not have IDispatch or IUnknown Interface"); } hr = SafeArrayPutElement(psa, pid, p); if (FAILED(hr)) { ole_raise(hr, eWIN32OLERuntimeError, "failed to SafeArrayPutElement"); } unlock_safe_array(psa); if (pid) free(pid); return argv[argc-1]; }
value #→ Ruby 对象. 点击切换源代码
从 OLE 变体返回 Ruby 对象值。
obj = WIN32OLE_VARIANT.new(1, WIN32OLE::VARIANT::VT_BSTR) obj.value # => "1" (not Integer object, but String object "1")
static VALUE folevariant_value(VALUE self) { struct olevariantdata *pvar; VALUE val = Qnil; VARTYPE vt; int dim; SAFEARRAY *psa; TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar); val = ole_variant2val(&(pvar->var)); vt = V_VT(&(pvar->var)); if ((vt & ~VT_BYREF) == (VT_UI1|VT_ARRAY)) { if (vt & VT_BYREF) { psa = *V_ARRAYREF(&(pvar->var)); } else { psa = V_ARRAY(&(pvar->var)); } if (!psa) { return val; } dim = SafeArrayGetDim(psa); if (dim == 1) { val = rb_funcall(val, rb_intern("pack"), 1, rb_str_new2("C*")); } } return val; }
value = val #→ 将 WIN32OLE_VARIANT 值设置为 val. 点击切换源代码
将变体值设置为 val。如果 val 类型与变体值类型(vartype)不匹配,则在设置 val 之前,val 将更改为与变体值类型(vartype)匹配。当 vartype 为 VT_ARRAY(VT_UI1|VT_ARRAY 除外)时,此方法不可用。如果 vartype 为 VT_UI1|VT_ARRAY,则 val 应为 String 对象。
obj = WIN32OLE_VARIANT.new(1) # obj.vartype is WIN32OLE::VARIANT::VT_I4 obj.value = 3.2 # 3.2 is changed to 3 when setting value. p obj.value # => 3
static VALUE folevariant_set_value(VALUE self, VALUE val) { struct olevariantdata *pvar; VARTYPE vt; TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar); vt = V_VT(&(pvar->var)); if (V_ISARRAY(&(pvar->var)) && ((vt & ~VT_BYREF) != (VT_UI1|VT_ARRAY) || !RB_TYPE_P(val, T_STRING))) { rb_raise(eWIN32OLERuntimeError, "`value=' is not available for this variant type object"); } ole_val2olevariantdata(val, vt, pvar); return Qnil; }
vartype #→ OLE 变体类型。 点击切换源代码
返回 OLE 变体类型。
obj = WIN32OLE_VARIANT.new("string") obj.vartype # => WIN32OLE::VARIANT::VT_BSTR
static VALUE folevariant_vartype(VALUE self) { struct olevariantdata *pvar; TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar); return RB_INT2FIX(V_VT(&pvar->var)); }