類別 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) 按一下以切換來源

傳回 Ruby 物件,包裝變異數類型為 VT_ARRAY 的 OLE 變異數。第一個引數應為 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 物件。 按一下以切換來源

傳回 Ruby 物件,包裝 OLE 變異數。第一個引數指定要轉換 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 應為 字串 物件。

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));
}