Migrate win32ole as bundled gems

This commit is contained in:
Hiroshi SHIBATA 2025-01-16 09:13:28 +09:00
parent d492cfdaad
commit 721891688b
No known key found for this signature in database
GPG Key ID: F9CF13417264FAC2
Notes: git 2025-01-16 04:07:37 +00:00
63 changed files with 1 additions and 21906 deletions

View File

@ -1 +0,0 @@
*.[ch]

View File

@ -1,12 +0,0 @@
WIN32OLE_HEADERS = $(HDRS) $(ruby_headers)
win32ole.o : win32ole.c $(WIN32OLE_HEADERS)
win32ole_variant_m.o : win32ole_variant_m.c $(WIN32OLE_HEADERS)
win32ole_typelib.o : win32ole_typelib.c $(WIN32OLE_HEADERS)
win32ole_type.o : win32ole_type.c $(WIN32OLE_HEADERS)
win32ole_variable.o : win32ole_variable.c $(WIN32OLE_HEADERS)
win32ole_method.o : win32ole_method.c $(WIN32OLE_HEADERS)
win32ole_param.o : win32ole_param.c $(WIN32OLE_HEADERS)
win32ole_variant.o : win32ole_variant.c $(WIN32OLE_HEADERS)
win32ole_event.o : win32ole_event.c $(WIN32OLE_HEADERS)
win32ole_record.o : win32ole_record.c $(WIN32OLE_HEADERS)
win32ole_error.o : win32ole_error.c $(WIN32OLE_HEADERS)

View File

@ -1,46 +0,0 @@
# frozen_string_literal: false
#----------------------------------
# extconf.rb
# $Revision$
#----------------------------------
require 'mkmf'
case RUBY_PLATFORM
when /cygwin/
inc = nil
lib = '/usr/lib/w32api'
end
dir_config("win32", inc, lib)
def create_win32ole_makefile
if have_library("ole32") and
have_library("oleaut32") and
have_library("uuid", "&CLSID_CMultiLanguage", "mlang.h") and
have_library("user32") and
have_library("kernel32") and
have_library("advapi32") and
have_header("windows.h")
unless have_type("IMultiLanguage2", "mlang.h")
have_type("IMultiLanguage", "mlang.h")
end
spec = nil
checking_for('thread_specific', '%s') do
spec = %w[__declspec(thread) __thread].find {|th|
try_compile("#{th} int foo;", "", :werror => true)
}
spec or 'no'
end
$defs << "-DRB_THREAD_SPECIFIC=#{spec}" if spec
have_func(%[rb_deprecate_constant(Qnil, "")])
create_makefile("win32ole")
end
end
case RUBY_PLATFORM
when /mswin/
$CFLAGS.sub!(/((?:\A|\s)[-\/])W\d(?=\z|\s)/, '\1W3') or
$CFLAGS += ' -W3'
end
create_win32ole_makefile

View File

@ -1,32 +0,0 @@
begin
require 'win32ole.so'
rescue LoadError
# do nothing
end
if defined?(WIN32OLE)
class WIN32OLE
#
# By overriding Object#methods, WIN32OLE might
# work well with did_you_mean gem.
# This is experimental.
#
# require 'win32ole'
# dict = WIN32OLE.new('Scripting.Dictionary')
# dict.Ade('a', 1)
# #=> Did you mean? Add
#
def methods(*args)
super + ole_methods_safely.map(&:name).map(&:to_sym)
end
private
def ole_methods_safely
ole_methods
rescue WIN32OLE::QueryInterfaceError
[]
end
end
end

View File

@ -1,29 +0,0 @@
# frozen_string_literal: false
class WIN32OLE
end
# OLEProperty is a helper class of Property with arguments, used by
# +olegen.rb+-generated files.
class WIN32OLE::Property
# :stopdoc:
def initialize(obj, dispid, gettypes, settypes)
@obj = obj
@dispid = dispid
@gettypes = gettypes
@settypes = settypes
end
def [](*args)
@obj._getproperty(@dispid, args, @gettypes)
end
def []=(*args)
@obj._setproperty(@dispid, args, @settypes)
end
# :stopdoc:
end
module WIN32OLE::VariantType
# Alias for +olegen.rb+-generated files, that should include
# WIN32OLE::VARIANT.
OLEProperty = WIN32OLE::Property
end

File diff suppressed because it is too large Load Diff

View File

@ -1,35 +0,0 @@
source_version = ["", "ext/win32ole/"].find do |dir|
begin
break File.open(File.join(__dir__, "#{dir}win32ole.c")) {|f|
f.gets("\n#define WIN32OLE_VERSION ")
f.gets[/\s*"(.+)"/, 1]
}
rescue Errno::ENOENT
end
end
Gem::Specification.new do |spec|
spec.name = "win32ole"
spec.version = source_version
spec.authors = ["Masaki Suketa"]
spec.email = ["suke@ruby-lang.org"]
spec.summary = %q{Provides an interface for OLE Automation in Ruby}
spec.description = spec.summary
spec.homepage = "https://github.com/ruby/win32ole"
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
spec.licenses = ["Ruby", "BSD-2-Clause"]
spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = spec.homepage
pathspecs = %W[
:(exclude,literal)#{File.basename(__FILE__)}
:^/bin/ :^/test/ :^/rakelib/ :^/.git* :^/Gemfile* :^/Rakefile*
]
spec.files = IO.popen(%w[git ls-files -z --] + pathspecs, chdir: __dir__, err: IO::NULL, exception: false, &:read).split("\x0")
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.extensions = "ext/win32ole/extconf.rb"
spec.require_paths = ["lib"]
end

View File

@ -1,159 +0,0 @@
#ifndef WIN32OLE_H
#define WIN32OLE_H 1
#include "ruby/ruby.h"
#include "ruby/st.h"
#include "ruby/encoding.h"
#define GNUC_OLDER_3_4_4 \
((__GNUC__ < 3) || \
((__GNUC__ <= 3) && (__GNUC_MINOR__ < 4)) || \
((__GNUC__ <= 3) && (__GNUC_MINOR__ <= 4) && (__GNUC_PATCHLEVEL__ <= 4)))
#if (defined(__GNUC__)) && (GNUC_OLDER_3_4_4)
#ifndef NONAMELESSUNION
#define NONAMELESSUNION 1
#endif
#endif
#include <ctype.h>
#include <windows.h>
#include <ocidl.h>
#include <olectl.h>
#include <ole2.h>
#if defined(HAVE_TYPE_IMULTILANGUAGE2) || defined(HAVE_TYPE_IMULTILANGUAGE)
#include <mlang.h>
#endif
#include <stdlib.h>
#include <math.h>
#ifdef HAVE_STDARG_PROTOTYPES
#include <stdarg.h>
#define va_init_list(a,b) va_start(a,b)
#else
#include <varargs.h>
#define va_init_list(a,b) va_start(a)
#endif
#include <objidl.h>
#define DOUT fprintf(stderr,"%s(%d)\n", __FILE__, __LINE__)
#define DOUTS(x) fprintf(stderr,"%s(%d):" #x "=%s\n",__FILE__, __LINE__,x)
#define DOUTMSG(x) fprintf(stderr, "%s(%d):" #x "\n",__FILE__, __LINE__)
#define DOUTI(x) fprintf(stderr, "%s(%d):" #x "=%d\n",__FILE__, __LINE__,x)
#define DOUTD(x) fprintf(stderr, "%s(%d):" #x "=%f\n",__FILE__, __LINE__,x)
#if (defined(__GNUC__)) && (GNUC_OLDER_3_4_4)
#define V_UNION1(X, Y) ((X)->u.Y)
#else
#define V_UNION1(X, Y) ((X)->Y)
#endif
#if (defined(__GNUC__)) && (GNUC_OLDER_3_4_4)
#undef V_UNION
#define V_UNION(X,Y) ((X)->n1.n2.n3.Y)
#undef V_VT
#define V_VT(X) ((X)->n1.n2.vt)
#undef V_BOOL
#define V_BOOL(X) V_UNION(X,boolVal)
#endif
#ifndef V_I1REF
#define V_I1REF(X) V_UNION(X, pcVal)
#endif
#ifndef V_UI2REF
#define V_UI2REF(X) V_UNION(X, puiVal)
#endif
#ifndef V_INT
#define V_INT(X) V_UNION(X, intVal)
#endif
#ifndef V_INTREF
#define V_INTREF(X) V_UNION(X, pintVal)
#endif
#ifndef V_UINT
#define V_UINT(X) V_UNION(X, uintVal)
#endif
#ifndef V_UINTREF
#define V_UINTREF(X) V_UNION(X, puintVal)
#endif
#ifdef HAVE_LONG_LONG
#define I8_2_NUM LL2NUM
#define UI8_2_NUM ULL2NUM
#define NUM2I8 RB_NUM2LL
#define NUM2UI8 RB_NUM2ULL
#else
#define I8_2_NUM RB_INT2NUM
#define UI8_2_NUM RB_UINT2NUM
#define NUM2I8 RB_NUM2INT
#define NUM2UI8 RB_NUM2UINT
#endif
#ifndef HAVE_RB_DEPRECATE_CONSTANT
# define rb_deprecate_constant(mod, name) (void)0
#endif
#define OLE_ADDREF(X) (X) ? ((X)->lpVtbl->AddRef(X)) : 0
#define OLE_RELEASE(X) (X) ? ((X)->lpVtbl->Release(X)) : 0
#define OLE_FREE(x) {\
if(ole_initialized() == TRUE) {\
if(x) {\
OLE_RELEASE(x);\
(x) = 0;\
}\
}\
}
#define OLE_GET_TYPEATTR(X, Y) ((X)->lpVtbl->GetTypeAttr((X), (Y)))
#define OLE_RELEASE_TYPEATTR(X, Y) ((X)->lpVtbl->ReleaseTypeAttr((X), (Y)))
struct oledata {
IDispatch *pDispatch;
};
extern VALUE cWIN32OLE;
extern LCID cWIN32OLE_lcid;
struct oledata *oledata_get_struct(VALUE obj);
LPWSTR ole_vstr2wc(VALUE vstr);
LONG reg_open_key(HKEY hkey, const char *name, HKEY *phkey);
LONG reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey);
VALUE reg_enum_key(HKEY hkey, DWORD i);
VALUE reg_get_val(HKEY hkey, const char *subkey);
VALUE reg_get_val2(HKEY hkey, const char *subkey);
void ole_initialize(void);
VALUE default_inspect(VALUE self, const char *class_name);
char *ole_wc2mb(LPWSTR pw);
VALUE ole_wc2vstr(LPWSTR pw, BOOL isfree);
#define WC2VSTR(x) ole_wc2vstr((x), TRUE)
BOOL ole_initialized(void);
HRESULT ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile);
VALUE ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails);
VALUE make_inspect(const char *class_name, VALUE detail);
void ole_val2variant(VALUE val, VARIANT *var);
void ole_val2variant2(VALUE val, VARIANT *var);
void ole_val2variant_ex(VALUE val, VARIANT *var, VARTYPE vt);
VALUE ole_variant2val(VARIANT *pvar);
HRESULT ole_val_ary2variant_ary(VALUE val, VARIANT *var, VARTYPE vt);
VOID *val2variant_ptr(VALUE val, VARIANT *var, VARTYPE vt);
HRESULT typelib_from_val(VALUE obj, ITypeLib **pTypeLib);
#include "win32ole_variant_m.h"
#include "win32ole_typelib.h"
#include "win32ole_type.h"
#include "win32ole_variable.h"
#include "win32ole_method.h"
#include "win32ole_param.h"
#include "win32ole_event.h"
#include "win32ole_variant.h"
#include "win32ole_record.h"
#include "win32ole_error.h"
#endif

View File

@ -1,98 +0,0 @@
#include "win32ole.h"
static VALUE ole_hresult2msg(HRESULT hr);
static VALUE
ole_hresult2msg(HRESULT hr)
{
VALUE msg = Qnil;
char *p_msg = NULL;
char *term = NULL;
DWORD dwCount;
char strhr[100];
sprintf(strhr, " HRESULT error code:0x%08x\n ", (unsigned)hr);
msg = rb_str_new2(strhr);
dwCount = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, hr,
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(LPTSTR)&p_msg, 0, NULL);
if (dwCount == 0) {
dwCount = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, hr, cWIN32OLE_lcid,
(LPTSTR)&p_msg, 0, NULL);
}
if (dwCount > 0) {
term = p_msg + strlen(p_msg);
while (p_msg < term) {
term--;
if (*term == '\r' || *term == '\n')
*term = '\0';
else break;
}
if (p_msg[0] != '\0') {
rb_str_cat2(msg, p_msg);
}
}
LocalFree(p_msg);
return msg;
}
void
ole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...)
{
va_list args;
VALUE msg;
VALUE err_msg;
va_init_list(args, fmt);
msg = rb_vsprintf(fmt, args);
va_end(args);
err_msg = ole_hresult2msg(hr);
if(err_msg != Qnil) {
rb_str_cat2(msg, "\n");
rb_str_append(msg, err_msg);
}
rb_exc_raise(rb_exc_new_str(ecs, msg));
}
VALUE eWIN32OLERuntimeError;
VALUE eWIN32OLEQueryInterfaceError;
void
Init_win32ole_error(void)
{
/*
* Document-class: WIN32OLE::RuntimeError
*
* Raised when OLE processing failed.
*
* EX:
*
* obj = WIN32OLE.new("NonExistProgID")
*
* raises the exception:
*
* WIN32OLE::RuntimeError: unknown OLE server: `NonExistProgID'
* HRESULT error code:0x800401f3
* Invalid class string
*
*/
eWIN32OLERuntimeError = rb_define_class_under(cWIN32OLE, "RuntimeError", rb_eRuntimeError);
/* Alias of WIN32OLE::RuntimeError, for the backward compatibility */
rb_define_const(rb_cObject, "WIN32OLE" "RuntimeError", eWIN32OLERuntimeError);
rb_deprecate_constant(rb_cObject, "WIN32OLE" "RuntimeError");
/*
* Document-class: WIN32OLE::QueryInterfaceError
*
* Raised when OLE query failed.
*/
eWIN32OLEQueryInterfaceError = rb_define_class_under(cWIN32OLE, "QueryInterfaceError", eWIN32OLERuntimeError);
/* Alias of WIN32OLE::QueryInterfaceError, for the backward compatibility */
rb_define_const(rb_cObject, "WIN32OLE" "QueryInterfaceError", eWIN32OLEQueryInterfaceError);
rb_deprecate_constant(rb_cObject, "WIN32OLE" "QueryInterfaceError");
}

View File

@ -1,9 +0,0 @@
#ifndef WIN32OLE_ERROR_H
#define WIN32OLE_ERROR_H 1
extern VALUE eWIN32OLERuntimeError;
extern VALUE eWIN32OLEQueryInterfaceError;
NORETURN(PRINTF_ARGS(void ole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...), 3, 4));
void Init_win32ole_error(void);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +0,0 @@
#ifndef WIN32OLE_EVENT_H
#define WIN32OLE_EVENT_H 1
void Init_win32ole_event(void);
#endif

View File

@ -1,955 +0,0 @@
#include "win32ole.h"
static void olemethod_free(void *ptr);
static size_t olemethod_size(const void *ptr);
static VALUE ole_method_sub(VALUE self, ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE name);
static VALUE olemethod_from_typeinfo(VALUE self, ITypeInfo *pTypeInfo, VALUE name);
static VALUE ole_methods_sub(ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE methods, int mask);
static VALUE olemethod_set_member(VALUE self, ITypeInfo *pTypeInfo, ITypeInfo *pOwnerTypeInfo, int index, VALUE name);
static VALUE folemethod_initialize(VALUE self, VALUE oletype, VALUE method);
static VALUE folemethod_name(VALUE self);
static VALUE ole_method_return_type(ITypeInfo *pTypeInfo, UINT method_index);
static VALUE folemethod_return_type(VALUE self);
static VALUE ole_method_return_vtype(ITypeInfo *pTypeInfo, UINT method_index);
static VALUE folemethod_return_vtype(VALUE self);
static VALUE ole_method_return_type_detail(ITypeInfo *pTypeInfo, UINT method_index);
static VALUE folemethod_return_type_detail(VALUE self);
static VALUE ole_method_invkind(ITypeInfo *pTypeInfo, UINT method_index);
static VALUE ole_method_invoke_kind(ITypeInfo *pTypeInfo, UINT method_index);
static VALUE folemethod_invkind(VALUE self);
static VALUE folemethod_invoke_kind(VALUE self);
static VALUE ole_method_visible(ITypeInfo *pTypeInfo, UINT method_index);
static VALUE folemethod_visible(VALUE self);
static VALUE ole_method_event(ITypeInfo *pTypeInfo, UINT method_index, VALUE method_name);
static VALUE folemethod_event(VALUE self);
static VALUE folemethod_event_interface(VALUE self);
static HRESULT ole_method_docinfo_from_type(ITypeInfo *pTypeInfo, UINT method_index, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile);
static VALUE ole_method_helpstring(ITypeInfo *pTypeInfo, UINT method_index);
static VALUE folemethod_helpstring(VALUE self);
static VALUE ole_method_helpfile(ITypeInfo *pTypeInfo, UINT method_index);
static VALUE folemethod_helpfile(VALUE self);
static VALUE ole_method_helpcontext(ITypeInfo *pTypeInfo, UINT method_index);
static VALUE folemethod_helpcontext(VALUE self);
static VALUE ole_method_dispid(ITypeInfo *pTypeInfo, UINT method_index);
static VALUE folemethod_dispid(VALUE self);
static VALUE ole_method_offset_vtbl(ITypeInfo *pTypeInfo, UINT method_index);
static VALUE folemethod_offset_vtbl(VALUE self);
static VALUE ole_method_size_params(ITypeInfo *pTypeInfo, UINT method_index);
static VALUE folemethod_size_params(VALUE self);
static VALUE ole_method_size_opt_params(ITypeInfo *pTypeInfo, UINT method_index);
static VALUE folemethod_size_opt_params(VALUE self);
static VALUE ole_method_params(ITypeInfo *pTypeInfo, UINT method_index);
static VALUE folemethod_params(VALUE self);
static VALUE folemethod_inspect(VALUE self);
static const rb_data_type_t olemethod_datatype = {
"win32ole_method",
{NULL, olemethod_free, olemethod_size,},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
static void
olemethod_free(void *ptr)
{
struct olemethoddata *polemethod = ptr;
OLE_FREE(polemethod->pTypeInfo);
OLE_FREE(polemethod->pOwnerTypeInfo);
free(polemethod);
}
static size_t
olemethod_size(const void *ptr)
{
return ptr ? sizeof(struct olemethoddata) : 0;
}
struct olemethoddata *
olemethod_data_get_struct(VALUE obj)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(obj, struct olemethoddata, &olemethod_datatype, pmethod);
return pmethod;
}
static VALUE
ole_method_sub(VALUE self, ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE name)
{
HRESULT hr;
TYPEATTR *pTypeAttr;
BSTR bstr;
FUNCDESC *pFuncDesc;
WORD i;
VALUE fname;
VALUE method = Qnil;
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr)) {
ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeAttr");
}
for(i = 0; i < pTypeAttr->cFuncs && method == Qnil; i++) {
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc);
if (FAILED(hr))
continue;
hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
&bstr, NULL, NULL, NULL);
if (FAILED(hr)) {
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
continue;
}
fname = WC2VSTR(bstr);
if (strcasecmp(StringValuePtr(name), StringValuePtr(fname)) == 0) {
olemethod_set_member(self, pTypeInfo, pOwnerTypeInfo, i, fname);
method = self;
}
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
pFuncDesc=NULL;
}
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return method;
}
VALUE
ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask)
{
HRESULT hr;
TYPEATTR *pTypeAttr;
WORD i;
HREFTYPE href;
ITypeInfo *pRefTypeInfo;
VALUE methods = rb_ary_new();
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr)) {
ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeAttr");
}
ole_methods_sub(0, pTypeInfo, methods, mask);
for(i=0; i < pTypeAttr->cImplTypes; i++){
hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
if(FAILED(hr))
continue;
hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
if (FAILED(hr))
continue;
ole_methods_sub(pTypeInfo, pRefTypeInfo, methods, mask);
OLE_RELEASE(pRefTypeInfo);
}
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return methods;
}
static VALUE
olemethod_from_typeinfo(VALUE self, ITypeInfo *pTypeInfo, VALUE name)
{
HRESULT hr;
TYPEATTR *pTypeAttr;
WORD i;
HREFTYPE href;
ITypeInfo *pRefTypeInfo;
VALUE method = Qnil;
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr)) {
ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeAttr");
}
method = ole_method_sub(self, 0, pTypeInfo, name);
if (method != Qnil) {
return method;
}
for(i=0; i < pTypeAttr->cImplTypes && method == Qnil; i++){
hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
if(FAILED(hr))
continue;
hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
if (FAILED(hr))
continue;
method = ole_method_sub(self, pTypeInfo, pRefTypeInfo, name);
OLE_RELEASE(pRefTypeInfo);
}
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return method;
}
static VALUE
ole_methods_sub(ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE methods, int mask)
{
HRESULT hr;
TYPEATTR *pTypeAttr;
BSTR bstr;
FUNCDESC *pFuncDesc;
VALUE method;
WORD i;
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr)) {
ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetTypeAttr");
}
for(i = 0; i < pTypeAttr->cFuncs; i++) {
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc);
if (FAILED(hr))
continue;
hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
&bstr, NULL, NULL, NULL);
if (FAILED(hr)) {
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
continue;
}
if(pFuncDesc->invkind & mask) {
method = folemethod_s_allocate(cWIN32OLE_METHOD);
olemethod_set_member(method, pTypeInfo, pOwnerTypeInfo,
i, WC2VSTR(bstr));
rb_ary_push(methods, method);
}
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
pFuncDesc=NULL;
}
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return methods;
}
VALUE
create_win32ole_method(ITypeInfo *pTypeInfo, VALUE name)
{
VALUE method = folemethod_s_allocate(cWIN32OLE_METHOD);
VALUE obj = olemethod_from_typeinfo(method, pTypeInfo, name);
return obj;
}
/*
* Document-class: WIN32OLE::Method
*
* +WIN32OLE::Method+ objects represent OLE method information.
*/
static VALUE
olemethod_set_member(VALUE self, ITypeInfo *pTypeInfo, ITypeInfo *pOwnerTypeInfo, int index, VALUE name)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
pmethod->pTypeInfo = pTypeInfo;
OLE_ADDREF(pTypeInfo);
pmethod->pOwnerTypeInfo = pOwnerTypeInfo;
OLE_ADDREF(pOwnerTypeInfo);
pmethod->index = index;
rb_ivar_set(self, rb_intern("name"), name);
return self;
}
VALUE
folemethod_s_allocate(VALUE klass)
{
struct olemethoddata *pmethod;
VALUE obj;
obj = TypedData_Make_Struct(klass,
struct olemethoddata,
&olemethod_datatype, pmethod);
pmethod->pTypeInfo = NULL;
pmethod->pOwnerTypeInfo = NULL;
pmethod->index = 0;
return obj;
}
/*
* call-seq:
* WIN32OLE::Method.new(ole_type, method) -> WIN32OLE::Method object
*
* Returns a new WIN32OLE::Method object which represents the information
* about OLE method.
* The first argument <i>ole_type</i> specifies WIN32OLE::Type object.
* The second argument <i>method</i> specifies OLE method name defined OLE class
* which represents WIN32OLE::Type object.
*
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbook')
* method = WIN32OLE::Method.new(tobj, 'SaveAs')
*/
static VALUE
folemethod_initialize(VALUE self, VALUE oletype, VALUE method)
{
VALUE obj = Qnil;
ITypeInfo *pTypeInfo;
if (rb_obj_is_kind_of(oletype, cWIN32OLE_TYPE)) {
SafeStringValue(method);
pTypeInfo = itypeinfo(oletype);
obj = olemethod_from_typeinfo(self, pTypeInfo, method);
if (obj == Qnil) {
rb_raise(eWIN32OLERuntimeError, "not found %s",
StringValuePtr(method));
}
}
else {
rb_raise(rb_eTypeError, "1st argument should be WIN32OLE::Type object");
}
return obj;
}
/*
* call-seq:
* name
*
* Returns the name of the method.
*
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbook')
* method = WIN32OLE::Method.new(tobj, 'SaveAs')
* puts method.name # => SaveAs
*
*/
static VALUE
folemethod_name(VALUE self)
{
return rb_ivar_get(self, rb_intern("name"));
}
static VALUE
ole_method_return_type(ITypeInfo *pTypeInfo, UINT method_index)
{
FUNCDESC *pFuncDesc;
HRESULT hr;
VALUE type;
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if (FAILED(hr))
ole_raise(hr, eWIN32OLEQueryInterfaceError, "failed to GetFuncDesc");
type = ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), Qnil);
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return type;
}
/*
* call-seq:
* return_type
*
* Returns string of return value type of method.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
* method = WIN32OLE::Method.new(tobj, 'Add')
* puts method.return_type # => Workbook
*
*/
static VALUE
folemethod_return_type(VALUE self)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
return ole_method_return_type(pmethod->pTypeInfo, pmethod->index);
}
static VALUE
ole_method_return_vtype(ITypeInfo *pTypeInfo, UINT method_index)
{
FUNCDESC *pFuncDesc;
HRESULT hr;
VALUE vvt;
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if (FAILED(hr))
ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc");
vvt = RB_INT2FIX(pFuncDesc->elemdescFunc.tdesc.vt);
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return vvt;
}
/*
* call-seq:
* return_vtype
*
* Returns number of return value type of method.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
* method = WIN32OLE::Method.new(tobj, 'Add')
* puts method.return_vtype # => 26
*
*/
static VALUE
folemethod_return_vtype(VALUE self)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
return ole_method_return_vtype(pmethod->pTypeInfo, pmethod->index);
}
static VALUE
ole_method_return_type_detail(ITypeInfo *pTypeInfo, UINT method_index)
{
FUNCDESC *pFuncDesc;
HRESULT hr;
VALUE type = rb_ary_new();
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if (FAILED(hr))
return type;
ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), type);
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return type;
}
/*
* call-seq:
* return_type_detail
*
* Returns detail information of return value type of method.
* The information is array.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
* method = WIN32OLE::Method.new(tobj, 'Add')
* p method.return_type_detail # => ["PTR", "USERDEFINED", "Workbook"]
*/
static VALUE
folemethod_return_type_detail(VALUE self)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
return ole_method_return_type_detail(pmethod->pTypeInfo, pmethod->index);
}
static VALUE
ole_method_invkind(ITypeInfo *pTypeInfo, UINT method_index)
{
FUNCDESC *pFuncDesc;
HRESULT hr;
VALUE invkind;
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if(FAILED(hr))
ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc");
invkind = RB_INT2FIX(pFuncDesc->invkind);
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return invkind;
}
static VALUE
ole_method_invoke_kind(ITypeInfo *pTypeInfo, UINT method_index)
{
VALUE type = rb_str_new2("UNKNOWN");
VALUE invkind = ole_method_invkind(pTypeInfo, method_index);
if((RB_FIX2INT(invkind) & INVOKE_PROPERTYGET) &&
(RB_FIX2INT(invkind) & INVOKE_PROPERTYPUT) ) {
type = rb_str_new2("PROPERTY");
} else if(RB_FIX2INT(invkind) & INVOKE_PROPERTYGET) {
type = rb_str_new2("PROPERTYGET");
} else if(RB_FIX2INT(invkind) & INVOKE_PROPERTYPUT) {
type = rb_str_new2("PROPERTYPUT");
} else if(RB_FIX2INT(invkind) & INVOKE_PROPERTYPUTREF) {
type = rb_str_new2("PROPERTYPUTREF");
} else if(RB_FIX2INT(invkind) & INVOKE_FUNC) {
type = rb_str_new2("FUNC");
}
return type;
}
/*
* call-seq:
* invkind
*
* Returns the method invoke kind.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
* method = WIN32OLE::Method.new(tobj, 'Add')
* puts method.invkind # => 1
*
*/
static VALUE
folemethod_invkind(VALUE self)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
return ole_method_invkind(pmethod->pTypeInfo, pmethod->index);
}
/*
* call-seq:
* invoke_kind
*
* Returns the method kind string. The string is "UNKNOWN" or "PROPERTY"
* or "PROPERTY" or "PROPERTYGET" or "PROPERTYPUT" or "PROPERTYPPUTREF"
* or "FUNC".
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
* method = WIN32OLE::Method.new(tobj, 'Add')
* puts method.invoke_kind # => "FUNC"
*/
static VALUE
folemethod_invoke_kind(VALUE self)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
return ole_method_invoke_kind(pmethod->pTypeInfo, pmethod->index);
}
static VALUE
ole_method_visible(ITypeInfo *pTypeInfo, UINT method_index)
{
FUNCDESC *pFuncDesc;
HRESULT hr;
VALUE visible;
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if(FAILED(hr))
return Qfalse;
if (pFuncDesc->wFuncFlags & (FUNCFLAG_FRESTRICTED |
FUNCFLAG_FHIDDEN |
FUNCFLAG_FNONBROWSABLE)) {
visible = Qfalse;
} else {
visible = Qtrue;
}
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return visible;
}
/*
* call-seq:
* visible?
*
* Returns true if the method is public.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
* method = WIN32OLE::Method.new(tobj, 'Add')
* puts method.visible? # => true
*/
static VALUE
folemethod_visible(VALUE self)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
return ole_method_visible(pmethod->pTypeInfo, pmethod->index);
}
static VALUE
ole_method_event(ITypeInfo *pTypeInfo, UINT method_index, VALUE method_name)
{
TYPEATTR *pTypeAttr;
HRESULT hr;
WORD i;
int flags;
HREFTYPE href;
ITypeInfo *pRefTypeInfo;
FUNCDESC *pFuncDesc;
BSTR bstr;
VALUE name;
VALUE event = Qfalse;
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr))
return event;
if(pTypeAttr->typekind != TKIND_COCLASS) {
pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr);
return event;
}
for (i = 0; i < pTypeAttr->cImplTypes; i++) {
hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags);
if (FAILED(hr))
continue;
if (flags & IMPLTYPEFLAG_FSOURCE) {
hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,
i, &href);
if (FAILED(hr))
continue;
hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
href, &pRefTypeInfo);
if (FAILED(hr))
continue;
hr = pRefTypeInfo->lpVtbl->GetFuncDesc(pRefTypeInfo, method_index,
&pFuncDesc);
if (FAILED(hr)) {
OLE_RELEASE(pRefTypeInfo);
continue;
}
hr = pRefTypeInfo->lpVtbl->GetDocumentation(pRefTypeInfo,
pFuncDesc->memid,
&bstr, NULL, NULL, NULL);
if (FAILED(hr)) {
pRefTypeInfo->lpVtbl->ReleaseFuncDesc(pRefTypeInfo, pFuncDesc);
OLE_RELEASE(pRefTypeInfo);
continue;
}
name = WC2VSTR(bstr);
pRefTypeInfo->lpVtbl->ReleaseFuncDesc(pRefTypeInfo, pFuncDesc);
OLE_RELEASE(pRefTypeInfo);
if (rb_str_cmp(method_name, name) == 0) {
event = Qtrue;
break;
}
}
}
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return event;
}
/*
* call-seq:
* event?
*
* Returns true if the method is event.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbook')
* method = WIN32OLE::Method.new(tobj, 'SheetActivate')
* puts method.event? # => true
*
*/
static VALUE
folemethod_event(VALUE self)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
if (!pmethod->pOwnerTypeInfo)
return Qfalse;
return ole_method_event(pmethod->pOwnerTypeInfo,
pmethod->index,
rb_ivar_get(self, rb_intern("name")));
}
/*
* call-seq:
* event_interface
*
* Returns event interface name if the method is event.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbook')
* method = WIN32OLE::Method.new(tobj, 'SheetActivate')
* puts method.event_interface # => WorkbookEvents
*/
static VALUE
folemethod_event_interface(VALUE self)
{
BSTR name;
struct olemethoddata *pmethod;
HRESULT hr;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
if(folemethod_event(self) == Qtrue) {
hr = ole_docinfo_from_type(pmethod->pTypeInfo, &name, NULL, NULL, NULL);
if(SUCCEEDED(hr))
return WC2VSTR(name);
}
return Qnil;
}
static HRESULT
ole_method_docinfo_from_type(
ITypeInfo *pTypeInfo,
UINT method_index,
BSTR *name,
BSTR *helpstr,
DWORD *helpcontext,
BSTR *helpfile
)
{
FUNCDESC *pFuncDesc;
HRESULT hr;
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if (FAILED(hr))
return hr;
hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
name, helpstr,
helpcontext, helpfile);
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return hr;
}
static VALUE
ole_method_helpstring(ITypeInfo *pTypeInfo, UINT method_index)
{
HRESULT hr;
BSTR bhelpstring;
hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, &bhelpstring,
NULL, NULL);
if (FAILED(hr))
return Qnil;
return WC2VSTR(bhelpstring);
}
/*
* call-seq:
* helpstring
*
* Returns help string of OLE method. If the help string is not found,
* then the method returns nil.
* tobj = WIN32OLE::Type.new('Microsoft Internet Controls', 'IWebBrowser')
* method = WIN32OLE::Method.new(tobj, 'Navigate')
* puts method.helpstring # => Navigates to a URL or file.
*
*/
static VALUE
folemethod_helpstring(VALUE self)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
return ole_method_helpstring(pmethod->pTypeInfo, pmethod->index);
}
static VALUE
ole_method_helpfile(ITypeInfo *pTypeInfo, UINT method_index)
{
HRESULT hr;
BSTR bhelpfile;
hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, NULL,
NULL, &bhelpfile);
if (FAILED(hr))
return Qnil;
return WC2VSTR(bhelpfile);
}
/*
* call-seq:
* helpfile
*
* Returns help file. If help file is not found, then
* the method returns nil.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
* method = WIN32OLE::Method.new(tobj, 'Add')
* puts method.helpfile # => C:\...\VBAXL9.CHM
*/
static VALUE
folemethod_helpfile(VALUE self)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
return ole_method_helpfile(pmethod->pTypeInfo, pmethod->index);
}
static VALUE
ole_method_helpcontext(ITypeInfo *pTypeInfo, UINT method_index)
{
HRESULT hr;
DWORD helpcontext = 0;
hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, NULL,
&helpcontext, NULL);
if (FAILED(hr))
return Qnil;
return RB_INT2FIX(helpcontext);
}
/*
* call-seq:
* helpcontext
*
* Returns help context.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
* method = WIN32OLE::Method.new(tobj, 'Add')
* puts method.helpcontext # => 65717
*/
static VALUE
folemethod_helpcontext(VALUE self)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
return ole_method_helpcontext(pmethod->pTypeInfo, pmethod->index);
}
static VALUE
ole_method_dispid(ITypeInfo *pTypeInfo, UINT method_index)
{
FUNCDESC *pFuncDesc;
HRESULT hr;
VALUE dispid = Qnil;
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if (FAILED(hr))
return dispid;
dispid = RB_INT2NUM(pFuncDesc->memid);
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return dispid;
}
/*
* call-seq:
* dispid
*
* Returns dispatch ID.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
* method = WIN32OLE::Method.new(tobj, 'Add')
* puts method.dispid # => 181
*/
static VALUE
folemethod_dispid(VALUE self)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
return ole_method_dispid(pmethod->pTypeInfo, pmethod->index);
}
static VALUE
ole_method_offset_vtbl(ITypeInfo *pTypeInfo, UINT method_index)
{
FUNCDESC *pFuncDesc;
HRESULT hr;
VALUE offset_vtbl = Qnil;
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if (FAILED(hr))
return offset_vtbl;
offset_vtbl = RB_INT2FIX(pFuncDesc->oVft);
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return offset_vtbl;
}
/*
* call-seq:
* offset_vtbl
*
* Returns the offset ov VTBL.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
* method = WIN32OLE::Method.new(tobj, 'Add')
* puts method.offset_vtbl # => 40
*/
static VALUE
folemethod_offset_vtbl(VALUE self)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
return ole_method_offset_vtbl(pmethod->pTypeInfo, pmethod->index);
}
static VALUE
ole_method_size_params(ITypeInfo *pTypeInfo, UINT method_index)
{
FUNCDESC *pFuncDesc;
HRESULT hr;
VALUE size_params = Qnil;
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if (FAILED(hr))
return size_params;
size_params = RB_INT2FIX(pFuncDesc->cParams);
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return size_params;
}
/*
* call-seq:
* size_params
*
* Returns the size of arguments of the method.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbook')
* method = WIN32OLE::Method.new(tobj, 'SaveAs')
* puts method.size_params # => 11
*
*/
static VALUE
folemethod_size_params(VALUE self)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
return ole_method_size_params(pmethod->pTypeInfo, pmethod->index);
}
static VALUE
ole_method_size_opt_params(ITypeInfo *pTypeInfo, UINT method_index)
{
FUNCDESC *pFuncDesc;
HRESULT hr;
VALUE size_opt_params = Qnil;
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if (FAILED(hr))
return size_opt_params;
size_opt_params = RB_INT2FIX(pFuncDesc->cParamsOpt);
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return size_opt_params;
}
/*
* call-seq:
* size_opt_params
*
* Returns the size of optional parameters.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbook')
* method = WIN32OLE::Method.new(tobj, 'SaveAs')
* puts method.size_opt_params # => 4
*/
static VALUE
folemethod_size_opt_params(VALUE self)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
return ole_method_size_opt_params(pmethod->pTypeInfo, pmethod->index);
}
static VALUE
ole_method_params(ITypeInfo *pTypeInfo, UINT method_index)
{
FUNCDESC *pFuncDesc;
HRESULT hr;
BSTR *bstrs;
UINT len, i;
VALUE param;
VALUE params = rb_ary_new();
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if (FAILED(hr))
return params;
len = 0;
bstrs = ALLOCA_N(BSTR, pFuncDesc->cParams + 1);
hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pFuncDesc->memid,
bstrs, pFuncDesc->cParams + 1,
&len);
if (FAILED(hr)) {
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return params;
}
SysFreeString(bstrs[0]);
if (pFuncDesc->cParams > 0) {
for(i = 1; i < len; i++) {
param = create_win32ole_param(pTypeInfo, method_index, i-1, WC2VSTR(bstrs[i]));
rb_ary_push(params, param);
}
}
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return params;
}
/*
* call-seq:
* params
*
* returns array of WIN32OLE::Param object corresponding with method parameters.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbook')
* method = WIN32OLE::Method.new(tobj, 'SaveAs')
* p method.params # => [Filename, FileFormat, Password, WriteResPassword,
* ReadOnlyRecommended, CreateBackup, AccessMode,
* ConflictResolution, AddToMru, TextCodepage,
* TextVisualLayout]
*/
static VALUE
folemethod_params(VALUE self)
{
struct olemethoddata *pmethod;
TypedData_Get_Struct(self, struct olemethoddata, &olemethod_datatype, pmethod);
return ole_method_params(pmethod->pTypeInfo, pmethod->index);
}
/*
* call-seq:
* inspect -> String
*
* Returns the method name with class name.
*
*/
static VALUE
folemethod_inspect(VALUE self)
{
return default_inspect(self, "WIN32OLE::Method");
}
VALUE cWIN32OLE_METHOD;
void Init_win32ole_method(void)
{
cWIN32OLE_METHOD = rb_define_class_under(cWIN32OLE, "Method", rb_cObject);
/* Alias of WIN32OLE::Method, for the backward compatibility */
rb_define_const(rb_cObject, "WIN32OLE" "_METHOD", cWIN32OLE_METHOD);
rb_deprecate_constant(rb_cObject, "WIN32OLE" "_METHOD");
rb_define_alloc_func(cWIN32OLE_METHOD, folemethod_s_allocate);
rb_define_method(cWIN32OLE_METHOD, "initialize", folemethod_initialize, 2);
rb_define_method(cWIN32OLE_METHOD, "name", folemethod_name, 0);
rb_define_method(cWIN32OLE_METHOD, "return_type", folemethod_return_type, 0);
rb_define_method(cWIN32OLE_METHOD, "return_vtype", folemethod_return_vtype, 0);
rb_define_method(cWIN32OLE_METHOD, "return_type_detail", folemethod_return_type_detail, 0);
rb_define_method(cWIN32OLE_METHOD, "invoke_kind", folemethod_invoke_kind, 0);
rb_define_method(cWIN32OLE_METHOD, "invkind", folemethod_invkind, 0);
rb_define_method(cWIN32OLE_METHOD, "visible?", folemethod_visible, 0);
rb_define_method(cWIN32OLE_METHOD, "event?", folemethod_event, 0);
rb_define_method(cWIN32OLE_METHOD, "event_interface", folemethod_event_interface, 0);
rb_define_method(cWIN32OLE_METHOD, "helpstring", folemethod_helpstring, 0);
rb_define_method(cWIN32OLE_METHOD, "helpfile", folemethod_helpfile, 0);
rb_define_method(cWIN32OLE_METHOD, "helpcontext", folemethod_helpcontext, 0);
rb_define_method(cWIN32OLE_METHOD, "dispid", folemethod_dispid, 0);
rb_define_method(cWIN32OLE_METHOD, "offset_vtbl", folemethod_offset_vtbl, 0);
rb_define_method(cWIN32OLE_METHOD, "size_params", folemethod_size_params, 0);
rb_define_method(cWIN32OLE_METHOD, "size_opt_params", folemethod_size_opt_params, 0);
rb_define_method(cWIN32OLE_METHOD, "params", folemethod_params, 0);
rb_define_alias(cWIN32OLE_METHOD, "to_s", "name");
rb_define_method(cWIN32OLE_METHOD, "inspect", folemethod_inspect, 0);
}

View File

@ -1,16 +0,0 @@
#ifndef WIN32OLE_METHOD_H
#define WIN32OLE_METHOD_H 1
struct olemethoddata {
ITypeInfo *pOwnerTypeInfo;
ITypeInfo *pTypeInfo;
UINT index;
};
extern VALUE cWIN32OLE_METHOD;
VALUE folemethod_s_allocate(VALUE klass);
VALUE ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask);
VALUE create_win32ole_method(ITypeInfo *pTypeInfo, VALUE name);
struct olemethoddata *olemethod_data_get_struct(VALUE obj);
void Init_win32ole_method(void);
#endif

View File

@ -1,441 +0,0 @@
#include "win32ole.h"
VALUE cWIN32OLE_PARAM;
struct oleparamdata {
ITypeInfo *pTypeInfo;
UINT method_index;
UINT index;
};
static void oleparam_free(void *ptr);
static size_t oleparam_size(const void *ptr);
static VALUE foleparam_s_allocate(VALUE klass);
static VALUE oleparam_ole_param_from_index(VALUE self, ITypeInfo *pTypeInfo, UINT method_index, int param_index);
static VALUE oleparam_ole_param(VALUE self, VALUE olemethod, int n);
static VALUE foleparam_initialize(VALUE self, VALUE olemethod, VALUE n);
static VALUE foleparam_name(VALUE self);
static VALUE ole_param_ole_type(ITypeInfo *pTypeInfo, UINT method_index, UINT index);
static VALUE foleparam_ole_type(VALUE self);
static VALUE ole_param_ole_type_detail(ITypeInfo *pTypeInfo, UINT method_index, UINT index);
static VALUE foleparam_ole_type_detail(VALUE self);
static VALUE ole_param_flag_mask(ITypeInfo *pTypeInfo, UINT method_index, UINT index, USHORT mask);
static VALUE foleparam_input(VALUE self);
static VALUE foleparam_output(VALUE self);
static VALUE foleparam_optional(VALUE self);
static VALUE foleparam_retval(VALUE self);
static VALUE ole_param_default(ITypeInfo *pTypeInfo, UINT method_index, UINT index);
static VALUE foleparam_default(VALUE self);
static VALUE foleparam_inspect(VALUE self);
static const rb_data_type_t oleparam_datatype = {
"win32ole_param",
{NULL, oleparam_free, oleparam_size,},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
static void
oleparam_free(void *ptr)
{
struct oleparamdata *pole = ptr;
OLE_FREE(pole->pTypeInfo);
free(pole);
}
static size_t
oleparam_size(const void *ptr)
{
return ptr ? sizeof(struct oleparamdata) : 0;
}
VALUE
create_win32ole_param(ITypeInfo *pTypeInfo, UINT method_index, UINT index, VALUE name)
{
struct oleparamdata *pparam;
VALUE obj = foleparam_s_allocate(cWIN32OLE_PARAM);
TypedData_Get_Struct(obj, struct oleparamdata, &oleparam_datatype, pparam);
pparam->pTypeInfo = pTypeInfo;
OLE_ADDREF(pTypeInfo);
pparam->method_index = method_index;
pparam->index = index;
rb_ivar_set(obj, rb_intern("name"), name);
return obj;
}
/*
* Document-class: WIN32OLE::Param
*
* +WIN32OLE::Param+ objects represent param information of
* the OLE method.
*/
static VALUE
foleparam_s_allocate(VALUE klass)
{
struct oleparamdata *pparam;
VALUE obj;
obj = TypedData_Make_Struct(klass,
struct oleparamdata,
&oleparam_datatype, pparam);
pparam->pTypeInfo = NULL;
pparam->method_index = 0;
pparam->index = 0;
return obj;
}
static VALUE
oleparam_ole_param_from_index(VALUE self, ITypeInfo *pTypeInfo, UINT method_index, int param_index)
{
FUNCDESC *pFuncDesc;
HRESULT hr;
BSTR *bstrs;
UINT len;
struct oleparamdata *pparam;
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if (FAILED(hr))
ole_raise(hr, rb_eRuntimeError, "fail to ITypeInfo::GetFuncDesc");
len = 0;
bstrs = ALLOCA_N(BSTR, pFuncDesc->cParams + 1);
hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pFuncDesc->memid,
bstrs, pFuncDesc->cParams + 1,
&len);
if (FAILED(hr)) {
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
ole_raise(hr, rb_eRuntimeError, "fail to ITypeInfo::GetNames");
}
SysFreeString(bstrs[0]);
if (param_index < 1 || len <= (UINT)param_index)
{
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
rb_raise(rb_eIndexError, "index of param must be in 1..%d", len);
}
TypedData_Get_Struct(self, struct oleparamdata, &oleparam_datatype, pparam);
pparam->pTypeInfo = pTypeInfo;
OLE_ADDREF(pTypeInfo);
pparam->method_index = method_index;
pparam->index = param_index - 1;
rb_ivar_set(self, rb_intern("name"), WC2VSTR(bstrs[param_index]));
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return self;
}
static VALUE
oleparam_ole_param(VALUE self, VALUE olemethod, int n)
{
struct olemethoddata *pmethod = olemethod_data_get_struct(olemethod);
return oleparam_ole_param_from_index(self, pmethod->pTypeInfo, pmethod->index, n);
}
/*
* call-seq:
* new(method, n) -> WIN32OLE::Param object
*
* Returns WIN32OLE::Param object which represents OLE parameter information.
* 1st argument should be WIN32OLE::Method object.
* 2nd argument `n' is n-th parameter of the method specified by 1st argument.
*
* tobj = WIN32OLE::Type.new('Microsoft Scripting Runtime', 'IFileSystem')
* method = WIN32OLE::Method.new(tobj, 'CreateTextFile')
* param = WIN32OLE::Param.new(method, 2) # => #<WIN32OLE::Param:Overwrite=true>
*
*/
static VALUE
foleparam_initialize(VALUE self, VALUE olemethod, VALUE n)
{
int idx;
if (!rb_obj_is_kind_of(olemethod, cWIN32OLE_METHOD)) {
rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE::Method object");
}
idx = RB_FIX2INT(n);
return oleparam_ole_param(self, olemethod, idx);
}
/*
* call-seq:
* name
*
* Returns name.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbook')
* method = WIN32OLE::Method.new(tobj, 'SaveAs')
* param1 = method.params[0]
* puts param1.name # => Filename
*/
static VALUE
foleparam_name(VALUE self)
{
return rb_ivar_get(self, rb_intern("name"));
}
static VALUE
ole_param_ole_type(ITypeInfo *pTypeInfo, UINT method_index, UINT index)
{
FUNCDESC *pFuncDesc;
HRESULT hr;
VALUE type = rb_str_new2("unknown type");
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if (FAILED(hr))
return type;
type = ole_typedesc2val(pTypeInfo,
&(pFuncDesc->lprgelemdescParam[index].tdesc), Qnil);
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return type;
}
/*
* call-seq:
* ole_type
*
* Returns OLE type of WIN32OLE::Param object(parameter of OLE method).
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbook')
* method = WIN32OLE::Method.new(tobj, 'SaveAs')
* param1 = method.params[0]
* puts param1.ole_type # => VARIANT
*/
static VALUE
foleparam_ole_type(VALUE self)
{
struct oleparamdata *pparam;
TypedData_Get_Struct(self, struct oleparamdata, &oleparam_datatype, pparam);
return ole_param_ole_type(pparam->pTypeInfo, pparam->method_index,
pparam->index);
}
static VALUE
ole_param_ole_type_detail(ITypeInfo *pTypeInfo, UINT method_index, UINT index)
{
FUNCDESC *pFuncDesc;
HRESULT hr;
VALUE typedetail = rb_ary_new();
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if (FAILED(hr))
return typedetail;
ole_typedesc2val(pTypeInfo,
&(pFuncDesc->lprgelemdescParam[index].tdesc), typedetail);
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return typedetail;
}
/*
* call-seq:
* ole_type_detail
*
* Returns detail information of type of argument.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'IWorksheetFunction')
* method = WIN32OLE::Method.new(tobj, 'SumIf')
* param1 = method.params[0]
* p param1.ole_type_detail # => ["PTR", "USERDEFINED", "Range"]
*/
static VALUE
foleparam_ole_type_detail(VALUE self)
{
struct oleparamdata *pparam;
TypedData_Get_Struct(self, struct oleparamdata, &oleparam_datatype, pparam);
return ole_param_ole_type_detail(pparam->pTypeInfo, pparam->method_index,
pparam->index);
}
static VALUE
ole_param_flag_mask(ITypeInfo *pTypeInfo, UINT method_index, UINT index, USHORT mask)
{
FUNCDESC *pFuncDesc;
HRESULT hr;
VALUE ret = Qfalse;
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if(FAILED(hr))
return ret;
if (V_UNION1((&(pFuncDesc->lprgelemdescParam[index])), paramdesc).wParamFlags &mask)
ret = Qtrue;
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return ret;
}
/*
* call-seq:
* input?
*
* Returns true if the parameter is input.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbook')
* method = WIN32OLE::Method.new(tobj, 'SaveAs')
* param1 = method.params[0]
* puts param1.input? # => true
*/
static VALUE
foleparam_input(VALUE self)
{
struct oleparamdata *pparam;
TypedData_Get_Struct(self, struct oleparamdata, &oleparam_datatype, pparam);
return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
pparam->index, PARAMFLAG_FIN);
}
/*
* call-seq:
* output?
*
* Returns true if argument is output.
* tobj = WIN32OLE::Type.new('Microsoft Internet Controls', 'DWebBrowserEvents')
* method = WIN32OLE::Method.new(tobj, 'NewWindow')
* method.params.each do |param|
* puts "#{param.name} #{param.output?}"
* end
*
* The result of above script is following:
* URL false
* Flags false
* TargetFrameName false
* PostData false
* Headers false
* Processed true
*/
static VALUE
foleparam_output(VALUE self)
{
struct oleparamdata *pparam;
TypedData_Get_Struct(self, struct oleparamdata, &oleparam_datatype, pparam);
return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
pparam->index, PARAMFLAG_FOUT);
}
/*
* call-seq:
* optional?
*
* Returns true if argument is optional.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbook')
* method = WIN32OLE::Method.new(tobj, 'SaveAs')
* param1 = method.params[0]
* puts "#{param1.name} #{param1.optional?}" # => Filename true
*/
static VALUE
foleparam_optional(VALUE self)
{
struct oleparamdata *pparam;
TypedData_Get_Struct(self, struct oleparamdata, &oleparam_datatype, pparam);
return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
pparam->index, PARAMFLAG_FOPT);
}
/*
* call-seq:
* retval?
*
* Returns true if argument is return value.
* tobj = WIN32OLE::Type.new('DirectX 7 for Visual Basic Type Library',
* 'DirectPlayLobbyConnection')
* method = WIN32OLE::Method.new(tobj, 'GetPlayerShortName')
* param = method.params[0]
* puts "#{param.name} #{param.retval?}" # => name true
*/
static VALUE
foleparam_retval(VALUE self)
{
struct oleparamdata *pparam;
TypedData_Get_Struct(self, struct oleparamdata, &oleparam_datatype, pparam);
return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
pparam->index, PARAMFLAG_FRETVAL);
}
static VALUE
ole_param_default(ITypeInfo *pTypeInfo, UINT method_index, UINT index)
{
FUNCDESC *pFuncDesc;
ELEMDESC *pElemDesc;
PARAMDESCEX * pParamDescEx;
HRESULT hr;
USHORT wParamFlags;
USHORT mask = PARAMFLAG_FOPT|PARAMFLAG_FHASDEFAULT;
VALUE defval = Qnil;
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
if (FAILED(hr))
return defval;
pElemDesc = &pFuncDesc->lprgelemdescParam[index];
wParamFlags = V_UNION1(pElemDesc, paramdesc).wParamFlags;
if ((wParamFlags & mask) == mask) {
pParamDescEx = V_UNION1(pElemDesc, paramdesc).pparamdescex;
defval = ole_variant2val(&pParamDescEx->varDefaultValue);
}
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
return defval;
}
/*
* call-seq:
* default
*
* Returns default value. If the default value does not exist,
* this method returns nil.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Workbook')
* method = WIN32OLE::Method.new(tobj, 'SaveAs')
* method.params.each do |param|
* if param.default
* puts "#{param.name} (= #{param.default})"
* else
* puts "#{param}"
* end
* end
*
* The above script result is following:
* Filename
* FileFormat
* Password
* WriteResPassword
* ReadOnlyRecommended
* CreateBackup
* AccessMode (= 1)
* ConflictResolution
* AddToMru
* TextCodepage
* TextVisualLayout
*/
static VALUE
foleparam_default(VALUE self)
{
struct oleparamdata *pparam;
TypedData_Get_Struct(self, struct oleparamdata, &oleparam_datatype, pparam);
return ole_param_default(pparam->pTypeInfo, pparam->method_index,
pparam->index);
}
/*
* call-seq:
* inspect -> String
*
* Returns the parameter name with class name. If the parameter has default value,
* then returns name=value string with class name.
*
*/
static VALUE
foleparam_inspect(VALUE self)
{
VALUE detail = foleparam_name(self);
VALUE defval = foleparam_default(self);
if (defval != Qnil) {
rb_str_cat2(detail, "=");
rb_str_concat(detail, rb_inspect(defval));
}
return make_inspect("WIN32OLE::Param", detail);
}
void
Init_win32ole_param(void)
{
cWIN32OLE_PARAM = rb_define_class_under(cWIN32OLE, "Param", rb_cObject);
/* Alias of WIN32OLE::Param, for the backward compatibility */
rb_define_const(rb_cObject, "WIN32OLE" "_PARAM", cWIN32OLE_PARAM);
rb_deprecate_constant(rb_cObject, "WIN32OLE" "_PARAM");
rb_define_alloc_func(cWIN32OLE_PARAM, foleparam_s_allocate);
rb_define_method(cWIN32OLE_PARAM, "initialize", foleparam_initialize, 2);
rb_define_method(cWIN32OLE_PARAM, "name", foleparam_name, 0);
rb_define_method(cWIN32OLE_PARAM, "ole_type", foleparam_ole_type, 0);
rb_define_method(cWIN32OLE_PARAM, "ole_type_detail", foleparam_ole_type_detail, 0);
rb_define_method(cWIN32OLE_PARAM, "input?", foleparam_input, 0);
rb_define_method(cWIN32OLE_PARAM, "output?", foleparam_output, 0);
rb_define_method(cWIN32OLE_PARAM, "optional?", foleparam_optional, 0);
rb_define_method(cWIN32OLE_PARAM, "retval?", foleparam_retval, 0);
rb_define_method(cWIN32OLE_PARAM, "default", foleparam_default, 0);
rb_define_alias(cWIN32OLE_PARAM, "to_s", "name");
rb_define_method(cWIN32OLE_PARAM, "inspect", foleparam_inspect, 0);
}

View File

@ -1,8 +0,0 @@
#ifndef WIN32OLE_PARAM_H
#define WIN32OLE_PARAM_H
VALUE create_win32ole_param(ITypeInfo *pTypeInfo, UINT method_index, UINT index, VALUE name);
void Init_win32ole_param(void);
#endif

View File

@ -1,609 +0,0 @@
#include "win32ole.h"
struct olerecorddata {
IRecordInfo *pri;
void *pdata;
};
static HRESULT recordinfo_from_itypelib(ITypeLib *pTypeLib, VALUE name, IRecordInfo **ppri);
static int hash2olerec(VALUE key, VALUE val, VALUE rec);
static void olerecord_free(void *pvar);
static size_t olerecord_size(const void *ptr);
static VALUE folerecord_s_allocate(VALUE klass);
static VALUE folerecord_initialize(VALUE self, VALUE typename, VALUE oleobj);
static VALUE folerecord_to_h(VALUE self);
static VALUE folerecord_typename(VALUE self);
static VALUE olerecord_ivar_get(VALUE self, VALUE name);
static VALUE olerecord_ivar_set(VALUE self, VALUE name, VALUE val);
static VALUE folerecord_method_missing(int argc, VALUE *argv, VALUE self);
static VALUE folerecord_ole_instance_variable_get(VALUE self, VALUE name);
static VALUE folerecord_ole_instance_variable_set(VALUE self, VALUE name, VALUE val);
static VALUE folerecord_inspect(VALUE self);
static const rb_data_type_t olerecord_datatype = {
"win32ole_record",
{NULL, olerecord_free, olerecord_size,},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
static HRESULT
recordinfo_from_itypelib(ITypeLib *pTypeLib, VALUE name, IRecordInfo **ppri)
{
unsigned int count;
unsigned int i;
ITypeInfo *pTypeInfo;
HRESULT hr = OLE_E_LAST;
BSTR bstr;
count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
for (i = 0; i < count; i++) {
hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
&bstr, NULL, NULL, NULL);
if (FAILED(hr))
continue;
hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
if (FAILED(hr))
continue;
if (rb_str_cmp(WC2VSTR(bstr), name) == 0) {
hr = GetRecordInfoFromTypeInfo(pTypeInfo, ppri);
OLE_RELEASE(pTypeInfo);
return hr;
}
OLE_RELEASE(pTypeInfo);
}
hr = OLE_E_LAST;
return hr;
}
static int
hash2olerec(VALUE key, VALUE val, VALUE rec)
{
VARIANT var;
OLECHAR *pbuf;
struct olerecorddata *prec;
IRecordInfo *pri;
HRESULT hr;
if (val != Qnil) {
TypedData_Get_Struct(rec, struct olerecorddata, &olerecord_datatype, prec);
pri = prec->pri;
VariantInit(&var);
ole_val2variant(val, &var);
pbuf = ole_vstr2wc(key);
hr = pri->lpVtbl->PutField(pri, INVOKE_PROPERTYPUT, prec->pdata, pbuf, &var);
SysFreeString(pbuf);
VariantClear(&var);
if (FAILED(hr)) {
ole_raise(hr, eWIN32OLERuntimeError, "failed to putfield of `%s`", StringValuePtr(key));
}
}
return ST_CONTINUE;
}
void
ole_rec2variant(VALUE rec, VARIANT *var)
{
struct olerecorddata *prec;
ULONG size = 0;
IRecordInfo *pri;
HRESULT hr;
VALUE fields;
TypedData_Get_Struct(rec, struct olerecorddata, &olerecord_datatype, prec);
pri = prec->pri;
if (pri) {
hr = pri->lpVtbl->GetSize(pri, &size);
if (FAILED(hr)) {
ole_raise(hr, eWIN32OLERuntimeError, "failed to get size for allocation of VT_RECORD object");
}
if (prec->pdata) {
free(prec->pdata);
}
prec->pdata = ALLOC_N(char, size);
if (!prec->pdata) {
rb_raise(rb_eRuntimeError, "failed to memory allocation of %lu bytes", (unsigned long)size);
}
hr = pri->lpVtbl->RecordInit(pri, prec->pdata);
if (FAILED(hr)) {
ole_raise(hr, eWIN32OLERuntimeError, "failed to initialize VT_RECORD object");
}
fields = folerecord_to_h(rec);
rb_hash_foreach(fields, hash2olerec, rec);
V_RECORDINFO(var) = pri;
V_RECORD(var) = prec->pdata;
V_VT(var) = VT_RECORD;
} else {
rb_raise(eWIN32OLERuntimeError, "failed to retrieve IRecordInfo interface");
}
}
void
olerecord_set_ivar(VALUE obj, IRecordInfo *pri, void *prec)
{
HRESULT hr;
BSTR bstr;
BSTR *bstrs;
ULONG count = 0;
ULONG i;
VALUE fields;
VALUE val;
VARIANT var;
void *pdata = NULL;
struct olerecorddata *pvar;
TypedData_Get_Struct(obj, struct olerecorddata, &olerecord_datatype, pvar);
OLE_ADDREF(pri);
OLE_RELEASE(pvar->pri);
pvar->pri = pri;
hr = pri->lpVtbl->GetName(pri, &bstr);
if (SUCCEEDED(hr)) {
rb_ivar_set(obj, rb_intern("typename"), WC2VSTR(bstr));
}
hr = pri->lpVtbl->GetFieldNames(pri, &count, NULL);
if (FAILED(hr) || count == 0)
return;
bstrs = ALLOCA_N(BSTR, count);
hr = pri->lpVtbl->GetFieldNames(pri, &count, bstrs);
if (FAILED(hr)) {
return;
}
fields = rb_hash_new();
rb_ivar_set(obj, rb_intern("fields"), fields);
for (i = 0; i < count; i++) {
pdata = NULL;
VariantInit(&var);
val = Qnil;
if (prec) {
hr = pri->lpVtbl->GetFieldNoCopy(pri, prec, bstrs[i], &var, &pdata);
if (SUCCEEDED(hr)) {
val = ole_variant2val(&var);
}
}
rb_hash_aset(fields, WC2VSTR(bstrs[i]), val);
}
}
VALUE
create_win32ole_record(IRecordInfo *pri, void *prec)
{
VALUE obj = folerecord_s_allocate(cWIN32OLE_RECORD);
olerecord_set_ivar(obj, pri, prec);
return obj;
}
/*
* Document-class: WIN32OLE::Record
*
* +WIN32OLE::Record+ objects represents VT_RECORD OLE variant.
* Win32OLE returns WIN32OLE::Record object if the result value of invoking
* OLE methods.
*
* If COM server in VB.NET ComServer project is the following:
*
* Imports System.Runtime.InteropServices
* Public Class ComClass
* Public Structure Book
* <MarshalAs(UnmanagedType.BStr)> _
* Public title As String
* Public cost As Integer
* End Structure
* Public Function getBook() As Book
* Dim book As New Book
* book.title = "The Ruby Book"
* book.cost = 20
* Return book
* End Function
* End Class
*
* then, you can retrieve getBook return value from the following
* Ruby script:
*
* require 'win32ole'
* obj = WIN32OLE.new('ComServer.ComClass')
* book = obj.getBook
* book.class # => WIN32OLE::Record
* book.title # => "The Ruby Book"
* book.cost # => 20
*
*/
static void
olerecord_free(void *ptr) {
struct olerecorddata *pvar = ptr;
OLE_FREE(pvar->pri);
if (pvar->pdata) {
free(pvar->pdata);
}
free(pvar);
}
static size_t
olerecord_size(const void *ptr)
{
const struct olerecorddata *pvar = ptr;
size_t s = 0;
ULONG size = 0;
HRESULT hr;
if (ptr) {
s += sizeof(struct olerecorddata);
if (pvar->pri) {
hr = pvar->pri->lpVtbl->GetSize(pvar->pri, &size);
if (SUCCEEDED(hr)) {
s += size;
}
}
}
return s;
}
static VALUE
folerecord_s_allocate(VALUE klass) {
VALUE obj = Qnil;
struct olerecorddata *pvar;
obj = TypedData_Make_Struct(klass, struct olerecorddata, &olerecord_datatype, pvar);
pvar->pri = NULL;
pvar->pdata = NULL;
return obj;
}
/*
* call-seq:
* new(typename, obj) -> WIN32OLE::Record object
*
* Returns WIN32OLE::Record object. The first argument is struct name (String
* or Symbol).
* The second parameter obj should be WIN32OLE object or WIN32OLE::TypeLib object.
* If COM server in VB.NET ComServer project is the following:
*
* Imports System.Runtime.InteropServices
* Public Class ComClass
* Public Structure Book
* <MarshalAs(UnmanagedType.BStr)> _
* Public title As String
* Public cost As Integer
* End Structure
* End Class
*
* then, you can create WIN32OLE::Record object is as following:
*
* require 'win32ole'
* obj = WIN32OLE.new('ComServer.ComClass')
* book1 = WIN32OLE::Record.new('Book', obj) # => WIN32OLE::Record object
* tlib = obj.ole_typelib
* book2 = WIN32OLE::Record.new('Book', tlib) # => WIN32OLE::Record object
*
*/
static VALUE
folerecord_initialize(VALUE self, VALUE typename, VALUE oleobj) {
HRESULT hr;
ITypeLib *pTypeLib = NULL;
IRecordInfo *pri = NULL;
if (!RB_TYPE_P(typename, T_STRING) && !RB_TYPE_P(typename, T_SYMBOL)) {
rb_raise(rb_eArgError, "1st argument should be String or Symbol");
}
if (RB_TYPE_P(typename, T_SYMBOL)) {
typename = rb_sym2str(typename);
}
hr = S_OK;
if(rb_obj_is_kind_of(oleobj, cWIN32OLE)) {
hr = typelib_from_val(oleobj, &pTypeLib);
} else if (rb_obj_is_kind_of(oleobj, cWIN32OLE_TYPELIB)) {
pTypeLib = itypelib(oleobj);
OLE_ADDREF(pTypeLib);
if (pTypeLib) {
hr = S_OK;
} else {
hr = E_FAIL;
}
} else {
rb_raise(rb_eArgError, "2nd argument should be WIN32OLE object or WIN32OLE::TypeLib object");
}
if (FAILED(hr)) {
ole_raise(hr, eWIN32OLERuntimeError, "fail to query ITypeLib interface");
}
hr = recordinfo_from_itypelib(pTypeLib, typename, &pri);
OLE_RELEASE(pTypeLib);
if (FAILED(hr)) {
ole_raise(hr, eWIN32OLERuntimeError, "fail to query IRecordInfo interface for `%s'", StringValuePtr(typename));
}
olerecord_set_ivar(self, pri, NULL);
return self;
}
/*
* call-seq:
* WIN32OLE::Record#to_h #=> Ruby Hash object.
*
* Returns Ruby Hash object which represents VT_RECORD variable.
* The keys of Hash object are member names of VT_RECORD OLE variable and
* the values of Hash object are values of VT_RECORD OLE variable.
*
* If COM server in VB.NET ComServer project is the following:
*
* Imports System.Runtime.InteropServices
* Public Class ComClass
* Public Structure Book
* <MarshalAs(UnmanagedType.BStr)> _
* Public title As String
* Public cost As Integer
* End Structure
* Public Function getBook() As Book
* Dim book As New Book
* book.title = "The Ruby Book"
* book.cost = 20
* Return book
* End Function
* End Class
*
* then, the result of WIN32OLE::Record#to_h is the following:
*
* require 'win32ole'
* obj = WIN32OLE.new('ComServer.ComClass')
* book = obj.getBook
* book.to_h # => {"title"=>"The Ruby Book", "cost"=>20}
*
*/
static VALUE
folerecord_to_h(VALUE self)
{
return rb_ivar_get(self, rb_intern("fields"));
}
/*
* call-seq:
* typename #=> String object
*
* Returns the type name of VT_RECORD OLE variable.
*
* If COM server in VB.NET ComServer project is the following:
*
* Imports System.Runtime.InteropServices
* Public Class ComClass
* Public Structure Book
* <MarshalAs(UnmanagedType.BStr)> _
* Public title As String
* Public cost As Integer
* End Structure
* Public Function getBook() As Book
* Dim book As New Book
* book.title = "The Ruby Book"
* book.cost = 20
* Return book
* End Function
* End Class
*
* then, the result of WIN32OLE::Record#typename is the following:
*
* require 'win32ole'
* obj = WIN32OLE.new('ComServer.ComClass')
* book = obj.getBook
* book.typename # => "Book"
*
*/
static VALUE
folerecord_typename(VALUE self)
{
return rb_ivar_get(self, rb_intern("typename"));
}
static VALUE
olerecord_ivar_get(VALUE self, VALUE name)
{
VALUE fields;
fields = rb_ivar_get(self, rb_intern("fields"));
return rb_hash_fetch(fields, name);
}
static VALUE
olerecord_ivar_set(VALUE self, VALUE name, VALUE val)
{
long len;
char *p;
VALUE fields;
len = RSTRING_LEN(name);
p = RSTRING_PTR(name);
if (p[len-1] == '=') {
name = rb_str_subseq(name, 0, len-1);
}
fields = rb_ivar_get(self, rb_intern("fields"));
rb_hash_fetch(fields, name);
return rb_hash_aset(fields, name, val);
}
/*
* call-seq:
* method_missing(name)
*
* Returns value specified by the member name of VT_RECORD OLE variable.
* Or sets value specified by the member name of VT_RECORD OLE variable.
* If the member name is not correct, KeyError exception is raised.
*
* If COM server in VB.NET ComServer project is the following:
*
* Imports System.Runtime.InteropServices
* Public Class ComClass
* Public Structure Book
* <MarshalAs(UnmanagedType.BStr)> _
* Public title As String
* Public cost As Integer
* End Structure
* End Class
*
* Then getting/setting value from Ruby is as the following:
*
* obj = WIN32OLE.new('ComServer.ComClass')
* book = WIN32OLE::Record.new('Book', obj)
* book.title # => nil ( book.method_missing(:title) is invoked. )
* book.title = "Ruby" # ( book.method_missing(:title=, "Ruby") is invoked. )
*/
static VALUE
folerecord_method_missing(int argc, VALUE *argv, VALUE self)
{
VALUE name;
rb_check_arity(argc, 1, 2);
name = rb_sym2str(argv[0]);
#if SIZEOF_SIZE_T > SIZEOF_LONG
{
size_t n = strlen(StringValueCStr(name));
if (n >= LONG_MAX) {
rb_raise(rb_eRuntimeError, "too long member name");
}
}
#endif
if (argc == 1) {
return olerecord_ivar_get(self, name);
} else if (argc == 2) {
return olerecord_ivar_set(self, name, argv[1]);
}
return Qnil;
}
/*
* call-seq:
* ole_instance_variable_get(name)
*
* Returns value specified by the member name of VT_RECORD OLE object.
* If the member name is not correct, KeyError exception is raised.
* If you can't access member variable of VT_RECORD OLE object directly,
* use this method.
*
* If COM server in VB.NET ComServer project is the following:
*
* Imports System.Runtime.InteropServices
* Public Class ComClass
* Public Structure ComObject
* Public object_id As Ineger
* End Structure
* End Class
*
* and Ruby Object class has title attribute:
*
* then accessing object_id of ComObject from Ruby is as the following:
*
* srver = WIN32OLE.new('ComServer.ComClass')
* obj = WIN32OLE::Record.new('ComObject', server)
* # obj.object_id returns Ruby Object#object_id
* obj.ole_instance_variable_get(:object_id) # => nil
*
*/
static VALUE
folerecord_ole_instance_variable_get(VALUE self, VALUE name)
{
VALUE sname;
if(!RB_TYPE_P(name, T_STRING) && !RB_TYPE_P(name, T_SYMBOL)) {
rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
}
sname = name;
if (RB_TYPE_P(name, T_SYMBOL)) {
sname = rb_sym2str(name);
}
return olerecord_ivar_get(self, sname);
}
/*
* call-seq:
* ole_instance_variable_set(name, val)
*
* Sets value specified by the member name of VT_RECORD OLE object.
* If the member name is not correct, KeyError exception is raised.
* If you can't set value of member of VT_RECORD OLE object directly,
* use this method.
*
* If COM server in VB.NET ComServer project is the following:
*
* Imports System.Runtime.InteropServices
* Public Class ComClass
* <MarshalAs(UnmanagedType.BStr)> _
* Public title As String
* Public cost As Integer
* End Class
*
* then setting value of the `title' member is as following:
*
* srver = WIN32OLE.new('ComServer.ComClass')
* obj = WIN32OLE::Record.new('Book', server)
* obj.ole_instance_variable_set(:title, "The Ruby Book")
*
*/
static VALUE
folerecord_ole_instance_variable_set(VALUE self, VALUE name, VALUE val)
{
VALUE sname;
if(!RB_TYPE_P(name, T_STRING) && !RB_TYPE_P(name, T_SYMBOL)) {
rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
}
sname = name;
if (RB_TYPE_P(name, T_SYMBOL)) {
sname = rb_sym2str(name);
}
return olerecord_ivar_set(self, sname, val);
}
/*
* call-seq:
* inspect -> String
*
* Returns the OLE struct name and member name and the value of member
*
* If COM server in VB.NET ComServer project is the following:
*
* Imports System.Runtime.InteropServices
* Public Class ComClass
* <MarshalAs(UnmanagedType.BStr)> _
* Public title As String
* Public cost As Integer
* End Class
*
* then
*
* srver = WIN32OLE.new('ComServer.ComClass')
* obj = WIN32OLE::Record.new('Book', server)
* obj.inspect # => <WIN32OLE::Record(ComClass) {"title" => nil, "cost" => nil}>
*
*/
static VALUE
folerecord_inspect(VALUE self)
{
VALUE tname;
VALUE field;
tname = folerecord_typename(self);
if (tname == Qnil) {
tname = rb_inspect(tname);
}
field = rb_inspect(folerecord_to_h(self));
return rb_sprintf("#<WIN32OLE::Record(%"PRIsVALUE") %"PRIsVALUE">",
tname,
field);
}
VALUE cWIN32OLE_RECORD;
void
Init_win32ole_record(void)
{
cWIN32OLE_RECORD = rb_define_class_under(cWIN32OLE, "Record", rb_cObject);
/* Alias of WIN32OLE::Record, for the backward compatibility */
rb_define_const(rb_cObject, "WIN32OLE" "_RECORD", cWIN32OLE_RECORD);
rb_deprecate_constant(rb_cObject, "WIN32OLE" "_RECORD");
rb_define_alloc_func(cWIN32OLE_RECORD, folerecord_s_allocate);
rb_define_method(cWIN32OLE_RECORD, "initialize", folerecord_initialize, 2);
rb_define_method(cWIN32OLE_RECORD, "to_h", folerecord_to_h, 0);
rb_define_method(cWIN32OLE_RECORD, "typename", folerecord_typename, 0);
rb_define_method(cWIN32OLE_RECORD, "method_missing", folerecord_method_missing, -1);
rb_define_method(cWIN32OLE_RECORD, "ole_instance_variable_get", folerecord_ole_instance_variable_get, 1);
rb_define_method(cWIN32OLE_RECORD, "ole_instance_variable_set", folerecord_ole_instance_variable_set, 2);
rb_define_method(cWIN32OLE_RECORD, "inspect", folerecord_inspect, 0);
}

View File

@ -1,10 +0,0 @@
#ifndef WIN32OLE_RECORD_H
#define WIN32OLE_RECORD_H 1
extern VALUE cWIN32OLE_RECORD;
void ole_rec2variant(VALUE rec, VARIANT *var);
void olerecord_set_ivar(VALUE obj, IRecordInfo *pri, void *prec);
VALUE create_win32ole_record(IRecordInfo *pri, void *prec);
void Init_win32ole_record(void);
#endif

View File

@ -1,923 +0,0 @@
#include "win32ole.h"
struct oletypedata {
ITypeInfo *pTypeInfo;
};
static void oletype_free(void *ptr);
static size_t oletype_size(const void *ptr);
static VALUE foletype_s_ole_classes(VALUE self, VALUE typelib);
static VALUE foletype_s_typelibs(VALUE self);
static VALUE foletype_s_progids(VALUE self);
static VALUE oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name);
static VALUE foletype_s_allocate(VALUE klass);
static VALUE oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass);
static VALUE foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass);
static VALUE foletype_name(VALUE self);
static VALUE ole_ole_type(ITypeInfo *pTypeInfo);
static VALUE foletype_ole_type(VALUE self);
static VALUE ole_type_guid(ITypeInfo *pTypeInfo);
static VALUE foletype_guid(VALUE self);
static VALUE ole_type_progid(ITypeInfo *pTypeInfo);
static VALUE foletype_progid(VALUE self);
static VALUE ole_type_visible(ITypeInfo *pTypeInfo);
static VALUE foletype_visible(VALUE self);
static VALUE ole_type_major_version(ITypeInfo *pTypeInfo);
static VALUE foletype_major_version(VALUE self);
static VALUE ole_type_minor_version(ITypeInfo *pTypeInfo);
static VALUE foletype_minor_version(VALUE self);
static VALUE ole_type_typekind(ITypeInfo *pTypeInfo);
static VALUE foletype_typekind(VALUE self);
static VALUE ole_type_helpstring(ITypeInfo *pTypeInfo);
static VALUE foletype_helpstring(VALUE self);
static VALUE ole_type_src_type(ITypeInfo *pTypeInfo);
static VALUE foletype_src_type(VALUE self);
static VALUE ole_type_helpfile(ITypeInfo *pTypeInfo);
static VALUE foletype_helpfile(VALUE self);
static VALUE ole_type_helpcontext(ITypeInfo *pTypeInfo);
static VALUE foletype_helpcontext(VALUE self);
static VALUE ole_variables(ITypeInfo *pTypeInfo);
static VALUE foletype_variables(VALUE self);
static VALUE foletype_methods(VALUE self);
static VALUE foletype_ole_typelib(VALUE self);
static VALUE ole_type_impl_ole_types(ITypeInfo *pTypeInfo, int implflags);
static VALUE foletype_impl_ole_types(VALUE self);
static VALUE foletype_source_ole_types(VALUE self);
static VALUE foletype_default_event_sources(VALUE self);
static VALUE foletype_default_ole_types(VALUE self);
static VALUE foletype_inspect(VALUE self);
static const rb_data_type_t oletype_datatype = {
"win32ole_type",
{NULL, oletype_free, oletype_size,},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
/*
* Document-class: WIN32OLE::Type
*
* +WIN32OLE::Type+ objects represent OLE type library information.
*/
static void
oletype_free(void *ptr)
{
struct oletypedata *poletype = ptr;
OLE_FREE(poletype->pTypeInfo);
free(poletype);
}
static size_t
oletype_size(const void *ptr)
{
return ptr ? sizeof(struct oletypedata) : 0;
}
ITypeInfo *itypeinfo(VALUE self)
{
struct oletypedata *ptype;
TypedData_Get_Struct(self, struct oletypedata, &oletype_datatype, ptype);
return ptype->pTypeInfo;
}
VALUE
ole_type_from_itypeinfo(ITypeInfo *pTypeInfo)
{
ITypeLib *pTypeLib;
VALUE type = Qnil;
HRESULT hr;
unsigned int index;
BSTR bstr;
hr = pTypeInfo->lpVtbl->GetContainingTypeLib( pTypeInfo, &pTypeLib, &index );
if(FAILED(hr)) {
return Qnil;
}
hr = pTypeLib->lpVtbl->GetDocumentation( pTypeLib, index,
&bstr, NULL, NULL, NULL);
OLE_RELEASE(pTypeLib);
if (FAILED(hr)) {
return Qnil;
}
type = create_win32ole_type(pTypeInfo, WC2VSTR(bstr));
return type;
}
/*
* call-seq:
* ole_classes(typelib)
*
* Returns array of WIN32OLE::Type objects defined by the <i>typelib</i> type library.
*
* This method will be OBSOLETE.
* Use <code>WIN32OLE::TypeLib.new(typelib).ole_classes</code> instead.
*/
static VALUE
foletype_s_ole_classes(VALUE self, VALUE typelib)
{
VALUE obj;
/*
rb_warn("%s is obsolete; use %s instead.",
"WIN32OLE::Type.ole_classes",
"WIN32OLE::TypeLib.new(typelib).ole_types");
*/
obj = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("new"), 1, typelib);
return rb_funcall(obj, rb_intern("ole_types"), 0);
}
/*
* call-seq:
* typelibs
*
* Returns array of type libraries.
*
* This method will be OBSOLETE.
* Use <code>WIN32OLE::TypeLib.typelibs.collect{|t| t.name}</code> instead.
*
*/
static VALUE
foletype_s_typelibs(VALUE self)
{
/*
rb_warn("%s is obsolete. use %s instead.",
"WIN32OLE::Type.typelibs",
"WIN32OLE::TypeLib.typelibs.collect{t|t.name}");
*/
return rb_eval_string("WIN32OLE::TypeLib.typelibs.collect{|t|t.name}");
}
/*
* call-seq:
* progids
*
* Returns array of ProgID.
*/
static VALUE
foletype_s_progids(VALUE self)
{
HKEY hclsids, hclsid;
DWORD i;
LONG err;
VALUE clsid;
VALUE v = rb_str_new2("");
VALUE progids = rb_ary_new();
err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hclsids);
if(err != ERROR_SUCCESS) {
return progids;
}
for(i = 0; ; i++) {
clsid = reg_enum_key(hclsids, i);
if (clsid == Qnil)
break;
err = reg_open_vkey(hclsids, clsid, &hclsid);
if (err != ERROR_SUCCESS)
continue;
if ((v = reg_get_val2(hclsid, "ProgID")) != Qnil)
rb_ary_push(progids, v);
if ((v = reg_get_val2(hclsid, "VersionIndependentProgID")) != Qnil)
rb_ary_push(progids, v);
RegCloseKey(hclsid);
}
RegCloseKey(hclsids);
return progids;
}
static VALUE
oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name)
{
struct oletypedata *ptype;
TypedData_Get_Struct(self, struct oletypedata, &oletype_datatype, ptype);
rb_ivar_set(self, rb_intern("name"), name);
ptype->pTypeInfo = pTypeInfo;
OLE_ADDREF(pTypeInfo);
return self;
}
static VALUE
foletype_s_allocate(VALUE klass)
{
struct oletypedata *poletype;
VALUE obj;
ole_initialize();
obj = TypedData_Make_Struct(klass,struct oletypedata, &oletype_datatype, poletype);
poletype->pTypeInfo = NULL;
return obj;
}
VALUE
create_win32ole_type(ITypeInfo *pTypeInfo, VALUE name)
{
VALUE obj = foletype_s_allocate(cWIN32OLE_TYPE);
oletype_set_member(obj, pTypeInfo, name);
return obj;
}
static VALUE
oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass)
{
long count;
int i;
HRESULT hr;
BSTR bstr;
VALUE typelib;
ITypeInfo *pTypeInfo;
VALUE found = Qfalse;
count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
for (i = 0; i < count && found == Qfalse; i++) {
hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
if (FAILED(hr))
continue;
hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
&bstr, NULL, NULL, NULL);
if (FAILED(hr))
continue;
typelib = WC2VSTR(bstr);
if (rb_str_cmp(oleclass, typelib) == 0) {
oletype_set_member(self, pTypeInfo, typelib);
found = Qtrue;
}
OLE_RELEASE(pTypeInfo);
}
return found;
}
/*
* call-seq:
* new(typelib, ole_class) -> WIN32OLE::Type object
*
* Returns a new WIN32OLE::Type object.
* The first argument <i>typelib</i> specifies OLE type library name.
* The second argument specifies OLE class name.
*
* WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Application')
* # => WIN32OLE::Type object of Application class of Excel.
*/
static VALUE
foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass)
{
VALUE file;
OLECHAR * pbuf;
ITypeLib *pTypeLib;
HRESULT hr;
SafeStringValue(oleclass);
SafeStringValue(typelib);
file = typelib_file(typelib);
if (file == Qnil) {
file = typelib;
}
pbuf = ole_vstr2wc(file);
hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);
if (FAILED(hr))
ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx");
SysFreeString(pbuf);
if (oleclass_from_typelib(self, pTypeLib, oleclass) == Qfalse) {
OLE_RELEASE(pTypeLib);
rb_raise(eWIN32OLERuntimeError, "not found `%s` in `%s`",
StringValuePtr(oleclass), StringValuePtr(typelib));
}
OLE_RELEASE(pTypeLib);
return self;
}
/*
* call-seq:
* name #=> OLE type name
*
* Returns OLE type name.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Application')
* puts tobj.name # => Application
*/
static VALUE
foletype_name(VALUE self)
{
return rb_ivar_get(self, rb_intern("name"));
}
static VALUE
ole_ole_type(ITypeInfo *pTypeInfo)
{
HRESULT hr;
TYPEATTR *pTypeAttr;
VALUE type = Qnil;
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if(FAILED(hr)){
return type;
}
switch(pTypeAttr->typekind) {
case TKIND_ENUM:
type = rb_str_new2("Enum");
break;
case TKIND_RECORD:
type = rb_str_new2("Record");
break;
case TKIND_MODULE:
type = rb_str_new2("Module");
break;
case TKIND_INTERFACE:
type = rb_str_new2("Interface");
break;
case TKIND_DISPATCH:
type = rb_str_new2("Dispatch");
break;
case TKIND_COCLASS:
type = rb_str_new2("Class");
break;
case TKIND_ALIAS:
type = rb_str_new2("Alias");
break;
case TKIND_UNION:
type = rb_str_new2("Union");
break;
case TKIND_MAX:
type = rb_str_new2("Max");
break;
default:
type = Qnil;
break;
}
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return type;
}
/*
* call-seq:
* ole_type #=> OLE type string.
*
* returns type of OLE class.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Application')
* puts tobj.ole_type # => Class
*/
static VALUE
foletype_ole_type(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_ole_type(pTypeInfo);
}
static VALUE
ole_type_guid(ITypeInfo *pTypeInfo)
{
HRESULT hr;
TYPEATTR *pTypeAttr;
int len;
OLECHAR bstr[80];
VALUE guid = Qnil;
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr))
return guid;
len = StringFromGUID2(&pTypeAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
if (len > 3) {
guid = ole_wc2vstr(bstr, FALSE);
}
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return guid;
}
/*
* call-seq:
* guid #=> GUID
*
* Returns GUID.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Application')
* puts tobj.guid # => {00024500-0000-0000-C000-000000000046}
*/
static VALUE
foletype_guid(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_type_guid(pTypeInfo);
}
static VALUE
ole_type_progid(ITypeInfo *pTypeInfo)
{
HRESULT hr;
TYPEATTR *pTypeAttr;
OLECHAR *pbuf;
VALUE progid = Qnil;
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr))
return progid;
hr = ProgIDFromCLSID(&pTypeAttr->guid, &pbuf);
if (SUCCEEDED(hr)) {
progid = ole_wc2vstr(pbuf, FALSE);
CoTaskMemFree(pbuf);
}
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return progid;
}
/*
* call-seq:
* progid #=> ProgID
*
* Returns ProgID if it exists. If not found, then returns nil.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Application')
* puts tobj.progid # => Excel.Application.9
*/
static VALUE
foletype_progid(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_type_progid(pTypeInfo);
}
static VALUE
ole_type_visible(ITypeInfo *pTypeInfo)
{
HRESULT hr;
TYPEATTR *pTypeAttr;
VALUE visible;
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr))
return Qtrue;
if (pTypeAttr->wTypeFlags & (TYPEFLAG_FHIDDEN | TYPEFLAG_FRESTRICTED)) {
visible = Qfalse;
} else {
visible = Qtrue;
}
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return visible;
}
/*
* call-seq:
* visible? #=> true or false
*
* Returns true if the OLE class is public.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Application')
* puts tobj.visible # => true
*/
static VALUE
foletype_visible(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_type_visible(pTypeInfo);
}
static VALUE
ole_type_major_version(ITypeInfo *pTypeInfo)
{
VALUE ver;
TYPEATTR *pTypeAttr;
HRESULT hr;
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr))
ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
ver = RB_INT2FIX(pTypeAttr->wMajorVerNum);
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return ver;
}
/*
* call-seq:
* major_version
*
* Returns major version.
* tobj = WIN32OLE::Type.new('Microsoft Word 10.0 Object Library', 'Documents')
* puts tobj.major_version # => 8
*/
static VALUE
foletype_major_version(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_type_major_version(pTypeInfo);
}
static VALUE
ole_type_minor_version(ITypeInfo *pTypeInfo)
{
VALUE ver;
TYPEATTR *pTypeAttr;
HRESULT hr;
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr))
ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
ver = RB_INT2FIX(pTypeAttr->wMinorVerNum);
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return ver;
}
/*
* call-seq:
* minor_version #=> OLE minor version
*
* Returns minor version.
* tobj = WIN32OLE::Type.new('Microsoft Word 10.0 Object Library', 'Documents')
* puts tobj.minor_version # => 2
*/
static VALUE
foletype_minor_version(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_type_minor_version(pTypeInfo);
}
static VALUE
ole_type_typekind(ITypeInfo *pTypeInfo)
{
VALUE typekind;
TYPEATTR *pTypeAttr;
HRESULT hr;
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr))
ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
typekind = RB_INT2FIX(pTypeAttr->typekind);
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return typekind;
}
/*
* call-seq:
* typekind #=> number of type.
*
* Returns number which represents type.
* tobj = WIN32OLE::Type.new('Microsoft Word 10.0 Object Library', 'Documents')
* puts tobj.typekind # => 4
*
*/
static VALUE
foletype_typekind(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_type_typekind(pTypeInfo);
}
static VALUE
ole_type_helpstring(ITypeInfo *pTypeInfo)
{
HRESULT hr;
BSTR bhelpstr;
hr = ole_docinfo_from_type(pTypeInfo, NULL, &bhelpstr, NULL, NULL);
if(FAILED(hr)) {
return Qnil;
}
return WC2VSTR(bhelpstr);
}
/*
* call-seq:
* helpstring #=> help string.
*
* Returns help string.
* tobj = WIN32OLE::Type.new('Microsoft Internet Controls', 'IWebBrowser')
* puts tobj.helpstring # => Web Browser interface
*/
static VALUE
foletype_helpstring(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_type_helpstring(pTypeInfo);
}
static VALUE
ole_type_src_type(ITypeInfo *pTypeInfo)
{
HRESULT hr;
TYPEATTR *pTypeAttr;
VALUE alias = Qnil;
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr))
return alias;
if(pTypeAttr->typekind != TKIND_ALIAS) {
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return alias;
}
alias = ole_typedesc2val(pTypeInfo, &(pTypeAttr->tdescAlias), Qnil);
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return alias;
}
/*
* call-seq:
* src_type #=> OLE source class
*
* Returns source class when the OLE class is 'Alias'.
* tobj = WIN32OLE::Type.new('Microsoft Office 9.0 Object Library', 'MsoRGBType')
* puts tobj.src_type # => I4
*
*/
static VALUE
foletype_src_type(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_type_src_type(pTypeInfo);
}
static VALUE
ole_type_helpfile(ITypeInfo *pTypeInfo)
{
HRESULT hr;
BSTR bhelpfile;
hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL, NULL, &bhelpfile);
if(FAILED(hr)) {
return Qnil;
}
return WC2VSTR(bhelpfile);
}
/*
* call-seq:
* helpfile
*
* Returns helpfile path. If helpfile is not found, then returns nil.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
* puts tobj.helpfile # => C:\...\VBAXL9.CHM
*
*/
static VALUE
foletype_helpfile(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_type_helpfile(pTypeInfo);
}
static VALUE
ole_type_helpcontext(ITypeInfo *pTypeInfo)
{
HRESULT hr;
DWORD helpcontext;
hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL,
&helpcontext, NULL);
if(FAILED(hr))
return Qnil;
return RB_INT2FIX(helpcontext);
}
/*
* call-seq:
* helpcontext
*
* Returns helpcontext. If helpcontext is not found, then returns nil.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
* puts tobj.helpfile # => 131185
*/
static VALUE
foletype_helpcontext(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_type_helpcontext(pTypeInfo);
}
static VALUE
ole_variables(ITypeInfo *pTypeInfo)
{
HRESULT hr;
TYPEATTR *pTypeAttr;
WORD i;
UINT len;
BSTR bstr;
VARDESC *pVarDesc;
VALUE var;
VALUE variables = rb_ary_new();
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr)) {
ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
}
for(i = 0; i < pTypeAttr->cVars; i++) {
hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, i, &pVarDesc);
if(FAILED(hr))
continue;
len = 0;
hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr,
1, &len);
if(FAILED(hr) || len == 0 || !bstr)
continue;
var = create_win32ole_variable(pTypeInfo, i, WC2VSTR(bstr));
rb_ary_push(variables, var);
pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
pVarDesc = NULL;
}
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return variables;
}
/*
* call-seq:
* variables
*
* Returns array of WIN32OLE::Variable objects which represent variables
* defined in OLE class.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
* vars = tobj.variables
* vars.each do |v|
* puts "#{v.name} = #{v.value}"
* end
*
* The result of above sample script is follows:
* xlChart = -4109
* xlDialogSheet = -4116
* xlExcel4IntlMacroSheet = 4
* xlExcel4MacroSheet = 3
* xlWorksheet = -4167
*
*/
static VALUE
foletype_variables(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_variables(pTypeInfo);
}
/*
* call-seq:
* ole_methods # the array of WIN32OLE::Method objects.
*
* Returns array of WIN32OLE::Method objects which represent OLE method defined in
* OLE type library.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
* methods = tobj.ole_methods.collect{|m|
* m.name
* }
* # => ['Activate', 'Copy', 'Delete',....]
*/
static VALUE
foletype_methods(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_methods_from_typeinfo(pTypeInfo, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);
}
/*
* call-seq:
* ole_typelib
*
* Returns the WIN32OLE::TypeLib object which is including the WIN32OLE::Type
* object. If it is not found, then returns nil.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
* puts tobj.ole_typelib # => 'Microsoft Excel 9.0 Object Library'
*/
static VALUE
foletype_ole_typelib(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_typelib_from_itypeinfo(pTypeInfo);
}
static VALUE
ole_type_impl_ole_types(ITypeInfo *pTypeInfo, int implflags)
{
HRESULT hr;
ITypeInfo *pRefTypeInfo;
HREFTYPE href;
WORD i;
VALUE type;
TYPEATTR *pTypeAttr;
int flags;
VALUE types = rb_ary_new();
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
if (FAILED(hr)) {
return types;
}
for (i = 0; i < pTypeAttr->cImplTypes; i++) {
hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags);
if (FAILED(hr))
continue;
hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
if (FAILED(hr))
continue;
hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
if (FAILED(hr))
continue;
if ((flags & implflags) == implflags) {
type = ole_type_from_itypeinfo(pRefTypeInfo);
if (type != Qnil) {
rb_ary_push(types, type);
}
}
OLE_RELEASE(pRefTypeInfo);
}
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
return types;
}
/*
* call-seq:
* implemented_ole_types
*
* Returns the array of WIN32OLE::Type object which is implemented by the WIN32OLE::Type
* object.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
* p tobj.implemented_ole_types # => [_Worksheet, DocEvents]
*/
static VALUE
foletype_impl_ole_types(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_type_impl_ole_types(pTypeInfo, 0);
}
/*
* call-seq:
* source_ole_types
*
* Returns the array of WIN32OLE::Type object which is implemented by the WIN32OLE::Type
* object and having IMPLTYPEFLAG_FSOURCE.
* tobj = WIN32OLE::Type.new('Microsoft Internet Controls', "InternetExplorer")
* p tobj.source_ole_types
* # => [#<WIN32OLE::Type:DWebBrowserEvents2>, #<WIN32OLE::Type:DWebBrowserEvents>]
*/
static VALUE
foletype_source_ole_types(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_type_impl_ole_types(pTypeInfo, IMPLTYPEFLAG_FSOURCE);
}
/*
* call-seq:
* default_event_sources
*
* Returns the array of WIN32OLE::Type object which is implemented by the WIN32OLE::Type
* object and having IMPLTYPEFLAG_FSOURCE and IMPLTYPEFLAG_FDEFAULT.
* tobj = WIN32OLE::Type.new('Microsoft Internet Controls', "InternetExplorer")
* p tobj.default_event_sources # => [#<WIN32OLE::Type:DWebBrowserEvents2>]
*/
static VALUE
foletype_default_event_sources(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_type_impl_ole_types(pTypeInfo, IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT);
}
/*
* call-seq:
* default_ole_types
*
* Returns the array of WIN32OLE::Type object which is implemented by the WIN32OLE::Type
* object and having IMPLTYPEFLAG_FDEFAULT.
* tobj = WIN32OLE::Type.new('Microsoft Internet Controls', "InternetExplorer")
* p tobj.default_ole_types
* # => [#<WIN32OLE::Type:IWebBrowser2>, #<WIN32OLE::Type:DWebBrowserEvents2>]
*/
static VALUE
foletype_default_ole_types(VALUE self)
{
ITypeInfo *pTypeInfo = itypeinfo(self);
return ole_type_impl_ole_types(pTypeInfo, IMPLTYPEFLAG_FDEFAULT);
}
/*
* call-seq:
* inspect -> String
*
* Returns the type name with class name.
*
* ie = WIN32OLE.new('InternetExplorer.Application')
* ie.ole_type.inspect => #<WIN32OLE::Type:IWebBrowser2>
*/
static VALUE
foletype_inspect(VALUE self)
{
return default_inspect(self, "WIN32OLE::Type");
}
VALUE cWIN32OLE_TYPE;
void Init_win32ole_type(void)
{
cWIN32OLE_TYPE = rb_define_class_under(cWIN32OLE, "Type", rb_cObject);
/* Alias of WIN32OLE::Type, for the backward compatibility */
rb_define_const(rb_cObject, "WIN32OLE" "_TYPE", cWIN32OLE_TYPE);
rb_deprecate_constant(rb_cObject, "WIN32OLE" "_TYPE");
rb_define_singleton_method(cWIN32OLE_TYPE, "ole_classes", foletype_s_ole_classes, 1);
rb_define_singleton_method(cWIN32OLE_TYPE, "typelibs", foletype_s_typelibs, 0);
rb_define_singleton_method(cWIN32OLE_TYPE, "progids", foletype_s_progids, 0);
rb_define_alloc_func(cWIN32OLE_TYPE, foletype_s_allocate);
rb_define_method(cWIN32OLE_TYPE, "initialize", foletype_initialize, 2);
rb_define_method(cWIN32OLE_TYPE, "name", foletype_name, 0);
rb_define_method(cWIN32OLE_TYPE, "ole_type", foletype_ole_type, 0);
rb_define_method(cWIN32OLE_TYPE, "guid", foletype_guid, 0);
rb_define_method(cWIN32OLE_TYPE, "progid", foletype_progid, 0);
rb_define_method(cWIN32OLE_TYPE, "visible?", foletype_visible, 0);
rb_define_alias(cWIN32OLE_TYPE, "to_s", "name");
rb_define_method(cWIN32OLE_TYPE, "major_version", foletype_major_version, 0);
rb_define_method(cWIN32OLE_TYPE, "minor_version", foletype_minor_version, 0);
rb_define_method(cWIN32OLE_TYPE, "typekind", foletype_typekind, 0);
rb_define_method(cWIN32OLE_TYPE, "helpstring", foletype_helpstring, 0);
rb_define_method(cWIN32OLE_TYPE, "src_type", foletype_src_type, 0);
rb_define_method(cWIN32OLE_TYPE, "helpfile", foletype_helpfile, 0);
rb_define_method(cWIN32OLE_TYPE, "helpcontext", foletype_helpcontext, 0);
rb_define_method(cWIN32OLE_TYPE, "variables", foletype_variables, 0);
rb_define_method(cWIN32OLE_TYPE, "ole_methods", foletype_methods, 0);
rb_define_method(cWIN32OLE_TYPE, "ole_typelib", foletype_ole_typelib, 0);
rb_define_method(cWIN32OLE_TYPE, "implemented_ole_types", foletype_impl_ole_types, 0);
rb_define_method(cWIN32OLE_TYPE, "source_ole_types", foletype_source_ole_types, 0);
rb_define_method(cWIN32OLE_TYPE, "default_event_sources", foletype_default_event_sources, 0);
rb_define_method(cWIN32OLE_TYPE, "default_ole_types", foletype_default_ole_types, 0);
rb_define_method(cWIN32OLE_TYPE, "inspect", foletype_inspect, 0);
}

View File

@ -1,8 +0,0 @@
#ifndef WIN32OLE_TYPE_H
#define WIN32OLE_TYPE_H 1
extern VALUE cWIN32OLE_TYPE;
VALUE create_win32ole_type(ITypeInfo *pTypeInfo, VALUE name);
ITypeInfo *itypeinfo(VALUE self);
VALUE ole_type_from_itypeinfo(ITypeInfo *pTypeInfo);
void Init_win32ole_type(void);
#endif

View File

@ -1,849 +0,0 @@
#include "win32ole.h"
struct oletypelibdata {
ITypeLib *pTypeLib;
};
static VALUE reg_get_typelib_file_path(HKEY hkey);
static VALUE oletypelib_path(VALUE guid, VALUE version);
static HRESULT oletypelib_from_guid(VALUE guid, VALUE version, ITypeLib **ppTypeLib);
static VALUE foletypelib_s_typelibs(VALUE self);
static VALUE oletypelib_set_member(VALUE self, ITypeLib *pTypeLib);
static void oletypelib_free(void *ptr);
static size_t oletypelib_size(const void *ptr);
static VALUE foletypelib_s_allocate(VALUE klass);
static VALUE oletypelib_search_registry(VALUE self, VALUE typelib);
static void oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr);
static VALUE oletypelib_search_registry2(VALUE self, VALUE args);
static VALUE foletypelib_initialize(VALUE self, VALUE args);
static VALUE foletypelib_guid(VALUE self);
static VALUE foletypelib_name(VALUE self);
static VALUE make_version_str(VALUE major, VALUE minor);
static VALUE foletypelib_version(VALUE self);
static VALUE foletypelib_major_version(VALUE self);
static VALUE foletypelib_minor_version(VALUE self);
static VALUE foletypelib_path(VALUE self);
static VALUE foletypelib_visible(VALUE self);
static VALUE foletypelib_library_name(VALUE self);
static VALUE ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes);
static VALUE typelib_file_from_typelib(VALUE ole);
static VALUE typelib_file_from_clsid(VALUE ole);
static VALUE foletypelib_ole_types(VALUE self);
static VALUE foletypelib_inspect(VALUE self);
static const rb_data_type_t oletypelib_datatype = {
"win32ole_typelib",
{NULL, oletypelib_free, oletypelib_size,},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
static VALUE
reg_get_typelib_file_path(HKEY hkey)
{
VALUE path = Qnil;
path = reg_get_val2(hkey, "win64");
if (path != Qnil) {
return path;
}
path = reg_get_val2(hkey, "win32");
if (path != Qnil) {
return path;
}
path = reg_get_val2(hkey, "win16");
return path;
}
static VALUE
oletypelib_path(VALUE guid, VALUE version)
{
int k;
LONG err;
HKEY hkey;
HKEY hlang;
VALUE lang;
VALUE path = Qnil;
VALUE key = rb_str_new2("TypeLib\\");
rb_str_concat(key, guid);
rb_str_cat2(key, "\\");
rb_str_concat(key, version);
err = reg_open_vkey(HKEY_CLASSES_ROOT, key, &hkey);
if (err != ERROR_SUCCESS) {
return Qnil;
}
for(k = 0; path == Qnil; k++) {
lang = reg_enum_key(hkey, k);
if (lang == Qnil)
break;
err = reg_open_vkey(hkey, lang, &hlang);
if (err == ERROR_SUCCESS) {
path = reg_get_typelib_file_path(hlang);
RegCloseKey(hlang);
}
}
RegCloseKey(hkey);
return path;
}
static HRESULT
oletypelib_from_guid(VALUE guid, VALUE version, ITypeLib **ppTypeLib)
{
VALUE path;
OLECHAR *pBuf;
HRESULT hr;
path = oletypelib_path(guid, version);
if (path == Qnil) {
return E_UNEXPECTED;
}
pBuf = ole_vstr2wc(path);
hr = LoadTypeLibEx(pBuf, REGKIND_NONE, ppTypeLib);
SysFreeString(pBuf);
return hr;
}
ITypeLib *
itypelib(VALUE self)
{
struct oletypelibdata *ptlib;
TypedData_Get_Struct(self, struct oletypelibdata, &oletypelib_datatype, ptlib);
return ptlib->pTypeLib;
}
VALUE
ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo)
{
HRESULT hr;
ITypeLib *pTypeLib;
unsigned int index;
VALUE retval = Qnil;
hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
if(FAILED(hr)) {
return Qnil;
}
retval = create_win32ole_typelib(pTypeLib);
return retval;
}
/*
* Document-class: WIN32OLE::TypeLib
*
* +WIN32OLE::TypeLib+ objects represent OLE tyblib information.
*/
/*
* call-seq:
*
* typelibs
*
* Returns the array of WIN32OLE::TypeLib object.
*
* tlibs = WIN32OLE::TypeLib.typelibs
*
*/
static VALUE
foletypelib_s_typelibs(VALUE self)
{
HKEY htypelib, hguid;
DWORD i, j;
LONG err;
VALUE guid;
VALUE version;
VALUE name = Qnil;
VALUE typelibs = rb_ary_new();
VALUE typelib = Qnil;
HRESULT hr;
ITypeLib *pTypeLib;
err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
if(err != ERROR_SUCCESS) {
return typelibs;
}
for(i = 0; ; i++) {
guid = reg_enum_key(htypelib, i);
if (guid == Qnil)
break;
err = reg_open_vkey(htypelib, guid, &hguid);
if (err != ERROR_SUCCESS)
continue;
for(j = 0; ; j++) {
version = reg_enum_key(hguid, j);
if (version == Qnil)
break;
if ( (name = reg_get_val2(hguid, StringValuePtr(version))) != Qnil ) {
hr = oletypelib_from_guid(guid, version, &pTypeLib);
if (SUCCEEDED(hr)) {
typelib = create_win32ole_typelib(pTypeLib);
rb_ary_push(typelibs, typelib);
}
}
}
RegCloseKey(hguid);
}
RegCloseKey(htypelib);
return typelibs;
}
static VALUE
oletypelib_set_member(VALUE self, ITypeLib *pTypeLib)
{
struct oletypelibdata *ptlib;
TypedData_Get_Struct(self, struct oletypelibdata, &oletypelib_datatype, ptlib);
ptlib->pTypeLib = pTypeLib;
return self;
}
static void
oletypelib_free(void *ptr)
{
struct oletypelibdata *poletypelib = ptr;
OLE_FREE(poletypelib->pTypeLib);
free(poletypelib);
}
static size_t
oletypelib_size(const void *ptr)
{
return ptr ? sizeof(struct oletypelibdata) : 0;
}
static VALUE
foletypelib_s_allocate(VALUE klass)
{
struct oletypelibdata *poletypelib;
VALUE obj;
ole_initialize();
obj = TypedData_Make_Struct(klass, struct oletypelibdata, &oletypelib_datatype, poletypelib);
poletypelib->pTypeLib = NULL;
return obj;
}
VALUE
create_win32ole_typelib(ITypeLib *pTypeLib)
{
VALUE obj = foletypelib_s_allocate(cWIN32OLE_TYPELIB);
oletypelib_set_member(obj, pTypeLib);
return obj;
}
static VALUE
oletypelib_search_registry(VALUE self, VALUE typelib)
{
HKEY htypelib, hguid, hversion;
DWORD i, j;
LONG err;
VALUE found = Qfalse;
VALUE tlib;
VALUE guid;
VALUE ver;
HRESULT hr;
ITypeLib *pTypeLib;
err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
if(err != ERROR_SUCCESS) {
return Qfalse;
}
for(i = 0; !found; i++) {
guid = reg_enum_key(htypelib, i);
if (guid == Qnil)
break;
err = reg_open_vkey(htypelib, guid, &hguid);
if (err != ERROR_SUCCESS)
continue;
for(j = 0; found == Qfalse; j++) {
ver = reg_enum_key(hguid, j);
if (ver == Qnil)
break;
err = reg_open_vkey(hguid, ver, &hversion);
if (err != ERROR_SUCCESS)
continue;
tlib = reg_get_val(hversion, NULL);
if (tlib == Qnil) {
RegCloseKey(hversion);
continue;
}
if (rb_str_cmp(typelib, tlib) == 0) {
hr = oletypelib_from_guid(guid, ver, &pTypeLib);
if (SUCCEEDED(hr)) {
oletypelib_set_member(self, pTypeLib);
found = Qtrue;
}
}
RegCloseKey(hversion);
}
RegCloseKey(hguid);
}
RegCloseKey(htypelib);
return found;
}
static void
oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr)
{
HRESULT hr;
hr = pTypeLib->lpVtbl->GetLibAttr(pTypeLib, ppTLibAttr);
if (FAILED(hr)) {
ole_raise(hr, eWIN32OLERuntimeError,
"failed to get library attribute(TLIBATTR) from ITypeLib");
}
}
static VALUE
oletypelib_search_registry2(VALUE self, VALUE args)
{
HKEY htypelib, hguid, hversion;
double fver;
DWORD j;
LONG err;
VALUE found = Qfalse;
VALUE tlib;
VALUE ver;
VALUE version_str;
VALUE version = Qnil;
VALUE typelib = Qnil;
HRESULT hr;
ITypeLib *pTypeLib;
VALUE guid = rb_ary_entry(args, 0);
version_str = make_version_str(rb_ary_entry(args, 1), rb_ary_entry(args, 2));
err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
if(err != ERROR_SUCCESS) {
return Qfalse;
}
err = reg_open_vkey(htypelib, guid, &hguid);
if (err != ERROR_SUCCESS) {
RegCloseKey(htypelib);
return Qfalse;
}
if (version_str != Qnil) {
err = reg_open_vkey(hguid, version_str, &hversion);
if (err == ERROR_SUCCESS) {
tlib = reg_get_val(hversion, NULL);
if (tlib != Qnil) {
typelib = tlib;
version = version_str;
}
}
RegCloseKey(hversion);
} else {
fver = 0.0;
for(j = 0; ;j++) {
ver = reg_enum_key(hguid, j);
if (ver == Qnil)
break;
err = reg_open_vkey(hguid, ver, &hversion);
if (err != ERROR_SUCCESS)
continue;
tlib = reg_get_val(hversion, NULL);
if (tlib == Qnil) {
RegCloseKey(hversion);
continue;
}
if (fver < atof(StringValuePtr(ver))) {
fver = atof(StringValuePtr(ver));
version = ver;
typelib = tlib;
}
RegCloseKey(hversion);
}
}
RegCloseKey(hguid);
RegCloseKey(htypelib);
if (typelib != Qnil) {
hr = oletypelib_from_guid(guid, version, &pTypeLib);
if (SUCCEEDED(hr)) {
found = Qtrue;
oletypelib_set_member(self, pTypeLib);
}
}
return found;
}
/*
* call-seq:
* new(typelib [, version1, version2]) -> WIN32OLE::TypeLib object
*
* Returns a new WIN32OLE::TypeLib object.
*
* The first argument <i>typelib</i> specifies OLE type library name or GUID or
* OLE library file.
* The second argument is major version or version of the type library.
* The third argument is minor version.
* The second argument and third argument are optional.
* If the first argument is type library name, then the second and third argument
* are ignored.
*
* tlib1 = WIN32OLE::TypeLib.new('Microsoft Excel 9.0 Object Library')
* tlib2 = WIN32OLE::TypeLib.new('{00020813-0000-0000-C000-000000000046}')
* tlib3 = WIN32OLE::TypeLib.new('{00020813-0000-0000-C000-000000000046}', 1.3)
* tlib4 = WIN32OLE::TypeLib.new('{00020813-0000-0000-C000-000000000046}', 1, 3)
* tlib5 = WIN32OLE::TypeLib.new("C:\\WINNT\\SYSTEM32\\SHELL32.DLL")
* puts tlib1.name # -> 'Microsoft Excel 9.0 Object Library'
* puts tlib2.name # -> 'Microsoft Excel 9.0 Object Library'
* puts tlib3.name # -> 'Microsoft Excel 9.0 Object Library'
* puts tlib4.name # -> 'Microsoft Excel 9.0 Object Library'
* puts tlib5.name # -> 'Microsoft Shell Controls And Automation'
*
*/
static VALUE
foletypelib_initialize(VALUE self, VALUE args)
{
VALUE found = Qfalse;
VALUE typelib = Qnil;
int len = 0;
OLECHAR * pbuf;
ITypeLib *pTypeLib;
HRESULT hr = S_OK;
len = RARRAY_LEN(args);
rb_check_arity(len, 1, 3);
typelib = rb_ary_entry(args, 0);
SafeStringValue(typelib);
found = oletypelib_search_registry(self, typelib);
if (found == Qfalse) {
found = oletypelib_search_registry2(self, args);
}
if (found == Qfalse) {
pbuf = ole_vstr2wc(typelib);
hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);
SysFreeString(pbuf);
if (SUCCEEDED(hr)) {
found = Qtrue;
oletypelib_set_member(self, pTypeLib);
}
}
if (found == Qfalse) {
rb_raise(eWIN32OLERuntimeError, "not found type library `%s`",
StringValuePtr(typelib));
}
return self;
}
/*
* call-seq:
* guid -> The guid string.
*
* Returns guid string which specifies type library.
*
* tlib = WIN32OLE::TypeLib.new('Microsoft Excel 9.0 Object Library')
* guid = tlib.guid # -> '{00020813-0000-0000-C000-000000000046}'
*/
static VALUE
foletypelib_guid(VALUE self)
{
ITypeLib *pTypeLib;
OLECHAR bstr[80];
VALUE guid = Qnil;
int len;
TLIBATTR *pTLibAttr;
pTypeLib = itypelib(self);
oletypelib_get_libattr(pTypeLib, &pTLibAttr);
len = StringFromGUID2(&pTLibAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
if (len > 3) {
guid = ole_wc2vstr(bstr, FALSE);
}
pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
return guid;
}
/*
* call-seq:
* name -> The type library name
*
* Returns the type library name.
*
* tlib = WIN32OLE::TypeLib.new('Microsoft Excel 9.0 Object Library')
* name = tlib.name # -> 'Microsoft Excel 9.0 Object Library'
*/
static VALUE
foletypelib_name(VALUE self)
{
ITypeLib *pTypeLib;
HRESULT hr;
BSTR bstr;
VALUE name;
pTypeLib = itypelib(self);
hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1,
NULL, &bstr, NULL, NULL);
if (FAILED(hr)) {
ole_raise(hr, eWIN32OLERuntimeError, "failed to get name from ITypeLib");
}
name = WC2VSTR(bstr);
return name;
}
static VALUE
make_version_str(VALUE major, VALUE minor)
{
VALUE version_str = Qnil;
VALUE minor_str = Qnil;
if (major == Qnil) {
return Qnil;
}
version_str = rb_String(major);
if (minor != Qnil) {
minor_str = rb_String(minor);
rb_str_cat2(version_str, ".");
rb_str_append(version_str, minor_str);
}
return version_str;
}
/*
* call-seq:
* version -> The type library version String object.
*
* Returns the type library version.
*
* tlib = WIN32OLE::TypeLib.new('Microsoft Excel 9.0 Object Library')
* puts tlib.version #-> "1.3"
*/
static VALUE
foletypelib_version(VALUE self)
{
TLIBATTR *pTLibAttr;
ITypeLib *pTypeLib;
VALUE version;
pTypeLib = itypelib(self);
oletypelib_get_libattr(pTypeLib, &pTLibAttr);
version = rb_sprintf("%d.%d", pTLibAttr->wMajorVerNum, pTLibAttr->wMinorVerNum);
pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
return version;
}
/*
* call-seq:
* major_version -> The type library major version.
*
* Returns the type library major version.
*
* tlib = WIN32OLE::TypeLib.new('Microsoft Excel 9.0 Object Library')
* puts tlib.major_version # -> 1
*/
static VALUE
foletypelib_major_version(VALUE self)
{
TLIBATTR *pTLibAttr;
VALUE major;
ITypeLib *pTypeLib;
pTypeLib = itypelib(self);
oletypelib_get_libattr(pTypeLib, &pTLibAttr);
major = RB_INT2NUM(pTLibAttr->wMajorVerNum);
pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
return major;
}
/*
* call-seq:
* minor_version -> The type library minor version.
*
* Returns the type library minor version.
*
* tlib = WIN32OLE::TypeLib.new('Microsoft Excel 9.0 Object Library')
* puts tlib.minor_version # -> 3
*/
static VALUE
foletypelib_minor_version(VALUE self)
{
TLIBATTR *pTLibAttr;
VALUE minor;
ITypeLib *pTypeLib;
pTypeLib = itypelib(self);
oletypelib_get_libattr(pTypeLib, &pTLibAttr);
minor = RB_INT2NUM(pTLibAttr->wMinorVerNum);
pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
return minor;
}
/*
* call-seq:
* path -> The type library file path.
*
* Returns the type library file path.
*
* tlib = WIN32OLE::TypeLib.new('Microsoft Excel 9.0 Object Library')
* puts tlib.path #-> 'C:\...\EXCEL9.OLB'
*/
static VALUE
foletypelib_path(VALUE self)
{
TLIBATTR *pTLibAttr;
HRESULT hr = S_OK;
BSTR bstr;
LCID lcid = cWIN32OLE_lcid;
VALUE path;
ITypeLib *pTypeLib;
pTypeLib = itypelib(self);
oletypelib_get_libattr(pTypeLib, &pTLibAttr);
hr = QueryPathOfRegTypeLib(&pTLibAttr->guid,
pTLibAttr->wMajorVerNum,
pTLibAttr->wMinorVerNum,
lcid,
&bstr);
if (FAILED(hr)) {
pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
ole_raise(hr, eWIN32OLERuntimeError, "failed to QueryPathOfRegTypeTypeLib");
}
pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
path = WC2VSTR(bstr);
return path;
}
/*
* call-seq:
* visible?
*
* Returns true if the type library information is not hidden.
* If wLibFlags of TLIBATTR is 0 or LIBFLAG_FRESTRICTED or LIBFLAG_FHIDDEN,
* the method returns false, otherwise, returns true.
* If the method fails to access the TLIBATTR information, then
* WIN32OLE::RuntimeError is raised.
*
* tlib = WIN32OLE::TypeLib.new('Microsoft Excel 9.0 Object Library')
* tlib.visible? # => true
*/
static VALUE
foletypelib_visible(VALUE self)
{
ITypeLib *pTypeLib = NULL;
VALUE visible = Qtrue;
TLIBATTR *pTLibAttr;
pTypeLib = itypelib(self);
oletypelib_get_libattr(pTypeLib, &pTLibAttr);
if ((pTLibAttr->wLibFlags == 0) ||
(pTLibAttr->wLibFlags & LIBFLAG_FRESTRICTED) ||
(pTLibAttr->wLibFlags & LIBFLAG_FHIDDEN)) {
visible = Qfalse;
}
pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
return visible;
}
/*
* call-seq:
* library_name
*
* Returns library name.
* If the method fails to access library name, WIN32OLE::RuntimeError is raised.
*
* tlib = WIN32OLE::TypeLib.new('Microsoft Excel 9.0 Object Library')
* tlib.library_name # => Excel
*/
static VALUE
foletypelib_library_name(VALUE self)
{
HRESULT hr;
ITypeLib *pTypeLib = NULL;
VALUE libname = Qnil;
BSTR bstr;
pTypeLib = itypelib(self);
hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1,
&bstr, NULL, NULL, NULL);
if (FAILED(hr)) {
ole_raise(hr, eWIN32OLERuntimeError, "failed to get library name");
}
libname = WC2VSTR(bstr);
return libname;
}
static VALUE
ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes)
{
long count;
int i;
HRESULT hr;
BSTR bstr;
ITypeInfo *pTypeInfo;
VALUE type;
count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
for (i = 0; i < count; i++) {
hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
&bstr, NULL, NULL, NULL);
if (FAILED(hr))
continue;
hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
if (FAILED(hr))
continue;
type = create_win32ole_type(pTypeInfo, WC2VSTR(bstr));
rb_ary_push(classes, type);
OLE_RELEASE(pTypeInfo);
}
return classes;
}
static VALUE
typelib_file_from_typelib(VALUE ole)
{
HKEY htypelib, hclsid, hversion, hlang;
double fver;
DWORD i, j, k;
LONG err;
BOOL found = FALSE;
VALUE typelib;
VALUE file = Qnil;
VALUE clsid;
VALUE ver;
VALUE lang;
err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
if(err != ERROR_SUCCESS) {
return Qnil;
}
for(i = 0; !found; i++) {
clsid = reg_enum_key(htypelib, i);
if (clsid == Qnil)
break;
err = reg_open_vkey(htypelib, clsid, &hclsid);
if (err != ERROR_SUCCESS)
continue;
fver = 0;
for(j = 0; !found; j++) {
ver = reg_enum_key(hclsid, j);
if (ver == Qnil)
break;
err = reg_open_vkey(hclsid, ver, &hversion);
if (err != ERROR_SUCCESS || fver > atof(StringValuePtr(ver)))
continue;
fver = atof(StringValuePtr(ver));
typelib = reg_get_val(hversion, NULL);
if (typelib == Qnil)
continue;
if (rb_str_cmp(typelib, ole) == 0) {
for(k = 0; !found; k++) {
lang = reg_enum_key(hversion, k);
if (lang == Qnil)
break;
err = reg_open_vkey(hversion, lang, &hlang);
if (err == ERROR_SUCCESS) {
if ((file = reg_get_typelib_file_path(hlang)) != Qnil)
found = TRUE;
RegCloseKey(hlang);
}
}
}
RegCloseKey(hversion);
}
RegCloseKey(hclsid);
}
RegCloseKey(htypelib);
return file;
}
static VALUE
typelib_file_from_clsid(VALUE ole)
{
HKEY hroot, hclsid;
LONG err;
VALUE typelib;
char path[MAX_PATH + 1];
err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hroot);
if (err != ERROR_SUCCESS) {
return Qnil;
}
err = reg_open_key(hroot, StringValuePtr(ole), &hclsid);
if (err != ERROR_SUCCESS) {
RegCloseKey(hroot);
return Qnil;
}
typelib = reg_get_val2(hclsid, "InprocServer32");
RegCloseKey(hroot);
RegCloseKey(hclsid);
if (typelib != Qnil) {
ExpandEnvironmentStrings(StringValuePtr(typelib), path, sizeof(path));
path[MAX_PATH] = '\0';
typelib = rb_str_new2(path);
}
return typelib;
}
VALUE
typelib_file(VALUE ole)
{
VALUE file = typelib_file_from_clsid(ole);
if (file != Qnil) {
return file;
}
return typelib_file_from_typelib(ole);
}
/*
* call-seq:
* ole_types -> The array of WIN32OLE::Type object included the type library.
*
* Returns the type library file path.
*
* tlib = WIN32OLE::TypeLib.new('Microsoft Excel 9.0 Object Library')
* classes = tlib.ole_types.collect{|k| k.name} # -> ['AddIn', 'AddIns' ...]
*/
static VALUE
foletypelib_ole_types(VALUE self)
{
ITypeLib *pTypeLib = NULL;
VALUE classes = rb_ary_new();
pTypeLib = itypelib(self);
ole_types_from_typelib(pTypeLib, classes);
return classes;
}
/*
* call-seq:
* inspect -> String
*
* Returns the type library name with class name.
*
* tlib = WIN32OLE::TypeLib.new('Microsoft Excel 9.0 Object Library')
* tlib.inspect # => "<#WIN32OLE::TypeLib:Microsoft Excel 9.0 Object Library>"
*/
static VALUE
foletypelib_inspect(VALUE self)
{
return default_inspect(self, "WIN32OLE::TypeLib");
}
VALUE cWIN32OLE_TYPELIB;
void
Init_win32ole_typelib(void)
{
cWIN32OLE_TYPELIB = rb_define_class_under(cWIN32OLE, "TypeLib", rb_cObject);
/* Alias of WIN32OLE::TypeLib, for the backward compatibility */
rb_define_const(rb_cObject, "WIN32OLE" "_TYPELIB", cWIN32OLE_TYPELIB);
rb_deprecate_constant(rb_cObject, "WIN32OLE" "_TYPELIB");
rb_define_singleton_method(cWIN32OLE_TYPELIB, "typelibs", foletypelib_s_typelibs, 0);
rb_define_alloc_func(cWIN32OLE_TYPELIB, foletypelib_s_allocate);
rb_define_method(cWIN32OLE_TYPELIB, "initialize", foletypelib_initialize, -2);
rb_define_method(cWIN32OLE_TYPELIB, "guid", foletypelib_guid, 0);
rb_define_method(cWIN32OLE_TYPELIB, "name", foletypelib_name, 0);
rb_define_method(cWIN32OLE_TYPELIB, "version", foletypelib_version, 0);
rb_define_method(cWIN32OLE_TYPELIB, "major_version", foletypelib_major_version, 0);
rb_define_method(cWIN32OLE_TYPELIB, "minor_version", foletypelib_minor_version, 0);
rb_define_method(cWIN32OLE_TYPELIB, "path", foletypelib_path, 0);
rb_define_method(cWIN32OLE_TYPELIB, "ole_types", foletypelib_ole_types, 0);
rb_define_alias(cWIN32OLE_TYPELIB, "ole_classes", "ole_types");
rb_define_method(cWIN32OLE_TYPELIB, "visible?", foletypelib_visible, 0);
rb_define_method(cWIN32OLE_TYPELIB, "library_name", foletypelib_library_name, 0);
rb_define_alias(cWIN32OLE_TYPELIB, "to_s", "name");
rb_define_method(cWIN32OLE_TYPELIB, "inspect", foletypelib_inspect, 0);
}

View File

@ -1,11 +0,0 @@
#ifndef WIN32OLE_TYPELIB_H
#define WIN32OLE_TYPELIB_H 1
extern VALUE cWIN32OLE_TYPELIB;
void Init_win32ole_typelib(void);
ITypeLib * itypelib(VALUE self);
VALUE typelib_file(VALUE ole);
VALUE create_win32ole_typelib(ITypeLib *pTypeLib);
VALUE ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo);
#endif

View File

@ -1,386 +0,0 @@
#include "win32ole.h"
struct olevariabledata {
ITypeInfo *pTypeInfo;
UINT index;
};
static void olevariable_free(void *ptr);
static size_t olevariable_size(const void *ptr);
static VALUE folevariable_name(VALUE self);
static VALUE ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index);
static VALUE folevariable_ole_type(VALUE self);
static VALUE ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index);
static VALUE folevariable_ole_type_detail(VALUE self);
static VALUE ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index);
static VALUE folevariable_value(VALUE self);
static VALUE ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index);
static VALUE folevariable_visible(VALUE self);
static VALUE ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index);
static VALUE folevariable_variable_kind(VALUE self);
static VALUE ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index);
static VALUE folevariable_varkind(VALUE self);
static VALUE folevariable_inspect(VALUE self);
static const rb_data_type_t olevariable_datatype = {
"win32ole_variable",
{NULL, olevariable_free, olevariable_size,},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
static void
olevariable_free(void *ptr)
{
struct olevariabledata *polevar = ptr;
OLE_FREE(polevar->pTypeInfo);
free(polevar);
}
static size_t
olevariable_size(const void *ptr)
{
return ptr ? sizeof(struct olevariabledata) : 0;
}
/*
* Document-class: WIN32OLE::Variable
*
* +WIN32OLE::Variable+ objects represent OLE variable information.
*/
VALUE
create_win32ole_variable(ITypeInfo *pTypeInfo, UINT index, VALUE name)
{
struct olevariabledata *pvar;
VALUE obj = TypedData_Make_Struct(cWIN32OLE_VARIABLE, struct olevariabledata,
&olevariable_datatype, pvar);
pvar->pTypeInfo = pTypeInfo;
OLE_ADDREF(pTypeInfo);
pvar->index = index;
rb_ivar_set(obj, rb_intern("name"), name);
return obj;
}
/*
* call-seq:
* name
*
* Returns the name of variable.
*
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
* variables = tobj.variables
* variables.each do |variable|
* puts "#{variable.name}"
* end
*
* The result of above script is following:
* xlChart
* xlDialogSheet
* xlExcel4IntlMacroSheet
* xlExcel4MacroSheet
* xlWorksheet
*
*/
static VALUE
folevariable_name(VALUE self)
{
return rb_ivar_get(self, rb_intern("name"));
}
static VALUE
ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index)
{
VARDESC *pVarDesc;
HRESULT hr;
VALUE type;
hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
if (FAILED(hr))
ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc");
type = ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), Qnil);
pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
return type;
}
/*
* call-seq:
* ole_type
*
* Returns OLE type string.
*
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
* variables = tobj.variables
* variables.each do |variable|
* puts "#{variable.ole_type} #{variable.name}"
* end
*
* The result of above script is following:
* INT xlChart
* INT xlDialogSheet
* INT xlExcel4IntlMacroSheet
* INT xlExcel4MacroSheet
* INT xlWorksheet
*
*/
static VALUE
folevariable_ole_type(VALUE self)
{
struct olevariabledata *pvar;
TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar);
return ole_variable_ole_type(pvar->pTypeInfo, pvar->index);
}
static VALUE
ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index)
{
VARDESC *pVarDesc;
HRESULT hr;
VALUE type = rb_ary_new();
hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
if (FAILED(hr))
ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc");
ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), type);
pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
return type;
}
/*
* call-seq:
* ole_type_detail
*
* Returns detail information of type. The information is array of type.
*
* tobj = WIN32OLE::Type.new('DirectX 7 for Visual Basic Type Library', 'D3DCLIPSTATUS')
* variable = tobj.variables.find {|variable| variable.name == 'lFlags'}
* tdetail = variable.ole_type_detail
* p tdetail # => ["USERDEFINED", "CONST_D3DCLIPSTATUSFLAGS"]
*
*/
static VALUE
folevariable_ole_type_detail(VALUE self)
{
struct olevariabledata *pvar;
TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar);
return ole_variable_ole_type_detail(pvar->pTypeInfo, pvar->index);
}
static VALUE
ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index)
{
VARDESC *pVarDesc;
HRESULT hr;
VALUE val = Qnil;
hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
if (FAILED(hr))
return Qnil;
if(pVarDesc->varkind == VAR_CONST)
val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue));
pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
return val;
}
/*
* call-seq:
* value
*
* Returns value if value is exists. If the value does not exist,
* this method returns nil.
*
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
* variables = tobj.variables
* variables.each do |variable|
* puts "#{variable.name} #{variable.value}"
* end
*
* The result of above script is following:
* xlChart = -4109
* xlDialogSheet = -4116
* xlExcel4IntlMacroSheet = 4
* xlExcel4MacroSheet = 3
* xlWorksheet = -4167
*
*/
static VALUE
folevariable_value(VALUE self)
{
struct olevariabledata *pvar;
TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar);
return ole_variable_value(pvar->pTypeInfo, pvar->index);
}
static VALUE
ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index)
{
VARDESC *pVarDesc;
HRESULT hr;
VALUE visible = Qfalse;
hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
if (FAILED(hr))
return visible;
if (!(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN |
VARFLAG_FRESTRICTED |
VARFLAG_FNONBROWSABLE))) {
visible = Qtrue;
}
pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
return visible;
}
/*
* call-seq:
* visible?
*
* Returns true if the variable is public.
*
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
* variables = tobj.variables
* variables.each do |variable|
* puts "#{variable.name} #{variable.visible?}"
* end
*
* The result of above script is following:
* xlChart true
* xlDialogSheet true
* xlExcel4IntlMacroSheet true
* xlExcel4MacroSheet true
* xlWorksheet true
*
*/
static VALUE
folevariable_visible(VALUE self)
{
struct olevariabledata *pvar;
TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar);
return ole_variable_visible(pvar->pTypeInfo, pvar->index);
}
static VALUE
ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index)
{
VARDESC *pVarDesc;
HRESULT hr;
VALUE kind = rb_str_new2("UNKNOWN");
hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
if (FAILED(hr))
return kind;
switch(pVarDesc->varkind) {
case VAR_PERINSTANCE:
kind = rb_str_new2("PERINSTANCE");
break;
case VAR_STATIC:
kind = rb_str_new2("STATIC");
break;
case VAR_CONST:
kind = rb_str_new2("CONSTANT");
break;
case VAR_DISPATCH:
kind = rb_str_new2("DISPATCH");
break;
default:
break;
}
pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
return kind;
}
/*
* call-seq:
* variable_kind
*
* Returns variable kind string.
*
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
* variables = tobj.variables
* variables.each do |variable|
* puts "#{variable.name} #{variable.variable_kind}"
* end
*
* The result of above script is following:
* xlChart CONSTANT
* xlDialogSheet CONSTANT
* xlExcel4IntlMacroSheet CONSTANT
* xlExcel4MacroSheet CONSTANT
* xlWorksheet CONSTANT
*/
static VALUE
folevariable_variable_kind(VALUE self)
{
struct olevariabledata *pvar;
TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar);
return ole_variable_kind(pvar->pTypeInfo, pvar->index);
}
static VALUE
ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index)
{
VARDESC *pVarDesc;
HRESULT hr;
VALUE kind = Qnil;
hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
if (FAILED(hr))
return kind;
pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
kind = RB_INT2FIX(pVarDesc->varkind);
return kind;
}
/*
* call-seq:
* varkind
*
* Returns the number which represents variable kind.
* tobj = WIN32OLE::Type.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
* variables = tobj.variables
* variables.each do |variable|
* puts "#{variable.name} #{variable.varkind}"
* end
*
* The result of above script is following:
* xlChart 2
* xlDialogSheet 2
* xlExcel4IntlMacroSheet 2
* xlExcel4MacroSheet 2
* xlWorksheet 2
*/
static VALUE
folevariable_varkind(VALUE self)
{
struct olevariabledata *pvar;
TypedData_Get_Struct(self, struct olevariabledata, &olevariable_datatype, pvar);
return ole_variable_varkind(pvar->pTypeInfo, pvar->index);
}
/*
* call-seq:
* inspect -> String
*
* Returns the OLE variable name and the value with class name.
*
*/
static VALUE
folevariable_inspect(VALUE self)
{
VALUE v = rb_inspect(folevariable_value(self));
VALUE n = folevariable_name(self);
VALUE detail = rb_sprintf("%"PRIsVALUE"=%"PRIsVALUE, n, v);
return make_inspect("WIN32OLE::Variable", detail);
}
VALUE cWIN32OLE_VARIABLE;
void Init_win32ole_variable(void)
{
cWIN32OLE_VARIABLE = rb_define_class_under(cWIN32OLE, "Variable", rb_cObject);
/* Alias of WIN32OLE::Variable, for the backward compatibility */
rb_define_const(rb_cObject, "WIN32OLE" "_VARIABLE", cWIN32OLE_VARIABLE);
rb_deprecate_constant(rb_cObject, "WIN32OLE" "_VARIABLE");
rb_undef_alloc_func(cWIN32OLE_VARIABLE);
rb_define_method(cWIN32OLE_VARIABLE, "name", folevariable_name, 0);
rb_define_method(cWIN32OLE_VARIABLE, "ole_type", folevariable_ole_type, 0);
rb_define_method(cWIN32OLE_VARIABLE, "ole_type_detail", folevariable_ole_type_detail, 0);
rb_define_method(cWIN32OLE_VARIABLE, "value", folevariable_value, 0);
rb_define_method(cWIN32OLE_VARIABLE, "visible?", folevariable_visible, 0);
rb_define_method(cWIN32OLE_VARIABLE, "variable_kind", folevariable_variable_kind, 0);
rb_define_method(cWIN32OLE_VARIABLE, "varkind", folevariable_varkind, 0);
rb_define_method(cWIN32OLE_VARIABLE, "inspect", folevariable_inspect, 0);
rb_define_alias(cWIN32OLE_VARIABLE, "to_s", "name");
}

View File

@ -1,8 +0,0 @@
#ifndef WIN32OLE_VARIABLE_H
#define WIN32OLE_VARIABLE_H 1
extern VALUE cWIN32OLE_VARIABLE;
VALUE create_win32ole_variable(ITypeInfo *pTypeInfo, UINT index, VALUE name);
void Init_win32ole_variable(void);
#endif

View File

@ -1,738 +0,0 @@
#include "win32ole.h"
struct olevariantdata {
VARIANT realvar;
VARIANT var;
};
static void olevariant_free(void *ptr);
static size_t olevariant_size(const void *ptr);
static void ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar);
static void ole_val2variant_err(VALUE val, VARIANT *var);
static void ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vt);
static VALUE folevariant_s_allocate(VALUE klass);
static VALUE folevariant_s_array(VALUE klass, VALUE dims, VALUE vvt);
static void check_type_val2variant(VALUE val);
static VALUE folevariant_initialize(VALUE self, VALUE args);
static LONG *ary2safe_array_index(int ary_size, VALUE *ary, SAFEARRAY *psa);
static void unlock_safe_array(SAFEARRAY *psa);
static SAFEARRAY *get_locked_safe_array(VALUE val);
static VALUE folevariant_ary_aref(int argc, VALUE *argv, VALUE self);
static VALUE folevariant_ary_aset(int argc, VALUE *argv, VALUE self);
static VALUE folevariant_value(VALUE self);
static VALUE folevariant_vartype(VALUE self);
static VALUE folevariant_set_value(VALUE self, VALUE val);
static const rb_data_type_t olevariant_datatype = {
"win32ole_variant",
{NULL, olevariant_free, olevariant_size,},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
static void
olevariant_free(void *ptr)
{
struct olevariantdata *pvar = ptr;
VariantClear(&(pvar->realvar));
VariantClear(&(pvar->var));
free(pvar);
}
static size_t
olevariant_size(const void *ptr)
{
return ptr ? sizeof(struct olevariantdata) : 0;
}
static void
ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar)
{
HRESULT hr = S_OK;
if (((vt & ~VT_BYREF) == (VT_ARRAY | VT_UI1)) && RB_TYPE_P(val, T_STRING)) {
long len = RSTRING_LEN(val);
void *pdest = NULL;
SAFEARRAY *p = NULL;
SAFEARRAY *psa = SafeArrayCreateVector(VT_UI1, 0, len);
if (!psa) {
rb_raise(rb_eRuntimeError, "fail to SafeArrayCreateVector");
}
hr = SafeArrayAccessData(psa, &pdest);
if (SUCCEEDED(hr)) {
memcpy(pdest, RSTRING_PTR(val), len);
SafeArrayUnaccessData(psa);
V_VT(&(pvar->realvar)) = (vt & ~VT_BYREF);
p = V_ARRAY(&(pvar->realvar));
if (p != NULL) {
SafeArrayDestroy(p);
}
V_ARRAY(&(pvar->realvar)) = psa;
if (vt & VT_BYREF) {
V_VT(&(pvar->var)) = vt;
V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar)));
} else {
hr = VariantCopy(&(pvar->var), &(pvar->realvar));
}
} else {
if (psa)
SafeArrayDestroy(psa);
}
} else if (vt & VT_ARRAY) {
if (val == Qnil) {
V_VT(&(pvar->var)) = vt;
if (vt & VT_BYREF) {
V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar)));
}
} else {
hr = ole_val_ary2variant_ary(val, &(pvar->realvar), (VARTYPE)(vt & ~VT_BYREF));
if (SUCCEEDED(hr)) {
if (vt & VT_BYREF) {
V_VT(&(pvar->var)) = vt;
V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar)));
} else {
hr = VariantCopy(&(pvar->var), &(pvar->realvar));
}
}
}
#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__CYGWIN__) || defined(__MINGW32__)
} else if ( (vt & ~VT_BYREF) == VT_I8 || (vt & ~VT_BYREF) == VT_UI8) {
ole_val2variant_ex(val, &(pvar->realvar), (vt & ~VT_BYREF));
ole_val2variant_ex(val, &(pvar->var), (vt & ~VT_BYREF));
V_VT(&(pvar->var)) = vt;
if (vt & VT_BYREF) {
ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
}
#endif
} else if ( (vt & ~VT_BYREF) == VT_ERROR) {
ole_val2variant_err(val, &(pvar->realvar));
if (vt & VT_BYREF) {
ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
} else {
hr = VariantCopy(&(pvar->var), &(pvar->realvar));
}
} else {
if (val == Qnil) {
V_VT(&(pvar->var)) = vt;
if (vt == (VT_BYREF | VT_VARIANT)) {
ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
} else {
V_VT(&(pvar->realvar)) = vt & ~VT_BYREF;
if (vt & VT_BYREF) {
ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
}
}
} else {
ole_val2variant_ex(val, &(pvar->realvar), (VARTYPE)(vt & ~VT_BYREF));
if (vt == (VT_BYREF | VT_VARIANT)) {
ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
} else if (vt & VT_BYREF) {
if ( (vt & ~VT_BYREF) != V_VT(&(pvar->realvar))) {
hr = VariantChangeTypeEx(&(pvar->realvar), &(pvar->realvar),
cWIN32OLE_lcid, 0, (VARTYPE)(vt & ~VT_BYREF));
}
if (SUCCEEDED(hr)) {
ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
}
} else {
if (vt == V_VT(&(pvar->realvar))) {
hr = VariantCopy(&(pvar->var), &(pvar->realvar));
} else {
hr = VariantChangeTypeEx(&(pvar->var), &(pvar->realvar),
cWIN32OLE_lcid, 0, vt);
}
}
}
}
if (FAILED(hr)) {
ole_raise(hr, eWIN32OLERuntimeError, "failed to change type");
}
}
static void
ole_val2variant_err(VALUE val, VARIANT *var)
{
VALUE v = val;
if (rb_obj_is_kind_of(v, cWIN32OLE_VARIANT)) {
v = folevariant_value(v);
}
if (!(FIXNUM_P(v) || RB_TYPE_P(v, T_BIGNUM) || v == Qnil)) {
rb_raise(eWIN32OLERuntimeError, "failed to convert VT_ERROR VARIANT:`%"PRIsVALUE"'", rb_inspect(v));
}
V_VT(var) = VT_ERROR;
if (v != Qnil) {
V_ERROR(var) = RB_NUM2LONG(val);
} else {
V_ERROR(var) = 0;
}
}
static void
ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vt)
{
V_VT(var) = vt;
if (vt == (VT_VARIANT|VT_BYREF)) {
V_VARIANTREF(var) = realvar;
} else {
if (V_VT(realvar) != (vt & ~VT_BYREF)) {
rb_raise(eWIN32OLERuntimeError, "variant type mismatch");
}
switch(vt & ~VT_BYREF) {
case VT_I1:
V_I1REF(var) = &V_I1(realvar);
break;
case VT_UI1:
V_UI1REF(var) = &V_UI1(realvar);
break;
case VT_I2:
V_I2REF(var) = &V_I2(realvar);
break;
case VT_UI2:
V_UI2REF(var) = &V_UI2(realvar);
break;
case VT_I4:
V_I4REF(var) = &V_I4(realvar);
break;
case VT_UI4:
V_UI4REF(var) = &V_UI4(realvar);
break;
case VT_R4:
V_R4REF(var) = &V_R4(realvar);
break;
case VT_R8:
V_R8REF(var) = &V_R8(realvar);
break;
#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__CYGWIN__) || defined(__MINGW32__)
#ifdef V_I8REF
case VT_I8:
V_I8REF(var) = &V_I8(realvar);
break;
#endif
#ifdef V_UI8REF
case VT_UI8:
V_UI8REF(var) = &V_UI8(realvar);
break;
#endif
#endif
case VT_INT:
V_INTREF(var) = &V_INT(realvar);
break;
case VT_UINT:
V_UINTREF(var) = &V_UINT(realvar);
break;
case VT_CY:
V_CYREF(var) = &V_CY(realvar);
break;
case VT_DATE:
V_DATEREF(var) = &V_DATE(realvar);
break;
case VT_BSTR:
V_BSTRREF(var) = &V_BSTR(realvar);
break;
case VT_DISPATCH:
V_DISPATCHREF(var) = &V_DISPATCH(realvar);
break;
case VT_ERROR:
V_ERRORREF(var) = &V_ERROR(realvar);
break;
case VT_BOOL:
V_BOOLREF(var) = &V_BOOL(realvar);
break;
case VT_UNKNOWN:
V_UNKNOWNREF(var) = &V_UNKNOWN(realvar);
break;
case VT_ARRAY:
V_ARRAYREF(var) = &V_ARRAY(realvar);
break;
default:
rb_raise(eWIN32OLERuntimeError, "unknown type specified(setting BYREF):%d", vt);
break;
}
}
}
static VALUE
folevariant_s_allocate(VALUE klass)
{
struct olevariantdata *pvar;
VALUE obj;
ole_initialize();
obj = TypedData_Make_Struct(klass, struct olevariantdata, &olevariant_datatype, pvar);
VariantInit(&(pvar->var));
VariantInit(&(pvar->realvar));
return obj;
}
/*
* call-seq:
* array(ary, vt)
*
* Returns Ruby object wrapping OLE variant whose variant type is VT_ARRAY.
* The first argument should be Array object which specifies dimensions
* and each size of dimensions of OLE array.
* The second argument specifies variant type of the element of OLE array.
*
* The following create 2 dimensions OLE array. The first dimensions size
* is 3, and the second is 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;
}
static void
check_type_val2variant(VALUE val)
{
VALUE elem;
int len = 0;
int i = 0;
if(!rb_obj_is_kind_of(val, cWIN32OLE) &&
!rb_obj_is_kind_of(val, cWIN32OLE_VARIANT) &&
!rb_obj_is_kind_of(val, rb_cTime)) {
switch (TYPE(val)) {
case T_ARRAY:
len = RARRAY_LEN(val);
for(i = 0; i < len; i++) {
elem = rb_ary_entry(val, i);
check_type_val2variant(elem);
}
break;
case T_STRING:
case T_FIXNUM:
case T_BIGNUM:
case T_FLOAT:
case T_TRUE:
case T_FALSE:
case T_NIL:
break;
default:
rb_raise(rb_eTypeError, "can not convert WIN32OLE::Variant from type %s",
rb_obj_classname(val));
}
}
}
/*
* Document-class: WIN32OLE::Variant
*
* +WIN32OLE::Variant+ objects represents OLE variant.
*
* Win32OLE converts Ruby object into OLE variant automatically when
* invoking OLE methods. If OLE method requires the argument which is
* different from the variant by automatic conversion of Win32OLE, you
* can convert the specified variant type by using WIN32OLE::Variant class.
*
* param = WIN32OLE::Variant.new(10, WIN32OLE::VARIANT::VT_R4)
* oleobj.method(param)
*
* WIN32OLE::Variant does not support VT_RECORD variant. Use WIN32OLE::Record
* class instead of WIN32OLE::Variant if the VT_RECORD variant is needed.
*/
/*
* call-seq:
* new(val, vartype) #=> WIN32OLE::Variant object.
*
* Returns Ruby object wrapping OLE variant.
* The first argument specifies Ruby object to convert OLE variant variable.
* The second argument specifies VARIANT type.
* In some situation, you need the WIN32OLE::Variant object to pass OLE method
*
* 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;
}
static SAFEARRAY *
get_locked_safe_array(VALUE val)
{
struct olevariantdata *pvar;
SAFEARRAY *psa = NULL;
HRESULT hr;
TypedData_Get_Struct(val, struct olevariantdata, &olevariant_datatype, pvar);
if (!(V_VT(&(pvar->var)) & VT_ARRAY)) {
rb_raise(rb_eTypeError, "variant type is not VT_ARRAY.");
}
psa = V_ISBYREF(&(pvar->var)) ? *V_ARRAYREF(&(pvar->var)) : V_ARRAY(&(pvar->var));
if (psa == NULL) {
return psa;
}
hr = SafeArrayLock(psa);
if (FAILED(hr)) {
ole_raise(hr, rb_eRuntimeError, "failed to SafeArrayLock");
}
return psa;
}
static LONG *
ary2safe_array_index(int ary_size, VALUE *ary, SAFEARRAY *psa)
{
long dim;
LONG *pid;
long i;
dim = SafeArrayGetDim(psa);
if (dim != ary_size) {
rb_raise(rb_eArgError, "unmatch number of indices");
}
pid = ALLOC_N(LONG, dim);
if (pid == NULL) {
rb_raise(rb_eRuntimeError, "failed to allocate memory for indices");
}
for (i = 0; i < dim; i++) {
pid[i] = RB_NUM2INT(ary[i]);
}
return pid;
}
static void
unlock_safe_array(SAFEARRAY *psa)
{
HRESULT hr;
hr = SafeArrayUnlock(psa);
if (FAILED(hr)) {
ole_raise(hr, rb_eRuntimeError, "failed to SafeArrayUnlock");
}
}
/*
* call-seq:
* variant[i,j,...] #=> element of OLE array.
*
* Returns the element of WIN32OLE::Variant object(OLE array).
* This method is available only when the variant type of
* WIN32OLE::Variant object is VT_ARRAY.
*
* REMARK:
* 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] # => WIN32OLE::RuntimeError
* p obj[0, -1] # => WIN32OLE::RuntimeError
*
*/
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;
}
/*
* call-seq:
* variant[i,j,...] = val #=> set the element of OLE array
*
* Set the element of WIN32OLE::Variant object(OLE array) to val.
* This method is available only when the variant type of
* WIN32OLE::Variant object is VT_ARRAY.
*
* REMARK:
* 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 # => WIN32OLE::RuntimeError
* obj[0, -1] = 9 # => WIN32OLE::RuntimeError
*
*/
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];
}
/*
* call-seq:
* value #=> Ruby object.
*
* Returns Ruby object value from OLE variant.
* 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;
}
/*
* call-seq:
* vartype #=> OLE variant type.
*
* Returns OLE variant type.
* 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));
}
/*
* call-seq:
* variant.value = val #=> set WIN32OLE::Variant value to val.
*
* Sets variant value to val. If the val type does not match variant value
* type(vartype), then val is changed to match variant value type(vartype)
* before setting val.
* This method is not available when vartype is VT_ARRAY(except VT_UI1|VT_ARRAY).
* If the vartype is VT_UI1|VT_ARRAY, the val should be String object.
*
* 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;
}
void
ole_variant2variant(VALUE val, VARIANT *var)
{
struct olevariantdata *pvar;
TypedData_Get_Struct(val, struct olevariantdata, &olevariant_datatype, pvar);
VariantCopy(var, &(pvar->var));
}
VALUE cWIN32OLE_VARIANT;
void
Init_win32ole_variant(void)
{
#undef rb_intern
cWIN32OLE_VARIANT = rb_define_class_under(cWIN32OLE, "Variant", rb_cObject);
/* Alias of WIN32OLE::Variant, for the backward compatibility */
rb_define_const(rb_cObject, "WIN32OLE" "_VARIANT", cWIN32OLE_VARIANT);
rb_deprecate_constant(rb_cObject, "WIN32OLE" "_VARIANT");
rb_define_alloc_func(cWIN32OLE_VARIANT, folevariant_s_allocate);
rb_define_singleton_method(cWIN32OLE_VARIANT, "array", folevariant_s_array, 2);
rb_define_method(cWIN32OLE_VARIANT, "initialize", folevariant_initialize, -2);
rb_define_method(cWIN32OLE_VARIANT, "value", folevariant_value, 0);
rb_define_method(cWIN32OLE_VARIANT, "value=", folevariant_set_value, 1);
rb_define_method(cWIN32OLE_VARIANT, "vartype", folevariant_vartype, 0);
rb_define_method(cWIN32OLE_VARIANT, "[]", folevariant_ary_aref, -1);
rb_define_method(cWIN32OLE_VARIANT, "[]=", folevariant_ary_aset, -1);
/*
* represents VT_EMPTY OLE object.
*/
rb_define_const(cWIN32OLE_VARIANT, "Empty",
rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, RB_INT2FIX(VT_EMPTY)));
/*
* represents VT_NULL OLE object.
*/
rb_define_const(cWIN32OLE_VARIANT, "Null",
rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, RB_INT2FIX(VT_NULL)));
/*
* represents Nothing of VB.NET or VB.
*/
rb_define_const(cWIN32OLE_VARIANT, "Nothing",
rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, RB_INT2FIX(VT_DISPATCH)));
/*
* represents VT_ERROR variant with DISP_E_PARAMNOTFOUND.
* This constants is used for not specified parameter.
*
* fso = WIN32OLE.new("Scripting.FileSystemObject")
* fso.openTextFile(filename, WIN32OLE::Variant::NoParam, false)
*/
rb_define_const(cWIN32OLE_VARIANT, "NoParam",
rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, INT2NUM(DISP_E_PARAMNOTFOUND), RB_INT2FIX(VT_ERROR)));
}

View File

@ -1,9 +0,0 @@
#ifndef WIN32OLE_VARIANT_H
#define WIN32OLE_VARIANT_H 1
extern VALUE cWIN32OLE_VARIANT;
void ole_variant2variant(VALUE val, VARIANT *var);
void Init_win32ole_variant(void);
#endif

View File

@ -1,153 +0,0 @@
#include "win32ole.h"
VALUE mWIN32OLE_VARIANT;
void Init_win32ole_variant_m(void)
{
/*
* Document-module: WIN32OLE::VariantType
*
* The +WIN32OLE::VariantType+ module includes constants of VARIANT type constants.
* The constants is used when creating WIN32OLE::Variant object.
*
* obj = WIN32OLE::Variant.new("2e3", WIN32OLE::VARIANT::VT_R4)
* obj.value # => 2000.0
*
*/
mWIN32OLE_VARIANT = rb_define_module_under(cWIN32OLE, "VariantType");
/* Alias of WIN32OLE::VariantType, for the backward compatibility */
rb_define_const(cWIN32OLE, "VARIANT", mWIN32OLE_VARIANT);
/*
* represents VT_EMPTY type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_EMPTY", RB_INT2FIX(VT_EMPTY));
/*
* represents VT_NULL type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_NULL", RB_INT2FIX(VT_NULL));
/*
* represents VT_I2 type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_I2", RB_INT2FIX(VT_I2));
/*
* represents VT_I4 type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_I4", RB_INT2FIX(VT_I4));
/*
* represents VT_R4 type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_R4", RB_INT2FIX(VT_R4));
/*
* represents VT_R8 type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_R8", RB_INT2FIX(VT_R8));
/*
* represents VT_CY type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_CY", RB_INT2FIX(VT_CY));
/*
* represents VT_DATE type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_DATE", RB_INT2FIX(VT_DATE));
/*
* represents VT_BSTR type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_BSTR", RB_INT2FIX(VT_BSTR));
/*
* represents VT_USERDEFINED type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_USERDEFINED", RB_INT2FIX(VT_USERDEFINED));
/*
* represents VT_PTR type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_PTR", RB_INT2FIX(VT_PTR));
/*
* represents VT_DISPATCH type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_DISPATCH", RB_INT2FIX(VT_DISPATCH));
/*
* represents VT_ERROR type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_ERROR", RB_INT2FIX(VT_ERROR));
/*
* represents VT_BOOL type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_BOOL", RB_INT2FIX(VT_BOOL));
/*
* represents VT_VARIANT type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_VARIANT", RB_INT2FIX(VT_VARIANT));
/*
* represents VT_UNKNOWN type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_UNKNOWN", RB_INT2FIX(VT_UNKNOWN));
/*
* represents VT_I1 type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_I1", RB_INT2FIX(VT_I1));
/*
* represents VT_UI1 type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_UI1", RB_INT2FIX(VT_UI1));
/*
* represents VT_UI2 type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_UI2", RB_INT2FIX(VT_UI2));
/*
* represents VT_UI4 type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_UI4", RB_INT2FIX(VT_UI4));
#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__CYGWIN__) || defined(__MINGW32__)
/*
* represents VT_I8 type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_I8", RB_INT2FIX(VT_I8));
/*
* represents VT_UI8 type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_UI8", RB_INT2FIX(VT_UI8));
#endif
/*
* represents VT_INT type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_INT", RB_INT2FIX(VT_INT));
/*
* represents VT_UINT type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_UINT", RB_INT2FIX(VT_UINT));
/*
* represents VT_ARRAY type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_ARRAY", RB_INT2FIX(VT_ARRAY));
/*
* represents VT_BYREF type constant.
*/
rb_define_const(mWIN32OLE_VARIANT, "VT_BYREF", RB_INT2FIX(VT_BYREF));
}

View File

@ -1,7 +0,0 @@
#ifndef WIN32OLE_VARIANT_M_H
#define WIN32OLE_VARIANT_M_H 1
extern VALUE mWIN32OLE_VARIANT;
void Init_win32ole_variant_m(void);
#endif

View File

@ -40,3 +40,4 @@ pstore 0.1.4 https://github.com/ruby/pstore b563c4d354615e12a6fa5
benchmark 0.4.0 https://github.com/ruby/benchmark
logger 1.6.5 https://github.com/ruby/logger
rdoc 6.10.0 https://github.com/ruby/rdoc
win32ole 1.9.1 https://github.com/ruby/win32ole

View File

@ -1,37 +0,0 @@
# frozen_string_literal: false
require 'win32ole'
application = WIN32OLE.new('Excel.Application')
application.visible = true
workbook = application.Workbooks.Add();
worksheet = workbook.Worksheets(1);
=begin
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;
=end
worksheet.Range("A1:B2").value = [["North","South"],
[5.2, 10]];
vals = WIN32OLE_VARIANT.new([["East","West"],
[8, 20]],
WIN32OLE::VARIANT::VT_ARRAY)
worksheet.Range("C1:D2").value = vals
range = worksheet.Range("A1:D2");
range.Select
chart = workbook.Charts.Add;
workbook.saved = true;
print "Now quit Excel... Please enter."
gets
application.ActiveWorkbook.Close(0);
application.Quit();

View File

@ -1,31 +0,0 @@
# frozen_string_literal: false
require 'win32ole'
# -4100 is the value for the Excel constant xl3DColumn.
ChartTypeVal = -4100;
# Creates OLE object to Excel
excel = WIN32OLE.new("excel.application")
# Create and rotate the chart
excel.visible = true;
excel.Workbooks.Add();
excel.Range("a1").value = 3;
excel.Range("a2").value = 2;
excel.Range("a3").value = 1;
excel.Range("a1:a3").Select();
excelchart = excel.Charts.Add();
excelchart.type = ChartTypeVal;
i = 0
i.step(180, 10) do |rot|
excelchart.rotation=rot;
sleep 0.1
end
# Done, bye
print "Now quit Excel... Please enter."
gets
excel.ActiveWorkbook.Close(0);
excel.Quit();

View File

@ -1,21 +0,0 @@
# frozen_string_literal: false
require 'win32ole'
#application = WIN32OLE.new('Excel.Application.5')
application = WIN32OLE.new('Excel.Application')
application.visible = true
workbook = application.Workbooks.Add();
sheet = workbook.Worksheets(1);
sheetS = workbook.Worksheets
puts "The number of sheets is #{sheetS.count}"
puts "Now add 2 sheets after of `#{sheet.name}`"
sheetS.add({'count'=>2, 'after'=>sheet})
puts "The number of sheets is #{sheetS.count}"
print "Now quit Excel... Please enter."
gets
application.ActiveWorkbook.Close(0);
application.Quit();

View File

@ -1,12 +0,0 @@
# frozen_string_literal: false
require 'win32ole'
url = 'http://www.ruby-lang.org/'
ie = WIN32OLE.new('InternetExplorer.Application')
ie.visible = true
ie.gohome
print "Now navigate Ruby home page... Please enter."
gets
ie.navigate(url)
print "Now quit Internet Explorer... Please enter."
gets
ie.Quit()

View File

@ -1,33 +0,0 @@
# frozen_string_literal: false
require 'win32ole'
ie = WIN32OLE.new('InternetExplorer.Application')
=begin
WIN32OLE.const_load(ie)
WIN32OLE.constants.sort.each do |c|
puts "#{c} = #{WIN32OLE.const_get(c)}"
end
=end
module IE_CONST
end
WIN32OLE.const_load(ie, IE_CONST)
IE_CONST.constants.sort.each do |c|
puts "#{c} = #{IE_CONST.const_get(c)}"
end
#------------------------------------------------------------
# Remark!!! CONSTANTS has not tested enoughly!!!
# CONSTANTS is alpha release.
# If there are constants which first letter is not [a-zA-Z],
# like a '_Foo', then maybe you can access the value by
# using CONSTANTS['_Foo']
#------------------------------------------------------------
IE_CONST::CONSTANTS.each do |k, v|
puts "#{k} = #{v}"
end
puts WIN32OLE::VERSION
ie.quit

View File

@ -1,41 +0,0 @@
# frozen_string_literal: false
require 'win32ole'
$urls = []
def navigate(url)
$urls << url
end
def stop_msg_loop
puts "Now Stop IE..."
$LOOP = false;
end
def default_handler(event, *args)
case event
when "BeforeNavigate"
puts "Now Navigate #{args[0]}..."
end
end
ie = WIN32OLE.new('InternetExplorer.Application')
ie.visible = true
ie.gohome
ev = WIN32OLE_EVENT.new(ie, 'DWebBrowserEvents')
ev.on_event {|*args| default_handler(*args)}
ev.on_event("NavigateComplete") {|url| navigate(url)}
ev.on_event("Quit") {|*args| stop_msg_loop}
$LOOP = true
while ($LOOP)
WIN32OLE_EVENT.message_loop
end
puts "You Navigated the URLs ..."
$urls.each_with_index do |url, i|
puts "(#{i+1}) #{url}"
end

View File

@ -1,41 +0,0 @@
# frozen_string_literal: false
require 'win32ole'
class IEHandler
attr_reader :loop
def initialize
@urls = []
@loop = true
end
def method_missing(event, *args)
case event
when "BeforeNavigate2"
puts "Now Navigate #{args[1]}..."
end
end
def onNavigateComplete2(pdisp, url)
@urls << url
end
def onOnQuit
puts "Now Stop IE..."
@loop = false
end
def put_urls
puts "You Navigated the URLs ..."
@urls.each_with_index do |url, i|
puts "(#{i+1}) #{url}"
end
end
end
ie = WIN32OLE.new('InternetExplorer.Application')
ie.visible = true
ie.gohome
ev = WIN32OLE_EVENT.new(ie)
ev.handler = IEHandler.new
while (ev.handler.loop)
WIN32OLE_EVENT.message_loop
end
ev.handler.put_urls

View File

@ -1,24 +0,0 @@
# frozen_string_literal: false
#
# You need WSH(Windows Scripting Host) to run this script.
#
require "win32ole"
def listup(items)
# items.each do |i|
for i in items
puts i.name
end
end
fs = WIN32OLE.new("Scripting.FileSystemObject")
folder = fs.GetFolder(".")
puts "--- folder of #{folder.path} ---"
listup(folder.SubFolders)
puts "--- files of #{folder.path} ---"
listup(folder.Files)

View File

@ -1,348 +0,0 @@
# frozen_string_literal: false
#-----------------------------
# olegen.rb
# $Revision$
#-----------------------------
require 'win32ole'
class WIN32COMGen
def initialize(typelib)
@typelib = typelib
@receiver = ""
end
attr_reader :typelib
def ole_classes(typelib)
begin
@ole = WIN32OLE.new(typelib)
[@ole.ole_obj_help]
rescue
WIN32OLE_TYPE.ole_classes(typelib)
end
end
def generate_args(method)
args = []
if method.size_opt_params >= 0
size_required_params = method.size_params - method.size_opt_params
else
size_required_params = method.size_params - 1
end
size_required_params.times do |i|
if method.params[i] && method.params[i].optional?
args.push "arg#{i}=nil"
else
args.push "arg#{i}"
end
end
if method.size_opt_params >= 0
method.size_opt_params.times do |i|
args.push "arg#{i + size_required_params}=nil"
end
else
args.push "*arg"
end
args.join(", ")
end
def generate_argtype(typedetails)
ts = ''
typedetails.each do |t|
case t
when 'CARRAY', 'VOID', 'UINT', 'RESULT', 'DECIMAL', 'I8', 'UI8'
# raise "Sorry type\"" + t + "\" not supported"
ts << "\"??? NOT SUPPORTED TYPE:`#{t}'\""
when 'USERDEFINED', 'Unknown Type 9'
ts << 'VT_DISPATCH'
break;
when 'SAFEARRAY'
ts << 'VT_ARRAY|'
when 'PTR'
ts << 'VT_BYREF|'
when 'INT'
ts << 'VT_I4'
else
if String === t
ts << 'VT_' + t
end
end
end
if ts.empty?
ts = 'VT_VARIANT'
elsif ts.end_with?(?|)
ts += 'VT_VARIANT'
end
ts
end
def generate_argtypes(method, proptypes)
types = method.params.collect{|param|
generate_argtype(param.ole_type_detail)
}.join(", ")
if proptypes
types += ", " if types.size > 0
types += generate_argtype(proptypes)
end
types
end
def generate_method_body(method, disptype, types=nil)
" ret = #{@receiver}#{disptype}(#{method.dispid}, [" +
generate_args(method).gsub("=nil", "") +
"], [" +
generate_argtypes(method, types) +
"])\n" +
" @lastargs = WIN32OLE::ARGV\n" +
" ret"
end
def generate_method_help(method, type = nil)
str = " # "
if type
str += type
else
str += method.return_type
end
str += " #{method.name}"
if method.event?
str += " EVENT"
str += " in #{method.event_interface}"
end
if method.helpstring && method.helpstring != ""
str += "\n # "
str += method.helpstring
end
args_help = generate_method_args_help(method)
if args_help
str += "\n"
str += args_help
end
str
end
def generate_method_args_help(method)
args = []
method.params.each_with_index {|param, i|
h = " # #{param.ole_type} arg#{i} --- #{param.name}"
inout = []
inout.push "IN" if param.input?
inout.push "OUT" if param.output?
h += " [#{inout.join('/')}]"
h += " ( = #{param.default})" if param.default
args.push h
}
if args.size > 0
args.join("\n")
else
nil
end
end
def generate_method(method, disptype, io = STDOUT, types = nil)
io.puts "\n"
io.puts generate_method_help(method)
if method.invoke_kind == 'PROPERTYPUT'
io.print " def #{method.name}=("
else
io.print " def #{method.name}("
end
io.print generate_args(method)
io.puts ")"
io.puts generate_method_body(method, disptype, types)
io.puts " end"
end
def generate_propputref_methods(klass, io = STDOUT)
klass.ole_methods.select {|method|
method.invoke_kind == 'PROPERTYPUTREF' && method.visible?
}.each do |method|
generate_method(method, io)
end
end
def generate_properties_with_args(klass, io = STDOUT)
klass.ole_methods.select {|method|
method.invoke_kind == 'PROPERTYGET' &&
method.visible? &&
method.size_params > 0
}.each do |method|
types = method.return_type_detail
io.puts "\n"
io.puts generate_method_help(method, types[0])
io.puts " def #{method.name}"
if klass.ole_type == "Class"
io.print " OLEProperty.new(@dispatch, #{method.dispid}, ["
else
io.print " OLEProperty.new(self, #{method.dispid}, ["
end
io.print generate_argtypes(method, nil)
io.print "], ["
io.print generate_argtypes(method, types)
io.puts "])"
io.puts " end"
end
end
def generate_propput_methods(klass, io = STDOUT)
klass.ole_methods.select {|method|
method.invoke_kind == 'PROPERTYPUT' && method.visible? &&
method.size_params == 1
}.each do |method|
ms = klass.ole_methods.select {|m|
m.invoke_kind == 'PROPERTYGET' &&
m.dispid == method.dispid
}
types = []
if ms.size == 1
types = ms[0].return_type_detail
end
generate_method(method, '_setproperty', io, types)
end
end
def generate_propget_methods(klass, io = STDOUT)
klass.ole_methods.select {|method|
method.invoke_kind == 'PROPERTYGET' && method.visible? &&
method.size_params == 0
}.each do |method|
generate_method(method, '_getproperty', io)
end
end
def generate_func_methods(klass, io = STDOUT)
klass.ole_methods.select {|method|
method.invoke_kind == "FUNC" && method.visible?
}.each do |method|
generate_method(method, '_invoke', io)
end
end
def generate_methods(klass, io = STDOUT)
generate_propget_methods(klass, io)
generate_propput_methods(klass, io)
generate_properties_with_args(klass, io)
generate_func_methods(klass, io)
# generate_propputref_methods(klass, io)
end
def generate_constants(klass, io = STDOUT)
klass.variables.select {|v|
v.visible? && v.variable_kind == 'CONSTANT'
}.each do |v|
io.print " "
io.print v.name.sub(/^./){$&.upcase}
io.print " = "
io.puts v.value
end
end
def class_name(klass)
klass_name = klass.name
if klass.ole_type == "Class" &&
klass.guid &&
klass.progid
klass_name = klass.progid.gsub(/\./, '_')
end
if /^[A-Z]/ !~ klass_name || Module.constants.include?(klass_name)
klass_name = 'OLE' + klass_name
end
klass_name
end
def define_initialize(klass)
<<STR
def initialize(obj = nil)
@clsid = "#{klass.guid}"
@progid = "#{klass.progid}"
if obj.nil?
@dispatch = WIN32OLE.new @progid
else
@dispatch = obj
end
end
STR
end
def define_include
" include WIN32OLE::VARIANT"
end
def define_instance_variables
" attr_reader :lastargs"
end
def define_method_missing
<<STR
def method_missing(cmd, *arg)
@dispatch.method_missing(cmd, *arg)
end
STR
end
def define_class(klass, io = STDOUT)
io.puts "class #{class_name(klass)} # #{klass.name}"
io.puts define_include
io.puts define_instance_variables
io.puts " attr_reader :dispatch"
io.puts " attr_reader :clsid"
io.puts " attr_reader :progid"
io.puts define_initialize(klass)
io.puts define_method_missing
end
def define_module(klass, io = STDOUT)
io.puts "module #{class_name(klass)}"
io.puts define_include
io.puts define_instance_variables
end
def generate_class(klass, io = STDOUT)
io.puts "\n# #{klass.helpstring}"
if klass.ole_type == "Class" &&
klass.guid &&
klass.progid
@receiver = "@dispatch."
define_class(klass, io)
else
@receiver = ""
define_module(klass, io)
end
generate_constants(klass, io)
generate_methods(klass, io)
io.puts "end"
end
def generate(io = STDOUT)
io.puts "require 'win32ole'"
io.puts "require 'win32ole/property'"
ole_classes(typelib).select{|klass|
klass.visible? &&
(klass.ole_type == "Class" ||
klass.ole_type == "Interface" ||
klass.ole_type == "Dispatch" ||
klass.ole_type == "Enum")
}.each do |klass|
generate_class(klass, io)
end
begin
@ole.quit if @ole
rescue
end
end
end
require 'win32ole'
if __FILE__ == $0
if ARGV.size == 0
$stderr.puts "usage: #{$0} Type Library [...]"
exit 1
end
ARGV.each do |typelib|
comgen = WIN32COMGen.new(typelib)
comgen.generate
end
end

File diff suppressed because it is too large Load Diff

View File

@ -1,41 +0,0 @@
begin
require 'win32ole'
rescue LoadError
end
if defined?(WIN32OLE)
module AvailableOLE
module_function
def sysmon_available?
WIN32OLE::Type.new('System Monitor Control', 'SystemMonitor')
true
rescue
false
end
def ado_available?
WIN32OLE.new('ADODB.Connection')
true
rescue
false
end
def msxml_available?
!WIN32OLE::TypeLib.typelibs.find { |t| t.name.start_with?('Microsoft XML') }.nil?
end
def event_param
method = if msxml_available?
typelib = WIN32OLE::TypeLib.typelibs.find { |t| t.name.start_with?('Microsoft XML') }
ole_type = WIN32OLE::Type.new(typelib.name, 'IVBSAXContentHandler')
WIN32OLE::Method.new(ole_type, 'startElement')
elsif ado_available?
typelib = WIN32OLE.new('ADODB.Connection').ole_typelib
ole_type = WIN32OLE::Type.new(typelib.name, 'Connection')
WIN32OLE::Method.new(ole_type, 'WillConnect')
end
method && method.params[0]
end
end
end

View File

@ -1,10 +0,0 @@
# frozen_string_literal: false
require 'win32ole'
db = WIN32OLE.new('ADODB.Connection')
db.connectionString = "Driver={Microsoft Text Driver (*.txt; *.csv)};DefaultDir=.;"
ev = WIN32OLE::Event.new(db)
ev.on_event('WillConnect') {|*args|
foo
}
db.open
WIN32OLE::Event.message_loop

View File

@ -1,5 +0,0 @@
ID,VALUE
1,"A"
2,"B"
3,"C"
4,"B"
1 ID VALUE
2 1 A
3 2 B
4 3 C
5 4 B

View File

@ -1,56 +0,0 @@
# frozen_string_literal: false
#
# test Win32OLE avoids cfp consistency error when the exception raised
# in WIN32OLE::Event handler block. [ruby-dev:35450]
#
begin
require 'win32ole'
rescue LoadError
end
if defined?(WIN32OLE)
require 'mkmf'
require 'pathname'
require 'test/unit'
require 'tmpdir'
class TestErrInCallBack < Test::Unit::TestCase
def setup
@ruby = nil
if File.exist?("./" + CONFIG["RUBY_INSTALL_NAME"] + CONFIG["EXEEXT"])
sep = File::ALT_SEPARATOR || "/"
@ruby = "." + sep + CONFIG["RUBY_INSTALL_NAME"]
cwd = Pathname.new(File.expand_path('.'))
@iopt = $:.map {|e|
" -I " + (Pathname.new(e).relative_path_from(cwd).to_s rescue e)
}.join("")
script = File.join(File.dirname(__FILE__), "err_in_callback.rb")
@script = Pathname.new(script).relative_path_from(cwd).to_s rescue script
end
end
def available_adodb?
begin
WIN32OLE.new('ADODB.Connection')
rescue WIN32OLE::RuntimeError
return false
end
return true
end
def test_err_in_callback
omit "'ADODB.Connection' is not available" unless available_adodb?
if @ruby
Dir.mktmpdir do |tmpdir|
logfile = File.join(tmpdir, "test_err_in_callback.log")
cmd = "#{@ruby} -v #{@iopt} #{@script} > #{logfile.gsub(%r(/), '\\')} 2>&1"
system(cmd)
str = ""
open(logfile) {|ifs|
str = ifs.read
}
assert_match(/NameError/, str)
end
end
end
end
end

View File

@ -1,66 +0,0 @@
# frozen_string_literal: false
#
# This script check that Win32OLE can execute InvokeVerb method of FolderItem2.
#
begin
require 'win32ole'
rescue LoadError
end
require 'test/unit'
if defined?(WIN32OLE)
class TestInvokeVerb < Test::Unit::TestCase
def setup
# make dummy file for InvokeVerb test.
@fso = WIN32OLE.new('Scripting.FileSystemObject')
dummy_file = @fso.GetTempName
@cfolder = @fso.getFolder(".")
f = @cfolder.CreateTextFile(dummy_file)
f.close
@dummy_path = @cfolder.path + "\\" + dummy_file
shell=WIN32OLE.new('Shell.Application')
@nsp = shell.NameSpace(@cfolder.path)
@fi2 = @nsp.parseName(dummy_file)
end
def find_link(path)
arlink = []
@cfolder.files.each do |f|
if /\.lnk$/ =~ f.path
linkinfo = @nsp.parseName(f.name).getLink
arlink.push f if linkinfo.path == path
end
end
arlink
end
def test_invokeverb
# in Windows Vista (not tested), Windows 7
# The verb must be in English.
# Creating Shortcut is "Link"
links = find_link(@dummy_path)
assert_equal(0, links.size)
# Now create shortcut to @dummy_path
arg = WIN32OLE::Variant.new("Link")
@fi2.InvokeVerb(arg)
# Now search shortcut to @dummy_path
links = find_link(@dummy_path)
assert_equal(1, links.size)
@lpath = links[0].path
end
def teardown
if @lpath
@fso.deleteFile(@lpath)
end
if @dummy_path
@fso.deleteFile(@dummy_path)
end
end
end
end

View File

@ -1,37 +0,0 @@
# frozen_string_literal: false
# This is test script to check that WIN32OLE should convert nil to VT_EMPTY in second try.
# [ruby-talk:137054]
begin
require 'win32ole'
rescue LoadError
end
require 'test/unit'
if defined?(WIN32OLE)
class TestNIL2VT_EMPTY < Test::Unit::TestCase
def setup
fs = WIN32OLE.new('Scripting.FileSystemObject')
@path = fs.GetFolder(".").path
end
def test_openSchema
con = nil
begin
con = WIN32OLE.new('ADODB.Connection')
con.connectionString = "Provider=MSDASQL;Extended Properties="
con.connectionString +="\"DRIVER={Microsoft Text Driver (*.txt; *.csv)};DBQ=#{@path}\""
con.open
rescue
con = nil
end
if con
rs = con.openSchema(4, [nil,nil,"DUMMY", "TABLE"])
assert(rs)
assert_equal("_Recordset", rs.ole_type.name)
rs = con.openSchema(4, [WIN32OLE::Variant::Empty, WIN32OLE::Variant::Empty, "DUMMY", "TABLE"])
assert(rs)
assert_equal("_Recordset", rs.ole_type.name)
end
end
end
end

View File

@ -1,35 +0,0 @@
# frozen_string_literal: false
#
# This is test for [ruby-talk:196897]
#
begin
require 'win32ole'
rescue LoadError
end
require "test/unit"
if defined?(WIN32OLE)
class TestWIN32OLE_FOR_PROPERTYPUTREF < Test::Unit::TestCase
def setup
@obj = WIN32OLE.new('Scripting.Dictionary')
end
def test_ole_methods
x = @obj.ole_methods.select {|m|
m.invoke_kind == 'PROPERTYPUTREF'
}
assert_equal(1, x.size)
assert_equal('Item', x[0].name)
end
def test_ole_put_methods
x = @obj.ole_put_methods.select {|m|
m.invoke_kind == 'PROPERTYPUTREF'
}
assert_equal(1, x.size)
assert_equal('Item', x[0].name)
end
end
end

View File

@ -1,31 +0,0 @@
# frozen_string_literal: false
require 'test/unit'
begin
require 'win32ole'
rescue LoadError
end
if defined?(WIN32OLE)
class TestWIN32OLE_PROPERTYPUTREF < Test::Unit::TestCase
def setup
begin
@sapi = WIN32OLE.new('SAPI.SpVoice')
@sv = @sapi.voice
rescue WIN32OLE::RuntimeError
@sapi = nil
end
end
def test_sapi
if @sapi
new_id = @sapi.getvoices.item(0).Id
@sapi.voice = @sapi.getvoices.item(0)
assert_equal(new_id, @sapi.voice.Id)
end
end
def teardown
if @sapi
@sapi.voice = @sv
end
end
end
end

View File

@ -1,34 +0,0 @@
# frozen_string_literal: false
begin
require 'win32ole'
rescue LoadError
end
require 'test/unit'
if defined?(WIN32OLE)
class TestWIN32OLE_THREAD < Test::Unit::TestCase
#
# test for Bug #2618(ruby-core:27634)
#
def assert_creating_win32ole_object_in_thread(meth)
t = Thread.__send__(meth) {
WIN32OLE.new('Scripting.Dictionary')
}
assert_nothing_raised(WIN32OLE::RuntimeError, "[Bug #2618] Thread.#{meth}") {
t.join
}
end
def test_creating_win32ole_object_in_thread_new
assert_creating_win32ole_object_in_thread(:new)
end
def test_creating_win32ole_object_in_thread_start
assert_creating_win32ole_object_in_thread(:start)
end
def test_creating_win32ole_object_in_thread_fork
assert_creating_win32ole_object_in_thread(:fork)
end
end
end

View File

@ -1,536 +0,0 @@
# coding: us-ascii
# frozen_string_literal: false
begin
require 'win32ole'
rescue LoadError
end
require 'test/unit'
if defined?(WIN32OLE)
module CONST1
end
module CONST2
end
module TestCaseForDict
def test_convert_bignum
@dict1.add("a", 9999999999)
@dict1.add("b", 999999999)
@dict1.add("c", @dict1.item("b") * 10 + 9)
assert_equal(9999999999, @dict1.item("a"))
assert_equal(9999999999, @dict1.item("c"))
end
def test_add
@dict1.add("a", 1000)
assert_equal(1000, @dict1.item("a"))
end
def test_setproperty_equal_ended
@dict1.compareMode = 1
@dict1.add("one", 1)
assert_equal(1, @dict1.item("ONE"))
@dict2.add("one", 1)
assert_nil(@dict2.item("ONE"))
assert_equal(1, @dict2.item("one"))
end
def test_non_exist_property
assert_raise(WIN32OLE::RuntimeError) {
@dict1.unknown_property = 1
}
end
def test_raise_message
exc = assert_raise(WIN32OLE::RuntimeError) {
@dict1.add
}
assert_match(/^\(in OLE method `add': \)/, exc.message) #`
exc = assert_raise(WIN32OLE::RuntimeError) {
@dict1._invoke(1, [], [])
}
assert_match(/^\(in OLE method `<dispatch id:1>': \)/, exc.message) #`
exc = assert_raise(WIN32OLE::RuntimeError) {
@dict1.compareMode = -1
}
assert_match(/^\(in setting property `compareMode': \)/, exc.message) #`
end
def test_no_method_error
exc = assert_raise(NoMethodError) {
@dict1.non_exist_method
}
assert_match(/non_exist_method/, exc.message)
assert_kind_of(WIN32OLE, exc.receiver)
end
def test_ole_methods
methods = @dict1.ole_methods
mnames = methods.collect {|m|
m.name
}
assert_include(mnames, 'Add')
end
def test_methods
methods = @dict1.methods
assert_include(methods, :Add)
end
def test_ole_func_methods
methods = @dict1.ole_func_methods
mnames = methods.collect {|m|
m.name
}
assert_include(mnames, 'Add')
end
def test_ole_put_methods
methods = @dict1.ole_put_methods
mnames = methods.collect {|m|
m.name
}
assert_include(mnames, 'CompareMode')
end
def test_ole_get_methods
methods = @dict1.ole_get_methods
mnames = methods.collect {|m|
m.name
}
assert_include(mnames, 'Count')
end
def test_ole_method_help
minfo = @dict1.ole_method_help("Add")
assert_equal(2, minfo.size_params)
end
def test_ole_typelib
tlib = @dict1.ole_typelib
assert_equal("Microsoft Scripting Runtime", tlib.name);
end
def test_each
@dict1.add("one", 1)
@dict1.add("two", 2)
i = 0
@dict1.keys.each do |item|
i += 1
end
assert_equal(2, i)
end
def test_bracket
@dict1.add("foo", "FOO")
assert_equal("FOO", @dict1.item("foo"))
assert_equal("FOO", @dict1["foo"])
end
def test_bracket_equal
@dict1.add("foo", "FOO")
@dict1["foo"] = "BAR"
assert_equal("BAR", @dict1["foo"])
end
def test_bracket_with_numkey
@dict1.add(1, "ONE")
@dict1.add(2, "two")
assert_equal("ONE", @dict1[1])
@dict1[2] = "TWO"
assert_equal("TWO", @dict1[2])
end
def test_invoke_with_array
@dict1.add("ary1", [1,2,3])
assert_equal([1,2,3], @dict1["ary1"])
@dict1.add("ary2", [[1,2,"a"], [3,4,"b"]])
assert_equal([[1,2,"a"], [3,4,"b"]], @dict1["ary2"])
@dict1.add("ary3", [[[1]]])
assert_equal([[[1]]], @dict1["ary3"])
@dict1.add("ary4", [[[1], [2], [3]], [[4], [5], [6]]])
assert_equal([[[1],[2], [3]], [[4], [5], [6]]], @dict1["ary4"])
end
end
class TestWin32OLE < Test::Unit::TestCase
include TestCaseForDict
def setup
@dict1 = WIN32OLE.new('Scripting.Dictionary')
@dict2 = WIN32OLE.new('Scripting.Dictionary')
end
def test_s_new
assert_instance_of(WIN32OLE, @dict1)
assert_instance_of(WIN32OLE, @dict2)
end
def test_s_new_exc
assert_raise(TypeError) {
WIN32OLE.new(1)
}
assert_raise(TypeError) {
WIN32OLE.new("Scripting.Dictionary", 1)
}
end
def test_s_new_DCOM
rshell = WIN32OLE.new("Shell.Application")
assert_instance_of(WIN32OLE, rshell)
end
def test_s_new_from_clsid
shell = WIN32OLE.new("{13709620-C279-11CE-A49E-444553540000}")
assert_instance_of(WIN32OLE, shell)
exc = assert_raise(WIN32OLE::RuntimeError) {
WIN32OLE.new("{000}")
}
assert_match(/unknown OLE server: `\{000\}'/, exc.message) #`
end
def test_s_connect
obj = WIN32OLE.connect("winmgmts:")
assert_instance_of(WIN32OLE, obj)
end
def test_s_connect_exc
assert_raise(TypeError) {
WIN32OLE.connect(1)
}
end
def test_invoke_accept_symbol_hash_key
fso = WIN32OLE.new('Scripting.FileSystemObject')
afolder = fso.getFolder(".")
bfolder = fso.getFolder({"FolderPath" => "."})
cfolder = fso.getFolder({:FolderPath => "."})
assert_equal(afolder.path, bfolder.path)
assert_equal(afolder.path, cfolder.path)
fso = nil
end
def test_setproperty
installer = WIN32OLE.new("WindowsInstaller.Installer")
record = installer.CreateRecord(2)
# this is the way to set property with argument in Win32OLE.
record.setproperty( "StringData", 1, 'dddd')
assert_equal('dddd', record.StringData(1))
end
def test_ole_type
fso = WIN32OLE.new('Scripting.FileSystemObject')
tobj = fso.ole_type
assert_match(/^IFileSystem/, tobj.name)
end
def test_ole_obj_help
fso = WIN32OLE.new('Scripting.FileSystemObject')
tobj = fso.ole_obj_help
assert_match(/^IFileSystem/, tobj.name)
end
def test_invoke_hash_key_non_str_sym
fso = WIN32OLE.new('Scripting.FileSystemObject')
begin
fso.getFolder({1 => "."})
assert(false)
rescue TypeError
assert(true)
end
fso = nil
end
def test_get_win32ole_object
shell = WIN32OLE.new('Shell.Application')
folder = shell.nameSpace(0)
assert_instance_of(WIN32OLE, folder)
end
def test_invoke_accept_multi_hash_key
shell = WIN32OLE.new('Shell.Application')
folder = shell.nameSpace(0)
item = folder.items.item(0)
name = folder.getDetailsOf(item, 0)
assert_equal(item.name, name)
name = folder.getDetailsOf({:vItem => item, :iColumn => 0})
assert_equal(item.name, name)
name = folder.getDetailsOf({"vItem" => item, :iColumn => 0})
assert_equal(item.name, name)
end
def test_ole_invoke_with_named_arg_last
shell = WIN32OLE.new('Shell.Application')
folder = shell.nameSpace(0)
item = folder.items.item(0)
name = folder.getDetailsOf(item, {:iColumn => 0})
assert_equal(item.name, name)
end
def test__invoke
shell=WIN32OLE.new('Shell.Application')
assert_equal(shell.NameSpace(0).title, shell._invoke(0x60020002, [0], [WIN32OLE::VARIANT::VT_VARIANT]).title)
end
def test_ole_query_interface
shell=WIN32OLE.new('Shell.Application')
assert_raise(ArgumentError) {
shell.ole_query_interface
}
assert_raise(TypeError) {
shell.ole_query_interface(0x11223344)
}
shell2 = shell.ole_query_interface('{A4C6892C-3BA9-11D2-9DEA-00C04FB16162}')
assert_instance_of(WIN32OLE, shell2)
end
def test_ole_respond_to
fso = WIN32OLE.new('Scripting.FileSystemObject')
assert(fso.ole_respond_to?('getFolder'))
assert(fso.ole_respond_to?('GETFOLDER'))
assert(fso.ole_respond_to?(:getFolder))
assert(!fso.ole_respond_to?('XXXXX'))
assert_raise(TypeError) {
assert_raise(fso.ole_respond_to?(1))
}
end
def test_invoke
fso = WIN32OLE.new('Scripting.FileSystemObject')
assert(fso.invoke(:getFolder, "."))
assert(fso.invoke('getFolder', "."))
end
def test_s_const_load
assert(!defined?(CONST1::SsfWINDOWS))
shell=WIN32OLE.new('Shell.Application')
WIN32OLE.const_load(shell, CONST1)
assert_equal(36, CONST1::SsfWINDOWS)
assert(!defined?(CONST2::SsfWINDOWS))
WIN32OLE.const_load("Microsoft Shell Controls And Automation", CONST2)
assert_equal(36, CONST2::SsfWINDOWS)
end
def test_s_create_guid
guid = WIN32OLE.create_guid
assert_match(/^\{[A-Z0-9]{8}\-[A-Z0-9]{4}\-[A-Z0-9]{4}\-[A-Z0-9]{4}\-[A-Z0-9]{12}/,
guid)
end
#
# WIN32OLE.codepage is initialized according to Encoding.default_external.
#
# def test_s_codepage
# assert_equal(WIN32OLE::CP_ACP, WIN32OLE.codepage)
# end
def test_s_codepage_set
cp = WIN32OLE.codepage
WIN32OLE.codepage = WIN32OLE::CP_UTF8
assert_equal(WIN32OLE::CP_UTF8, WIN32OLE.codepage)
WIN32OLE.codepage = cp
end
def test_s_codepage_changed
omit if RUBY_PLATFORM.match("mswin")
cp = WIN32OLE.codepage
fso = WIN32OLE.new("Scripting.FileSystemObject")
fname = fso.getTempName
begin
obj = WIN32OLE::Variant.new([0x3042].pack("U*").force_encoding("UTF-8"))
WIN32OLE.codepage = WIN32OLE::CP_UTF8
assert_equal("\xE3\x81\x82".force_encoding("CP65001"), obj.value)
begin
WIN32OLE.codepage = 932 # Windows-31J
rescue WIN32OLE::RuntimeError
end
if (WIN32OLE.codepage == 932)
assert_equal("\x82\xA0".force_encoding("CP932"), obj.value)
end
begin
WIN32OLE.codepage = 20932 # MS EUC-JP
rescue WIN32OLE::RuntimeError
end
if (WIN32OLE.codepage == 20932)
assert_equal("\xA4\xA2".force_encoding("CP20932"), obj.value)
end
WIN32OLE.codepage = cp
file = fso.opentextfile(fname, 2, true)
test_str = [0x3042].pack("U*").encode("UTF-16LE")
begin
file.write test_str.force_encoding("UTF-16")
ensure
file.close
end
str = ""
open(fname, "r:ascii-8bit") {|ifs|
str = ifs.read
}
assert_equal(test_str.force_encoding("ascii-8bit"), str)
# This test fail if codepage 20932 (euc) is not installed.
begin
WIN32OLE.codepage = 20932
rescue WIN32OLE::RuntimeError
end
if (WIN32OLE.codepage == 20932)
WIN32OLE.codepage = cp
file = fso.opentextfile(fname, 2, true)
begin
file.write [164, 162].pack("c*").force_encoding("UTF-16")
ensure
file.close
end
open(fname, "r:ascii-8bit") {|ifs|
str = ifs.read
}
assert_equal("\244\242", str)
end
ensure
WIN32OLE.codepage = cp
if (File.exist?(fname))
File.unlink(fname)
end
end
end
def test_cp51932
cp = WIN32OLE.codepage
begin
obj = WIN32OLE::Variant.new([0x3042].pack("U*").force_encoding("UTF-8"))
begin
WIN32OLE.codepage = 51932
rescue
end
if WIN32OLE.codepage == 51932
assert_equal("\xA4\xA2".force_encoding("CP51932"), obj.value)
end
ensure
WIN32OLE.codepage = cp
end
end
def test_s_locale
assert_equal(WIN32OLE::LOCALE_SYSTEM_DEFAULT, WIN32OLE.locale)
end
def test_s_locale_set
begin
begin
WIN32OLE.locale = 1041
rescue WIN32OLE::RuntimeError
STDERR.puts("\n#{__FILE__}:#{__LINE__}:#{self.class.name}.test_s_locale_set is skipped(Japanese locale is not installed)")
return
end
assert_equal(1041, WIN32OLE.locale)
WIN32OLE.locale = WIN32OLE::LOCALE_SYSTEM_DEFAULT
assert_raise(WIN32OLE::RuntimeError) {
WIN32OLE.locale = 111
}
assert_equal(WIN32OLE::LOCALE_SYSTEM_DEFAULT, WIN32OLE.locale)
ensure
WIN32OLE.locale = WIN32OLE::LOCALE_SYSTEM_DEFAULT
end
end
def test_s_locale_change
begin
begin
WIN32OLE.locale = 0x0411
rescue WIN32OLE::RuntimeError
end
if WIN32OLE.locale == 0x0411
obj = WIN32OLE::Variant.new("\\100,000", WIN32OLE::VARIANT::VT_CY)
assert_equal("100000", obj.value)
assert_raise(WIN32OLE::RuntimeError) {
obj = WIN32OLE::Variant.new("$100.000", WIN32OLE::VARIANT::VT_CY)
}
else
STDERR.puts("\n#{__FILE__}:#{__LINE__}:#{self.class.name}.test_s_locale_change is skipped(Japanese locale is not installed)")
end
begin
WIN32OLE.locale = 1033
rescue WIN32OLE::RuntimeError
end
if WIN32OLE.locale == 1033
obj = WIN32OLE::Variant.new("$100,000", WIN32OLE::VARIANT::VT_CY)
assert_equal("100000", obj.value)
else
STDERR.puts("\n#{__FILE__}:#{__LINE__}:#{self.class.name}.test_s_locale_change is skipped(US English locale is not installed)")
end
ensure
WIN32OLE.locale = WIN32OLE::LOCALE_SYSTEM_DEFAULT
end
end
def test_const_CP_ACP
assert_equal(0, WIN32OLE::CP_ACP)
end
def test_const_CP_OEMCP
assert_equal(1, WIN32OLE::CP_OEMCP)
end
def test_const_CP_MACCP
assert_equal(2, WIN32OLE::CP_MACCP)
end
def test_const_CP_THREAD_ACP
assert_equal(3, WIN32OLE::CP_THREAD_ACP)
end
def test_const_CP_SYMBOL
assert_equal(42, WIN32OLE::CP_SYMBOL)
end
def test_const_CP_UTF7
assert_equal(65000, WIN32OLE::CP_UTF7)
end
def test_const_CP_UTF8
assert_equal(65001, WIN32OLE::CP_UTF8)
end
def test_const_LOCALE_SYSTEM_DEFAULT
assert_equal(0x0800, WIN32OLE::LOCALE_SYSTEM_DEFAULT);
end
def test_const_LOCALE_USER_DEFAULT
assert_equal(0x0400, WIN32OLE::LOCALE_USER_DEFAULT);
end
def test_method_missing
assert_raise(ArgumentError) {@dict1.method_missing}
assert_raise(TypeError) {@dict1.method_missing(1)}
assert_raise(ArgumentError) {@dict1.method_missing("foo=")}
assert_raise(ArgumentError) {@dict1.method_missing("foo=", 1, 2)}
end
end
# test of subclass of WIN32OLE
class MyDict < WIN32OLE
def MyDict.new
super('Scripting.Dictionary')
end
end
class TestMyDict < Test::Unit::TestCase
include TestCaseForDict
def setup
@dict1 = MyDict.new
@dict2 = MyDict.new
end
def test_s_new
assert_instance_of(MyDict, @dict1)
assert_instance_of(MyDict, @dict2)
end
end
end

View File

@ -1,407 +0,0 @@
# frozen_string_literal: false
begin
require 'win32ole'
rescue LoadError
end
require 'test/unit'
ado_installed =
if defined?(WIN32OLE)
db = nil
begin
db = WIN32OLE.new('ADODB.Connection')
db.connectionString = "Driver={Microsoft Text Driver (*.txt; *.csv)};DefaultDir=.;"
db.open
db.close
db = nil
true
rescue
end
end
swbemsink_available =
if defined?(WIN32OLE)
begin
WIN32OLE.new('WbemScripting.SWbemSink')
true
rescue
end
end
if defined?(WIN32OLE::Event)
class TestWIN32OLE_EVENT < Test::Unit::TestCase
def test_s_new_exception
assert_raise(TypeError) {
WIN32OLE::Event.new("A")
}
end
def test_s_new_non_exist_event
dict = WIN32OLE.new('Scripting.Dictionary')
assert_raise(RuntimeError) {
WIN32OLE::Event.new(dict)
}
end
end
if swbemsink_available
class TestWIN32OLE_EVENT_SWbemSink < Test::Unit::TestCase
def setup
@wmi = WIN32OLE.connect('winmgmts://localhost/root/cimv2')
@sws = WIN32OLE.new('WbemScripting.SWbemSink')
@event = @event1 = @event2 = ""
@sql = "SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_LocalTime'"
end
def message_loop(watch_ivar = nil)
if watch_ivar
orig_ivar = instance_variable_get(watch_ivar)
end
2.times do
WIN32OLE::Event.message_loop
sleep 1
end
if watch_ivar
# wait until event is proceeded
tries = 0
seconds = EnvUtil.apply_timeout_scale(1)
while tries < 5 && instance_variable_get(watch_ivar) == orig_ivar
$stderr.puts "test_win32ole_event.rb: retrying and sleeping #{seconds}s until #{watch_ivar} is changed from #{orig_ivar.inspect}..."
WIN32OLE::Event.message_loop
sleep(seconds)
tries += 1
seconds *= 2 # sleep at most 31s in total
end
end
end
def default_handler(event, *args)
@event += event
end
def handler1
@event1 = "handler1"
end
def test_s_new_non_exist_event
assert_raise(RuntimeError) {
WIN32OLE::Event.new(@sws, 'XXXXX')
}
end
def test_s_new
obj = WIN32OLE::Event.new(@sws, 'ISWbemSinkEvents')
assert_instance_of(WIN32OLE::Event, obj)
obj = WIN32OLE::Event.new(@sws)
assert_instance_of(WIN32OLE::Event, obj)
end
def test_s_new_loop
exec_notification_query_async
ev = WIN32OLE::Event.new(@sws)
ev.on_event {|*args| default_handler(*args)}
message_loop
10.times do |i|
WIN32OLE::Event.new(@sws)
message_loop
GC.start
end
# @event randomly becomes "OnCompleted" here. Try to wait until it matches.
# https://ci.appveyor.com/project/ruby/ruby/builds/19963142/job/8gaxepksa0i3b998
assert_match_with_retries(/OnObjectReady/, :@event)
end
def test_on_event
exec_notification_query_async
ev = WIN32OLE::Event.new(@sws, 'ISWbemSinkEvents')
ev.on_event {|*args| default_handler(*args)}
message_loop(:@event)
assert_match(/OnObjectReady/, @event)
end
def test_on_event_symbol
exec_notification_query_async
ev = WIN32OLE::Event.new(@sws)
ev.on_event(:OnObjectReady) {|*args|
handler1
}
message_loop(:@event1)
assert_equal("handler1", @event1)
end
private
def exec_notification_query_async
@wmi.ExecNotificationQueryAsync(@sws, @sql)
rescue => e
if /OLE error code:80041008 in SWbemServicesEx/ =~ e.message
omit "No administrator privilege?"
end
raise
end
def assert_match_with_retries(regexp, ivarname)
ivar = instance_variable_get(ivarname)
tries = 0
while tries < 6 && !ivar.match(regexp)
$stderr.puts "test_win32ole_event.rb: retrying until #{ivarname} (#{ivar}) matches #{regexp} (tries: #{tries})..."
sleep(2 ** tries) # sleep at most 63s in total
ivar = instance_variable_get(ivarname)
tries += 1
end
assert_match(regexp, ivar)
end
end
end
if ado_installed
class TestWIN32OLE_EVENT_ADO < Test::Unit::TestCase
CONNSTR="Driver={Microsoft Text Driver (*.txt; *.csv)};DefaultDir=.;"
module ADO
end
def message_loop
WIN32OLE::Event.message_loop
end
def default_handler(event, *args)
@event += event
end
def setup
@db = WIN32OLE.new('ADODB.Connection')
if !defined?(ADO::AdStateOpen)
WIN32OLE.const_load(@db, ADO)
end
@db.connectionString = CONNSTR
@event = ""
@event2 = ""
@event3 = ""
end
def test_on_event2
ev = WIN32OLE::Event.new(@db, 'ConnectionEvents')
ev.on_event('WillConnect') {|*args| handler1}
ev.on_event('WillConnect') {|*args| handler2}
@db.open
message_loop
assert_equal("handler2", @event2)
end
def test_on_event4
ev = WIN32OLE::Event.new(@db, 'ConnectionEvents')
ev.on_event{|*args| handler1}
ev.on_event{|*args| handler2}
ev.on_event('WillConnect'){|*args| handler3(*args)}
@db.open
message_loop
assert_equal(CONNSTR, @event3)
assert("handler2", @event2)
end
def test_on_event5
ev = WIN32OLE::Event.new(@db, 'ConnectionEvents')
ev.on_event {|*args| default_handler(*args)}
ev.on_event('WillConnect'){|*args| handler3(*args)}
@db.open
message_loop
assert_match(/ConnectComplete/, @event)
assert(/WillConnect/ !~ @event)
assert_equal(CONNSTR, @event3)
end
def test_unadvise
ev = WIN32OLE::Event.new(@db, 'ConnectionEvents')
ev.on_event {|*args| default_handler(*args)}
@db.open
message_loop
assert_match(/WillConnect/, @event)
ev.unadvise
@event = ""
@db.close
@db.open
message_loop
assert_equal("", @event);
assert_raise(WIN32OLE::RuntimeError) {
ev.on_event {|*args| default_handler(*args)}
}
end
def test_on_event_with_outargs
ev = WIN32OLE::Event.new(@db)
@db.connectionString = 'XXX' # set illegal connection string
assert_raise(WIN32OLE::RuntimeError) {
@db.open
}
ev.on_event_with_outargs('WillConnect'){|*args|
args.last[0] = CONNSTR # ConnectionString = CONNSTR
}
@db.open
message_loop
assert(true)
end
def test_on_event_hash_return
ev = WIN32OLE::Event.new(@db)
ev.on_event('WillConnect'){|*args|
{:return => 1, :ConnectionString => CONNSTR}
}
@db.connectionString = 'XXX'
@db.open
assert(true)
end
def test_on_event_hash_return2
ev = WIN32OLE::Event.new(@db)
ev.on_event('WillConnect'){|*args|
{:ConnectionString => CONNSTR}
}
@db.connectionString = 'XXX'
@db.open
assert(true)
end
def test_on_event_hash_return3
ev = WIN32OLE::Event.new(@db)
ev.on_event('WillConnect'){|*args|
{'ConnectionString' => CONNSTR}
}
@db.connectionString = 'XXX'
@db.open
assert(true)
end
def test_on_event_hash_return4
ev = WIN32OLE::Event.new(@db)
ev.on_event('WillConnect'){|*args|
{'return' => 1, 'ConnectionString' => CONNSTR}
}
@db.connectionString = 'XXX'
@db.open
assert(true)
end
def test_on_event_hash_return5
ev = WIN32OLE::Event.new(@db)
ev.on_event('WillConnect'){|*args|
{0 => CONNSTR}
}
@db.connectionString = 'XXX'
@db.open
assert(true)
end
def test_off_event
ev = WIN32OLE::Event.new(@db)
ev.on_event{handler1}
ev.off_event
@db.open
message_loop
assert_equal("", @event2)
end
def test_off_event_arg
ev = WIN32OLE::Event.new(@db)
ev.on_event('WillConnect'){handler1}
ev.off_event('WillConnect')
@db.open
message_loop
assert_equal("", @event2)
end
def test_off_event_arg2
ev = WIN32OLE::Event.new(@db)
ev.on_event('WillConnect'){handler1}
ev.on_event('ConnectComplete'){handler1}
ev.off_event('WillConnect')
@db.open
message_loop
assert_equal("handler1", @event2)
end
def test_off_event_sym_arg
ev = WIN32OLE::Event.new(@db)
ev.on_event('WillConnect'){handler1}
ev.off_event(:WillConnect)
@db.open
message_loop
assert_equal("", @event2)
end
def handler1
@event2 = "handler1"
end
def handler2
@event2 = "handler2"
end
def handler3(*arg)
@event3 += arg[0]
end
def teardown
if @db && @db.state == ADO::AdStateOpen
@db.close
end
message_loop
@db = nil
end
class Handler1
attr_reader :val1, :val2, :val3, :val4
def initialize
@val1 = nil
@val2 = nil
@val3 = nil
@val4 = nil
end
def onWillConnect(conn, uid, pwd, opts, stat, pconn)
@val1 = conn
end
def onConnectComplete(err, stat, pconn)
@val2 = err
@val3 = stat
end
def onInfoMessage(err, stat, pconn)
@val4 = stat
end
end
class Handler2
attr_reader :ev
def initialize
@ev = ""
end
def method_missing(ev, *arg)
@ev += ev
end
end
def test_handler1
ev = WIN32OLE::Event.new(@db)
h1 = Handler1.new
ev.handler = h1
@db.open
message_loop
assert_equal(CONNSTR, h1.val1)
assert_equal(h1.val1, ev.handler.val1)
assert_equal(nil, h1.val2)
assert_equal(ADO::AdStateOpen, h1.val3)
assert_equal(ADO::AdStateOpen, h1.val4)
end
def test_handler2
ev = WIN32OLE::Event.new(@db)
h2 = Handler2.new
ev.handler = h2
@db.open
message_loop
assert(h2.ev != "")
end
end
end
end

View File

@ -1,134 +0,0 @@
# frozen_string_literal: false
begin
require 'win32ole'
rescue LoadError
end
require "test/unit"
if defined?(WIN32OLE::Method)
class TestWIN32OLE_METHOD < Test::Unit::TestCase
def setup
ole_type = WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "Shell")
@m_open = WIN32OLE::Method.new(ole_type, "open")
@m_namespace = WIN32OLE::Method.new(ole_type, "namespace")
@m_parent = WIN32OLE::Method.new(ole_type, "parent")
@m_invoke = WIN32OLE::Method.new(ole_type, "invoke")
@m_browse_for_folder = WIN32OLE::Method.new(ole_type, "BrowseForFolder")
ole_type = WIN32OLE::Type.new("Microsoft Scripting Runtime", "File")
@m_file_name = WIN32OLE::Method.new(ole_type, "name")
end
def test_initialize
ole_type = WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "Shell")
assert_raise(TypeError) {
WIN32OLE::Method.new(1, 2)
}
assert_raise(ArgumentError) {
WIN32OLE::Method.new("foo")
}
assert_raise(ArgumentError) {
WIN32OLE::Method.new(ole_type)
}
assert_raise(WIN32OLE::RuntimeError) {
WIN32OLE::Method.new(ole_type, "NonExistMethod")
}
assert_raise(TypeError) {
WIN32OLE::Method.new(ole_type, 1)
}
method = WIN32OLE::Method.new(ole_type, "Open")
assert_instance_of(WIN32OLE::Method, method)
method = WIN32OLE::Method.new(ole_type, "open")
assert_instance_of(WIN32OLE::Method, method)
end
def test_name
assert_equal("Open", @m_open.name)
end
def test_return_type
assert_equal("VOID", @m_open.return_type)
assert_equal("Folder", @m_namespace.return_type)
end
def test_return_vtype
assert_equal(24, @m_open.return_vtype)
assert_equal(26, @m_namespace.return_vtype)
end
def test_return_type_detail
assert_equal(['VOID'], @m_open.return_type_detail)
assert_equal(['PTR', 'USERDEFINED', 'Folder'], @m_namespace.return_type_detail)
end
def test_invoke_kind
assert_equal('FUNC', @m_open.invoke_kind)
assert_equal('FUNC', @m_namespace.invoke_kind)
assert_equal('PROPERTYGET', @m_parent.invoke_kind)
end
def test_invkind
assert_equal(1, @m_namespace.invkind)
assert_equal(2, @m_parent.invkind)
end
def test_visible?
assert(@m_namespace.visible?)
assert(!@m_invoke.visible?)
end
def test_helpstring
assert_equal("Get special folder from ShellSpecialFolderConstants", @m_namespace.helpstring)
end
def test_helpfile
assert_equal("", @m_namespace.helpfile)
assert_match(/VBENLR.*\.CHM$/i, @m_file_name.helpfile)
end
def test_helpcontext
assert_equal(0, @m_namespace.helpcontext)
assert_equal(2181996, @m_file_name.helpcontext)
end
def test_dispid
assert_equal(1610743810, @m_namespace.dispid)
end
def is_ruby64?
/mswin64|x64-mingw/ =~ RUBY_PLATFORM
end
def test_offset_vtbl
exp = is_ruby64? ? 48 : 24
assert_equal(exp, @m_invoke.offset_vtbl)
end
def test_size_params
assert_equal(1, @m_open.size_params)
assert_equal(4, @m_browse_for_folder.size_params)
end
def test_size_opt_params
assert_equal(0, @m_open.size_opt_params)
assert_equal(1, @m_browse_for_folder.size_opt_params)
end
def test_params
params = @m_browse_for_folder.params
assert_instance_of(Array, params)
assert_equal(4, params.size)
assert_instance_of(WIN32OLE::Param, params[0])
end
def test_to_s
assert_equal(@m_namespace.name, @m_namespace.to_s)
end
def test_inspect
assert_equal("#<WIN32OLE::Method:NameSpace>", @m_namespace.inspect)
end
end
end

View File

@ -1,36 +0,0 @@
begin
require 'win32ole'
rescue LoadError
end
require 'test/unit'
if defined?(WIN32OLE::Method)
require_relative 'available_ole'
class TestWIN32OLE_METHOD_EVENT < Test::Unit::TestCase
unless AvailableOLE.sysmon_available?
def test_dummy_for_skip_message
omit 'System Monitor Control is not available'
end
else
def setup
ole_type = WIN32OLE::Type.new('System Monitor Control', 'SystemMonitor')
@on_dbl_click = WIN32OLE::Method.new(ole_type, 'OnDblClick')
ole_type = WIN32OLE::Type.new('Microsoft Shell Controls And Automation', 'Shell')
@namespace = WIN32OLE::Method.new(ole_type, 'namespace')
end
def test_event?
assert(@on_dbl_click.event?)
end
def test_event_interface
assert('DISystemMonitorEvents', @on_dbl_click.event_interface)
end
def test_event_interface_is_nil
assert_equal(nil, @namespace.event_interface)
end
end
end
end

View File

@ -1,98 +0,0 @@
# frozen_string_literal: false
begin
require 'win32ole'
rescue LoadError
end
require "test/unit"
if defined?(WIN32OLE::Param)
class TestWIN32OLE_PARAM < Test::Unit::TestCase
def setup
ole_type = WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "ShellLinkObject")
m_geticonlocation = WIN32OLE::Method.new(ole_type, "GetIconLocation")
@param_pbs = m_geticonlocation.params[0]
ole_type = WIN32OLE::Type.new("Microsoft HTML Object Library", "FontNames")
m_count = WIN32OLE::Method.new(ole_type, "Count")
@param_p = m_count.params[0]
ole_type = WIN32OLE::Type.new("Microsoft Scripting Runtime", "FileSystemObject")
m_copyfile = WIN32OLE::Method.new(ole_type, "CopyFile")
@param_source = m_copyfile.params[0]
@param_overwritefiles = m_copyfile.params[2]
ole_type = WIN32OLE::Type.new("Microsoft Scripting Runtime", "Dictionary")
m_add = WIN32OLE::Method.new(ole_type, "Add")
@param_key = m_add.params[0]
end
def test_s_new
assert_raise(ArgumentError) {
WIN32OLE::Param.new("hoge")
}
ole_type = WIN32OLE::Type.new("Microsoft Scripting Runtime", "FileSystemObject")
m_copyfile = WIN32OLE::Method.new(ole_type, "CopyFile")
assert_raise(IndexError) {
WIN32OLE::Param.new(m_copyfile, 4);
}
assert_raise(IndexError) {
WIN32OLE::Param.new(m_copyfile, 0);
}
param = WIN32OLE::Param.new(m_copyfile, 3)
assert_equal("OverWriteFiles", param.name)
assert_equal(WIN32OLE::Param, param.class)
assert_equal(true, param.default)
assert_equal("#<WIN32OLE::Param:OverWriteFiles=true>", param.inspect)
end
def test_name
assert_equal('Source', @param_source.name)
assert_equal('Key', @param_key.name)
end
def test_ole_type
assert_equal('BSTR', @param_source.ole_type)
assert_equal('VARIANT', @param_key.ole_type)
end
def test_ole_type_detail
assert_equal(['BSTR'], @param_source.ole_type_detail)
assert_equal(['PTR', 'VARIANT'], @param_key.ole_type_detail)
end
def test_input?
assert_equal(true, @param_source.input?)
assert_equal(false, @param_pbs.input?)
end
def test_output?
assert_equal(false, @param_source.output?)
assert_equal(true, @param_pbs.output?)
end
def test_optional?
assert_equal(false, @param_source.optional?)
assert_equal(true, @param_overwritefiles.optional?)
end
def test_retval?
assert_equal(false, @param_source.retval?)
assert_equal(true, @param_p.retval?)
end
def test_default
assert_equal(nil, @param_source.default)
assert_equal(true, @param_overwritefiles.default)
end
def test_to_s
assert_equal(@param_source.name, @param_source.to_s)
end
def test_inspect
assert_equal("#<WIN32OLE::Param:Source>", @param_source.inspect)
assert_equal("#<WIN32OLE::Param:OverWriteFiles=true>", @param_overwritefiles.inspect)
end
end
end

View File

@ -1,30 +0,0 @@
begin
require 'win32ole'
rescue LoadError
end
require 'test/unit'
if defined?(WIN32OLE::Param)
require_relative 'available_ole'
class TestWIN32OLE_PARAM_EVENT < Test::Unit::TestCase
if AvailableOLE.msxml_available? || AvailableOLE.ado_available?
def setup
@param = AvailableOLE.event_param
end
def test_input?
assert_equal(true, @param.input?)
end
def test_output?
assert_equal(true, @param.output?)
end
else
def test_dummy_for_skip_message
omit 'ActiveX Data Object Library and MS XML not found'
end
end
end
end

View File

@ -1,212 +0,0 @@
# coding: us-ascii
# frozen_string_literal: false
begin
require 'win32ole'
rescue LoadError
end
require 'test/unit'
PROGID_RBCOMTEST='RbComTest.ComSrvTest'
=begin
RbComTest.ComSrvTest is following VB.NET COM server(RbComTest solution).
(You must check COM interoperability.)
Imports System.Runtime.InteropServices
Public Class ComSrvTest
<StructLayout(LayoutKind.Sequential)> _
Public Structure Book
<MarshalAs(UnmanagedType.BStr)> _
Public title As String
Public cost As Integer
End Structure
Public Function getBook() As Book
Dim book As New Book
book.title = "The Ruby Book"
book.cost = 20
Return book
End Function
Public Function getBooks() As Book()
Dim book() As Book = {New Book, New Book}
book(0).title = "The CRuby Book"
book(0).cost = 30
book(1).title = "The JRuby Book"
book(1).cost = 40
Return book
End Function
Public Sub getBookByRefObject(ByRef obj As Object)
Dim book As New Book
book.title = "The Ruby Reference Book"
book.cost = 50
obj = book
End Sub
Public Function getVer2BookByValBook(<MarshalAs(UnmanagedType.Struct)> ByVal book As Book) As Book
Dim ret As New Book
ret.title = book.title + " ver2"
ret.cost = book.cost * 1.1
Return ret
End Function
Public Sub getBookByRefBook(<MarshalAs(UnmanagedType.LPStruct)> ByRef book As Book)
book.title = "The Ruby Reference Book2"
book.cost = 44
End Sub
Public Sub getVer3BookByRefBook(<MarshalAs(UnmanagedType.LPStruct)> ByRef book As Book)
book.title += " ver3"
book.cost *= 1.2
End Sub
End Class
=end
if defined?(WIN32OLE::Record)
class TestWIN32OLE_RECORD < Test::Unit::TestCase
end
def rbcomtest_exist?
WIN32OLE.new(PROGID_RBCOMTEST)
true
rescue WIN32OLE::RuntimeError
false
end
class TestWIN32OLE_RECORD_BY_RBCOMTEST < Test::Unit::TestCase
unless rbcomtest_exist?
def test_dummy_for_skip_message
omit "#{PROGID_RBCOMTEST} for WIN32OLE::Record test is not installed"
end
else
def setup
@obj = WIN32OLE.new(PROGID_RBCOMTEST)
end
def test_s_new_from_win32ole
rec = WIN32OLE::Record.new('Book', @obj)
assert(rec)
assert_instance_of(WIN32OLE::Record, rec)
end
def test_s_new_from_win32ole_typelib
tlib = @obj.ole_typelib
rec = WIN32OLE::Record.new('Book', tlib)
assert(rec)
assert_instance_of(WIN32OLE::Record, rec)
end
def test_s_new_raise
assert_raise(WIN32OLE::RuntimeError) {
WIN32OLE::Record.new('NonExistRecordName', @obj)
}
assert_raise(ArgumentError) {
WIN32OLE::Record.new
}
assert_raise(ArgumentError) {
WIN32OLE::Record.new('NonExistRecordName')
}
end
def test_to_h
rec = WIN32OLE::Record.new('Book', @obj)
assert_equal({'title'=>nil, 'cost'=>nil}, rec.to_h)
end
def test_typename
rec = WIN32OLE::Record.new('Book', @obj)
assert_equal('Book', rec.typename)
end
def test_method_missing_getter
rec = WIN32OLE::Record.new('Book', @obj)
assert_equal(nil, rec.title)
assert_raise(KeyError) {
rec.non_exist_name
}
end
def test_method_missing_setter
rec = WIN32OLE::Record.new('Book', @obj)
rec.title = "Ruby Book"
assert_equal("Ruby Book", rec.title)
end
def test_get_record_from_comserver
rec = @obj.getBook
assert_instance_of(WIN32OLE::Record, rec)
assert_equal("The Ruby Book", rec.title)
assert_equal(20, rec.cost)
end
def test_get_record_array_from_comserver
rec = @obj.getBooks
assert_instance_of(Array, rec)
assert_equal(2, rec.size)
assert_instance_of(WIN32OLE::Record, rec[0])
assert_equal("The CRuby Book", rec[0].title)
assert_equal(30, rec[0].cost)
assert_instance_of(WIN32OLE::Record, rec[1])
assert_equal("The JRuby Book", rec[1].title)
assert_equal(40, rec[1].cost)
end
def test_pass_record_parameter
rec = WIN32OLE::Record.new('Book', @obj)
rec.title = "Ruby Book"
rec.cost = 60
book = @obj.getVer2BookByValBook(rec)
assert_equal("Ruby Book ver2", book.title)
assert_equal(66, book.cost)
end
def test_pass_variant_parameter_byref
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF)
@obj.getBookByRefBook(obj)
assert_instance_of(WIN32OLE::Record, obj.value)
book = obj.value
assert_equal("The Ruby Reference Book2", book.title)
assert_equal(44, book.cost)
end
def test_pass_record_parameter_byref
book = WIN32OLE::Record.new('Book', @obj)
@obj.getBookByRefBook(book)
assert_equal("The Ruby Reference Book2", book.title)
assert_equal(44, book.cost)
end
def test_pass_and_get_record_parameter_byref
book = WIN32OLE::Record.new('Book', @obj)
book.title = "Ruby Book"
book.cost = 60
@obj.getVer3BookByRefBook(book)
assert_equal("Ruby Book ver3", book.title)
assert_equal(72, book.cost)
end
def test_ole_instance_variable_get
obj = WIN32OLE::Record.new('Book', @obj)
assert_equal(nil, obj.ole_instance_variable_get(:title))
assert_equal(nil, obj.ole_instance_variable_get('title'))
end
def test_ole_instance_variable_set
book = WIN32OLE::Record.new('Book', @obj)
book.ole_instance_variable_set(:title, "Ruby Book")
assert_equal("Ruby Book", book.title)
book.ole_instance_variable_set('title', "Ruby Book2")
assert_equal("Ruby Book2", book.title)
end
def test_inspect
book = WIN32OLE::Record.new('Book', @obj)
assert_equal(%q[#<WIN32OLE::Record(Book) {"title"=>nil, "cost"=>nil}>], book.inspect)
end
end
end
end

View File

@ -1,199 +0,0 @@
# frozen_string_literal: false
begin
require 'win32ole'
rescue LoadError
end
require "test/unit"
if defined?(WIN32OLE::Type)
class TestWIN32OLE_TYPE < Test::Unit::TestCase
def test_s_progids
progids = WIN32OLE::Type.progids
assert_instance_of(Array, progids)
assert(progids.size > 0)
assert_instance_of(String, progids[0])
assert(progids.include?("Shell.Application.1"))
end
def test_initialize
assert_raise(ArgumentError) {
WIN32OLE::Type.new
}
assert_raise(ArgumentError) {
WIN32OLE::Type.new("foo")
}
assert_raise(TypeError) {
WIN32OLE::Type.new(1, 2)
}
assert_raise(TypeError) {
WIN32OLE::Type.new("Microsoft Shell Controls And Automation", 1)
}
assert_raise(WIN32OLE::RuntimeError) {
WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "foo")
}
assert_raise(WIN32OLE::RuntimeError) {
WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "Application")
}
ole_type = WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "Shell")
assert_instance_of(WIN32OLE::Type, ole_type)
assert_equal("Shell", ole_type.name)
assert_equal("Class", ole_type.ole_type)
assert_equal("{13709620-C279-11CE-A49E-444553540000}", ole_type.guid)
assert_equal("Shell.Application.1", ole_type.progid)
assert_equal(true, ole_type.visible?)
assert_equal("Shell", ole_type.to_s)
assert_equal(0, ole_type.major_version)
assert_equal(0, ole_type.minor_version)
assert_equal(5, ole_type.typekind)
assert_equal("Shell Object Type Information", ole_type.helpstring)
assert_equal(nil, ole_type.src_type)
assert_equal("", ole_type.helpfile)
assert_equal(0, ole_type.helpcontext)
assert_equal([], ole_type.variables)
assert(ole_type.ole_methods.select{|m|/NameSpace/i =~ m.name}.size > 0)
ole_type2 = WIN32OLE::Type.new("{13709620-C279-11CE-A49E-444553540000}", "Shell")
assert_instance_of(WIN32OLE::Type, ole_type)
assert_equal(ole_type.name, ole_type2.name)
assert_equal(ole_type.ole_type, ole_type2.ole_type)
assert_equal(ole_type.guid, ole_type2.guid)
assert_equal(ole_type.progid, ole_type2.progid)
assert_equal(ole_type.visible?, ole_type2.visible?)
assert_equal(ole_type.to_s, ole_type2.to_s)
assert_equal(ole_type.major_version, ole_type2.major_version)
assert_equal(ole_type.minor_version, ole_type2.minor_version)
assert_equal(ole_type.typekind, ole_type2.typekind)
assert_equal(ole_type.helpstring, ole_type2.helpstring)
assert_equal(ole_type.src_type, ole_type2.src_type)
assert_equal(ole_type.helpfile, ole_type2.helpfile)
assert_equal(ole_type.helpcontext, ole_type2.helpcontext)
assert_equal(ole_type.variables.size, ole_type2.variables.size)
assert_equal(ole_type.ole_methods[0].name, ole_type2.ole_methods[0].name)
assert_equal(ole_type.ole_typelib.name, ole_type2.ole_typelib.name)
assert_equal(ole_type.implemented_ole_types.size, ole_type2.implemented_ole_types.size)
assert_equal(ole_type.inspect, ole_type2.inspect)
end
def setup
@ole_type = WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "Shell")
end
def test_name
assert_equal("Shell", @ole_type.name)
end
def test_ole_type
assert_equal("Class", @ole_type.ole_type)
end
def test_guid
assert_equal("{13709620-C279-11CE-A49E-444553540000}", @ole_type.guid)
end
def test_progid
assert_equal("Shell.Application.1", @ole_type.progid)
end
def test_visible?
assert(@ole_type.visible?)
ole_type = WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "IShellDispatch")
assert(!ole_type.visible?)
end
def test_to_s
assert_equal(@ole_type.to_s, @ole_type.name)
end
def test_major_version
assert_equal(0, @ole_type.major_version)
# ole_type = WIN32OLE::Type.new("Microsoft Word 11.0 Object Library", "Documents")
# assert_equal(8, ole_type.major_version)
end
def test_minor_version
assert_equal(0, @ole_type.minor_version)
# ole_type = WIN32OLE::Type.new("Microsoft Word 11.0 Object Library", "Documents")
# assert_equal(3, ole_type.minor_version)
end
def test_typekind
assert_equal(5, @ole_type.typekind)
end
def test_helpstring
assert_equal("Shell Object Type Information", @ole_type.helpstring)
end
def test_src_type
ole_type = WIN32OLE::Type.new("Microsoft Scripting Runtime", "DriveTypeConst")
assert_match(/__MIDL___MIDL_itf_scrrun_/, ole_type.src_type)
assert_equal(nil, @ole_type.src_type)
end
def test_helpfile
assert_equal("", @ole_type.helpfile)
ole_type = WIN32OLE::Type.new("Microsoft Scripting Runtime", "Folders")
assert_match(/VBENLR98\.CHM$/i, ole_type.helpfile)
end
def test_helpcontext
assert_equal(0, @ole_type.helpcontext)
ole_type = WIN32OLE::Type.new("Microsoft Scripting Runtime", "Folders")
assert_equal(2181929, ole_type.helpcontext)
end
def test_variables
variables = @ole_type.variables
assert_instance_of(Array, variables)
assert(variables.size == 0)
ole_type = WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "ShellSpecialFolderConstants")
variables = ole_type.variables
assert_instance_of(Array, variables)
assert(variables.size > 0)
assert_instance_of(WIN32OLE::Variable, variables[0])
end
def test_ole_methods
methods = @ole_type.ole_methods
assert_instance_of(Array, methods)
assert(methods.size > 0)
assert_instance_of(WIN32OLE::Method, methods[0]);
assert(methods.collect{|m| m.name}.include?("Application"))
end
def test_ole_typelib
tlib = @ole_type.ole_typelib
assert_instance_of(WIN32OLE::TypeLib, tlib)
assert_equal("Microsoft Shell Controls And Automation", tlib.name)
end
def test_implemented_ole_types
ole_types = @ole_type.implemented_ole_types
assert_instance_of(Array, ole_types)
assert_equal(1, ole_types.size)
assert_match(/^IShellDispatch\d{0,1}$/, ole_types[0].name)
end
def test_inspect
assert_equal("#<WIN32OLE::Type:Shell>", @ole_type.inspect)
end
# WIN32OLE::Type.typelibs will be obsoleted.
def test_s_typelibs
tlibs = WIN32OLE::Type.typelibs.sort
tlibs2 = WIN32OLE::TypeLib.typelibs.collect{|t|t.name}.sort
assert_equal(tlibs2, tlibs)
end
# WIN32OLE::Type.ole_classes will be obsoleted.
def test_s_ole_classes
ots1 = WIN32OLE::Type.ole_classes("Microsoft Shell Controls And Automation")
ots2 = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation").ole_types
otns1 = ots1.collect{|t| t.name}.sort
otns2 = ots2.collect{|t| t.name}.sort
assert_equal(otns2, otns1)
end
end
end

View File

@ -1,44 +0,0 @@
# frozen_string_literal: false
begin
require 'win32ole'
rescue LoadError
end
require 'test/unit'
if defined?(WIN32OLE::Type)
require_relative 'available_ole'
class TestWIN32OLE_TYPE_EVENT < Test::Unit::TestCase
unless AvailableOLE.sysmon_available?
def test_dummy_for_skip_message
omit 'System Monitor Control is not available'
end
else
def setup
@ole_type = WIN32OLE::Type.new('System Monitor Control', 'SystemMonitor')
end
def test_implemented_ole_types
ole_types = @ole_type.implemented_ole_types.map(&:name).sort
assert_equal(['DISystemMonitor', 'DISystemMonitorEvents', 'ISystemMonitor'], ole_types)
end
def test_default_ole_types
ole_types = @ole_type.default_ole_types.map(&:name).sort
assert_equal(['DISystemMonitor', 'DISystemMonitorEvents'], ole_types)
end
def test_source_ole_types
ole_types = @ole_type.source_ole_types.map(&:name)
assert_equal(['DISystemMonitorEvents'], ole_types)
end
def test_default_event_sources
event_sources = @ole_type.default_event_sources.map(&:name)
assert_equal(['DISystemMonitorEvents'], event_sources)
end
end
end
end

View File

@ -1,117 +0,0 @@
# frozen_string_literal: false
begin
require 'win32ole'
rescue LoadError
end
require "test/unit"
if defined?(WIN32OLE::TypeLib)
class TestWIN32OLE_TYPELIB < Test::Unit::TestCase
def test_s_typelibs
tlibs = WIN32OLE::TypeLib.typelibs
assert_instance_of(Array, tlibs)
assert(tlibs.size > 0)
tlib = tlibs.find {|t| t.name == "Microsoft Shell Controls And Automation"}
assert(tlib)
end
def test_initialize
assert_raise(ArgumentError) {
WIN32OLE::TypeLib.new(1,2,3,4)
}
assert_raise(TypeError) {
WIN32OLE::TypeLib.new(100)
}
tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_instance_of(WIN32OLE::TypeLib, tlib)
tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation", 1.0)
assert_instance_of(WIN32OLE::TypeLib, tlib)
tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation", 1, 0)
assert_instance_of(WIN32OLE::TypeLib, tlib)
guid = tlib.guid
tlib_by_guid = WIN32OLE::TypeLib.new(guid, 1, 0)
assert_instance_of(WIN32OLE::TypeLib, tlib_by_guid)
assert_equal("Microsoft Shell Controls And Automation" , tlib_by_guid.name)
path = tlib.path
tlib_by_path = WIN32OLE::TypeLib.new(path)
assert_equal("Microsoft Shell Controls And Automation" , tlib_by_path.name)
assert_raise(WIN32OLE::RuntimeError) {
WIN32OLE::TypeLib.new("Non Exist Type Library")
}
end
# #Bug:3907 [ruby-dev:42338]
def test_initialize_with_REG_EXPAND_SZ
tlib = WIN32OLE::TypeLib.new("Disk Management Snap-In Object Library")
assert_instance_of(WIN32OLE::TypeLib, tlib)
end
def test_guid
tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_equal("{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}", tlib.guid)
end
def test_name
tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_equal("Microsoft Shell Controls And Automation", tlib.name)
tlib = WIN32OLE::TypeLib.new("{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}")
assert_equal("Microsoft Shell Controls And Automation", tlib.name)
end
def test_version
tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_equal("1.0", tlib.version)
end
def test_major_version
tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_equal(1, tlib.major_version)
end
def test_minor_version
tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_equal(0, tlib.minor_version)
end
def test_path
tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_match(/shell32\.dll$/i, tlib.path)
end
def test_visible?
tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert(tlib.visible?)
end
def test_library_name
tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_equal("Shell32", tlib.library_name)
end
def test_to_s
tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_equal("Microsoft Shell Controls And Automation", tlib.to_s)
end
def test_ole_types
tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
ole_types = tlib.ole_types
assert_instance_of(Array, ole_types)
assert(ole_types.size > 0)
assert_instance_of(WIN32OLE::Type, ole_types[0])
end
def test_inspect
tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_equal("#<WIN32OLE::TypeLib:Microsoft Shell Controls And Automation>", tlib.inspect)
end
end
end

View File

@ -1,66 +0,0 @@
# frozen_string_literal: false
begin
require 'win32ole'
rescue LoadError
end
require "test/unit"
if defined?(WIN32OLE::Variable)
class TestWIN32OLE_VARIABLE < Test::Unit::TestCase
def setup
ole_type = WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "ShellSpecialFolderConstants")
@var1 = ole_type.variables.find {|v| v.name == 'ssfDESKTOP'}
variables = WIN32OLE::Type.new("Microsoft Windows Installer Object Library", "Installer").variables
@var2 = variables.find {|v| v.name == 'UILevel'}
end
def test_initialize
assert_raise(TypeError) {WIN32OLE::Variable.new}
end
def test_name
assert_equal('ssfDESKTOP', @var1.name)
end
def test_ole_type
assert_equal('INT', @var1.ole_type)
assert_equal('MsiUILevel', @var2.ole_type)
end
def test_ole_type_detail
assert_equal(['INT'], @var1.ole_type_detail)
assert_equal(['USERDEFINED', 'MsiUILevel'], @var2.ole_type_detail)
end
def test_ole_type_value
assert_equal(0, @var1.value)
assert_equal(nil, @var2.value)
end
def test_ole_type_visible?
assert(@var1.visible?)
end
def test_ole_type_variable_kind
assert_equal("CONSTANT", @var1.variable_kind)
assert_equal("DISPATCH", @var2.variable_kind)
end
def test_ole_type_varkind
assert_equal(2, @var1.varkind)
assert_equal(3, @var2.varkind)
end
def test_to_s
assert_equal(@var1.name, @var1.to_s)
end
def test_inspect
assert_equal("#<WIN32OLE::Variable:ssfDESKTOP=0>", @var1.inspect)
assert_equal("#<WIN32OLE::Variable:UILevel=nil>", @var2.inspect)
end
end
end

View File

@ -1,722 +0,0 @@
# frozen_string_literal: false
begin
require 'win32ole'
rescue LoadError
end
require "test/unit"
if defined?(WIN32OLE::Variant)
class TestWIN32OLE_VARIANT < Test::Unit::TestCase
def setup
@orglocale = WIN32OLE.locale
WIN32OLE.locale = 0x0409 # set locale US-Eng
end
def teardown
WIN32OLE.locale = @orglocale
end
def test_s_new
obj = WIN32OLE::Variant.new('foo')
assert_instance_of(WIN32OLE::Variant, obj)
end
def test_s_new_exc
assert_raise(TypeError) {
WIN32OLE::Variant.new(/foo/)
}
end
def test_s_new_ary
obj = WIN32OLE::Variant.new([1])
assert_instance_of(WIN32OLE::Variant, obj)
assert_raise(TypeError) {
WIN32OLE::Variant.new([/foo/])
}
end
def test_s_new_no_argument
pat = /wrong number of arguments \(.*\b0\b.* 1\.\.3\)/
assert_raise_with_message(ArgumentError, pat) do
WIN32OLE::Variant.new
end
end
def test_s_new_one_argument
ex = nil
begin
WIN32OLE::Variant.new('foo')
rescue
ex = $!
end
assert_equal(nil, ex);
end
def test_s_new_with_nil
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_I2)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I2, obj.vartype)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_I4)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I4, obj.vartype)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_R4)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_R4, obj.vartype)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_R8)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_R8, obj.vartype)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_CY)
assert_equal("0", obj.value)
assert_equal(WIN32OLE::VARIANT::VT_CY, obj.vartype)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(1899,12,30), obj.value)
assert_equal(WIN32OLE::VARIANT::VT_DATE, obj.vartype)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_BSTR)
assert_equal("", obj.value)
assert_equal(WIN32OLE::VARIANT::VT_BSTR, obj.vartype)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_DISPATCH)
assert_nil(obj.value)
assert_equal(WIN32OLE::VARIANT::VT_DISPATCH, obj.vartype)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_BOOL)
assert_equal(false, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_BOOL, obj.vartype)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_VARIANT)
assert_nil(obj.value)
assert_equal(WIN32OLE::VARIANT::VT_VARIANT, obj.vartype)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_I1)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I1, obj.vartype)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_UI1)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI1, obj.vartype)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_UI2)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI2, obj.vartype)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_UI4)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI4, obj.vartype)
if defined?(WIN32OLE::VARIANT::VT_I8)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_I8)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I8, obj.vartype)
end
if defined?(WIN32OLE::VARIANT::VT_UI8)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_UI8)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI8, obj.vartype)
end
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_INT)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_INT, obj.vartype)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_UINT)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UINT, obj.vartype)
end
def test_s_new_with_non_nil
obj = WIN32OLE::Variant.new(2, WIN32OLE::VARIANT::VT_I2)
assert_equal(2, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I2, obj.vartype)
obj = WIN32OLE::Variant.new(3, WIN32OLE::VARIANT::VT_I4)
assert_equal(3, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I4, obj.vartype)
obj = WIN32OLE::Variant.new(4.5, WIN32OLE::VARIANT::VT_R4)
assert_equal(4.5, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_R4, obj.vartype)
obj = WIN32OLE::Variant.new(5.5, WIN32OLE::VARIANT::VT_R8)
assert_equal(5.5, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_R8, obj.vartype)
obj = WIN32OLE::Variant.new(600, WIN32OLE::VARIANT::VT_CY)
assert_equal("600", obj.value)
assert_equal(WIN32OLE::VARIANT::VT_CY, obj.vartype)
obj = WIN32OLE::Variant.new("2001-06-15 12:17:34", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(2001,06,15,12,17,34), obj.value)
assert_equal(WIN32OLE::VARIANT::VT_DATE, obj.vartype)
obj = WIN32OLE::Variant.new("foo", WIN32OLE::VARIANT::VT_BSTR)
assert_equal("foo", obj.value)
assert_equal(WIN32OLE::VARIANT::VT_BSTR, obj.vartype)
obj = WIN32OLE::Variant.new(true, WIN32OLE::VARIANT::VT_BOOL)
assert_equal(true, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_BOOL, obj.vartype)
obj = WIN32OLE::Variant.new(2, WIN32OLE::VARIANT::VT_I1)
assert_equal(2, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I1, obj.vartype)
obj = WIN32OLE::Variant.new(3, WIN32OLE::VARIANT::VT_UI1)
assert_equal(3, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI1, obj.vartype)
obj = WIN32OLE::Variant.new(4, WIN32OLE::VARIANT::VT_UI2)
assert_equal(4, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI2, obj.vartype)
obj = WIN32OLE::Variant.new(5, WIN32OLE::VARIANT::VT_UI4)
assert_equal(5, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI4, obj.vartype)
if defined?(WIN32OLE::VARIANT::VT_I8)
obj = WIN32OLE::Variant.new(-123456789012345, WIN32OLE::VARIANT::VT_I8)
assert_equal(-123456789012345, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I8, obj.vartype)
end
if defined?(WIN32OLE::VARIANT::VT_UI8)
obj = WIN32OLE::Variant.new(123456789012345, WIN32OLE::VARIANT::VT_UI8)
assert_equal(123456789012345, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI8, obj.vartype)
end
obj = WIN32OLE::Variant.new(4, WIN32OLE::VARIANT::VT_INT)
assert_equal(4, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_INT, obj.vartype)
obj = WIN32OLE::Variant.new(5, WIN32OLE::VARIANT::VT_UINT)
assert_equal(5, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UINT, obj.vartype)
end
def test_s_new_with_non_nil_byref
obj = WIN32OLE::Variant.new(2, WIN32OLE::VARIANT::VT_I2|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(2, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I2|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
obj = WIN32OLE::Variant.new(3, WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(3, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
obj = WIN32OLE::Variant.new(4.5, WIN32OLE::VARIANT::VT_R4|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(4.5, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_R4|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
obj = WIN32OLE::Variant.new(5.5, WIN32OLE::VARIANT::VT_R8|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(5.5, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_R8|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
obj = WIN32OLE::Variant.new(600, WIN32OLE::VARIANT::VT_CY|WIN32OLE::VARIANT::VT_BYREF)
assert_equal("600", obj.value)
assert_equal(WIN32OLE::VARIANT::VT_CY|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
obj = WIN32OLE::Variant.new("2001-06-15 12:17:34", WIN32OLE::VARIANT::VT_DATE|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(Time.new(2001,06,15,12,17,34), obj.value)
assert_equal(WIN32OLE::VARIANT::VT_DATE|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
obj = WIN32OLE::Variant.new("foo", WIN32OLE::VARIANT::VT_BSTR|WIN32OLE::VARIANT::VT_BYREF)
assert_equal("foo", obj.value)
assert_equal(WIN32OLE::VARIANT::VT_BSTR|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
obj = WIN32OLE::Variant.new(true, WIN32OLE::VARIANT::VT_BOOL|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(true, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_BOOL|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
obj = WIN32OLE::Variant.new(2, WIN32OLE::VARIANT::VT_I1|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(2, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I1|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
obj = WIN32OLE::Variant.new(3, WIN32OLE::VARIANT::VT_UI1|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(3, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI1|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
obj = WIN32OLE::Variant.new(4, WIN32OLE::VARIANT::VT_UI2|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(4, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI2|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
obj = WIN32OLE::Variant.new(5, WIN32OLE::VARIANT::VT_UI4|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(5, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI4|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
obj = WIN32OLE::Variant.new(4, WIN32OLE::VARIANT::VT_INT|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(4, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_INT|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
obj = WIN32OLE::Variant.new(5, WIN32OLE::VARIANT::VT_UINT|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(5, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UINT|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
end
def test_s_new_with_i8_byref
obj = WIN32OLE::Variant.new(-123456789012345, WIN32OLE::VARIANT::VT_I8|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(-123456789012345, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I8|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
end
def test_s_new_with_ui8_byref
obj = WIN32OLE::Variant.new(123456789012345, WIN32OLE::VARIANT::VT_UI8|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(123456789012345, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI8|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
end
def test_value
obj = WIN32OLE::Variant.new('foo')
assert_equal('foo', obj.value)
end
def test_s_new_2_argument
obj = WIN32OLE::Variant.new('foo', WIN32OLE::VARIANT::VT_BSTR|WIN32OLE::VARIANT::VT_BYREF)
assert_equal('foo', obj.value);
end
def test_s_new_2_argument2
obj = WIN32OLE::Variant.new('foo', WIN32OLE::VARIANT::VT_BSTR)
assert_equal('foo', obj.value);
end
def test_s_new_dispatch_array
vt = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_DISPATCH
obj = WIN32OLE::Variant.new(nil, vt)
assert_equal(vt, obj.vartype)
assert_nil(obj.value)
vt = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_DISPATCH|WIN32OLE::VARIANT::VT_BYREF
obj = WIN32OLE::Variant.new(nil, vt)
assert_equal(vt, obj.vartype)
assert_nil(obj.value)
end
def test_s_new_array
# should not occur stack over flow
ar = (1..500000).to_a.map{|i| [i]}
ar2 = WIN32OLE::Variant.new(ar)
assert_equal(ar, ar2.value)
end
def test_s_new_vt_record_exc
# VT_RECORD (= 36) should not be allowed in WIN32OLE::Variant#new
assert_raise(ArgumentError) {
WIN32OLE::Variant.new(nil, 36)
}
end
def test_s_array
obj = WIN32OLE::Variant.array([2,3], WIN32OLE::VARIANT::VT_I4)
assert_instance_of(WIN32OLE::Variant, obj)
assert_equal(WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_ARRAY, obj.vartype)
assert_equal([[0, 0, 0],[0, 0, 0]], obj.value)
obj = WIN32OLE::Variant.array([2,3], WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF|WIN32OLE::VARIANT::VT_ARRAY, obj.vartype)
assert_equal([[0, 0, 0],[0, 0, 0]], obj.value)
obj = WIN32OLE::Variant.array([2,3], WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_ARRAY)
assert_instance_of(WIN32OLE::Variant, obj)
assert_equal(WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_ARRAY, obj.vartype)
assert_equal([[0, 0, 0],[0, 0, 0]], obj.value)
assert_equal(0, obj[0,0])
obj[0,0] = 10
assert_equal([[10, 0, 0],[0, 0, 0]], obj.value)
obj[0,1] = "13.2"
assert_equal([[10, 13, 0],[0, 0, 0]], obj.value)
obj = WIN32OLE::Variant.array([3, 2], WIN32OLE::VARIANT::VT_VARIANT)
obj[0,0] = 10
obj[0,1] = "string"
obj[1,0] = 12.735
assert_equal([[10, "string"],[12.735, nil],[nil,nil]], obj.value)
obj = WIN32OLE::Variant.array([2,3], WIN32OLE::VARIANT::VT_DISPATCH)
assert_equal([[nil, nil, nil],[nil,nil,nil]], obj.value)
end
def test_s_array_exc
assert_raise(TypeError) {
WIN32OLE::Variant.array(2, WIN32OLE::VARIANT::VT_I4)
}
end
def test_conversion_num2str
obj = WIN32OLE::Variant.new(124, WIN32OLE::VARIANT::VT_BSTR)
assert_equal("124", obj.value);
end
def test_conversion_float2int
obj = WIN32OLE::Variant.new(12.345, WIN32OLE::VARIANT::VT_I4)
assert_equal(12, obj.value)
obj = WIN32OLE::Variant.new(12.345, WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(12, obj.value)
end
def test_conversion_str2num
obj = WIN32OLE::Variant.new("12.345", WIN32OLE::VARIANT::VT_R8)
assert_equal(12.345, obj.value)
end
def test_conversion_ole_variant2ole_variant
obj = WIN32OLE::Variant.new("12.345", WIN32OLE::VARIANT::VT_R4)
obj = WIN32OLE::Variant.new(obj, WIN32OLE::VARIANT::VT_I4)
assert_equal(12, obj.value)
end
def test_conversion_str2date
obj = WIN32OLE::Variant.new("2004-12-24 12:24:45", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(2004,12,24,12,24,45), obj.value)
end
def test_conversion_time2date
dt = Time.mktime(2004, 12, 24, 12, 24, 45)
obj = WIN32OLE::Variant.new(dt, WIN32OLE::VARIANT::VT_DATE)
assert_equal(dt, obj.value)
end
def test_conversion_dbl2date_with_msec
# Date is "2014/8/27 12:34:56.789"
obj = WIN32OLE::Variant.new(41878.524268391200167, WIN32OLE::VARIANT::VT_DATE)
t = obj.value
assert_equal("2014-08-27 12:34:56", t.strftime('%Y-%m-%d %H:%M:%S'))
assert_in_delta(0.789, t.nsec / 1000000000.0, 0.001)
end
def test_conversion_time2date_with_msec
t0 = Time.new(2014, 8, 27, 12, 34, 56)
t0 += 0.789
t1 = WIN32OLE::Variant.new(t0).value
# The t0.nsec is 789000000 and t1.nsec is 789000465
# because of error range by conversion Time between VT_DATE Variant.
# So check t1 and t0 are in error by less than one millisecond.
msg = "Expected:#{t0.strftime('%Y-%m-%dT%H:%M:%S.%N')} but was:#{t1.strftime('%Y-%m-%dT%H:%M:%S.%N')}"
assert_in_delta(t0, t1, 0.001, msg)
t0 = Time.new(2014, 8, 27, 12, 34, 56)
t0 += 0.999999999
t1 = WIN32OLE::Variant.new(t0).value
msg = "Expected:#{t0.strftime('%Y-%m-%dT%H:%M:%S.%N')} but was:#{t1.strftime('%Y-%m-%dT%H:%M:%S.%N')}"
# The t0 is "2014/08/27 12:34.56.999999999" and
# the t1 is "2014/08/27 12:34:57.000000628"
assert_in_delta(t0, t1, 0.001, msg)
t0 = Time.now
t1 = WIN32OLE::Variant.new(t0).value
msg = "Expected:#{t0.strftime('%Y-%m-%dT%H:%M:%S.%N')} but was:#{t1.strftime('%Y-%m-%dT%H:%M:%S.%N')}"
assert_in_delta(t0, t1, 0.001, msg)
end
# this test failed because of VariantTimeToSystemTime
# and SystemTimeToVariantTime API ignores wMilliseconds
# member of SYSTEMTIME struct.
#
# def test_conversion_time_nsec2date
# dt = Time.new(2004, 12,24, 12, 24, 45)
# dt += 0.1
# obj = WIN32OLE::Variant.new(dt, WIN32OLE::VARIANT::VT_DATE)
# assert_equal(dt, obj.value)
# end
def test_conversion_str2cy
begin
WIN32OLE.locale = 0x0411 # set locale Japanese
rescue WIN32OLE::RuntimeError
omit("Japanese locale is not installed")
end
if WIN32OLE.locale == 0x0411
obj = WIN32OLE::Variant.new("\\10,000", WIN32OLE::VARIANT::VT_CY)
assert_equal("10000", obj.value)
end
end
def test_create_vt_array
obj = WIN32OLE::Variant.new([1.2, 2.3], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_R8)
assert_equal([1.2, 2.3], obj.value)
assert_equal(WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_R8, obj.vartype)
obj = WIN32OLE::Variant.new([1.2, 2.3], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_R8|WIN32OLE::VARIANT::VT_BYREF)
assert_equal([1.2, 2.3], obj.value)
assert_equal(WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_R8|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
end
def test_create_vt_array2
obj = WIN32OLE::Variant.new([1.2, "a"], WIN32OLE::VARIANT::VT_ARRAY)
assert_equal([1.2, "a"], obj.value)
assert_equal(WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_VARIANT, obj.vartype)
obj = WIN32OLE::Variant.new([1.2, "a"])
assert_equal([1.2, "a"], obj.value)
assert_equal(WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_VARIANT, obj.vartype)
end
def test_create_vt_nested_array
obj = WIN32OLE::Variant.new([[1.2, "a", "b"], [3.4, "C", "D"]], WIN32OLE::VARIANT::VT_ARRAY)
assert_equal([[1.2, "a", "b"], [3.4, "C", "D"]], obj.value)
obj = WIN32OLE::Variant.new([[1.2, "a", "b"], [3.4, "C", "D"]])
assert_equal([[1.2, "a", "b"], [3.4, "C", "D"]], obj.value)
obj = WIN32OLE::Variant.new([[1.2, "a", "b"], [3.4, "C", "D"], [5.6, "E", "F"]])
assert_equal([[1.2, "a", "b"], [3.4, "C", "D"], [5.6, "E", "F"]], obj.value)
obj = WIN32OLE::Variant.new([[[1.2], [3.4]], [[5.6], [7.8]], [[9.1],[9.2]]])
assert_equal([[[1.2], [3.4]], [[5.6], [7.8]], [[9.1],[9.2]]], obj.value)
end
def test_create_vt_array3
obj = WIN32OLE::Variant.new([])
assert_equal([], obj.value)
obj = WIN32OLE::Variant.new([[]])
assert_equal([[]], obj.value)
obj = WIN32OLE::Variant.new([[],[]])
assert_equal([[],[]], obj.value)
obj = WIN32OLE::Variant.new([], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BYREF)
assert_equal([], obj.value)
obj = WIN32OLE::Variant.new([[]], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BYREF)
assert_equal([[]], obj.value)
obj = WIN32OLE::Variant.new([[],[]], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BYREF)
assert_equal([[],[]], obj.value)
end
def test_create_vt_array_nil
vartype = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_DISPATCH|WIN32OLE::VARIANT::VT_BYREF
obj = WIN32OLE::Variant.new(nil, vartype)
assert_nil(obj.value)
assert_equal(vartype, obj.vartype)
vartype = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_DISPATCH
obj = WIN32OLE::Variant.new(nil, vartype)
assert_nil(obj.value)
assert_equal(vartype, obj.vartype)
end
def test_create_vt_array_str
vartype = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BSTR
obj = WIN32OLE::Variant.new(["abc", "123"], vartype)
assert_equal(vartype, obj.vartype)
assert_equal(["abc", "123"], obj.value)
vartype = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BYREF|WIN32OLE::VARIANT::VT_BSTR
obj = WIN32OLE::Variant.new(["abc", "123"], vartype)
assert_equal(vartype, obj.vartype)
assert_equal(["abc", "123"], obj.value)
end
def test_create_vt_array_exc
exc = assert_raise(TypeError) {
WIN32OLE::Variant.new("", WIN32OLE::VARIANT::VT_ARRAY)
}
assert_match(/wrong argument type String \(expected Array\)/, exc.message)
end
def test_create_vt_array_str2ui1array
obj = WIN32OLE::Variant.new("ABC", WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1)
assert_equal("ABC", obj.value)
obj.value = "DEF"
assert_equal("DEF", obj.value)
obj[0] = 71
assert_equal("GEF", obj.value)
obj = WIN32OLE::Variant.new([65, 0].pack("C*"), WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1)
assert_equal([65, 0].pack("C*"), obj.value)
obj = WIN32OLE::Variant.new("abc", WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1|WIN32OLE::VARIANT::VT_BYREF)
assert_equal("abc", obj.value)
obj.value = "DEF"
assert_equal("DEF", obj.value)
assert_equal(WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
obj[1] = 71
assert_equal("DGF", obj.value)
end
def test_create_vt_array_int
obj = WIN32OLE::Variant.new([65, 0], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1)
assert_equal([65, 0].pack("C*"), obj.value)
obj = WIN32OLE::Variant.new([65, 0])
assert_equal([65, 0], obj.value)
obj = WIN32OLE::Variant.new([65, 0], WIN32OLE::VARIANT::VT_I2|WIN32OLE::VARIANT::VT_ARRAY)
assert_equal([65, 0], obj.value)
end
def test_vt_array_bracket
obj = WIN32OLE::Variant.new([[1,2,3],[4,5,6]])
assert_equal(1, obj[0,0])
assert_equal(2, obj[0,1])
assert_equal(3, obj[0,2])
assert_equal(4, obj[1,0])
assert_equal(5, obj[1,1])
assert_equal(6, obj[1,2])
assert_raise(WIN32OLE::RuntimeError) {
obj[0,4]
}
assert_raise(WIN32OLE::RuntimeError) {
obj[0,-1]
}
assert_raise(ArgumentError) {
obj[0]
}
obj[0,0] = 7
obj[1,2] = 8
assert_equal([[7,2,3], [4,5,8]], obj.value)
assert_raise(WIN32OLE::RuntimeError) {
obj[0,4] = 9
}
assert_raise(WIN32OLE::RuntimeError) {
obj[0,-1] = 10
}
assert_raise(ArgumentError) {
obj[0] = 11
}
end
def test_conversion_vt_date
obj = WIN32OLE::Variant.new(-657434, WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(100,1,1), obj.value)
obj = WIN32OLE::Variant.new("1500/12/29 23:59:59", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(1500,12,29,23,59,59), obj.value)
obj = WIN32OLE::Variant.new("1500/12/30 00:00:00", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(1500,12,30), obj.value)
obj = WIN32OLE::Variant.new("1500/12/30 00:00:01", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(1500,12,30,0,0,1), obj.value)
obj = WIN32OLE::Variant.new("1899/12/29 23:59:59", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(1899,12,29,23,59,59), obj.value)
obj = WIN32OLE::Variant.new("1899/12/30 00:00:00", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(1899,12,30), obj.value)
obj = WIN32OLE::Variant.new("1899/12/30 00:00:01", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(1899,12,30,0,0,1), obj.value)
obj = WIN32OLE::Variant.new(0, WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(1899,12,30), obj.value)
obj = WIN32OLE::Variant.new("2008/12/29 23:59:59", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(2008,12,29,23,59,59), obj.value)
obj = WIN32OLE::Variant.new("2008/12/30 00:00:00", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(2008,12,30,0,0,0), obj.value)
obj = WIN32OLE::Variant.new("2008/12/30 00:00:01", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(2008,12,30,0,0,1), obj.value)
obj = WIN32OLE::Variant.new("9999/12/31 23:59:59", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(9999,12,31,23,59,59), obj.value)
end
def test_create_nil_dispatch
var = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_DISPATCH)
assert_nil(var.value)
end
def test_create_variant_byref
obj = WIN32OLE::Variant.new("Str", WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF);
assert_equal("Str", obj.value);
end
def test_vartype
obj = WIN32OLE::Variant.new("Str")
assert_equal(WIN32OLE::VARIANT::VT_BSTR, obj.vartype)
end
def test_set_value
obj = WIN32OLE::Variant.new(10)
obj.value = 12
assert_equal(12, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I4, obj.vartype)
obj.value = "14"
assert_equal(14, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I4, obj.vartype)
obj.value = 11.2
assert_equal(11, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I4, obj.vartype)
obj = WIN32OLE::Variant.new([1,2])
assert_raise(WIN32OLE::RuntimeError) {
obj.value = [3,4]
}
obj = WIN32OLE::Variant.new("2007/01/01", WIN32OLE::VARIANT::VT_DATE)
assert_raise(WIN32OLE::RuntimeError) {
obj.value = "hogehoge"
}
assert_equal(Time.new(2007,1,1), obj.value)
obj2 = WIN32OLE::Variant.new("2006/01/01", WIN32OLE::VARIANT::VT_DATE)
obj.value = obj2
assert_equal(Time.new(2006,01,01), obj.value)
end
def test_c_nothing
assert_nil(WIN32OLE::Variant::Nothing.value)
end
def test_c_empty
assert_nil(WIN32OLE::Variant::Empty.value)
end
def test_c_null
assert_nil(WIN32OLE::Variant::Null.value)
end
def test_c_noparam
# DISP_E_PARAMNOTFOUND
assert_equal(-2147352572, WIN32OLE::Variant::NoParam.value)
end
def test_vt_error_noparam
v = WIN32OLE::Variant.new(-1, WIN32OLE::VARIANT::VT_ERROR)
assert_equal(-1, v.value)
fso = WIN32OLE.new("Scripting.FileSystemObject")
exc = assert_raise(WIN32OLE::RuntimeError) {
fso.openTextFile("NonExistingFile", v, false)
}
assert_match(/Type mismatch/i, exc.message)
exc = assert_raise(WIN32OLE::RuntimeError) {
fso.openTextFile("NonExistingFile", WIN32OLE::Variant::NoParam, false)
}
# 800A0035 is 'file not found' error.
assert_match(/800A0035/, exc.message)
# -2147352572 is DISP_E_PARAMNOTFOUND
v = WIN32OLE::Variant.new(-2147352572, WIN32OLE::VARIANT::VT_ERROR)
exc = assert_raise(WIN32OLE::RuntimeError) {
fso.openTextFile("NonExistingFile", WIN32OLE::Variant::NoParam, false)
}
# 800A0035 is 'file not found' error code.
assert_match(/800A0035/, exc.message)
end
end
end

View File

@ -1,37 +0,0 @@
# frozen_string_literal: false
begin
require 'win32ole'
rescue LoadError
end
require "test/unit"
if defined?(WIN32OLE::VARIANT)
class TestWin32OLE_VARIANT_MODULE < Test::Unit::TestCase
include WIN32OLE::VARIANT
def test_variant
assert_equal(0, VT_EMPTY)
assert_equal(1, VT_NULL)
assert_equal(2, VT_I2)
assert_equal(3, VT_I4)
assert_equal(4, VT_R4)
assert_equal(5, VT_R8)
assert_equal(6, VT_CY)
assert_equal(7, VT_DATE)
assert_equal(8, VT_BSTR)
assert_equal(9, VT_DISPATCH)
assert_equal(10, VT_ERROR)
assert_equal(11, VT_BOOL)
assert_equal(12, VT_VARIANT)
assert_equal(13, VT_UNKNOWN)
assert_equal(16, VT_I1)
assert_equal(17, VT_UI1)
assert_equal(18, VT_UI2)
assert_equal(19, VT_UI4)
assert_equal(22, VT_INT)
assert_equal(23, VT_UINT)
assert_equal(0x2000, VT_ARRAY)
assert_equal(0x4000, VT_BYREF)
end
end
end

View File

@ -1,69 +0,0 @@
# frozen_string_literal: false
begin
require 'win32ole'
rescue LoadError
end
require 'test/unit'
require 'fileutils'
def ado_csv_installed?
installed = false
if defined?(WIN32OLE)
db = nil
begin
db = WIN32OLE.new('ADODB.Connection')
db.connectionString = "Driver={Microsoft Text Driver (*.txt; *.csv)};DefaultDir=.;"
db.open
db.close
db = nil
installed = true
rescue
end
end
installed
end
if defined?(WIN32OLE::Variant)
class TestWIN32OLE_VARIANT_OUTARG < Test::Unit::TestCase
module ADO
end
CONNSTR="Driver={Microsoft Text Driver (*.txt; *.csv)};DefaultDir=.;"
def setup
return if !ado_csv_installed?
FileUtils.cp(File.dirname(__FILE__) + '/orig_data.csv', './data.csv')
@db = WIN32OLE.new('ADODB.Connection')
if !defined?(ADO::AdStateOpen)
WIN32OLE.const_load(@db, ADO)
end
@db.connectionString = CONNSTR
@db.open
end
def test_variant_ref_and_argv
if !ado_csv_installed?
omit("ActiveX Data Object Library not found")
end
sql = "INSERT INTO data.csv VALUES (5, 'E')"
@db.execute(sql, -1)
c = WIN32OLE::ARGV[1]
assert_equal(1, c)
obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(nil, obj.value)
@db.execute(sql , obj)
assert_equal(1, obj.value)
obj = WIN32OLE::Variant.new(-100, WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(-100, obj.value)
@db.execute(sql, obj)
assert_equal(1, obj.value)
end
def teardown
return if !ado_csv_installed?
if @db && @db.state == ADO::AdStateOpen
@db.close
end
File.unlink("data.csv")
end
end
end

View File

@ -1,73 +0,0 @@
# frozen_string_literal: false
#
# This is test for [ruby-Bugs#3237]
#
begin
require 'win32ole'
rescue LoadError
end
require "test/unit"
if defined?(WIN32OLE)
module Word; end
end
def word_installed?
installed = false
w = nil
if defined?(WIN32OLE)
begin
w = WIN32OLE.new('Word.Application')
WIN32OLE.const_load(w, Word)
installed = true
rescue
ensure
if w
w.quit(Word::WdDoNotSaveChanges)
w = nil
end
end
end
return installed
end
if defined?(WIN32OLE)
class TestWIN32OLE_WITH_WORD < Test::Unit::TestCase
unless word_installed?
def test_dummy_for_skip_message
omit "Microsoft Word is not installed"
end
else
def setup
begin
@obj = WIN32OLE.new('Word.Application')
rescue WIN32OLE::RuntimeError
@obj = nil
end
end
def test_ole_methods
if @obj
@obj.visible = true
@obj.wordbasic.disableAutoMacros(true)
assert(true)
end
end
def test_s_connect
if @obj
obj2 = WIN32OLE.connect("Word.Application")
assert_instance_of(WIN32OLE, obj2)
obj2.visible = true
end
end
def teardown
if @obj
@obj.quit(Word::WdDoNotSaveChanges)
@obj = nil
end
end
end
end
end