类 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.codepage
和WIN32OLE.codepage=
。- CP_MACCP
2
- CP_OEMCP
OEM 代码页。参见
WIN32OLE.codepage
和WIN32OLE.codepage=
。- CP_SYMBOL
符号代码页。参见
WIN32OLE.codepage
和WIN32OLE.codepage=
。- CP_THREAD_ACP
当前线程的 ANSI 代码页。参见
WIN32OLE.codepage
和WIN32OLE.codepage=
。- CP_UTF7
UTF-7 代码页。参见
WIN32OLE.codepage
和WIN32OLE.codepage=
。- CP_UTF8
UTF-8 代码页。参见
WIN32OLE.codepage
和WIN32OLE.codepage=
。- LOCALE_SYSTEM_DEFAULT
操作系统的默认区域设置。参见
WIN32OLE.locale
和WIN32OLE.locale=
。- LOCALE_USER_DEFAULT
用户或进程的默认区域设置。参见
WIN32OLE.locale
和WIN32OLE.locale=
。- VERSION
WIN32OLE
的版本字符串。
公共类方法
返回当前代码页。
WIN32OLE.codepage # => WIN32OLE::CP_ACP
static VALUE fole_s_get_code_page(VALUE self) { return RB_INT2FIX(cWIN32OLE_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; }
返回正在运行的 OLE 自动化对象或 WIN32OLE
对象,从别名获取。第一个参数应该是 OLE 程序 ID 或类 ID 或别名。
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); }
将 OLE 自动化服务器的常量定义为 mod 的常量。第一个参数是 WIN32OLE
对象或类型库名称。如果省略第二个参数,则默认为 WIN32OLE
。Ruby 常量变量名的第一个字母是大写,因此 WIN32OLE
对象的常量变量名是大写的。例如,Excel 的 ‘xlTop’ 常量在 WIN32OLE
中更改为 ‘XlTop’。如果常量变量的第一个字母不是 [A-Z],则该常量将定义为 CONSTANTS 哈希元素。
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; }
创建 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); }
返回当前区域设置 ID (lcid)。默认区域设置是 WIN32OLE::LOCALE_SYSTEM_DEFAULT
。
lcid = WIN32OLE.locale
static VALUE fole_s_get_locale(VALUE self) { return RB_INT2FIX(cWIN32OLE_lcid); }
设置当前区域设置 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; }
返回一个新的 WIN32OLE
对象(OLE 自动化对象)。第一个参数 server 指定 OLE 自动化服务器。第一个参数应该是 CLSID 或 PROGID。如果指定了第二个参数 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; }
调用 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); }
显示帮助文件。第一个参数指定 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; }
公共实例方法
返回由 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; }
将值设置到由 a1、a2 等指定的 WIN32OLE
对象。
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; }
运行早期绑定方法以获取属性。第一个参数指定调度 ID,第二个参数指定参数数组,第三个参数指定参数类型的数组。
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); }
运行早期绑定方法。第一个参数指定调度 ID,第二个参数指定参数数组,第三个参数指定参数类型的数组。
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); }
运行早期绑定方法来设置属性。第一个参数指定调度 ID,第二个参数指定参数数组,第三个参数指定参数类型的数组。
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); }
迭代具有 IEnumVARIANT 接口的 OLE 集合中的每个项目。
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; }
运行 OLE 方法。第一个参数指定 OLE 自动化对象的 method 名称。其他参数指定 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#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; } }
通过覆盖 Object#methods,WIN32OLE
可能与 did_you_mean gem 很好地配合使用。这属于实验性功能。
require 'win32ole' dict = WIN32OLE.new('Scripting.Dictionary') dict.Ade('a', 1) #=> Did you mean? Add
# File win32ole/lib/win32ole.rb, line 21 def methods(*args) super + ole_methods_safely.map(&:name).map(&:to_sym) end
通过调用 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_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_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); }
返回与第一个参数指定的 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; }
返回与第一个参数指定的 method 对应的 WIN32OLE_METHOD 对象。
excel = WIN32OLE.new('Excel.Application') method = excel.ole_method_help('Quit')
返回 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_TYPE 对象。
excel = WIN32OLE.new('Excel.Application') tobj = excel.ole_type
返回 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
对象,用于由 iid 指定的特定调度或双重接口。
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); }
当 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_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; }
返回 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; }
设置 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; }
私有实例方法
# File win32ole/lib/win32ole.rb, line 27 def ole_methods_safely ole_methods rescue WIN32OLEQueryInterfaceError [] end