類別 WIN32OLE

WIN32OLE

WIN32OLE 物件在 Ruby 中代表 OLE 自動化物件。

透過使用 WIN32OLE,您可以像 VBScript 一樣存取 OLE 伺服器。

以下是範例腳本。

require 'win32ole'

excel = WIN32OLE.new('Excel.Application')
excel.visible = true
workbook = excel.Workbooks.Add();
worksheet = workbook.Worksheets(1);
worksheet.Range("A1:D1").value = ["North","South","East","West"];
worksheet.Range("A2:B2").value = [5.2, 10];
worksheet.Range("C2").value = 8;
worksheet.Range("D2").value = 20;

range = worksheet.Range("A1:D2");
range.select
chart = workbook.Charts.Add;

workbook.saved = true;

excel.ActiveWorkbook.Close(0);
excel.Quit();

很遺憾的是,Win32OLE 不直接支援透過參照傳遞的引數。相反地,Win32OLE 提供 WIN32OLE::ARGV 或 WIN32OLE_VARIANT 物件。如果您想要取得透過參照傳遞的引數的結果值,您可以使用 WIN32OLE::ARGV 或 WIN32OLE_VARIANT。

oleobj.method(arg1, arg2, refargv3)
puts WIN32OLE::ARGV[2]   # the value of refargv3 after called oleobj.method

refargv3 = WIN32OLE_VARIANT.new(XXX,
            WIN32OLE::VARIANT::VT_BYREF|WIN32OLE::VARIANT::VT_XXX)
oleobj.method(arg1, arg2, refargv3)
p refargv3.value # the value of refargv3 after called oleobj.method.

常數

ARGV

在呼叫具有參考引數的 OLE 方法後,您可以使用 ARGV 存取引數的值。

如果 C#.NET 編寫的 OLE(COM) 伺服器方法如下:

void calcsum(int a, int b, out int c) {
    c = a + b;
}

則呼叫 calcsum 方法後,用於擷取引數 c 值的 Ruby OLE(COM) 程式碼如下:

a = 10
b = 20
c = 0
comserver.calcsum(a, b, c)
p c # => 0
p WIN32OLE::ARGV # => [10, 20, 30]

您可以使用 WIN32OLE_VARIANT 物件來擷取參考引數的值,而不是參照 WIN32OLE::ARGV

CP_ACP

ANSI 編碼頁。請參閱 WIN32OLE.codepageWIN32OLE.codepage=

CP_MACCP

2

CP_OEMCP

OEM 編碼頁。請參閱 WIN32OLE.codepageWIN32OLE.codepage=

CP_SYMBOL

符號編碼頁。請參閱 WIN32OLE.codepageWIN32OLE.codepage=

CP_THREAD_ACP

目前執行緒的 ANSI 編碼頁。請參閱 WIN32OLE.codepageWIN32OLE.codepage=

CP_UTF7

UTF-7 編碼頁。請參閱 WIN32OLE.codepageWIN32OLE.codepage=

CP_UTF8

UTF-8 編碼頁。請參閱 WIN32OLE.codepageWIN32OLE.codepage=

LOCALE_SYSTEM_DEFAULT

作業系統的預設區域設定。請參閱 WIN32OLE.localeWIN32OLE.locale=

LOCALE_USER_DEFAULT

使用者或程序的預設區域設定。請參閱 WIN32OLE.localeWIN32OLE.locale=

VERSION

WIN32OLE 的版本字串。

共用類別方法

codepage 按一下以切換來源

傳回目前的編碼頁。

WIN32OLE.codepage # => WIN32OLE::CP_ACP
static VALUE
fole_s_get_code_page(VALUE self)
{
    return RB_INT2FIX(cWIN32OLE_cp);
}
codepage = CP 按一下以切換來源

設定目前的編碼頁。 WIN32OLE.codepage 會根據 Encoding.default_internal 初始化。如果 Encoding.default_internal 為 nil,則 WIN32OLE.codepage 會根據 Encoding.default_external 初始化。

WIN32OLE.codepage = WIN32OLE::CP_UTF8
WIN32OLE.codepage = 65001
static VALUE
fole_s_set_code_page(VALUE self, VALUE vcp)
{
    UINT cp = RB_FIX2INT(vcp);
    set_ole_codepage(cp);
    /*
     * Should this method return old codepage?
     */
    return Qnil;
}
connect( ole ) -→ aWIN32OLE 按一下以切換來源

傳回正在執行的 OLE 自動化物件或從 moniker 取得的 WIN32OLE 物件。第一個參數應該是 OLE 程式 ID、類別 ID 或 moniker。

WIN32OLE.connect('Excel.Application') # => WIN32OLE object which represents running Excel.
static VALUE
fole_s_connect(int argc, VALUE *argv, VALUE self)
{
    VALUE svr_name;
    VALUE others;
    HRESULT hr;
    CLSID   clsid;
    OLECHAR *pBuf;
    IDispatch *pDispatch;
    void *p;
    IUnknown *pUnknown;

    /* initialize to use OLE */
    ole_initialize();

    rb_scan_args(argc, argv, "1*", &svr_name, &others);
    StringValue(svr_name);

    /* get CLSID from OLE server name */
    pBuf = ole_vstr2wc(svr_name);
    hr = CLSIDFromProgID(pBuf, &clsid);
    if(FAILED(hr)) {
        hr = CLSIDFromString(pBuf, &clsid);
    }
    SysFreeString(pBuf);
    if(FAILED(hr)) {
        return ole_bind_obj(svr_name, argc, argv, self);
    }

    hr = GetActiveObject(&clsid, 0, &pUnknown);
    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError,
                  "OLE server `%s' not running", StringValuePtr(svr_name));
    }
    hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IDispatch, &p);
    pDispatch = p;
    if(FAILED(hr)) {
        OLE_RELEASE(pUnknown);
        ole_raise(hr, eWIN32OLERuntimeError,
                  "failed to create WIN32OLE server `%s'",
                  StringValuePtr(svr_name));
    }

    OLE_RELEASE(pUnknown);

    return create_win32ole_object(self, pDispatch, argc, argv);
}
const_load( ole, mod = WIN32OLE) 按一下以切換來源

將 OLE 自動化伺服器的常數定義為 mod 的常數。第一個參數是 WIN32OLE 物件或類型庫名稱。如果省略第二個參數,預設值為 WIN32OLE。Ruby 常數變數名稱的第一個字母為大寫,因此 WIN32OLE 物件的常數變數名稱會大寫。例如,Excel 的「xlTop」常數在 WIN32OLE 中會變更為「XlTop」。如果常數變數的第一個字母不是 [A-Z],則常數會定義為 CONSTANTS hash 元素。

module EXCEL_CONST
end
excel = WIN32OLE.new('Excel.Application')
WIN32OLE.const_load(excel, EXCEL_CONST)
puts EXCEL_CONST::XlTop # => -4160
puts EXCEL_CONST::CONSTANTS['_xlDialogChartSourceData'] # => 541

WIN32OLE.const_load(excel)
puts WIN32OLE::XlTop # => -4160

module MSO
end
WIN32OLE.const_load('Microsoft Office 9.0 Object Library', MSO)
puts MSO::MsoLineSingle # => 1
static VALUE
fole_s_const_load(int argc, VALUE *argv, VALUE self)
{
    VALUE ole;
    VALUE klass;
    struct oledata *pole = NULL;
    ITypeInfo *pTypeInfo;
    ITypeLib *pTypeLib;
    unsigned int index;
    HRESULT hr;
    OLECHAR *pBuf;
    VALUE file;
    LCID    lcid = cWIN32OLE_lcid;

    rb_scan_args(argc, argv, "11", &ole, &klass);
    if (!RB_TYPE_P(klass, T_CLASS) &&
        !RB_TYPE_P(klass, T_MODULE) &&
        !RB_TYPE_P(klass, T_NIL)) {
        rb_raise(rb_eTypeError, "2nd parameter must be Class or Module");
    }
    if (rb_obj_is_kind_of(ole, cWIN32OLE)) {
        pole = oledata_get_struct(ole);
        hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
                                                  0, lcid, &pTypeInfo);
        if(FAILED(hr)) {
            ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeInfo");
        }
        hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
        if(FAILED(hr)) {
            OLE_RELEASE(pTypeInfo);
            ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetContainingTypeLib");
        }
        OLE_RELEASE(pTypeInfo);
        if(!RB_TYPE_P(klass, T_NIL)) {
            ole_const_load(pTypeLib, klass, self);
        }
        else {
            ole_const_load(pTypeLib, cWIN32OLE, self);
        }
        OLE_RELEASE(pTypeLib);
    }
    else if(RB_TYPE_P(ole, T_STRING)) {
        file = typelib_file(ole);
        if (file == Qnil) {
            file = ole;
        }
        pBuf = ole_vstr2wc(file);
        hr = LoadTypeLibEx(pBuf, REGKIND_NONE, &pTypeLib);
        SysFreeString(pBuf);
        if (FAILED(hr))
          ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx");
        if(!RB_TYPE_P(klass, T_NIL)) {
            ole_const_load(pTypeLib, klass, self);
        }
        else {
            ole_const_load(pTypeLib, cWIN32OLE, self);
        }
        OLE_RELEASE(pTypeLib);
    }
    else {
        rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE instance");
    }
    return Qnil;
}
create_guid 按一下以切換來源

建立 GUID。

WIN32OLE.create_guid # => {1CB530F1-F6B1-404D-BCE6-1959BF91F4A8}
static VALUE
fole_s_create_guid(VALUE self)
{
    GUID guid;
    HRESULT hr;
    OLECHAR bstr[80];
    int len = 0;
    hr = CoCreateGuid(&guid);
    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError, "failed to create GUID");
    }
    len = StringFromGUID2(&guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
    if (len == 0) {
        rb_raise(rb_eRuntimeError, "failed to create GUID(buffer over)");
    }
    return ole_wc2vstr(bstr, FALSE);
}
locale → locale id. 按一下以切換來源

傳回目前的 locale id (lcid)。預設的 locale 是 WIN32OLE::LOCALE_SYSTEM_DEFAULT

lcid = WIN32OLE.locale
static VALUE
fole_s_get_locale(VALUE self)
{
    return RB_INT2FIX(cWIN32OLE_lcid);
}
locale = lcid 按一下以切換來源

設定目前的 locale id (lcid)。

WIN32OLE.locale = 1033 # set locale English(U.S)
obj = WIN32OLE_VARIANT.new("$100,000", WIN32OLE::VARIANT::VT_CY)
static VALUE
fole_s_set_locale(VALUE self, VALUE vlcid)
{
    LCID lcid = RB_FIX2INT(vlcid);
    if (lcid_installed(lcid)) {
        cWIN32OLE_lcid = lcid;
    } else {
        switch (lcid) {
        case LOCALE_SYSTEM_DEFAULT:
        case LOCALE_USER_DEFAULT:
            cWIN32OLE_lcid = lcid;
            break;
        default:
            rb_raise(eWIN32OLERuntimeError, "not installed locale: %u", (unsigned int)lcid);
        }
    }
    return Qnil;
}
new(server, [host]) → WIN32OLE 物件 按一下以切換來源
new(server, license: 'key') → WIN32OLE 物件

傳回新的 WIN32OLE 物件 (OLE 自動化物件)。第一個參數 server 指定 OLE 自動化伺服器。第一個參數應該是 CLSID 或 PROGID。如果指定第二個參數 host,則傳回 host 上的 OLE 自動化物件。如果提供 :license 關鍵字參數,則會使用 IClassFactory2::CreateInstanceLic 來建立授權伺服器的執行個體。

WIN32OLE.new('Excel.Application') # => Excel OLE Automation WIN32OLE object.
WIN32OLE.new('{00024500-0000-0000-C000-000000000046}') # => Excel OLE Automation WIN32OLE object.
static VALUE
fole_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE svr_name;
    VALUE host;
    VALUE others;
    VALUE opts;
    HRESULT hr;
    CLSID   clsid;
    OLECHAR *pBuf;
    OLECHAR *key_buf;
    IDispatch *pDispatch;
    IClassFactory2 * pIClassFactory2;
    void *p;
    static ID keyword_ids[1];
    VALUE kwargs[1];

    rb_call_super(0, 0);
    rb_scan_args(argc, argv, "11*:", &svr_name, &host, &others, &opts);

    StringValue(svr_name);
    if (!NIL_P(host)) {
        StringValue(host);
        return ole_create_dcom(self, svr_name, host, others);
    }

    /* get CLSID from OLE server name */
    pBuf  = ole_vstr2wc(svr_name);
    hr = CLSIDFromProgID(pBuf, &clsid);
    if(FAILED(hr)) {
        hr = CLSIDFromString(pBuf, &clsid);
    }
    SysFreeString(pBuf);
    if(FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError,
                  "unknown OLE server: `%s'",
                  StringValuePtr(svr_name));
    }

    if (!keyword_ids[0]) {
        keyword_ids[0] = rb_intern_const("license");
    }
    rb_get_kwargs(opts, keyword_ids, 0, 1, kwargs);

    if (kwargs[0] == Qundef) {
        /* get IDispatch interface */
        hr = CoCreateInstance(
            &clsid,
            NULL,
            CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
            &IID_IDispatch,
            &p
        );
    } else {
        hr = CoGetClassObject(
            &clsid,
            CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
            NULL,
            &IID_IClassFactory2,
            (LPVOID)&pIClassFactory2
        );
        if (hr == S_OK) {
            key_buf = ole_vstr2wc(kwargs[0]);
            hr = pIClassFactory2->lpVtbl->CreateInstanceLic(pIClassFactory2, NULL, NULL, &IID_IDispatch, key_buf, &p);
            SysFreeString(key_buf);
            OLE_RELEASE(pIClassFactory2);
        }
    }
    if(FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError,
                  "failed to create WIN32OLE object from `%s'",
                  StringValuePtr(svr_name));
    }
    pDispatch = p;

    ole_set_member(self, pDispatch);
    return self;
}
ole_free(aWIN32OLE) -→ number 按一下以切換來源

呼叫 WIN32OLE 物件的 Dispatch 介面的 Release 方法。您不應該使用這個方法,因為這個方法只存在於 WIN32OLE 的偵錯中。傳回值是 OLE 物件的參考計數器。

static VALUE
fole_s_free(VALUE self, VALUE obj)
{
    ULONG n = 0;
    struct oledata * pole = NULL;
    pole = oledata_get_struct(obj);
    if(pole->pDispatch) {
        if (reference_count(pole) > 0) {
            n = OLE_RELEASE(pole->pDispatch);
        }
    }
    return RB_INT2NUM(n);
}
ole_reference_count(aWIN32OLE) -→ number 按一下以切換來源

傳回 WIN32OLE 物件的 Dispatch 介面的參考計數器。您不應該使用這個方法,因為這個方法只存在於 WIN32OLE 的偵錯中。

static VALUE
fole_s_reference_count(VALUE self, VALUE obj)
{
    struct oledata * pole = NULL;
    pole = oledata_get_struct(obj);
    return RB_INT2NUM(reference_count(pole));
}
ole_show_help(obj [,helpcontext]) 按一下以切換來源

顯示說明檔案。第一個參數指定 WIN32OLE_TYPE 物件、WIN32OLE_METHOD 物件或說明檔案。

excel = WIN32OLE.new('Excel.Application')
typeobj = excel.ole_type
WIN32OLE.ole_show_help(typeobj)
static VALUE
fole_s_show_help(int argc, VALUE *argv, VALUE self)
{
    VALUE target;
    VALUE helpcontext;
    VALUE helpfile;
    VALUE name;
    HWND  hwnd;
    rb_scan_args(argc, argv, "11", &target, &helpcontext);
    if (rb_obj_is_kind_of(target, cWIN32OLE_TYPE) ||
        rb_obj_is_kind_of(target, cWIN32OLE_METHOD)) {
        helpfile = rb_funcall(target, rb_intern("helpfile"), 0);
        if(strlen(StringValuePtr(helpfile)) == 0) {
            name = rb_ivar_get(target, rb_intern("name"));
            rb_raise(rb_eRuntimeError, "no helpfile of `%s'",
                     StringValuePtr(name));
        }
        helpcontext = rb_funcall(target, rb_intern("helpcontext"), 0);
    } else {
        helpfile = target;
    }
    if (!RB_TYPE_P(helpfile, T_STRING)) {
        rb_raise(rb_eTypeError, "1st parameter must be (String|WIN32OLE_TYPE|WIN32OLE_METHOD)");
    }
    hwnd = ole_show_help(helpfile, helpcontext);
    if(hwnd == 0) {
        rb_raise(rb_eRuntimeError, "failed to open help file `%s'",
                 StringValuePtr(helpfile));
    }
    return Qnil;
}

公開執行個體方法

WIN32OLE[a1,a2,...] 按一下以切換來源

傳回 a1、a2 等指定的集合的值。

dict = WIN32OLE.new('Scripting.Dictionary')
dict.add('ruby', 'Ruby')
puts dict['ruby'] # => 'Ruby' (same as `puts dict.item('ruby')')

備註:您無法使用這個方法來取得屬性。

excel = WIN32OLE.new('Excel.Application')
# puts excel['Visible']  This is error !!!
puts excel.Visible # You should to use this style to get the property.
static VALUE
fole_getproperty_with_bracket(int argc, VALUE *argv, VALUE self)
{
    VALUE v = ole_invoke(argc, argv, self, DISPATCH_PROPERTYGET, TRUE);
    if (v == rb_eNoMethodError) {
        return rb_call_super(argc, argv);
    }
    return v;
}
WIN32OLE[a1, a2, ...]=val 按一下以切換原始碼

設定 WIN32OLE 物件的值,由 a1、a2、… 指定

dict = WIN32OLE.new('Scripting.Dictionary')
dict.add('ruby', 'RUBY')
dict['ruby'] = 'Ruby'
puts dict['ruby'] # => 'Ruby'

備註:您無法使用這個方法設定屬性值。

excel = WIN32OLE.new('Excel.Application')
# excel['Visible'] = true # This is error !!!
excel.Visible = true # You should to use this style to set the property.
static VALUE
fole_setproperty_with_bracket(int argc, VALUE *argv, VALUE self)
{
    VALUE v = ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, TRUE);
    if (v == rb_eNoMethodError) {
        return rb_call_super(argc, argv);
    }
    return v;
}
WIN32OLE#_getproperty(dispid, args, types) 按一下以切換原始碼

執行早期繫結方法以取得屬性。第 1 個引數指定傳送 ID,第 2 個引數指定引數陣列,第 3 個引數指定引數類型的陣列。

excel = WIN32OLE.new('Excel.Application')
puts excel._getproperty(558, [], []) # same effect as puts excel.visible
static VALUE
fole_getproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
{
    return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYGET);
}
WIN32OLE#_invoke(dispid, args, types) 按一下以切換原始碼

執行早期繫結方法。第 1 個引數指定傳送 ID,第 2 個引數指定引數陣列,第 3 個引數指定引數類型的陣列。

excel = WIN32OLE.new('Excel.Application')
excel._invoke(302, [], []) #  same effect as excel.Quit
static VALUE
fole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types)
{
    return ole_invoke2(self, dispid, args, types, DISPATCH_METHOD);
}
WIN32OLE#_setproperty(dispid, args, types) 按一下以切換原始碼

執行早期繫結方法以設定屬性。第 1 個引數指定傳送 ID,第 2 個引數指定引數陣列,第 3 個引數指定引數類型的陣列。

excel = WIN32OLE.new('Excel.Application')
excel._setproperty(558, [true], [WIN32OLE::VARIANT::VT_BOOL]) # same effect as excel.visible = true
static VALUE
fole_setproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
{
    return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYPUT);
}
WIN32OLE#each {|i|...} 按一下以切換原始碼

反覆執行 OLE 集合的每個項目,該集合具有 IEnumVARIANT 介面。

excel = WIN32OLE.new('Excel.Application')
book = excel.workbooks.add
sheets = book.worksheets(1)
cells = sheets.cells("A1:A5")
cells.each do |cell|
  cell.value = 10
end
static VALUE
fole_each(VALUE self)
{
    LCID    lcid = cWIN32OLE_lcid;

    struct oledata *pole = NULL;

    unsigned int argErr;
    EXCEPINFO excepinfo;
    DISPPARAMS dispParams;
    VARIANT result;
    HRESULT hr;
    IEnumVARIANT *pEnum = NULL;
    void *p;

    RETURN_ENUMERATOR(self, 0, 0);

    VariantInit(&result);
    dispParams.rgvarg = NULL;
    dispParams.rgdispidNamedArgs = NULL;
    dispParams.cNamedArgs = 0;
    dispParams.cArgs = 0;
    memset(&excepinfo, 0, sizeof(excepinfo));

    pole = oledata_get_struct(self);
    hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DISPID_NEWENUM,
                                         &IID_NULL, lcid,
                                         DISPATCH_METHOD | DISPATCH_PROPERTYGET,
                                         &dispParams, &result,
                                         &excepinfo, &argErr);

    if (FAILED(hr)) {
        VariantClear(&result);
        ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to get IEnum Interface");
    }

    if (V_VT(&result) == VT_UNKNOWN) {
        hr = V_UNKNOWN(&result)->lpVtbl->QueryInterface(V_UNKNOWN(&result),
                                                        &IID_IEnumVARIANT,
                                                        &p);
        pEnum = p;
    } else if (V_VT(&result) == VT_DISPATCH) {
        hr = V_DISPATCH(&result)->lpVtbl->QueryInterface(V_DISPATCH(&result),
                                                         &IID_IEnumVARIANT,
                                                         &p);
        pEnum = p;
    }
    if (FAILED(hr) || !pEnum) {
        VariantClear(&result);
        ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to get IEnum Interface");
    }

    VariantClear(&result);
    rb_ensure(ole_each_sub, (VALUE)pEnum, ole_ienum_free, (VALUE)pEnum);
    return Qnil;
}
WIN32OLE#invoke(method, [arg1,...]) → method 的傳回值。 按一下以切換原始碼

執行 OLE 方法。第一個引數指定 OLE 自動化物件的方法名稱。其他引數指定 method 的引數。如果您無法直接執行 method,請改用這個方法。

excel = WIN32OLE.new('Excel.Application')
excel.invoke('Quit')  # => same as excel.Quit
static VALUE
fole_invoke(int argc, VALUE *argv, VALUE self)
{
    VALUE v = ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
    if (v == rb_eNoMethodError) {
        return rb_call_super(argc, argv);
    }
    return v;
}
WIN32OLE#method_missing(id [,arg1, arg2, ...]) 按一下以切換原始碼

呼叫 WIN32OLE#invoke 方法。

static VALUE
fole_missing(int argc, VALUE *argv, VALUE self)
{
    VALUE mid, org_mid, sym, v;
    const char* mname;
    long n;
    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
    mid = org_mid = argv[0];
    sym = rb_check_symbol(&mid);
    if (!NIL_P(sym)) mid = rb_sym2str(sym);
    mname = StringValueCStr(mid);
    if(!mname) {
        rb_raise(rb_eRuntimeError, "fail: unknown method or property");
    }
    n = RSTRING_LEN(mid);
    if(mname[n-1] == '=') {
        rb_check_arity(argc, 2, 2);
        argv[0] = rb_enc_associate(rb_str_subseq(mid, 0, n-1), cWIN32OLE_enc);

        return ole_propertyput(self, argv[0], argv[1]);
    }
    else {
        argv[0] = rb_enc_associate(rb_str_dup(mid), cWIN32OLE_enc);
        v = ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
        if (v == rb_eNoMethodError) {
            argv[0] = org_mid;
            return rb_call_super(argc, argv);
        }
        return v;
    }
}
methods(*args) 按一下以切換原始碼

透過覆寫 Object#methodsWIN32OLE 可能與 did_you_mean gem 合作良好。這是實驗性的。

require 'win32ole'
dict = WIN32OLE.new('Scripting.Dictionary')
dict.Ade('a', 1)
#=> Did you mean?  Add
呼叫超類別方法 Object#methods
# File ext/win32ole/lib/win32ole.rb, line 21
def methods(*args)
  super + ole_methods_safely.map(&:name).map(&:to_sym)
end
WIN32OLE#ole_activex_initialize() → Qnil 按一下以切換原始碼

透過呼叫 IPersistMemory::InitNew 初始化 WIN32OLE 物件(ActiveX 控制項)。

在呼叫 OLE 方法之前,某些使用 MFC 建立的 ActiveX 控制項應透過呼叫 IPersistXXX::InitNew 初始化。

如果您收到例外狀況「HRESULT 錯誤碼:0x8000ffff 災難性失敗」,請在呼叫任何 ole_method 之前嘗試這個方法。

obj = WIN32OLE.new("ProgID_or_GUID_of_ActiveX_Control")
obj.ole_activex_initialize
obj.method(...)
static VALUE
fole_activex_initialize(VALUE self)
{
    struct oledata *pole = NULL;
    IPersistMemory *pPersistMemory;
    void *p;

    HRESULT hr = S_OK;

    pole = oledata_get_struct(self);

    hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &IID_IPersistMemory, &p);
    pPersistMemory = p;
    if (SUCCEEDED(hr)) {
        hr = pPersistMemory->lpVtbl->InitNew(pPersistMemory);
        OLE_RELEASE(pPersistMemory);
        if (SUCCEEDED(hr)) {
            return Qnil;
        }
    }

    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError, "fail to initialize ActiveX control");
    }

    return Qnil;
}
WIN32OLE#ole_free 按一下以切換原始碼

呼叫 WIN32OLE 物件的 Dispatch 介面的 Release 方法。通常,您不需要呼叫這個方法,因為當 WIN32OLE 物件被當成垃圾時,Release 方法會自動呼叫。

static VALUE
fole_free(VALUE self)
{
    struct oledata *pole = NULL;
    pole = oledata_get_struct(self);
    OLE_FREE(pole->pDispatch);
    pole->pDispatch = NULL;
    return Qnil;
}
WIN32OLE#ole_func_methods 按一下以切換原始碼

傳回 WIN32OLE_METHOD 物件的陣列。陣列的元素是 WIN32OLE 物件的屬性 (可設定)。

excel = WIN32OLE.new('Excel.Application')
properties = excel.ole_func_methods
static VALUE
fole_func_methods(VALUE self)
{
    return ole_methods( self, INVOKE_FUNC);
}
WIN32OLE#ole_get_methods 按一下以切換原始碼

傳回 WIN32OLE_METHOD 物件的陣列。陣列的元素是 WIN32OLE 物件的屬性 (可取得)。

excel = WIN32OLE.new('Excel.Application')
properties = excel.ole_get_methods
static VALUE
fole_get_methods(VALUE self)
{
    return ole_methods( self, INVOKE_PROPERTYGET);
}
WIN32OLE#ole_method_help(method) 按一下以切換原始碼

傳回與第一個引數指定的 method 相應的 WIN32OLE_METHOD 物件。

excel = WIN32OLE.new('Excel.Application')
method = excel.ole_method_help('Quit')
static VALUE
fole_method_help(VALUE self, VALUE cmdname)
{
    ITypeInfo *pTypeInfo;
    HRESULT hr;
    struct oledata *pole = NULL;
    VALUE obj;

    SafeStringValue(cmdname);
    pole = oledata_get_struct(self);
    hr = typeinfo_from_ole(pole, &pTypeInfo);
    if(FAILED(hr))
        ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to get ITypeInfo");

    obj = create_win32ole_method(pTypeInfo, cmdname);

    OLE_RELEASE(pTypeInfo);
    if (obj == Qnil)
        rb_raise(eWIN32OLERuntimeError, "not found %s",
                 StringValuePtr(cmdname));
    return obj;
}
別名為: ole_method_help
WIN32OLE#ole_method_help(method)

傳回與第一個引數指定的 method 相應的 WIN32OLE_METHOD 物件。

excel = WIN32OLE.new('Excel.Application')
method = excel.ole_method_help('Quit')
別名為: ole_method
WIN32OLE#ole_methods 按一下以切換原始碼

傳回 WIN32OLE_METHOD 物件的陣列。元素是 WIN32OLE 物件的 OLE 方法。

excel = WIN32OLE.new('Excel.Application')
methods = excel.ole_methods
static VALUE
fole_methods(VALUE self)
{
    return ole_methods( self, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);
}
WIN32OLE#ole_type

傳回 WIN32OLE_TYPE 物件。

excel = WIN32OLE.new('Excel.Application')
tobj = excel.ole_type
別名為: ole_type
WIN32OLE#ole_put_methods 按一下以切換原始碼

傳回 WIN32OLE_METHOD 物件的陣列。陣列的元素是 WIN32OLE 物件的屬性 (可設定)。

excel = WIN32OLE.new('Excel.Application')
properties = excel.ole_put_methods
static VALUE
fole_put_methods(VALUE self)
{
    return ole_methods( self, INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF);
}
WIN32OLE#ole_query_interface(iid) → WIN32OLE 物件 按一下以切換原始碼

傳回 iid 指定的特定 dispatch 或 dual 介面的 WIN32OLE 物件。

ie = WIN32OLE.new('InternetExplorer.Application')
ie_web_app = ie.ole_query_interface('{0002DF05-0000-0000-C000-000000000046}') # => WIN32OLE object for dispinterface IWebBrowserApp
static VALUE
fole_query_interface(VALUE self, VALUE str_iid)
{
    HRESULT hr;
    OLECHAR *pBuf;
    IID iid;
    struct oledata *pole = NULL;
    IDispatch *pDispatch;
    void *p;

    pBuf  = ole_vstr2wc(str_iid);
    hr = CLSIDFromString(pBuf, &iid);
    SysFreeString(pBuf);
    if(FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError,
                  "invalid iid: `%s'",
                  StringValuePtr(str_iid));
    }

    pole = oledata_get_struct(self);
    if(!pole->pDispatch) {
        rb_raise(rb_eRuntimeError, "failed to get dispatch interface");
    }

    hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &iid,
                                                 &p);
    if(FAILED(hr)) {
        ole_raise(hr, eWIN32OLEQueryInterfaceError,
                  "failed to get interface `%s'",
                  StringValuePtr(str_iid));
    }

    pDispatch = p;
    return create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);
}
WIN32OLE#ole_respond_to?(method) → true 或 false 按一下以切換原始碼

當 OLE 物件有 OLE 方法時傳回 true,否則傳回 false。

ie = WIN32OLE.new('InternetExplorer.Application')
ie.ole_respond_to?("gohome") => true
static VALUE
fole_respond_to(VALUE self, VALUE method)
{
    struct oledata *pole = NULL;
    BSTR wcmdname;
    DISPID DispID;
    HRESULT hr;
    if(!RB_TYPE_P(method, T_STRING) && !RB_TYPE_P(method, T_SYMBOL)) {
        rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
    }
    if (RB_TYPE_P(method, T_SYMBOL)) {
        method = rb_sym2str(method);
    }
    pole = oledata_get_struct(self);
    wcmdname = ole_vstr2wc(method);
    hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL,
            &wcmdname, 1, cWIN32OLE_lcid, &DispID);
    SysFreeString(wcmdname);
    return SUCCEEDED(hr) ? Qtrue : Qfalse;
}
WIN32OLE#ole_type 按一下以切換原始碼

傳回 WIN32OLE_TYPE 物件。

excel = WIN32OLE.new('Excel.Application')
tobj = excel.ole_type
static VALUE
fole_type(VALUE self)
{
    ITypeInfo *pTypeInfo;
    HRESULT hr;
    struct oledata *pole = NULL;
    LCID  lcid = cWIN32OLE_lcid;
    VALUE type = Qnil;

    pole = oledata_get_struct(self);

    hr = pole->pDispatch->lpVtbl->GetTypeInfo( pole->pDispatch, 0, lcid, &pTypeInfo );
    if(FAILED(hr)) {
        ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeInfo");
    }
    type = ole_type_from_itypeinfo(pTypeInfo);
    OLE_RELEASE(pTypeInfo);
    if (type == Qnil) {
        rb_raise(rb_eRuntimeError, "failed to create WIN32OLE_TYPE obj from ITypeInfo");
    }
    return type;
}
別名為: ole_obj_help
WIN32OLE#ole_typelib → WIN32OLE_TYPELIB 物件 按一下以切換原始碼

傳回 WIN32OLE_TYPELIB 物件。該物件代表包含 WIN32OLE 物件的類型庫。

excel = WIN32OLE.new('Excel.Application')
tlib = excel.ole_typelib
puts tlib.name  # -> 'Microsoft Excel 9.0 Object Library'
static VALUE
fole_typelib(VALUE self)
{
    struct oledata *pole = NULL;
    HRESULT hr;
    ITypeInfo *pTypeInfo;
    LCID  lcid = cWIN32OLE_lcid;
    VALUE vtlib = Qnil;

    pole = oledata_get_struct(self);
    hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
                                              0, lcid, &pTypeInfo);
    if(FAILED(hr)) {
        ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeInfo");
    }
    vtlib = ole_typelib_from_itypeinfo(pTypeInfo);
    OLE_RELEASE(pTypeInfo);
    if (vtlib == Qnil) {
        rb_raise(rb_eRuntimeError, "failed to get type library info.");
    }
    return vtlib;
}
setproperty('property', [arg1, arg2,...] val) 按一下以切換來源

設定 OLE 物件的屬性。當您想要設定帶有引數的屬性時,可以使用此方法。

excel = WIN32OLE.new('Excel.Application')
excel.Visible = true
book = excel.workbooks.add
sheet = book.worksheets(1)
sheet.setproperty('Cells', 1, 2, 10) # => The B1 cell value is 10.
static VALUE
fole_setproperty(int argc, VALUE *argv, VALUE self)
{
    VALUE v = ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, FALSE);
    if (v == rb_eNoMethodError) {
        return rb_call_super(argc, argv);
    }
    return v;
}

私人執行個體方法

ole_methods_safely() 按一下以切換來源
# File ext/win32ole/lib/win32ole.rb, line 27
def ole_methods_safely
  ole_methods
rescue WIN32OLEQueryInterfaceError
  []
end