summaryrefslogtreecommitdiff
path: root/jni/ruby/ext/win32ole
diff options
context:
space:
mode:
Diffstat (limited to 'jni/ruby/ext/win32ole')
-rw-r--r--jni/ruby/ext/win32ole/Makefile150
-rw-r--r--jni/ruby/ext/win32ole/depend12
-rw-r--r--jni/ruby/ext/win32ole/extconf.rb44
-rw-r--r--jni/ruby/ext/win32ole/lib/win32ole/property.rb16
-rw-r--r--jni/ruby/ext/win32ole/sample/excel1.rb36
-rw-r--r--jni/ruby/ext/win32ole/sample/excel2.rb30
-rw-r--r--jni/ruby/ext/win32ole/sample/excel3.rb20
-rw-r--r--jni/ruby/ext/win32ole/sample/ie.rb11
-rw-r--r--jni/ruby/ext/win32ole/sample/ieconst.rb32
-rw-r--r--jni/ruby/ext/win32ole/sample/ienavi.rb40
-rw-r--r--jni/ruby/ext/win32ole/sample/ienavi2.rb40
-rw-r--r--jni/ruby/ext/win32ole/sample/oledirs.rb23
-rw-r--r--jni/ruby/ext/win32ole/sample/olegen.rb347
-rw-r--r--jni/ruby/ext/win32ole/sample/xml.rb7306
-rw-r--r--jni/ruby/ext/win32ole/win32ole.c4073
-rw-r--r--jni/ruby/ext/win32ole/win32ole.h155
-rw-r--r--jni/ruby/ext/win32ole/win32ole_error.c83
-rw-r--r--jni/ruby/ext/win32ole/win32ole_error.h8
-rw-r--r--jni/ruby/ext/win32ole/win32ole_event.c1275
-rw-r--r--jni/ruby/ext/win32ole/win32ole_event.h6
-rw-r--r--jni/ruby/ext/win32ole/win32ole_method.c950
-rw-r--r--jni/ruby/ext/win32ole/win32ole_method.h16
-rw-r--r--jni/ruby/ext/win32ole/win32ole_param.c438
-rw-r--r--jni/ruby/ext/win32ole/win32ole_param.h8
-rw-r--r--jni/ruby/ext/win32ole/win32ole_record.c604
-rw-r--r--jni/ruby/ext/win32ole/win32ole_record.h10
-rw-r--r--jni/ruby/ext/win32ole/win32ole_type.c915
-rw-r--r--jni/ruby/ext/win32ole/win32ole_type.h8
-rw-r--r--jni/ruby/ext/win32ole/win32ole_typelib.c846
-rw-r--r--jni/ruby/ext/win32ole/win32ole_typelib.h11
-rw-r--r--jni/ruby/ext/win32ole/win32ole_variable.c380
-rw-r--r--jni/ruby/ext/win32ole/win32ole_variable.h8
-rw-r--r--jni/ruby/ext/win32ole/win32ole_variant.c734
-rw-r--r--jni/ruby/ext/win32ole/win32ole_variant.h9
-rw-r--r--jni/ruby/ext/win32ole/win32ole_variant_m.c149
-rw-r--r--jni/ruby/ext/win32ole/win32ole_variant_m.h7
36 files changed, 18800 insertions, 0 deletions
diff --git a/jni/ruby/ext/win32ole/Makefile b/jni/ruby/ext/win32ole/Makefile
new file mode 100644
index 0000000..e4fe34e
--- /dev/null
+++ b/jni/ruby/ext/win32ole/Makefile
@@ -0,0 +1,150 @@
+# ***DUMMY MAKEFILE***
+
+SHELL = /bin/sh
+
+# V=0 quiet, V=1 verbose. other values don't work.
+V = 0
+Q1 = $(V:1=)
+Q = $(Q1:0=@)
+ECHO1 = $(V:1=@:)
+ECHO = $(ECHO1:0=@echo)
+NULLCMD = :
+
+#### Start of system configuration section. ####
+top_srcdir = $(topdir)/.
+srcdir = $(top_srcdir)/ext/win32ole
+topdir = ../..
+hdrdir = $(top_srcdir)/include
+arch_hdrdir = $(extout)/include/$(arch)
+PATH_SEPARATOR = :
+VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
+RUBYLIB =
+RUBYOPT = -
+prefix = $(DESTDIR)/usr/local
+rubysitearchprefix = $(rubylibprefix)/$(sitearch)
+rubyarchprefix = $(rubylibprefix)/$(arch)
+rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
+exec_prefix = $(prefix)
+vendorarchhdrdir = $(vendorhdrdir)/$(sitearch)
+sitearchhdrdir = $(sitehdrdir)/$(sitearch)
+rubyarchhdrdir = $(rubyhdrdir)/$(arch)
+vendorhdrdir = $(rubyhdrdir)/vendor_ruby
+sitehdrdir = $(rubyhdrdir)/site_ruby
+rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME)
+vendorarchdir = $(vendorlibdir)/$(sitearch)
+vendorlibdir = $(vendordir)/$(ruby_version)
+vendordir = $(rubylibprefix)/vendor_ruby
+sitearchdir = $(sitelibdir)/$(sitearch)
+sitelibdir = $(sitedir)/$(ruby_version)
+sitedir = $(rubylibprefix)/site_ruby
+rubyarchdir = $(rubylibdir)/$(arch)
+rubylibdir = $(rubylibprefix)/$(ruby_version)
+sitearchincludedir = $(includedir)/$(sitearch)
+archincludedir = $(includedir)/$(arch)
+sitearchlibdir = $(libdir)/$(sitearch)
+archlibdir = $(libdir)/$(arch)
+ridir = $(datarootdir)/$(RI_BASE_NAME)
+mandir = $(datarootdir)/man
+localedir = $(datarootdir)/locale
+libdir = $(exec_prefix)/lib
+psdir = $(docdir)
+pdfdir = $(docdir)
+dvidir = $(docdir)
+htmldir = $(docdir)
+infodir = $(datarootdir)/info
+docdir = $(datarootdir)/doc/$(PACKAGE)
+oldincludedir = $(DESTDIR)/usr/include
+includedir = $(prefix)/include
+localstatedir = $(prefix)/var
+sharedstatedir = $(prefix)/com
+sysconfdir = $(prefix)/etc
+datadir = $(datarootdir)
+datarootdir = $(prefix)/share
+libexecdir = $(exec_prefix)/libexec
+sbindir = $(exec_prefix)/sbin
+bindir = $(exec_prefix)/bin
+archdir = $(rubyarchdir)
+
+
+CC = gcc
+CXX = g++
+LIBRUBY = $(LIBRUBY_SO)
+LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
+LIBRUBYARG_SHARED = -Wl,-R$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)
+LIBRUBYARG_STATIC = -Wl,-R$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static
+empty =
+OUTFLAG = -o $(empty)
+COUTFLAG = -o $(empty)
+
+RUBY_EXTCONF_H =
+cflags = $(optflags) $(debugflags) $(warnflags)
+optflags = -O3 -fno-fast-math
+debugflags = -ggdb3
+warnflags = -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration -Wdeprecated-declarations -Wno-packed-bitfield-compat
+CCDLFLAGS = -fPIC
+CFLAGS = $(CCDLFLAGS) $(cflags) -fPIC $(ARCH_FLAG)
+INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir) -I$(srcdir)
+DEFS =
+CPPFLAGS = $(DEFS) $(cppflags)
+CXXFLAGS = $(CCDLFLAGS) $(cxxflags) $(ARCH_FLAG)
+ldflags = -L. -fstack-protector -rdynamic -Wl,-export-dynamic
+dldflags =
+ARCH_FLAG =
+DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
+LDSHARED = $(CC) -shared
+LDSHAREDXX = $(CXX) -shared
+AR = ar
+EXEEXT =
+
+RUBY_INSTALL_NAME = $(RUBY_BASE_NAME)
+RUBY_SO_NAME = ruby
+RUBYW_INSTALL_NAME =
+RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version)
+RUBYW_BASE_NAME = rubyw
+RUBY_BASE_NAME = ruby
+
+arch = x86_64-linux
+sitearch = $(arch)
+ruby_version = 2.2.0
+ruby = $(topdir)/miniruby -I'$(topdir)' -I'$(top_srcdir)/lib' -I'$(extout)/$(arch)' -I'$(extout)/common'
+RUBY = $(ruby)
+ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h
+
+RM = rm -f
+RM_RF = $(RUBY) -run -e rm -- -rf
+RMDIRS = rmdir --ignore-fail-on-non-empty -p
+MAKEDIRS = /bin/mkdir -p
+INSTALL = /usr/bin/install -c
+INSTALL_PROG = $(INSTALL) -m 0755
+INSTALL_DATA = $(INSTALL) -m 644
+COPY = cp
+TOUCH = exit >
+
+#### End of system configuration section. ####
+
+preload =
+CLEANFILES = mkmf.log
+DISTCLEANFILES =
+
+all install static install-so install-rb: Makefile
+.PHONY: all install static install-so install-rb
+.PHONY: clean clean-so clean-static clean-rb
+
+
+clean-static::
+clean-rb-default::
+clean-rb::
+clean-so::
+clean: clean-so clean-static clean-rb-default clean-rb
+ -$(Q)$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time
+
+distclean-rb-default::
+distclean-rb::
+distclean-so::
+distclean-static::
+distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
+ -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
+ -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
+ -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true
+
+realclean: distclean
diff --git a/jni/ruby/ext/win32ole/depend b/jni/ruby/ext/win32ole/depend
new file mode 100644
index 0000000..c8445ad
--- /dev/null
+++ b/jni/ruby/ext/win32ole/depend
@@ -0,0 +1,12 @@
+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)
diff --git a/jni/ruby/ext/win32ole/extconf.rb b/jni/ruby/ext/win32ole/extconf.rb
new file mode 100644
index 0000000..59da40b
--- /dev/null
+++ b/jni/ruby/ext/win32ole/extconf.rb
@@ -0,0 +1,44 @@
+#----------------------------------
+# extconf.rb
+# $Revision: 38867 $
+#----------------------------------
+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
+ 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
diff --git a/jni/ruby/ext/win32ole/lib/win32ole/property.rb b/jni/ruby/ext/win32ole/lib/win32ole/property.rb
new file mode 100644
index 0000000..a68bad9
--- /dev/null
+++ b/jni/ruby/ext/win32ole/lib/win32ole/property.rb
@@ -0,0 +1,16 @@
+# OLEProperty
+# helper class of Property with arguments.
+class OLEProperty
+ 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
+end
diff --git a/jni/ruby/ext/win32ole/sample/excel1.rb b/jni/ruby/ext/win32ole/sample/excel1.rb
new file mode 100644
index 0000000..7136c93
--- /dev/null
+++ b/jni/ruby/ext/win32ole/sample/excel1.rb
@@ -0,0 +1,36 @@
+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();
+
diff --git a/jni/ruby/ext/win32ole/sample/excel2.rb b/jni/ruby/ext/win32ole/sample/excel2.rb
new file mode 100644
index 0000000..6328826
--- /dev/null
+++ b/jni/ruby/ext/win32ole/sample/excel2.rb
@@ -0,0 +1,30 @@
+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();
diff --git a/jni/ruby/ext/win32ole/sample/excel3.rb b/jni/ruby/ext/win32ole/sample/excel3.rb
new file mode 100644
index 0000000..1ace478
--- /dev/null
+++ b/jni/ruby/ext/win32ole/sample/excel3.rb
@@ -0,0 +1,20 @@
+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();
+
diff --git a/jni/ruby/ext/win32ole/sample/ie.rb b/jni/ruby/ext/win32ole/sample/ie.rb
new file mode 100644
index 0000000..11dc861
--- /dev/null
+++ b/jni/ruby/ext/win32ole/sample/ie.rb
@@ -0,0 +1,11 @@
+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()
diff --git a/jni/ruby/ext/win32ole/sample/ieconst.rb b/jni/ruby/ext/win32ole/sample/ieconst.rb
new file mode 100644
index 0000000..2c6a7a3
--- /dev/null
+++ b/jni/ruby/ext/win32ole/sample/ieconst.rb
@@ -0,0 +1,32 @@
+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
+
diff --git a/jni/ruby/ext/win32ole/sample/ienavi.rb b/jni/ruby/ext/win32ole/sample/ienavi.rb
new file mode 100644
index 0000000..8b279dd
--- /dev/null
+++ b/jni/ruby/ext/win32ole/sample/ienavi.rb
@@ -0,0 +1,40 @@
+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
+
diff --git a/jni/ruby/ext/win32ole/sample/ienavi2.rb b/jni/ruby/ext/win32ole/sample/ienavi2.rb
new file mode 100644
index 0000000..67977e2
--- /dev/null
+++ b/jni/ruby/ext/win32ole/sample/ienavi2.rb
@@ -0,0 +1,40 @@
+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
diff --git a/jni/ruby/ext/win32ole/sample/oledirs.rb b/jni/ruby/ext/win32ole/sample/oledirs.rb
new file mode 100644
index 0000000..dbacc21
--- /dev/null
+++ b/jni/ruby/ext/win32ole/sample/oledirs.rb
@@ -0,0 +1,23 @@
+#
+# 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)
+
diff --git a/jni/ruby/ext/win32ole/sample/olegen.rb b/jni/ruby/ext/win32ole/sample/olegen.rb
new file mode 100644
index 0000000..17653e7
--- /dev/null
+++ b/jni/ruby/ext/win32ole/sample/olegen.rb
@@ -0,0 +1,347 @@
+#-----------------------------
+# olegen.rb
+# $Revision: 44134 $
+#-----------------------------
+
+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[-1] == ?|
+ 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
diff --git a/jni/ruby/ext/win32ole/sample/xml.rb b/jni/ruby/ext/win32ole/sample/xml.rb
new file mode 100644
index 0000000..4b1a54d
--- /dev/null
+++ b/jni/ruby/ext/win32ole/sample/xml.rb
@@ -0,0 +1,7306 @@
+#
+# This file created by olegen.rb as following.
+# ruby olegen.rb 'Microsoft XML, version 2.0' > xml.rb
+#
+require 'win32ole'
+require 'win32ole/property'
+
+#
+module IXMLDOMImplementation
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # BOOL hasFeature
+ # BSTR arg0 --- feature [IN]
+ # BSTR arg1 --- version [IN]
+ def hasFeature(arg0, arg1)
+ ret = _invoke(145, [arg0, arg1], [VT_BSTR, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+# Core DOM node interface
+module IXMLDOMNode
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = _getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = _getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = _getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = _getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = _getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = _getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = _getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = _getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = _getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = _getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = _getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = _getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = _getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = _getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = _getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = _getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = _getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = _getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = _getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = _getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = _getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = _getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = _setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = _setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = _setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = _setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = _invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = _invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = _invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = _invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+# Constants that define a node's type
+module OLEtagDOMNodeType
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+ NODE_INVALID = 0
+ NODE_ELEMENT = 1
+ NODE_ATTRIBUTE = 2
+ NODE_TEXT = 3
+ NODE_CDATA_SECTION = 4
+ NODE_ENTITY_REFERENCE = 5
+ NODE_ENTITY = 6
+ NODE_PROCESSING_INSTRUCTION = 7
+ NODE_COMMENT = 8
+ NODE_DOCUMENT = 9
+ NODE_DOCUMENT_TYPE = 10
+ NODE_DOCUMENT_FRAGMENT = 11
+ NODE_NOTATION = 12
+end
+
+#
+module IXMLDOMNodeList
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # I4 length
+ # number of nodes in the collection
+ def length()
+ ret = _getproperty(74, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # PTR item
+ # collection of nodes
+ # I4 arg0 --- index [IN]
+ def item
+ OLEProperty.new(self, 0, [VT_I4], [VT_I4, VT_BYREF|VT_DISPATCH])
+ end
+
+ # IXMLDOMNode nextNode
+ # get next node from iterator
+ def nextNode()
+ ret = _invoke(76, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID reset
+ # reset the position of iterator
+ def reset()
+ ret = _invoke(77, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+#
+module IXMLDOMNamedNodeMap
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # I4 length
+ # number of nodes in the collection
+ def length()
+ ret = _getproperty(74, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # PTR item
+ # collection of nodes
+ # I4 arg0 --- index [IN]
+ def item
+ OLEProperty.new(self, 0, [VT_I4], [VT_I4, VT_BYREF|VT_DISPATCH])
+ end
+
+ # IXMLDOMNode getNamedItem
+ # lookup item by name
+ # BSTR arg0 --- name [IN]
+ def getNamedItem(arg0)
+ ret = _invoke(83, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode setNamedItem
+ # set item by name
+ # IXMLDOMNode arg0 --- newItem [IN]
+ def setNamedItem(arg0)
+ ret = _invoke(84, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeNamedItem
+ # remove item by name
+ # BSTR arg0 --- name [IN]
+ def removeNamedItem(arg0)
+ ret = _invoke(85, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode getQualifiedItem
+ # lookup the item by name and namespace
+ # BSTR arg0 --- baseName [IN]
+ # BSTR arg1 --- namespaceURI [IN]
+ def getQualifiedItem(arg0, arg1)
+ ret = _invoke(87, [arg0, arg1], [VT_BSTR, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeQualifiedItem
+ # remove the item by name and namespace
+ # BSTR arg0 --- baseName [IN]
+ # BSTR arg1 --- namespaceURI [IN]
+ def removeQualifiedItem(arg0, arg1)
+ ret = _invoke(88, [arg0, arg1], [VT_BSTR, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextNode
+ # get next node from iterator
+ def nextNode()
+ ret = _invoke(89, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID reset
+ # reset the position of iterator
+ def reset()
+ ret = _invoke(90, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+#
+module IXMLDOMDocument
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = _getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = _getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = _getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = _getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = _getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = _getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = _getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = _getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = _getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = _getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = _getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = _getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = _getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = _getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = _getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = _getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = _getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = _getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = _getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = _getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = _getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = _getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocumentType doctype
+ # node corresponding to the DOCTYPE
+ def doctype()
+ ret = _getproperty(38, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMImplementation implementation
+ # info on this DOM implementation
+ def implementation()
+ ret = _getproperty(39, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMElement documentElement
+ # the root of the tree
+ def documentElement()
+ ret = _getproperty(40, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 readyState
+ # get the state of the XML document
+ def readyState()
+ ret = _getproperty(-525, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMParseError parseError
+ # get the last parser error
+ def parseError()
+ ret = _getproperty(59, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR url
+ # get the URL for the loaded XML document
+ def url()
+ ret = _getproperty(60, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL async
+ # flag for asynchronous download
+ def async()
+ ret = _getproperty(61, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL validateOnParse
+ # indicates whether the parser performs validation
+ def validateOnParse()
+ ret = _getproperty(65, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL resolveExternals
+ # indicates whether the parser resolves references to external DTD/Entities/Schema
+ def resolveExternals()
+ ret = _getproperty(66, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL preserveWhiteSpace
+ # indicates whether the parser preserves whitespace
+ def preserveWhiteSpace()
+ ret = _getproperty(67, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = _setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = _setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = _setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = _setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID async
+ # flag for asynchronous download
+ def async=(arg0)
+ ret = _setproperty(61, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID validateOnParse
+ # indicates whether the parser performs validation
+ def validateOnParse=(arg0)
+ ret = _setproperty(65, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID resolveExternals
+ # indicates whether the parser resolves references to external DTD/Entities/Schema
+ def resolveExternals=(arg0)
+ ret = _setproperty(66, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID preserveWhiteSpace
+ # indicates whether the parser preserves whitespace
+ def preserveWhiteSpace=(arg0)
+ ret = _setproperty(67, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID onreadystatechange
+ # register a readystatechange event handler
+ def onreadystatechange=(arg0)
+ ret = _setproperty(68, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID ondataavailable
+ # register an ondataavailable event handler
+ def ondataavailable=(arg0)
+ ret = _setproperty(69, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID ontransformnode
+ # register an ontransformnode event handler
+ def ontransformnode=(arg0)
+ ret = _setproperty(70, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = _invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = _invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = _invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = _invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMElement createElement
+ # create an Element node
+ # BSTR arg0 --- tagName [IN]
+ def createElement(arg0)
+ ret = _invoke(41, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocumentFragment createDocumentFragment
+ # create a DocumentFragment node
+ def createDocumentFragment()
+ ret = _invoke(42, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMText createTextNode
+ # create a text node
+ # BSTR arg0 --- data [IN]
+ def createTextNode(arg0)
+ ret = _invoke(43, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMComment createComment
+ # create a comment node
+ # BSTR arg0 --- data [IN]
+ def createComment(arg0)
+ ret = _invoke(44, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMCDATASection createCDATASection
+ # create a CDATA section node
+ # BSTR arg0 --- data [IN]
+ def createCDATASection(arg0)
+ ret = _invoke(45, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMProcessingInstruction createProcessingInstruction
+ # create a processing instruction node
+ # BSTR arg0 --- target [IN]
+ # BSTR arg1 --- data [IN]
+ def createProcessingInstruction(arg0, arg1)
+ ret = _invoke(46, [arg0, arg1], [VT_BSTR, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMAttribute createAttribute
+ # create an attribute node
+ # BSTR arg0 --- name [IN]
+ def createAttribute(arg0)
+ ret = _invoke(47, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMEntityReference createEntityReference
+ # create an entity reference node
+ # BSTR arg0 --- name [IN]
+ def createEntityReference(arg0)
+ ret = _invoke(49, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList getElementsByTagName
+ # build a list of elements by name
+ # BSTR arg0 --- tagName [IN]
+ def getElementsByTagName(arg0)
+ ret = _invoke(50, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode createNode
+ # create a node of the specified node type and name
+ # VARIANT arg0 --- type [IN]
+ # BSTR arg1 --- name [IN]
+ # BSTR arg2 --- namespaceURI [IN]
+ def createNode(arg0, arg1, arg2)
+ ret = _invoke(54, [arg0, arg1, arg2], [VT_VARIANT, VT_BSTR, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nodeFromID
+ # retrieve node from it's ID
+ # BSTR arg0 --- idString [IN]
+ def nodeFromID(arg0)
+ ret = _invoke(56, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL load
+ # load document from the specified XML source
+ # VARIANT arg0 --- xmlSource [IN]
+ def load(arg0)
+ ret = _invoke(58, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID abort
+ # abort an asynchronous download
+ def abort()
+ ret = _invoke(62, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL loadXML
+ # load the document from a string
+ # BSTR arg0 --- bstrXML [IN]
+ def loadXML(arg0)
+ ret = _invoke(63, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID save
+ # save the document to a specified desination
+ # VARIANT arg0 --- desination [IN]
+ def save(arg0)
+ ret = _invoke(64, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+#
+module IXMLDOMDocumentType
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = _getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = _getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = _getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = _getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = _getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = _getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = _getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = _getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = _getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = _getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = _getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = _getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = _getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = _getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = _getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = _getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = _getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = _getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = _getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = _getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = _getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = _getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR name
+ # name of the document type (root of the tree)
+ def name()
+ ret = _getproperty(131, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap entities
+ # a list of entities in the document
+ def entities()
+ ret = _getproperty(132, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap notations
+ # a list of notations in the document
+ def notations()
+ ret = _getproperty(133, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = _setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = _setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = _setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = _setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = _invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = _invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = _invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = _invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+#
+module IXMLDOMElement
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = _getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = _getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = _getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = _getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = _getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = _getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = _getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = _getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = _getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = _getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = _getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = _getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = _getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = _getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = _getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = _getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = _getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = _getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = _getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = _getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = _getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = _getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR tagName
+ # get the tagName of the element
+ def tagName()
+ ret = _getproperty(97, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = _setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = _setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = _setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = _setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = _invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = _invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = _invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = _invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT getAttribute
+ # look up the string value of an attribute by name
+ # BSTR arg0 --- name [IN]
+ def getAttribute(arg0)
+ ret = _invoke(99, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID setAttribute
+ # set the string value of an attribute by name
+ # BSTR arg0 --- name [IN]
+ # VARIANT arg1 --- value [IN]
+ def setAttribute(arg0, arg1)
+ ret = _invoke(100, [arg0, arg1], [VT_BSTR, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID removeAttribute
+ # remove an attribute by name
+ # BSTR arg0 --- name [IN]
+ def removeAttribute(arg0)
+ ret = _invoke(101, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMAttribute getAttributeNode
+ # look up the attribute node by name
+ # BSTR arg0 --- name [IN]
+ def getAttributeNode(arg0)
+ ret = _invoke(102, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMAttribute setAttributeNode
+ # set the specified attribute on the element
+ # IXMLDOMAttribute arg0 --- DOMAttribute [IN]
+ def setAttributeNode(arg0)
+ ret = _invoke(103, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMAttribute removeAttributeNode
+ # remove the specified attribute
+ # IXMLDOMAttribute arg0 --- DOMAttribute [IN]
+ def removeAttributeNode(arg0)
+ ret = _invoke(104, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList getElementsByTagName
+ # build a list of elements by name
+ # BSTR arg0 --- tagName [IN]
+ def getElementsByTagName(arg0)
+ ret = _invoke(105, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID normalize
+ # collapse all adjacent text nodes in sub-tree
+ def normalize()
+ ret = _invoke(106, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+#
+module IXMLDOMAttribute
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = _getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = _getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = _getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = _getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = _getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = _getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = _getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = _getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = _getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = _getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = _getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = _getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = _getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = _getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = _getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = _getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = _getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = _getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = _getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = _getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = _getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = _getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR name
+ # get name of the attribute
+ def name()
+ ret = _getproperty(118, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT value
+ # string value of the attribute
+ def value()
+ ret = _getproperty(120, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = _setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = _setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = _setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = _setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID value
+ # string value of the attribute
+ def value=(arg0)
+ ret = _setproperty(120, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = _invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = _invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = _invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = _invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+#
+module IXMLDOMDocumentFragment
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = _getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = _getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = _getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = _getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = _getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = _getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = _getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = _getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = _getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = _getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = _getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = _getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = _getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = _getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = _getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = _getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = _getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = _getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = _getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = _getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = _getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = _getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = _setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = _setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = _setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = _setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = _invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = _invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = _invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = _invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+#
+module IXMLDOMText
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = _getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = _getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = _getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = _getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = _getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = _getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = _getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = _getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = _getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = _getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = _getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = _getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = _getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = _getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = _getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = _getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = _getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = _getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = _getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = _getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = _getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = _getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR data
+ # value of the node
+ def data()
+ ret = _getproperty(109, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 length
+ # number of characters in value
+ def length()
+ ret = _getproperty(110, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = _setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = _setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = _setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = _setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID data
+ # value of the node
+ def data=(arg0)
+ ret = _setproperty(109, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = _invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = _invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = _invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = _invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR substringData
+ # retrieve substring of value
+ # I4 arg0 --- offset [IN]
+ # I4 arg1 --- count [IN]
+ def substringData(arg0, arg1)
+ ret = _invoke(111, [arg0, arg1], [VT_I4, VT_I4])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID appendData
+ # append string to value
+ # BSTR arg0 --- data [IN]
+ def appendData(arg0)
+ ret = _invoke(112, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID insertData
+ # insert string into value
+ # I4 arg0 --- offset [IN]
+ # BSTR arg1 --- data [IN]
+ def insertData(arg0, arg1)
+ ret = _invoke(113, [arg0, arg1], [VT_I4, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID deleteData
+ # delete string within the value
+ # I4 arg0 --- offset [IN]
+ # I4 arg1 --- count [IN]
+ def deleteData(arg0, arg1)
+ ret = _invoke(114, [arg0, arg1], [VT_I4, VT_I4])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID replaceData
+ # replace string within the value
+ # I4 arg0 --- offset [IN]
+ # I4 arg1 --- count [IN]
+ # BSTR arg2 --- data [IN]
+ def replaceData(arg0, arg1, arg2)
+ ret = _invoke(115, [arg0, arg1, arg2], [VT_I4, VT_I4, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMText splitText
+ # split the text node into two text nodes at the position specified
+ # I4 arg0 --- offset [IN]
+ def splitText(arg0)
+ ret = _invoke(123, [arg0], [VT_I4])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+#
+module IXMLDOMCharacterData
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = _getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = _getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = _getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = _getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = _getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = _getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = _getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = _getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = _getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = _getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = _getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = _getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = _getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = _getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = _getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = _getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = _getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = _getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = _getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = _getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = _getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = _getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR data
+ # value of the node
+ def data()
+ ret = _getproperty(109, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 length
+ # number of characters in value
+ def length()
+ ret = _getproperty(110, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = _setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = _setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = _setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = _setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID data
+ # value of the node
+ def data=(arg0)
+ ret = _setproperty(109, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = _invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = _invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = _invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = _invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR substringData
+ # retrieve substring of value
+ # I4 arg0 --- offset [IN]
+ # I4 arg1 --- count [IN]
+ def substringData(arg0, arg1)
+ ret = _invoke(111, [arg0, arg1], [VT_I4, VT_I4])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID appendData
+ # append string to value
+ # BSTR arg0 --- data [IN]
+ def appendData(arg0)
+ ret = _invoke(112, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID insertData
+ # insert string into value
+ # I4 arg0 --- offset [IN]
+ # BSTR arg1 --- data [IN]
+ def insertData(arg0, arg1)
+ ret = _invoke(113, [arg0, arg1], [VT_I4, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID deleteData
+ # delete string within the value
+ # I4 arg0 --- offset [IN]
+ # I4 arg1 --- count [IN]
+ def deleteData(arg0, arg1)
+ ret = _invoke(114, [arg0, arg1], [VT_I4, VT_I4])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID replaceData
+ # replace string within the value
+ # I4 arg0 --- offset [IN]
+ # I4 arg1 --- count [IN]
+ # BSTR arg2 --- data [IN]
+ def replaceData(arg0, arg1, arg2)
+ ret = _invoke(115, [arg0, arg1, arg2], [VT_I4, VT_I4, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+#
+module IXMLDOMComment
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = _getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = _getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = _getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = _getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = _getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = _getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = _getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = _getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = _getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = _getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = _getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = _getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = _getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = _getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = _getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = _getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = _getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = _getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = _getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = _getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = _getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = _getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR data
+ # value of the node
+ def data()
+ ret = _getproperty(109, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 length
+ # number of characters in value
+ def length()
+ ret = _getproperty(110, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = _setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = _setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = _setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = _setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID data
+ # value of the node
+ def data=(arg0)
+ ret = _setproperty(109, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = _invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = _invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = _invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = _invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR substringData
+ # retrieve substring of value
+ # I4 arg0 --- offset [IN]
+ # I4 arg1 --- count [IN]
+ def substringData(arg0, arg1)
+ ret = _invoke(111, [arg0, arg1], [VT_I4, VT_I4])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID appendData
+ # append string to value
+ # BSTR arg0 --- data [IN]
+ def appendData(arg0)
+ ret = _invoke(112, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID insertData
+ # insert string into value
+ # I4 arg0 --- offset [IN]
+ # BSTR arg1 --- data [IN]
+ def insertData(arg0, arg1)
+ ret = _invoke(113, [arg0, arg1], [VT_I4, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID deleteData
+ # delete string within the value
+ # I4 arg0 --- offset [IN]
+ # I4 arg1 --- count [IN]
+ def deleteData(arg0, arg1)
+ ret = _invoke(114, [arg0, arg1], [VT_I4, VT_I4])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID replaceData
+ # replace string within the value
+ # I4 arg0 --- offset [IN]
+ # I4 arg1 --- count [IN]
+ # BSTR arg2 --- data [IN]
+ def replaceData(arg0, arg1, arg2)
+ ret = _invoke(115, [arg0, arg1, arg2], [VT_I4, VT_I4, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+#
+module IXMLDOMCDATASection
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = _getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = _getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = _getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = _getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = _getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = _getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = _getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = _getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = _getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = _getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = _getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = _getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = _getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = _getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = _getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = _getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = _getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = _getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = _getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = _getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = _getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = _getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR data
+ # value of the node
+ def data()
+ ret = _getproperty(109, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 length
+ # number of characters in value
+ def length()
+ ret = _getproperty(110, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = _setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = _setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = _setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = _setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID data
+ # value of the node
+ def data=(arg0)
+ ret = _setproperty(109, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = _invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = _invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = _invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = _invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR substringData
+ # retrieve substring of value
+ # I4 arg0 --- offset [IN]
+ # I4 arg1 --- count [IN]
+ def substringData(arg0, arg1)
+ ret = _invoke(111, [arg0, arg1], [VT_I4, VT_I4])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID appendData
+ # append string to value
+ # BSTR arg0 --- data [IN]
+ def appendData(arg0)
+ ret = _invoke(112, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID insertData
+ # insert string into value
+ # I4 arg0 --- offset [IN]
+ # BSTR arg1 --- data [IN]
+ def insertData(arg0, arg1)
+ ret = _invoke(113, [arg0, arg1], [VT_I4, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID deleteData
+ # delete string within the value
+ # I4 arg0 --- offset [IN]
+ # I4 arg1 --- count [IN]
+ def deleteData(arg0, arg1)
+ ret = _invoke(114, [arg0, arg1], [VT_I4, VT_I4])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID replaceData
+ # replace string within the value
+ # I4 arg0 --- offset [IN]
+ # I4 arg1 --- count [IN]
+ # BSTR arg2 --- data [IN]
+ def replaceData(arg0, arg1, arg2)
+ ret = _invoke(115, [arg0, arg1, arg2], [VT_I4, VT_I4, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMText splitText
+ # split the text node into two text nodes at the position specified
+ # I4 arg0 --- offset [IN]
+ def splitText(arg0)
+ ret = _invoke(123, [arg0], [VT_I4])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+#
+module IXMLDOMProcessingInstruction
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = _getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = _getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = _getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = _getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = _getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = _getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = _getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = _getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = _getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = _getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = _getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = _getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = _getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = _getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = _getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = _getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = _getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = _getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = _getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = _getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = _getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = _getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR target
+ # the target
+ def target()
+ ret = _getproperty(127, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR data
+ # the data
+ def data()
+ ret = _getproperty(128, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = _setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = _setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = _setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = _setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID data
+ # the data
+ def data=(arg0)
+ ret = _setproperty(128, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = _invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = _invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = _invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = _invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+#
+module IXMLDOMEntityReference
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = _getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = _getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = _getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = _getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = _getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = _getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = _getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = _getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = _getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = _getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = _getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = _getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = _getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = _getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = _getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = _getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = _getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = _getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = _getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = _getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = _getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = _getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = _setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = _setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = _setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = _setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = _invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = _invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = _invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = _invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+# structure for reporting parser errors
+module IXMLDOMParseError
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # I4 errorCode
+ # the error code
+ def errorCode()
+ ret = _getproperty(0, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR url
+ # the URL of the XML document containing the error
+ def url()
+ ret = _getproperty(179, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR reason
+ # the cause of the error
+ def reason()
+ ret = _getproperty(180, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR srcText
+ # the data where the error occurred
+ def srcText()
+ ret = _getproperty(181, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 line
+ # the line number in the XML document where the error occurred
+ def line()
+ ret = _getproperty(182, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 linepos
+ # the character position in the line containing the error
+ def linepos()
+ ret = _getproperty(183, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 filepos
+ # the absolute file position in the XML document containing the error
+ def filepos()
+ ret = _getproperty(184, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+#
+module IXMLDOMNotation
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = _getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = _getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = _getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = _getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = _getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = _getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = _getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = _getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = _getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = _getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = _getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = _getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = _getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = _getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = _getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = _getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = _getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = _getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = _getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = _getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = _getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = _getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT publicId
+ # the public ID
+ def publicId()
+ ret = _getproperty(136, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT systemId
+ # the system ID
+ def systemId()
+ ret = _getproperty(137, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = _setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = _setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = _setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = _setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = _invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = _invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = _invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = _invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+#
+module IXMLDOMEntity
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = _getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = _getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = _getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = _getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = _getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = _getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = _getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = _getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = _getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = _getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = _getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = _getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = _getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = _getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = _getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = _getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = _getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = _getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = _getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = _getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = _getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = _getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT publicId
+ # the public ID
+ def publicId()
+ ret = _getproperty(140, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT systemId
+ # the system ID
+ def systemId()
+ ret = _getproperty(141, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR notationName
+ # the name of the notation
+ def notationName()
+ ret = _getproperty(142, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = _setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = _setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = _setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = _setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = _invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = _invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = _invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = _invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+# XTL runtime object
+module IXTLRuntime
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = _getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = _getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = _getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = _getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = _getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = _getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = _getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = _getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = _getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = _getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = _getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = _getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = _getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = _getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = _getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = _getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = _getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = _getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = _getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = _getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = _getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = _getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = _setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = _setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = _setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = _setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = _invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = _invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = _invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = _invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 uniqueID
+ # IXMLDOMNode arg0 --- pNode [IN]
+ def uniqueID(arg0)
+ ret = _invoke(187, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 depth
+ # IXMLDOMNode arg0 --- pNode [IN]
+ def depth(arg0)
+ ret = _invoke(188, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 childNumber
+ # IXMLDOMNode arg0 --- pNode [IN]
+ def childNumber(arg0)
+ ret = _invoke(189, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 ancestorChildNumber
+ # BSTR arg0 --- bstrNodeName [IN]
+ # IXMLDOMNode arg1 --- pNode [IN]
+ def ancestorChildNumber(arg0, arg1)
+ ret = _invoke(190, [arg0, arg1], [VT_BSTR, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 absoluteChildNumber
+ # IXMLDOMNode arg0 --- pNode [IN]
+ def absoluteChildNumber(arg0)
+ ret = _invoke(191, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR formatIndex
+ # I4 arg0 --- lIndex [IN]
+ # BSTR arg1 --- bstrFormat [IN]
+ def formatIndex(arg0, arg1)
+ ret = _invoke(192, [arg0, arg1], [VT_I4, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR formatNumber
+ # R8 arg0 --- dblNumber [IN]
+ # BSTR arg1 --- bstrFormat [IN]
+ def formatNumber(arg0, arg1)
+ ret = _invoke(193, [arg0, arg1], [VT_R8, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR formatDate
+ # VARIANT arg0 --- varDate [IN]
+ # BSTR arg1 --- bstrFormat [IN]
+ # VARIANT arg2 --- varDestLocale [IN]
+ def formatDate(arg0, arg1, arg2=nil)
+ ret = _invoke(194, [arg0, arg1, arg2], [VT_VARIANT, VT_BSTR, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR formatTime
+ # VARIANT arg0 --- varTime [IN]
+ # BSTR arg1 --- bstrFormat [IN]
+ # VARIANT arg2 --- varDestLocale [IN]
+ def formatTime(arg0, arg1, arg2=nil)
+ ret = _invoke(195, [arg0, arg1, arg2], [VT_VARIANT, VT_BSTR, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+# W3C-DOM XML Document
+class Microsoft_XMLDOM_1_0 # DOMDocument
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+ attr_reader :dispatch
+ attr_reader :clsid
+ attr_reader :progid
+
+ def initialize(obj = nil)
+ @clsid = "{2933BF90-7B36-11D2-B20E-00C04F983E60}"
+ @progid = "Microsoft.XMLDOM.1.0"
+ if obj.nil?
+ @dispatch = WIN32OLE.new(@progid)
+ else
+ @dispatch = obj
+ end
+ end
+
+ def method_missing(cmd, *arg)
+ @dispatch.method_missing(cmd, *arg)
+ end
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = @dispatch._getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = @dispatch._getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = @dispatch._getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = @dispatch._getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = @dispatch._getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = @dispatch._getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = @dispatch._getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = @dispatch._getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = @dispatch._getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = @dispatch._getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = @dispatch._getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = @dispatch._getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = @dispatch._getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = @dispatch._getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = @dispatch._getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = @dispatch._getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = @dispatch._getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = @dispatch._getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = @dispatch._getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = @dispatch._getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = @dispatch._getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = @dispatch._getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocumentType doctype
+ # node corresponding to the DOCTYPE
+ def doctype()
+ ret = @dispatch._getproperty(38, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMImplementation implementation
+ # info on this DOM implementation
+ def implementation()
+ ret = @dispatch._getproperty(39, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMElement documentElement
+ # the root of the tree
+ def documentElement()
+ ret = @dispatch._getproperty(40, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 readyState
+ # get the state of the XML document
+ def readyState()
+ ret = @dispatch._getproperty(-525, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMParseError parseError
+ # get the last parser error
+ def parseError()
+ ret = @dispatch._getproperty(59, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR url
+ # get the URL for the loaded XML document
+ def url()
+ ret = @dispatch._getproperty(60, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL async
+ # flag for asynchronous download
+ def async()
+ ret = @dispatch._getproperty(61, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL validateOnParse
+ # indicates whether the parser performs validation
+ def validateOnParse()
+ ret = @dispatch._getproperty(65, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL resolveExternals
+ # indicates whether the parser resolves references to external DTD/Entities/Schema
+ def resolveExternals()
+ ret = @dispatch._getproperty(66, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL preserveWhiteSpace
+ # indicates whether the parser preserves whitespace
+ def preserveWhiteSpace()
+ ret = @dispatch._getproperty(67, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = @dispatch._setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = @dispatch._setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = @dispatch._setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = @dispatch._setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID async
+ # flag for asynchronous download
+ def async=(arg0)
+ ret = @dispatch._setproperty(61, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID validateOnParse
+ # indicates whether the parser performs validation
+ def validateOnParse=(arg0)
+ ret = @dispatch._setproperty(65, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID resolveExternals
+ # indicates whether the parser resolves references to external DTD/Entities/Schema
+ def resolveExternals=(arg0)
+ ret = @dispatch._setproperty(66, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID preserveWhiteSpace
+ # indicates whether the parser preserves whitespace
+ def preserveWhiteSpace=(arg0)
+ ret = @dispatch._setproperty(67, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID onreadystatechange
+ # register a readystatechange event handler
+ def onreadystatechange=(arg0)
+ ret = @dispatch._setproperty(68, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID ondataavailable
+ # register an ondataavailable event handler
+ def ondataavailable=(arg0)
+ ret = @dispatch._setproperty(69, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID ontransformnode
+ # register an ontransformnode event handler
+ def ontransformnode=(arg0)
+ ret = @dispatch._setproperty(70, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = @dispatch._invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = @dispatch._invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = @dispatch._invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = @dispatch._invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = @dispatch._invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = @dispatch._invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = @dispatch._invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = @dispatch._invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = @dispatch._invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = @dispatch._invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMElement createElement
+ # create an Element node
+ # BSTR arg0 --- tagName [IN]
+ def createElement(arg0)
+ ret = @dispatch._invoke(41, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocumentFragment createDocumentFragment
+ # create a DocumentFragment node
+ def createDocumentFragment()
+ ret = @dispatch._invoke(42, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMText createTextNode
+ # create a text node
+ # BSTR arg0 --- data [IN]
+ def createTextNode(arg0)
+ ret = @dispatch._invoke(43, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMComment createComment
+ # create a comment node
+ # BSTR arg0 --- data [IN]
+ def createComment(arg0)
+ ret = @dispatch._invoke(44, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMCDATASection createCDATASection
+ # create a CDATA section node
+ # BSTR arg0 --- data [IN]
+ def createCDATASection(arg0)
+ ret = @dispatch._invoke(45, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMProcessingInstruction createProcessingInstruction
+ # create a processing instruction node
+ # BSTR arg0 --- target [IN]
+ # BSTR arg1 --- data [IN]
+ def createProcessingInstruction(arg0, arg1)
+ ret = @dispatch._invoke(46, [arg0, arg1], [VT_BSTR, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMAttribute createAttribute
+ # create an attribute node
+ # BSTR arg0 --- name [IN]
+ def createAttribute(arg0)
+ ret = @dispatch._invoke(47, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMEntityReference createEntityReference
+ # create an entity reference node
+ # BSTR arg0 --- name [IN]
+ def createEntityReference(arg0)
+ ret = @dispatch._invoke(49, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList getElementsByTagName
+ # build a list of elements by name
+ # BSTR arg0 --- tagName [IN]
+ def getElementsByTagName(arg0)
+ ret = @dispatch._invoke(50, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode createNode
+ # create a node of the specified node type and name
+ # VARIANT arg0 --- type [IN]
+ # BSTR arg1 --- name [IN]
+ # BSTR arg2 --- namespaceURI [IN]
+ def createNode(arg0, arg1, arg2)
+ ret = @dispatch._invoke(54, [arg0, arg1, arg2], [VT_VARIANT, VT_BSTR, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nodeFromID
+ # retrieve node from it's ID
+ # BSTR arg0 --- idString [IN]
+ def nodeFromID(arg0)
+ ret = @dispatch._invoke(56, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL load
+ # load document from the specified XML source
+ # VARIANT arg0 --- xmlSource [IN]
+ def load(arg0)
+ ret = @dispatch._invoke(58, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID abort
+ # abort an asynchronous download
+ def abort()
+ ret = @dispatch._invoke(62, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL loadXML
+ # load the document from a string
+ # BSTR arg0 --- bstrXML [IN]
+ def loadXML(arg0)
+ ret = @dispatch._invoke(63, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID save
+ # save the document to a specified desination
+ # VARIANT arg0 --- desination [IN]
+ def save(arg0)
+ ret = @dispatch._invoke(64, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # HRESULT ondataavailable EVENT in XMLDOMDocumentEvents
+ def ondataavailable()
+ ret = @dispatch._invoke(198, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # HRESULT onreadystatechange EVENT in XMLDOMDocumentEvents
+ def onreadystatechange()
+ ret = @dispatch._invoke(-609, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+# W3C-DOM XML Document (Apartment)
+class Microsoft_FreeThreadedXMLDOM_1_0 # DOMFreeThreadedDocument
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+ attr_reader :dispatch
+ attr_reader :clsid
+ attr_reader :progid
+
+ def initialize(obj = nil)
+ @clsid = "{2933BF91-7B36-11D2-B20E-00C04F983E60}"
+ @progid = "Microsoft.FreeThreadedXMLDOM.1.0"
+ if obj.nil?
+ @dispatch = WIN32OLE.new(@progid)
+ else
+ @dispatch = obj
+ end
+ end
+
+ def method_missing(cmd, *arg)
+ @dispatch.method_missing(cmd, *arg)
+ end
+
+ # BSTR nodeName
+ # name of the node
+ def nodeName()
+ ret = @dispatch._getproperty(2, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeValue
+ # value stored in the node
+ def nodeValue()
+ ret = @dispatch._getproperty(3, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DOMNodeType nodeType
+ # the node's type
+ def nodeType()
+ ret = @dispatch._getproperty(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode parentNode
+ # parent of the node
+ def parentNode()
+ ret = @dispatch._getproperty(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList childNodes
+ # the collection of the node's children
+ def childNodes()
+ ret = @dispatch._getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode firstChild
+ # first child of the node
+ def firstChild()
+ ret = @dispatch._getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode lastChild
+ # first child of the node
+ def lastChild()
+ ret = @dispatch._getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode previousSibling
+ # left sibling of the node
+ def previousSibling()
+ ret = @dispatch._getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nextSibling
+ # right sibling of the node
+ def nextSibling()
+ ret = @dispatch._getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNamedNodeMap attributes
+ # the collection of the node's attributes
+ def attributes()
+ ret = @dispatch._getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocument ownerDocument
+ # document that contains the node
+ def ownerDocument()
+ ret = @dispatch._getproperty(18, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR nodeTypeString
+ # the type of node in string form
+ def nodeTypeString()
+ ret = @dispatch._getproperty(21, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR text
+ # text content of the node and subtree
+ def text()
+ ret = @dispatch._getproperty(24, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL specified
+ # indicates whether node is a default value
+ def specified()
+ ret = @dispatch._getproperty(22, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode definition
+ # pointer to the definition of the node in the DTD or schema
+ def definition()
+ ret = @dispatch._getproperty(23, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue()
+ ret = @dispatch._getproperty(25, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT dataType
+ # the data type of the node
+ def dataType()
+ ret = @dispatch._getproperty(26, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR xml
+ # return the XML source for the node and each of its descendants
+ def xml()
+ ret = @dispatch._getproperty(27, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL parsed
+ # has sub-tree been completely parsed
+ def parsed()
+ ret = @dispatch._getproperty(31, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR namespaceURI
+ # the URI for the namespace applying to the node
+ def namespaceURI()
+ ret = @dispatch._getproperty(32, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR prefix
+ # the prefix for the namespace applying to the node
+ def prefix()
+ ret = @dispatch._getproperty(33, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR baseName
+ # the base name of the node (nodename with the prefix stripped off)
+ def baseName()
+ ret = @dispatch._getproperty(34, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocumentType doctype
+ # node corresponding to the DOCTYPE
+ def doctype()
+ ret = @dispatch._getproperty(38, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMImplementation implementation
+ # info on this DOM implementation
+ def implementation()
+ ret = @dispatch._getproperty(39, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMElement documentElement
+ # the root of the tree
+ def documentElement()
+ ret = @dispatch._getproperty(40, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 readyState
+ # get the state of the XML document
+ def readyState()
+ ret = @dispatch._getproperty(-525, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMParseError parseError
+ # get the last parser error
+ def parseError()
+ ret = @dispatch._getproperty(59, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR url
+ # get the URL for the loaded XML document
+ def url()
+ ret = @dispatch._getproperty(60, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL async
+ # flag for asynchronous download
+ def async()
+ ret = @dispatch._getproperty(61, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL validateOnParse
+ # indicates whether the parser performs validation
+ def validateOnParse()
+ ret = @dispatch._getproperty(65, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL resolveExternals
+ # indicates whether the parser resolves references to external DTD/Entities/Schema
+ def resolveExternals()
+ ret = @dispatch._getproperty(66, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL preserveWhiteSpace
+ # indicates whether the parser preserves whitespace
+ def preserveWhiteSpace()
+ ret = @dispatch._getproperty(67, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeValue
+ # value stored in the node
+ def nodeValue=(arg0)
+ ret = @dispatch._setproperty(3, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID text
+ # text content of the node and subtree
+ def text=(arg0)
+ ret = @dispatch._setproperty(24, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID nodeTypedValue
+ # get the strongly typed value of the node
+ def nodeTypedValue=(arg0)
+ ret = @dispatch._setproperty(25, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID dataType
+ # the data type of the node
+ def dataType=(arg0)
+ ret = @dispatch._setproperty(26, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID async
+ # flag for asynchronous download
+ def async=(arg0)
+ ret = @dispatch._setproperty(61, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID validateOnParse
+ # indicates whether the parser performs validation
+ def validateOnParse=(arg0)
+ ret = @dispatch._setproperty(65, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID resolveExternals
+ # indicates whether the parser resolves references to external DTD/Entities/Schema
+ def resolveExternals=(arg0)
+ ret = @dispatch._setproperty(66, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID preserveWhiteSpace
+ # indicates whether the parser preserves whitespace
+ def preserveWhiteSpace=(arg0)
+ ret = @dispatch._setproperty(67, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID onreadystatechange
+ # register a readystatechange event handler
+ def onreadystatechange=(arg0)
+ ret = @dispatch._setproperty(68, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID ondataavailable
+ # register an ondataavailable event handler
+ def ondataavailable=(arg0)
+ ret = @dispatch._setproperty(69, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID ontransformnode
+ # register an ontransformnode event handler
+ def ontransformnode=(arg0)
+ ret = @dispatch._setproperty(70, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode insertBefore
+ # insert a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # VARIANT arg1 --- refChild [IN]
+ def insertBefore(arg0, arg1)
+ ret = @dispatch._invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode replaceChild
+ # replace a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ # IXMLDOMNode arg1 --- oldChild [IN]
+ def replaceChild(arg0, arg1)
+ ret = @dispatch._invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode removeChild
+ # remove a child node
+ # IXMLDOMNode arg0 --- childNode [IN]
+ def removeChild(arg0)
+ ret = @dispatch._invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode appendChild
+ # append a child node
+ # IXMLDOMNode arg0 --- newChild [IN]
+ def appendChild(arg0)
+ ret = @dispatch._invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL hasChildNodes
+ def hasChildNodes()
+ ret = @dispatch._invoke(17, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode cloneNode
+ # BOOL arg0 --- deep [IN]
+ def cloneNode(arg0)
+ ret = @dispatch._invoke(19, [arg0], [VT_BOOL])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR transformNode
+ # apply the stylesheet to the subtree
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ def transformNode(arg0)
+ ret = @dispatch._invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList selectNodes
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectNodes(arg0)
+ ret = @dispatch._invoke(29, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode selectSingleNode
+ # execute query on the subtree
+ # BSTR arg0 --- queryString [IN]
+ def selectSingleNode(arg0)
+ ret = @dispatch._invoke(30, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID transformNodeToObject
+ # apply the stylesheet to the subtree, returning the result through a document or a stream
+ # IXMLDOMNode arg0 --- stylesheet [IN]
+ # VARIANT arg1 --- outputObject [IN]
+ def transformNodeToObject(arg0, arg1)
+ ret = @dispatch._invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMElement createElement
+ # create an Element node
+ # BSTR arg0 --- tagName [IN]
+ def createElement(arg0)
+ ret = @dispatch._invoke(41, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMDocumentFragment createDocumentFragment
+ # create a DocumentFragment node
+ def createDocumentFragment()
+ ret = @dispatch._invoke(42, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMText createTextNode
+ # create a text node
+ # BSTR arg0 --- data [IN]
+ def createTextNode(arg0)
+ ret = @dispatch._invoke(43, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMComment createComment
+ # create a comment node
+ # BSTR arg0 --- data [IN]
+ def createComment(arg0)
+ ret = @dispatch._invoke(44, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMCDATASection createCDATASection
+ # create a CDATA section node
+ # BSTR arg0 --- data [IN]
+ def createCDATASection(arg0)
+ ret = @dispatch._invoke(45, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMProcessingInstruction createProcessingInstruction
+ # create a processing instruction node
+ # BSTR arg0 --- target [IN]
+ # BSTR arg1 --- data [IN]
+ def createProcessingInstruction(arg0, arg1)
+ ret = @dispatch._invoke(46, [arg0, arg1], [VT_BSTR, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMAttribute createAttribute
+ # create an attribute node
+ # BSTR arg0 --- name [IN]
+ def createAttribute(arg0)
+ ret = @dispatch._invoke(47, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMEntityReference createEntityReference
+ # create an entity reference node
+ # BSTR arg0 --- name [IN]
+ def createEntityReference(arg0)
+ ret = @dispatch._invoke(49, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNodeList getElementsByTagName
+ # build a list of elements by name
+ # BSTR arg0 --- tagName [IN]
+ def getElementsByTagName(arg0)
+ ret = @dispatch._invoke(50, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode createNode
+ # create a node of the specified node type and name
+ # VARIANT arg0 --- type [IN]
+ # BSTR arg1 --- name [IN]
+ # BSTR arg2 --- namespaceURI [IN]
+ def createNode(arg0, arg1, arg2)
+ ret = @dispatch._invoke(54, [arg0, arg1, arg2], [VT_VARIANT, VT_BSTR, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # IXMLDOMNode nodeFromID
+ # retrieve node from it's ID
+ # BSTR arg0 --- idString [IN]
+ def nodeFromID(arg0)
+ ret = @dispatch._invoke(56, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL load
+ # load document from the specified XML source
+ # VARIANT arg0 --- xmlSource [IN]
+ def load(arg0)
+ ret = @dispatch._invoke(58, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID abort
+ # abort an asynchronous download
+ def abort()
+ ret = @dispatch._invoke(62, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BOOL loadXML
+ # load the document from a string
+ # BSTR arg0 --- bstrXML [IN]
+ def loadXML(arg0)
+ ret = @dispatch._invoke(63, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID save
+ # save the document to a specified desination
+ # VARIANT arg0 --- desination [IN]
+ def save(arg0)
+ ret = @dispatch._invoke(64, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # HRESULT ondataavailable EVENT in XMLDOMDocumentEvents
+ def ondataavailable()
+ ret = @dispatch._invoke(198, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # HRESULT onreadystatechange EVENT in XMLDOMDocumentEvents
+ def onreadystatechange()
+ ret = @dispatch._invoke(-609, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+# IXMLHttpRequest Interface
+module IXMLHttpRequest
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+
+ # I4 status
+ # Get HTTP status code
+ def status()
+ ret = _getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR statusText
+ # Get HTTP status text
+ def statusText()
+ ret = _getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DISPATCH responseXML
+ # Get response body
+ def responseXML()
+ ret = _getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR responseText
+ # Get response body
+ def responseText()
+ ret = _getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT responseBody
+ # Get response body
+ def responseBody()
+ ret = _getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT responseStream
+ # Get response body
+ def responseStream()
+ ret = _getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 readyState
+ # Get ready state
+ def readyState()
+ ret = _getproperty(13, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID onreadystatechange
+ # Register a complete event handler
+ def onreadystatechange=(arg0)
+ ret = _setproperty(14, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID open
+ # Open HTTP connection
+ # BSTR arg0 --- bstrMethod [IN]
+ # BSTR arg1 --- bstrUrl [IN]
+ # VARIANT arg2 --- varAsync [IN]
+ # VARIANT arg3 --- bstrUser [IN]
+ # VARIANT arg4 --- bstrPassword [IN]
+ def open(arg0, arg1, arg2=nil, arg3=nil, arg4=nil)
+ ret = _invoke(1, [arg0, arg1, arg2, arg3, arg4], [VT_BSTR, VT_BSTR, VT_VARIANT, VT_VARIANT, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID setRequestHeader
+ # Add HTTP request header
+ # BSTR arg0 --- bstrHeader [IN]
+ # BSTR arg1 --- bstrValue [IN]
+ def setRequestHeader(arg0, arg1)
+ ret = _invoke(2, [arg0, arg1], [VT_BSTR, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR getResponseHeader
+ # Get HTTP response header
+ # BSTR arg0 --- bstrHeader [IN]
+ def getResponseHeader(arg0)
+ ret = _invoke(3, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR getAllResponseHeaders
+ # Get all HTTP response headers
+ def getAllResponseHeaders()
+ ret = _invoke(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID send
+ # Send HTTP request
+ # VARIANT arg0 --- varBody [IN]
+ def send(arg0=nil)
+ ret = _invoke(5, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID abort
+ # Abort HTTP request
+ def abort()
+ ret = _invoke(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+# XML HTTP Request class.
+class Microsoft_XMLHTTP_1 # XMLHTTPRequest
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+ attr_reader :dispatch
+ attr_reader :clsid
+ attr_reader :progid
+
+ def initialize(obj = nil)
+ @clsid = "{ED8C108E-4349-11D2-91A4-00C04F7969E8}"
+ @progid = "Microsoft.XMLHTTP.1"
+ if obj.nil?
+ @dispatch = WIN32OLE.new(@progid)
+ else
+ @dispatch = obj
+ end
+ end
+
+ def method_missing(cmd, *arg)
+ @dispatch.method_missing(cmd, *arg)
+ end
+
+ # I4 status
+ # Get HTTP status code
+ def status()
+ ret = @dispatch._getproperty(7, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR statusText
+ # Get HTTP status text
+ def statusText()
+ ret = @dispatch._getproperty(8, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # DISPATCH responseXML
+ # Get response body
+ def responseXML()
+ ret = @dispatch._getproperty(9, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR responseText
+ # Get response body
+ def responseText()
+ ret = @dispatch._getproperty(10, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT responseBody
+ # Get response body
+ def responseBody()
+ ret = @dispatch._getproperty(11, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VARIANT responseStream
+ # Get response body
+ def responseStream()
+ ret = @dispatch._getproperty(12, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 readyState
+ # Get ready state
+ def readyState()
+ ret = @dispatch._getproperty(13, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID onreadystatechange
+ # Register a complete event handler
+ def onreadystatechange=(arg0)
+ ret = @dispatch._setproperty(14, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID open
+ # Open HTTP connection
+ # BSTR arg0 --- bstrMethod [IN]
+ # BSTR arg1 --- bstrUrl [IN]
+ # VARIANT arg2 --- varAsync [IN]
+ # VARIANT arg3 --- bstrUser [IN]
+ # VARIANT arg4 --- bstrPassword [IN]
+ def open(arg0, arg1, arg2=nil, arg3=nil, arg4=nil)
+ ret = @dispatch._invoke(1, [arg0, arg1, arg2, arg3, arg4], [VT_BSTR, VT_BSTR, VT_VARIANT, VT_VARIANT, VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID setRequestHeader
+ # Add HTTP request header
+ # BSTR arg0 --- bstrHeader [IN]
+ # BSTR arg1 --- bstrValue [IN]
+ def setRequestHeader(arg0, arg1)
+ ret = @dispatch._invoke(2, [arg0, arg1], [VT_BSTR, VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR getResponseHeader
+ # Get HTTP response header
+ # BSTR arg0 --- bstrHeader [IN]
+ def getResponseHeader(arg0)
+ ret = @dispatch._invoke(3, [arg0], [VT_BSTR])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # BSTR getAllResponseHeaders
+ # Get all HTTP response headers
+ def getAllResponseHeaders()
+ ret = @dispatch._invoke(4, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID send
+ # Send HTTP request
+ # VARIANT arg0 --- varBody [IN]
+ def send(arg0=nil)
+ ret = @dispatch._invoke(5, [arg0], [VT_VARIANT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID abort
+ # Abort HTTP request
+ def abort()
+ ret = @dispatch._invoke(6, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+# XML Data Source Object
+class Microsoft_XMLDSO_1_0 # XMLDSOControl
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+ attr_reader :dispatch
+ attr_reader :clsid
+ attr_reader :progid
+
+ def initialize(obj = nil)
+ @clsid = "{550DDA30-0541-11D2-9CA9-0060B0EC3D39}"
+ @progid = "Microsoft.XMLDSO.1.0"
+ if obj.nil?
+ @dispatch = WIN32OLE.new(@progid)
+ else
+ @dispatch = obj
+ end
+ end
+
+ def method_missing(cmd, *arg)
+ @dispatch.method_missing(cmd, *arg)
+ end
+
+ # IXMLDOMDocument XMLDocument
+ def XMLDocument()
+ ret = @dispatch._getproperty(65537, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 JavaDSOCompatible
+ def JavaDSOCompatible()
+ ret = @dispatch._getproperty(65538, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # I4 readyState
+ def readyState()
+ ret = @dispatch._getproperty(-525, [], [])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID XMLDocument
+ def XMLDocument=(arg0)
+ ret = @dispatch._setproperty(65537, [arg0], [VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # VOID JavaDSOCompatible
+ def JavaDSOCompatible=(arg0)
+ ret = @dispatch._setproperty(65538, [arg0], [VT_I4])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
+
+# Constants that define types for IXMLElement.
+module OLEtagXMLEMEM_TYPE
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+ XMLELEMTYPE_ELEMENT = 0
+ XMLELEMTYPE_TEXT = 1
+ XMLELEMTYPE_COMMENT = 2
+ XMLELEMTYPE_DOCUMENT = 3
+ XMLELEMTYPE_DTD = 4
+ XMLELEMTYPE_PI = 5
+ XMLELEMTYPE_OTHER = 6
+end
+
+# XMLDocument extends IXML Document. It is obsolete. You should use DOMDocument. This object should not be confused with the XMLDocument property on the XML data island.
+class Msxml # XMLDocument
+ include WIN32OLE::VARIANT
+ attr_reader :lastargs
+ attr_reader :dispatch
+ attr_reader :clsid
+ attr_reader :progid
+
+ def initialize(obj = nil)
+ @clsid = "{CFC399AF-D876-11D0-9C10-00C04FC99C8E}"
+ @progid = "Msxml"
+ if obj.nil?
+ @dispatch = WIN32OLE.new(@progid)
+ else
+ @dispatch = obj
+ end
+ end
+
+ def method_missing(cmd, *arg)
+ @dispatch.method_missing(cmd, *arg)
+ end
+
+ # HRESULT url
+ # set URL to load an XML document from the URL.
+ # BSTR arg0 --- p [IN]
+ def url=(arg0)
+ ret = @dispatch._setproperty(65641, [arg0], [VT_BSTR, VT_HRESULT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # HRESULT charset
+ # get encoding.
+ # BSTR arg0 --- p [IN]
+ def charset=(arg0)
+ ret = @dispatch._setproperty(65645, [arg0], [VT_BSTR, VT_HRESULT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # HRESULT async
+ # get asynchronous loading flag.
+ # BOOL arg0 --- pf [IN]
+ def async=(arg0)
+ ret = @dispatch._setproperty(65649, [arg0], [VT_BOOL, VT_HRESULT])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+
+ # HRESULT root
+ # get root IXMLElement of the XML document.
+ # IXMLElement2,IXMLElement2 arg0 --- p [OUT]
+ def root
+ OLEProperty.new(@dispatch, 65637, [VT_BYREF|VT_BYREF|VT_DISPATCH], [VT_BYREF|VT_BYREF|VT_DISPATCH, VT_HRESULT])
+ end
+
+ # HRESULT url
+ # set URL to load an XML document from the URL.
+ # BSTR arg0 --- p [OUT]
+ def url
+ OLEProperty.new(@dispatch, 65641, [VT_BYREF|VT_BSTR], [VT_BYREF|VT_BSTR, VT_HRESULT])
+ end
+
+ # HRESULT readyState
+ # get ready state.
+ # I4 arg0 --- pl [OUT]
+ def readyState
+ OLEProperty.new(@dispatch, 65643, [VT_BYREF|VT_I4], [VT_BYREF|VT_I4, VT_HRESULT])
+ end
+
+ # HRESULT charset
+ # get encoding.
+ # BSTR arg0 --- p [OUT]
+ def charset
+ OLEProperty.new(@dispatch, 65645, [VT_BYREF|VT_BSTR], [VT_BYREF|VT_BSTR, VT_HRESULT])
+ end
+
+ # HRESULT version
+ # get XML version number.
+ # BSTR arg0 --- p [OUT]
+ def version
+ OLEProperty.new(@dispatch, 65646, [VT_BYREF|VT_BSTR], [VT_BYREF|VT_BSTR, VT_HRESULT])
+ end
+
+ # HRESULT doctype
+ # get document type.
+ # BSTR arg0 --- p [OUT]
+ def doctype
+ OLEProperty.new(@dispatch, 65647, [VT_BYREF|VT_BSTR], [VT_BYREF|VT_BSTR, VT_HRESULT])
+ end
+
+ # HRESULT async
+ # get asynchronous loading flag.
+ # BOOL arg0 --- pf [OUT]
+ def async
+ OLEProperty.new(@dispatch, 65649, [VT_BYREF|VT_BOOL], [VT_BYREF|VT_BOOL, VT_HRESULT])
+ end
+
+ # HRESULT createElement
+ # create different types of IXMLElements.
+ # VARIANT arg0 --- vType [IN]
+ # VARIANT arg1 --- var1 [IN]
+ # IXMLElement2,IXMLElement2 arg2 --- ppElem [OUT]
+ def createElement(arg0, arg1=nil, arg2=nil)
+ ret = @dispatch._invoke(65644, [arg0, arg1, arg2], [VT_VARIANT, VT_VARIANT, VT_BYREF|VT_BYREF|VT_DISPATCH])
+ @lastargs = WIN32OLE::ARGV
+ ret
+ end
+end
diff --git a/jni/ruby/ext/win32ole/win32ole.c b/jni/ruby/ext/win32ole/win32ole.c
new file mode 100644
index 0000000..4d664e8
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole.c
@@ -0,0 +1,4073 @@
+/*
+ * (c) 1995 Microsoft Corporation. All rights reserved.
+ * Developed by ActiveWare Internet Corp., http://www.ActiveWare.com
+ *
+ * Other modifications Copyright (c) 1997, 1998 by Gurusamy Sarathy
+ * <gsar@umich.edu> and Jan Dubois <jan.dubois@ibm.net>
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file
+ * of the Perl distribution.
+ *
+ */
+
+/*
+ modified for win32ole (ruby) by Masaki.Suketa <masaki.suketa@nifty.ne.jp>
+ */
+
+#include "win32ole.h"
+
+/*
+ * unfortunately IID_IMultiLanguage2 is not included in any libXXX.a
+ * in Cygwin(mingw32).
+ */
+#if defined(__CYGWIN__) || defined(__MINGW32__)
+#undef IID_IMultiLanguage2
+const IID IID_IMultiLanguage2 = {0xDCCFC164, 0x2B38, 0x11d2, {0xB7, 0xEC, 0x00, 0xC0, 0x4F, 0x8F, 0x5D, 0x9A}};
+#endif
+
+#define WIN32OLE_VERSION "1.8.3"
+
+typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
+ (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
+
+typedef HWND (WINAPI FNHTMLHELP)(HWND hwndCaller, LPCSTR pszFile,
+ UINT uCommand, DWORD dwData);
+typedef BOOL (FNENUMSYSEMCODEPAGES) (CODEPAGE_ENUMPROC, DWORD);
+VALUE cWIN32OLE;
+
+#if defined(RB_THREAD_SPECIFIC) && (defined(__CYGWIN__) || defined(__MINGW32__))
+static RB_THREAD_SPECIFIC BOOL g_ole_initialized;
+# define g_ole_initialized_init() ((void)0)
+# define g_ole_initialized_set(val) (g_ole_initialized = (val))
+#else
+static volatile DWORD g_ole_initialized_key = TLS_OUT_OF_INDEXES;
+# define g_ole_initialized (BOOL)TlsGetValue(g_ole_initialized_key)
+# define g_ole_initialized_init() (g_ole_initialized_key = TlsAlloc())
+# define g_ole_initialized_set(val) TlsSetValue(g_ole_initialized_key, (void*)(val))
+#endif
+
+static BOOL g_uninitialize_hooked = FALSE;
+static BOOL g_cp_installed = FALSE;
+static BOOL g_lcid_installed = FALSE;
+static HINSTANCE ghhctrl = NULL;
+static HINSTANCE gole32 = NULL;
+static FNCOCREATEINSTANCEEX *gCoCreateInstanceEx = NULL;
+static VALUE com_hash;
+static IDispatchVtbl com_vtbl;
+static UINT cWIN32OLE_cp = CP_ACP;
+static rb_encoding *cWIN32OLE_enc;
+static UINT g_cp_to_check = CP_ACP;
+static char g_lcid_to_check[8 + 1];
+static VARTYPE g_nil_to = VT_ERROR;
+static st_table *enc2cp_table;
+static IMessageFilterVtbl message_filter;
+static IMessageFilter imessage_filter = { &message_filter };
+static IMessageFilter* previous_filter;
+
+#if defined(HAVE_TYPE_IMULTILANGUAGE2)
+static IMultiLanguage2 *pIMultiLanguage = NULL;
+#elif defined(HAVE_TYPE_IMULTILANGUAGE)
+static IMultiLanguage *pIMultiLanguage = NULL;
+#else
+#define pIMultiLanguage NULL /* dummy */
+#endif
+
+struct oleparam {
+ DISPPARAMS dp;
+ OLECHAR** pNamedArgs;
+};
+
+static HRESULT ( STDMETHODCALLTYPE QueryInterface )(IDispatch __RPC_FAR *, REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject);
+static ULONG ( STDMETHODCALLTYPE AddRef )(IDispatch __RPC_FAR * This);
+static ULONG ( STDMETHODCALLTYPE Release )(IDispatch __RPC_FAR * This);
+static HRESULT ( STDMETHODCALLTYPE GetTypeInfoCount )(IDispatch __RPC_FAR * This, UINT __RPC_FAR *pctinfo);
+static HRESULT ( STDMETHODCALLTYPE GetTypeInfo )(IDispatch __RPC_FAR * This, UINT iTInfo, LCID lcid, ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
+static HRESULT ( STDMETHODCALLTYPE GetIDsOfNames )(IDispatch __RPC_FAR * This, REFIID riid, LPOLESTR __RPC_FAR *rgszNames, UINT cNames, LCID lcid, DISPID __RPC_FAR *rgDispId);
+static HRESULT ( STDMETHODCALLTYPE Invoke )( IDispatch __RPC_FAR * This, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS __RPC_FAR *pDispParams, VARIANT __RPC_FAR *pVarResult, EXCEPINFO __RPC_FAR *pExcepInfo, UINT __RPC_FAR *puArgErr);
+static IDispatch* val2dispatch(VALUE val);
+static double rbtime2vtdate(VALUE tmobj);
+static VALUE vtdate2rbtime(double date);
+static rb_encoding *ole_cp2encoding(UINT cp);
+static UINT ole_encoding2cp(rb_encoding *enc);
+NORETURN(static void failed_load_conv51932(void));
+#ifndef pIMultiLanguage
+static void load_conv_function51932(void);
+#endif
+static UINT ole_init_cp(void);
+static void ole_freeexceptinfo(EXCEPINFO *pExInfo);
+static VALUE ole_excepinfo2msg(EXCEPINFO *pExInfo);
+static void ole_free(void *ptr);
+static size_t ole_size(const void *ptr);
+static LPWSTR ole_mb2wc(char *pm, int len);
+static VALUE ole_ary_m_entry(VALUE val, LONG *pid);
+static VALUE is_all_index_under(LONG *pid, long *pub, long dim);
+static void * get_ptr_of_variant(VARIANT *pvar);
+static void ole_set_safe_array(long n, SAFEARRAY *psa, LONG *pid, long *pub, VALUE val, long dim, VARTYPE vt);
+static long dimension(VALUE val);
+static long ary_len_of_dim(VALUE ary, long dim);
+static VALUE ole_set_member(VALUE self, IDispatch *dispatch);
+static VALUE fole_s_allocate(VALUE klass);
+static VALUE create_win32ole_object(VALUE klass, IDispatch *pDispatch, int argc, VALUE *argv);
+static VALUE ary_new_dim(VALUE myary, LONG *pid, LONG *plb, LONG dim);
+static void ary_store_dim(VALUE myary, LONG *pid, LONG *plb, LONG dim, VALUE val);
+static void ole_const_load(ITypeLib *pTypeLib, VALUE klass, VALUE self);
+static HRESULT clsid_from_remote(VALUE host, VALUE com, CLSID *pclsid);
+static VALUE ole_create_dcom(VALUE self, VALUE ole, VALUE host, VALUE others);
+static VALUE ole_bind_obj(VALUE moniker, int argc, VALUE *argv, VALUE self);
+static VALUE fole_s_connect(int argc, VALUE *argv, VALUE self);
+static VALUE fole_s_const_load(int argc, VALUE *argv, VALUE self);
+static ULONG reference_count(struct oledata * pole);
+static VALUE fole_s_reference_count(VALUE self, VALUE obj);
+static VALUE fole_s_free(VALUE self, VALUE obj);
+static HWND ole_show_help(VALUE helpfile, VALUE helpcontext);
+static VALUE fole_s_show_help(int argc, VALUE *argv, VALUE self);
+static VALUE fole_s_get_code_page(VALUE self);
+static BOOL CALLBACK installed_code_page_proc(LPTSTR str);
+static BOOL code_page_installed(UINT cp);
+static VALUE fole_s_set_code_page(VALUE self, VALUE vcp);
+static VALUE fole_s_get_locale(VALUE self);
+static BOOL CALLBACK installed_lcid_proc(LPTSTR str);
+static BOOL lcid_installed(LCID lcid);
+static VALUE fole_s_set_locale(VALUE self, VALUE vlcid);
+static VALUE fole_s_create_guid(VALUE self);
+static VALUE fole_s_ole_initialize(VALUE self);
+static VALUE fole_s_ole_uninitialize(VALUE self);
+static VALUE fole_initialize(int argc, VALUE *argv, VALUE self);
+static int hash2named_arg(VALUE key, VALUE val, VALUE pop);
+static VALUE set_argv(VARIANTARG* realargs, unsigned int beg, unsigned int end);
+static VALUE ole_invoke(int argc, VALUE *argv, VALUE self, USHORT wFlags, BOOL is_bracket);
+static VALUE fole_invoke(int argc, VALUE *argv, VALUE self);
+static VALUE ole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types, USHORT dispkind);
+static VALUE fole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types);
+static VALUE fole_getproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types);
+static VALUE fole_setproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types);
+static VALUE fole_setproperty_with_bracket(int argc, VALUE *argv, VALUE self);
+static VALUE fole_setproperty(int argc, VALUE *argv, VALUE self);
+static VALUE fole_getproperty_with_bracket(int argc, VALUE *argv, VALUE self);
+static VALUE ole_propertyput(VALUE self, VALUE property, VALUE value);
+static VALUE fole_free(VALUE self);
+static VALUE ole_each_sub(VALUE pEnumV);
+static VALUE ole_ienum_free(VALUE pEnumV);
+static VALUE fole_each(VALUE self);
+static VALUE fole_missing(int argc, VALUE *argv, VALUE self);
+static HRESULT typeinfo_from_ole(struct oledata *pole, ITypeInfo **ppti);
+static VALUE ole_methods(VALUE self, int mask);
+static VALUE fole_methods(VALUE self);
+static VALUE fole_get_methods(VALUE self);
+static VALUE fole_put_methods(VALUE self);
+static VALUE fole_func_methods(VALUE self);
+static VALUE fole_type(VALUE self);
+static VALUE fole_typelib(VALUE self);
+static VALUE fole_query_interface(VALUE self, VALUE str_iid);
+static VALUE fole_respond_to(VALUE self, VALUE method);
+static VALUE ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails);
+static VALUE ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails);
+static VALUE fole_method_help(VALUE self, VALUE cmdname);
+static VALUE fole_activex_initialize(VALUE self);
+
+static void init_enc2cp(void);
+static void free_enc2cp(void);
+
+static void com_hash_free(void *ptr);
+static void com_hash_mark(void *ptr);
+static size_t com_hash_size(const void *ptr);
+
+static const rb_data_type_t ole_datatype = {
+ "win32ole",
+ {NULL, ole_free, ole_size,},
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+static const rb_data_type_t com_hash_datatype = {
+ "com_hash",
+ {com_hash_mark, com_hash_free, com_hash_size,},
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+static HRESULT (STDMETHODCALLTYPE mf_QueryInterface)(
+ IMessageFilter __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
+{
+ if (MEMCMP(riid, &IID_IUnknown, GUID, 1) == 0
+ || MEMCMP(riid, &IID_IMessageFilter, GUID, 1) == 0)
+ {
+ *ppvObject = &message_filter;
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+}
+
+static ULONG (STDMETHODCALLTYPE mf_AddRef)(
+ IMessageFilter __RPC_FAR * This)
+{
+ return 1;
+}
+
+static ULONG (STDMETHODCALLTYPE mf_Release)(
+ IMessageFilter __RPC_FAR * This)
+{
+ return 1;
+}
+
+static DWORD (STDMETHODCALLTYPE mf_HandleInComingCall)(
+ IMessageFilter __RPC_FAR * pThis,
+ DWORD dwCallType, //Type of incoming call
+ HTASK threadIDCaller, //Task handle calling this task
+ DWORD dwTickCount, //Elapsed tick count
+ LPINTERFACEINFO lpInterfaceInfo //Pointer to INTERFACEINFO structure
+ )
+{
+#ifdef DEBUG_MESSAGEFILTER
+ printf("incoming %08X, %08X, %d\n", dwCallType, threadIDCaller, dwTickCount);
+ fflush(stdout);
+#endif
+ switch (dwCallType)
+ {
+ case CALLTYPE_ASYNC:
+ case CALLTYPE_TOPLEVEL_CALLPENDING:
+ case CALLTYPE_ASYNC_CALLPENDING:
+ if (rb_during_gc()) {
+ return SERVERCALL_RETRYLATER;
+ }
+ break;
+ default:
+ break;
+ }
+ if (previous_filter) {
+ return previous_filter->lpVtbl->HandleInComingCall(previous_filter,
+ dwCallType,
+ threadIDCaller,
+ dwTickCount,
+ lpInterfaceInfo);
+ }
+ return SERVERCALL_ISHANDLED;
+}
+
+static DWORD (STDMETHODCALLTYPE mf_RetryRejectedCall)(
+ IMessageFilter* pThis,
+ HTASK threadIDCallee, //Server task handle
+ DWORD dwTickCount, //Elapsed tick count
+ DWORD dwRejectType //Returned rejection message
+ )
+{
+ if (previous_filter) {
+ return previous_filter->lpVtbl->RetryRejectedCall(previous_filter,
+ threadIDCallee,
+ dwTickCount,
+ dwRejectType);
+ }
+ return 1000;
+}
+
+static DWORD (STDMETHODCALLTYPE mf_MessagePending)(
+ IMessageFilter* pThis,
+ HTASK threadIDCallee, //Called applications task handle
+ DWORD dwTickCount, //Elapsed tick count
+ DWORD dwPendingType //Call type
+ )
+{
+ if (rb_during_gc()) {
+ return PENDINGMSG_WAITNOPROCESS;
+ }
+ if (previous_filter) {
+ return previous_filter->lpVtbl->MessagePending(previous_filter,
+ threadIDCallee,
+ dwTickCount,
+ dwPendingType);
+ }
+ return PENDINGMSG_WAITNOPROCESS;
+}
+
+typedef struct _Win32OLEIDispatch
+{
+ IDispatch dispatch;
+ ULONG refcount;
+ VALUE obj;
+} Win32OLEIDispatch;
+
+static HRESULT ( STDMETHODCALLTYPE QueryInterface )(
+ IDispatch __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
+{
+ if (MEMCMP(riid, &IID_IUnknown, GUID, 1) == 0
+ || MEMCMP(riid, &IID_IDispatch, GUID, 1) == 0)
+ {
+ Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
+ p->refcount++;
+ *ppvObject = This;
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+}
+
+static ULONG ( STDMETHODCALLTYPE AddRef )(
+ IDispatch __RPC_FAR * This)
+{
+ Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
+ return ++(p->refcount);
+}
+
+static ULONG ( STDMETHODCALLTYPE Release )(
+ IDispatch __RPC_FAR * This)
+{
+ Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
+ ULONG u = --(p->refcount);
+ if (u == 0) {
+ st_data_t key = p->obj;
+ st_delete(DATA_PTR(com_hash), &key, 0);
+ free(p);
+ }
+ return u;
+}
+
+static HRESULT ( STDMETHODCALLTYPE GetTypeInfoCount )(
+ IDispatch __RPC_FAR * This,
+ /* [out] */ UINT __RPC_FAR *pctinfo)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT ( STDMETHODCALLTYPE GetTypeInfo )(
+ IDispatch __RPC_FAR * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo)
+{
+ return E_NOTIMPL;
+}
+
+
+static HRESULT ( STDMETHODCALLTYPE GetIDsOfNames )(
+ IDispatch __RPC_FAR * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
+ /* [in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID __RPC_FAR *rgDispId)
+{
+ /*
+ Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
+ */
+ char* psz = ole_wc2mb(*rgszNames); // support only one method
+ ID nameid = rb_intern(psz);
+ free(psz);
+ if ((ID)(DISPID)nameid != nameid) return E_NOINTERFACE;
+ *rgDispId = (DISPID)nameid;
+ return S_OK;
+}
+
+static /* [local] */ HRESULT ( STDMETHODCALLTYPE Invoke )(
+ IDispatch __RPC_FAR * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
+ /* [out] */ VARIANT __RPC_FAR *pVarResult,
+ /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
+ /* [out] */ UINT __RPC_FAR *puArgErr)
+{
+ VALUE v;
+ int i;
+ int args = pDispParams->cArgs;
+ Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
+ VALUE* parg = ALLOCA_N(VALUE, args);
+ ID mid = (ID)dispIdMember;
+ for (i = 0; i < args; i++) {
+ *(parg + i) = ole_variant2val(&pDispParams->rgvarg[args - i - 1]);
+ }
+ if (dispIdMember == DISPID_VALUE) {
+ if (wFlags == DISPATCH_METHOD) {
+ mid = rb_intern("call");
+ } else if (wFlags & DISPATCH_PROPERTYGET) {
+ mid = rb_intern("value");
+ }
+ }
+ v = rb_funcall2(p->obj, mid, args, parg);
+ ole_val2variant(v, pVarResult);
+ return S_OK;
+}
+
+BOOL
+ole_initialized(void)
+{
+ return g_ole_initialized;
+}
+
+static IDispatch*
+val2dispatch(VALUE val)
+{
+ struct st_table *tbl = DATA_PTR(com_hash);
+ Win32OLEIDispatch* pdisp;
+ st_data_t data;
+ if (st_lookup(tbl, val, &data)) {
+ pdisp = (Win32OLEIDispatch *)(data & ~FIXNUM_FLAG);
+ pdisp->refcount++;
+ }
+ else {
+ pdisp = ALLOC(Win32OLEIDispatch);
+ pdisp->dispatch.lpVtbl = &com_vtbl;
+ pdisp->refcount = 1;
+ pdisp->obj = val;
+ st_insert(tbl, val, (VALUE)pdisp | FIXNUM_FLAG);
+ }
+ return &pdisp->dispatch;
+}
+
+static double
+rbtime2vtdate(VALUE tmobj)
+{
+ SYSTEMTIME st;
+ double t;
+ double nsec;
+
+ st.wYear = FIX2INT(rb_funcall(tmobj, rb_intern("year"), 0));
+ st.wMonth = FIX2INT(rb_funcall(tmobj, rb_intern("month"), 0));
+ st.wDay = FIX2INT(rb_funcall(tmobj, rb_intern("mday"), 0));
+ st.wHour = FIX2INT(rb_funcall(tmobj, rb_intern("hour"), 0));
+ st.wMinute = FIX2INT(rb_funcall(tmobj, rb_intern("min"), 0));
+ st.wSecond = FIX2INT(rb_funcall(tmobj, rb_intern("sec"), 0));
+ st.wMilliseconds = 0;
+ SystemTimeToVariantTime(&st, &t);
+
+ /*
+ * Unfortunately SystemTimeToVariantTime function always ignores the
+ * wMilliseconds of SYSTEMTIME struct.
+ * So, we need to calculate milliseconds by ourselves.
+ */
+ nsec = FIX2INT(rb_funcall(tmobj, rb_intern("nsec"), 0));
+ nsec /= 1000000.0;
+ nsec /= (24.0 * 3600.0);
+ nsec /= 1000;
+ return t + nsec;
+}
+
+static VALUE
+vtdate2rbtime(double date)
+{
+ SYSTEMTIME st;
+ VALUE v;
+ double msec;
+ double sec;
+ VariantTimeToSystemTime(date, &st);
+ v = rb_funcall(rb_cTime, rb_intern("new"), 6,
+ INT2FIX(st.wYear),
+ INT2FIX(st.wMonth),
+ INT2FIX(st.wDay),
+ INT2FIX(st.wHour),
+ INT2FIX(st.wMinute),
+ INT2FIX(st.wSecond));
+ st.wYear = FIX2INT(rb_funcall(v, rb_intern("year"), 0));
+ st.wMonth = FIX2INT(rb_funcall(v, rb_intern("month"), 0));
+ st.wDay = FIX2INT(rb_funcall(v, rb_intern("mday"), 0));
+ st.wHour = FIX2INT(rb_funcall(v, rb_intern("hour"), 0));
+ st.wMinute = FIX2INT(rb_funcall(v, rb_intern("min"), 0));
+ st.wSecond = FIX2INT(rb_funcall(v, rb_intern("sec"), 0));
+ st.wMilliseconds = 0;
+ SystemTimeToVariantTime(&st, &sec);
+ /*
+ * Unfortunately VariantTimeToSystemTime always ignores the
+ * wMilliseconds of SYSTEMTIME struct(The wMilliseconds is 0).
+ * So, we need to calculate milliseconds by ourselves.
+ */
+ msec = date - sec;
+ msec *= 24 * 60;
+ msec -= floor(msec);
+ msec *= 60;
+ if (msec >= 59) {
+ msec -= 60;
+ }
+ if (msec != 0) {
+ return rb_funcall(v, rb_intern("+"), 1, rb_float_new(msec));
+ }
+ return v;
+}
+
+#define ENC_MACHING_CP(enc,encname,cp) if(strcasecmp(rb_enc_name((enc)),(encname)) == 0) return cp
+
+static UINT ole_encoding2cp(rb_encoding *enc)
+{
+ /*
+ * Is there any better solution to convert
+ * Ruby encoding to Windows codepage???
+ */
+ ENC_MACHING_CP(enc, "Big5", 950);
+ ENC_MACHING_CP(enc, "CP51932", 51932);
+ ENC_MACHING_CP(enc, "CP850", 850);
+ ENC_MACHING_CP(enc, "CP852", 852);
+ ENC_MACHING_CP(enc, "CP855", 855);
+ ENC_MACHING_CP(enc, "CP949", 949);
+ ENC_MACHING_CP(enc, "EUC-JP", 20932);
+ ENC_MACHING_CP(enc, "EUC-KR", 51949);
+ ENC_MACHING_CP(enc, "EUC-TW", 51950);
+ ENC_MACHING_CP(enc, "GB18030", 54936);
+ ENC_MACHING_CP(enc, "GB2312", 20936);
+ ENC_MACHING_CP(enc, "GBK", 936);
+ ENC_MACHING_CP(enc, "IBM437", 437);
+ ENC_MACHING_CP(enc, "IBM737", 737);
+ ENC_MACHING_CP(enc, "IBM775", 775);
+ ENC_MACHING_CP(enc, "IBM852", 852);
+ ENC_MACHING_CP(enc, "IBM855", 855);
+ ENC_MACHING_CP(enc, "IBM857", 857);
+ ENC_MACHING_CP(enc, "IBM860", 860);
+ ENC_MACHING_CP(enc, "IBM861", 861);
+ ENC_MACHING_CP(enc, "IBM862", 862);
+ ENC_MACHING_CP(enc, "IBM863", 863);
+ ENC_MACHING_CP(enc, "IBM864", 864);
+ ENC_MACHING_CP(enc, "IBM865", 865);
+ ENC_MACHING_CP(enc, "IBM866", 866);
+ ENC_MACHING_CP(enc, "IBM869", 869);
+ ENC_MACHING_CP(enc, "ISO-2022-JP", 50220);
+ ENC_MACHING_CP(enc, "ISO-8859-1", 28591);
+ ENC_MACHING_CP(enc, "ISO-8859-15", 28605);
+ ENC_MACHING_CP(enc, "ISO-8859-2", 28592);
+ ENC_MACHING_CP(enc, "ISO-8859-3", 28593);
+ ENC_MACHING_CP(enc, "ISO-8859-4", 28594);
+ ENC_MACHING_CP(enc, "ISO-8859-5", 28595);
+ ENC_MACHING_CP(enc, "ISO-8859-6", 28596);
+ ENC_MACHING_CP(enc, "ISO-8859-7", 28597);
+ ENC_MACHING_CP(enc, "ISO-8859-8", 28598);
+ ENC_MACHING_CP(enc, "ISO-8859-9", 28599);
+ ENC_MACHING_CP(enc, "KOI8-R", 20866);
+ ENC_MACHING_CP(enc, "KOI8-U", 21866);
+ ENC_MACHING_CP(enc, "Shift_JIS", 932);
+ ENC_MACHING_CP(enc, "UTF-16BE", 1201);
+ ENC_MACHING_CP(enc, "UTF-16LE", 1200);
+ ENC_MACHING_CP(enc, "UTF-7", 65000);
+ ENC_MACHING_CP(enc, "UTF-8", 65001);
+ ENC_MACHING_CP(enc, "Windows-1250", 1250);
+ ENC_MACHING_CP(enc, "Windows-1251", 1251);
+ ENC_MACHING_CP(enc, "Windows-1252", 1252);
+ ENC_MACHING_CP(enc, "Windows-1253", 1253);
+ ENC_MACHING_CP(enc, "Windows-1254", 1254);
+ ENC_MACHING_CP(enc, "Windows-1255", 1255);
+ ENC_MACHING_CP(enc, "Windows-1256", 1256);
+ ENC_MACHING_CP(enc, "Windows-1257", 1257);
+ ENC_MACHING_CP(enc, "Windows-1258", 1258);
+ ENC_MACHING_CP(enc, "Windows-31J", 932);
+ ENC_MACHING_CP(enc, "Windows-874", 874);
+ ENC_MACHING_CP(enc, "eucJP-ms", 20932);
+ return CP_ACP;
+}
+
+static void
+failed_load_conv51932(void)
+{
+ rb_raise(eWIN32OLERuntimeError, "fail to load convert function for CP51932");
+}
+
+#ifndef pIMultiLanguage
+static void
+load_conv_function51932(void)
+{
+ HRESULT hr = E_NOINTERFACE;
+ void *p;
+ if (!pIMultiLanguage) {
+#if defined(HAVE_TYPE_IMULTILANGUAGE2)
+ hr = CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IMultiLanguage2, &p);
+#elif defined(HAVE_TYPE_IMULTILANGUAGE)
+ hr = CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IMultiLanguage, &p);
+#endif
+ if (FAILED(hr)) {
+ failed_load_conv51932();
+ }
+ pIMultiLanguage = p;
+ }
+}
+#else
+#define load_conv_function51932() failed_load_conv51932()
+#endif
+
+#define conv_51932(cp) ((cp) == 51932 && (load_conv_function51932(), 1))
+
+static void
+set_ole_codepage(UINT cp)
+{
+ if (code_page_installed(cp)) {
+ cWIN32OLE_cp = cp;
+ } else {
+ switch(cp) {
+ case CP_ACP:
+ case CP_OEMCP:
+ case CP_MACCP:
+ case CP_THREAD_ACP:
+ case CP_SYMBOL:
+ case CP_UTF7:
+ case CP_UTF8:
+ cWIN32OLE_cp = cp;
+ break;
+ case 51932:
+ cWIN32OLE_cp = cp;
+ load_conv_function51932();
+ break;
+ default:
+ rb_raise(eWIN32OLERuntimeError, "codepage should be WIN32OLE::CP_ACP, WIN32OLE::CP_OEMCP, WIN32OLE::CP_MACCP, WIN32OLE::CP_THREAD_ACP, WIN32OLE::CP_SYMBOL, WIN32OLE::CP_UTF7, WIN32OLE::CP_UTF8, or installed codepage.");
+ break;
+ }
+ }
+ cWIN32OLE_enc = ole_cp2encoding(cWIN32OLE_cp);
+}
+
+
+static UINT
+ole_init_cp(void)
+{
+ UINT cp;
+ rb_encoding *encdef;
+ encdef = rb_default_internal_encoding();
+ if (!encdef) {
+ encdef = rb_default_external_encoding();
+ }
+ cp = ole_encoding2cp(encdef);
+ set_ole_codepage(cp);
+ return cp;
+}
+
+struct myCPINFOEX {
+ UINT MaxCharSize;
+ BYTE DefaultChar[2];
+ BYTE LeadByte[12];
+ WCHAR UnicodeDefaultChar;
+ UINT CodePage;
+ char CodePageName[MAX_PATH];
+};
+
+static rb_encoding *
+ole_cp2encoding(UINT cp)
+{
+ static BOOL (*pGetCPInfoEx)(UINT, DWORD, struct myCPINFOEX *) = NULL;
+ struct myCPINFOEX* buf;
+ VALUE enc_name;
+ char *enc_cstr;
+ int idx;
+
+ if (!code_page_installed(cp)) {
+ switch(cp) {
+ case CP_ACP:
+ cp = GetACP();
+ break;
+ case CP_OEMCP:
+ cp = GetOEMCP();
+ break;
+ case CP_MACCP:
+ case CP_THREAD_ACP:
+ if (!pGetCPInfoEx) {
+ pGetCPInfoEx = (BOOL (*)(UINT, DWORD, struct myCPINFOEX *))
+ GetProcAddress(GetModuleHandle("kernel32"), "GetCPInfoEx");
+ if (!pGetCPInfoEx) {
+ pGetCPInfoEx = (void*)-1;
+ }
+ }
+ buf = ALLOCA_N(struct myCPINFOEX, 1);
+ ZeroMemory(buf, sizeof(struct myCPINFOEX));
+ if (pGetCPInfoEx == (void*)-1 || !pGetCPInfoEx(cp, 0, buf)) {
+ rb_raise(eWIN32OLERuntimeError, "cannot map codepage to encoding.");
+ break; /* never reach here */
+ }
+ cp = buf->CodePage;
+ break;
+ case CP_SYMBOL:
+ case CP_UTF7:
+ case CP_UTF8:
+ break;
+ case 51932:
+ load_conv_function51932();
+ break;
+ default:
+ rb_raise(eWIN32OLERuntimeError, "codepage should be WIN32OLE::CP_ACP, WIN32OLE::CP_OEMCP, WIN32OLE::CP_MACCP, WIN32OLE::CP_THREAD_ACP, WIN32OLE::CP_SYMBOL, WIN32OLE::CP_UTF7, WIN32OLE::CP_UTF8, or installed codepage.");
+ break;
+ }
+ }
+
+ enc_name = rb_sprintf("CP%d", cp);
+ idx = rb_enc_find_index(enc_cstr = StringValueCStr(enc_name));
+ if (idx < 0)
+ idx = rb_define_dummy_encoding(enc_cstr);
+ return rb_enc_from_index(idx);
+}
+
+static char *
+ole_wc2mb_alloc(LPWSTR pw, char *(alloc)(UINT size, void *arg), void *arg)
+{
+ LPSTR pm;
+ UINT size = 0;
+ if (conv_51932(cWIN32OLE_cp)) {
+#ifndef pIMultiLanguage
+ DWORD dw = 0;
+ HRESULT hr = pIMultiLanguage->lpVtbl->ConvertStringFromUnicode(pIMultiLanguage,
+ &dw, cWIN32OLE_cp, pw, NULL, NULL, &size);
+ if (FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError, "fail to convert Unicode to CP%d", cWIN32OLE_cp);
+ }
+ pm = alloc(size, arg);
+ hr = pIMultiLanguage->lpVtbl->ConvertStringFromUnicode(pIMultiLanguage,
+ &dw, cWIN32OLE_cp, pw, NULL, pm, &size);
+ if (FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError, "fail to convert Unicode to CP%d", cWIN32OLE_cp);
+ }
+ pm[size] = '\0';
+#endif
+ return pm;
+ }
+ size = WideCharToMultiByte(cWIN32OLE_cp, 0, pw, -1, NULL, 0, NULL, NULL);
+ if (size) {
+ pm = alloc(size, arg);
+ WideCharToMultiByte(cWIN32OLE_cp, 0, pw, -1, pm, size, NULL, NULL);
+ pm[size] = '\0';
+ }
+ else {
+ pm = alloc(0, arg);
+ *pm = '\0';
+ }
+ return pm;
+}
+
+static char *
+ole_alloc_str(UINT size, void *arg)
+{
+ return ALLOC_N(char, size + 1);
+}
+
+char *
+ole_wc2mb(LPWSTR pw)
+{
+ return ole_wc2mb_alloc(pw, ole_alloc_str, NULL);
+}
+
+static void
+ole_freeexceptinfo(EXCEPINFO *pExInfo)
+{
+ SysFreeString(pExInfo->bstrDescription);
+ SysFreeString(pExInfo->bstrSource);
+ SysFreeString(pExInfo->bstrHelpFile);
+}
+
+static VALUE
+ole_excepinfo2msg(EXCEPINFO *pExInfo)
+{
+ char error_code[40];
+ char *pSource = NULL;
+ char *pDescription = NULL;
+ VALUE error_msg;
+ if(pExInfo->pfnDeferredFillIn != NULL) {
+ (*pExInfo->pfnDeferredFillIn)(pExInfo);
+ }
+ if (pExInfo->bstrSource != NULL) {
+ pSource = ole_wc2mb(pExInfo->bstrSource);
+ }
+ if (pExInfo->bstrDescription != NULL) {
+ pDescription = ole_wc2mb(pExInfo->bstrDescription);
+ }
+ if(pExInfo->wCode == 0) {
+ sprintf(error_code, "\n OLE error code:%lX in ", (unsigned long)pExInfo->scode);
+ }
+ else{
+ sprintf(error_code, "\n OLE error code:%u in ", pExInfo->wCode);
+ }
+ error_msg = rb_str_new2(error_code);
+ if(pSource != NULL) {
+ rb_str_cat2(error_msg, pSource);
+ }
+ else {
+ rb_str_cat(error_msg, "<Unknown>", 9);
+ }
+ rb_str_cat2(error_msg, "\n ");
+ if(pDescription != NULL) {
+ rb_str_cat2(error_msg, pDescription);
+ }
+ else {
+ rb_str_cat2(error_msg, "<No Description>");
+ }
+ if(pSource) free(pSource);
+ if(pDescription) free(pDescription);
+ ole_freeexceptinfo(pExInfo);
+ return error_msg;
+}
+
+void
+ole_uninitialize(void)
+{
+ if (!g_ole_initialized) return;
+ OleUninitialize();
+ g_ole_initialized_set(FALSE);
+}
+
+static void
+ole_uninitialize_hook(rb_event_flag_t evflag, VALUE data, VALUE self, ID mid, VALUE klass)
+{
+ ole_uninitialize();
+}
+
+void
+ole_initialize(void)
+{
+ HRESULT hr;
+
+ if(!g_uninitialize_hooked) {
+ rb_add_event_hook(ole_uninitialize_hook, RUBY_EVENT_THREAD_END, Qnil);
+ g_uninitialize_hooked = TRUE;
+ }
+
+ if(g_ole_initialized == FALSE) {
+ hr = OleInitialize(NULL);
+ if(FAILED(hr)) {
+ ole_raise(hr, rb_eRuntimeError, "fail: OLE initialize");
+ }
+ g_ole_initialized_set(TRUE);
+
+ hr = CoRegisterMessageFilter(&imessage_filter, &previous_filter);
+ if(FAILED(hr)) {
+ previous_filter = NULL;
+ ole_raise(hr, rb_eRuntimeError, "fail: install OLE MessageFilter");
+ }
+ }
+}
+
+static void
+ole_free(void *ptr)
+{
+ struct oledata *pole = ptr;
+ OLE_FREE(pole->pDispatch);
+ free(pole);
+}
+
+static size_t ole_size(const void *ptr)
+{
+ return ptr ? sizeof(struct oledata) : 0;
+}
+
+struct oledata *
+oledata_get_struct(VALUE ole)
+{
+ struct oledata *pole;
+ TypedData_Get_Struct(ole, struct oledata, &ole_datatype, pole);
+ return pole;
+}
+
+LPWSTR
+ole_vstr2wc(VALUE vstr)
+{
+ rb_encoding *enc;
+ int cp;
+ UINT size = 0;
+ LPWSTR pw;
+ st_data_t data;
+ enc = rb_enc_get(vstr);
+
+ if (st_lookup(enc2cp_table, (st_data_t)enc, &data)) {
+ cp = (int)data;
+ } else {
+ cp = ole_encoding2cp(enc);
+ if (code_page_installed(cp) ||
+ cp == CP_ACP ||
+ cp == CP_OEMCP ||
+ cp == CP_MACCP ||
+ cp == CP_THREAD_ACP ||
+ cp == CP_SYMBOL ||
+ cp == CP_UTF7 ||
+ cp == CP_UTF8 ||
+ cp == 51932) {
+ st_insert(enc2cp_table, (st_data_t)enc, (st_data_t)cp);
+ } else {
+ rb_raise(eWIN32OLERuntimeError, "not installed Windows codepage(%d) according to `%s'", cp, rb_enc_name(enc));
+ }
+ }
+ if (conv_51932(cp)) {
+#ifndef pIMultiLanguage
+ DWORD dw = 0;
+ UINT len = RSTRING_LENINT(vstr);
+ HRESULT hr = pIMultiLanguage->lpVtbl->ConvertStringToUnicode(pIMultiLanguage,
+ &dw, cp, RSTRING_PTR(vstr), &len, NULL, &size);
+ if (FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError, "fail to convert CP%d to Unicode", cp);
+ }
+ pw = SysAllocStringLen(NULL, size);
+ len = RSTRING_LEN(vstr);
+ hr = pIMultiLanguage->lpVtbl->ConvertStringToUnicode(pIMultiLanguage,
+ &dw, cp, RSTRING_PTR(vstr), &len, pw, &size);
+ if (FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError, "fail to convert CP%d to Unicode", cp);
+ }
+#endif
+ return pw;
+ }
+ size = MultiByteToWideChar(cp, 0, RSTRING_PTR(vstr), RSTRING_LEN(vstr), NULL, 0);
+ pw = SysAllocStringLen(NULL, size);
+ MultiByteToWideChar(cp, 0, RSTRING_PTR(vstr), RSTRING_LEN(vstr), pw, size);
+ return pw;
+}
+
+static LPWSTR
+ole_mb2wc(char *pm, int len)
+{
+ UINT size = 0;
+ LPWSTR pw;
+
+ if (conv_51932(cWIN32OLE_cp)) {
+#ifndef pIMultiLanguage
+ DWORD dw = 0;
+ UINT n = len;
+ HRESULT hr = pIMultiLanguage->lpVtbl->ConvertStringToUnicode(pIMultiLanguage,
+ &dw, cWIN32OLE_cp, pm, &n, NULL, &size);
+ if (FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError, "fail to convert CP%d to Unicode", cWIN32OLE_cp);
+ }
+ pw = SysAllocStringLen(NULL, size);
+ hr = pIMultiLanguage->lpVtbl->ConvertStringToUnicode(pIMultiLanguage,
+ &dw, cWIN32OLE_cp, pm, &n, pw, &size);
+ if (FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError, "fail to convert CP%d to Unicode", cWIN32OLE_cp);
+ }
+#endif
+ return pw;
+ }
+ size = MultiByteToWideChar(cWIN32OLE_cp, 0, pm, len, NULL, 0);
+ pw = SysAllocStringLen(NULL, size - 1);
+ MultiByteToWideChar(cWIN32OLE_cp, 0, pm, len, pw, size);
+ return pw;
+}
+
+static char *
+ole_alloc_vstr(UINT size, void *arg)
+{
+ VALUE str = rb_enc_str_new(NULL, size, cWIN32OLE_enc);
+ *(VALUE *)arg = str;
+ return RSTRING_PTR(str);
+}
+
+VALUE
+ole_wc2vstr(LPWSTR pw, BOOL isfree)
+{
+ VALUE vstr;
+ ole_wc2mb_alloc(pw, ole_alloc_vstr, &vstr);
+ rb_str_set_len(vstr, (long)strlen(RSTRING_PTR(vstr)));
+ if(isfree)
+ SysFreeString(pw);
+ return vstr;
+}
+
+static VALUE
+ole_ary_m_entry(VALUE val, LONG *pid)
+{
+ VALUE obj = Qnil;
+ int i = 0;
+ obj = val;
+ while(RB_TYPE_P(obj, T_ARRAY)) {
+ obj = rb_ary_entry(obj, pid[i]);
+ i++;
+ }
+ return obj;
+}
+
+static VALUE
+is_all_index_under(LONG *pid, long *pub, long dim)
+{
+ long i = 0;
+ for (i = 0; i < dim; i++) {
+ if (pid[i] > pub[i]) {
+ return Qfalse;
+ }
+ }
+ return Qtrue;
+}
+
+void
+ole_val2variant_ex(VALUE val, VARIANT *var, VARTYPE vt)
+{
+ if (val == Qnil) {
+ if (vt == VT_VARIANT) {
+ ole_val2variant2(val, var);
+ } else {
+ V_VT(var) = (vt & ~VT_BYREF);
+ if (V_VT(var) == VT_DISPATCH) {
+ V_DISPATCH(var) = NULL;
+ } else if (V_VT(var) == VT_UNKNOWN) {
+ V_UNKNOWN(var) = NULL;
+ }
+ }
+ return;
+ }
+#if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
+ switch(vt & ~VT_BYREF) {
+ case VT_I8:
+ V_VT(var) = VT_I8;
+ V_I8(var) = NUM2I8 (val);
+ break;
+ case VT_UI8:
+ V_VT(var) = VT_UI8;
+ V_UI8(var) = NUM2UI8(val);
+ break;
+ default:
+ ole_val2variant2(val, var);
+ break;
+ }
+#else /* (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__) */
+ ole_val2variant2(val, var);
+#endif
+}
+
+VOID *
+val2variant_ptr(VALUE val, VARIANT *var, VARTYPE vt)
+{
+ VOID *p = NULL;
+ HRESULT hr = S_OK;
+ ole_val2variant_ex(val, var, vt);
+ if ((vt & ~VT_BYREF) == VT_VARIANT) {
+ p = var;
+ } else {
+ if ( (vt & ~VT_BYREF) != V_VT(var)) {
+ hr = VariantChangeTypeEx(var, var,
+ cWIN32OLE_lcid, 0, (VARTYPE)(vt & ~VT_BYREF));
+ if (FAILED(hr)) {
+ ole_raise(hr, rb_eRuntimeError, "failed to change type");
+ }
+ }
+ p = get_ptr_of_variant(var);
+ }
+ if (p == NULL) {
+ rb_raise(rb_eRuntimeError, "failed to get pointer of variant");
+ }
+ return p;
+}
+
+static void *
+get_ptr_of_variant(VARIANT *pvar)
+{
+ switch(V_VT(pvar)) {
+ case VT_UI1:
+ return &V_UI1(pvar);
+ break;
+ case VT_I2:
+ return &V_I2(pvar);
+ break;
+ case VT_UI2:
+ return &V_UI2(pvar);
+ break;
+ case VT_I4:
+ return &V_I4(pvar);
+ break;
+ case VT_UI4:
+ return &V_UI4(pvar);
+ break;
+ case VT_R4:
+ return &V_R4(pvar);
+ break;
+ case VT_R8:
+ return &V_R8(pvar);
+ break;
+#if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
+ case VT_I8:
+ return &V_I8(pvar);
+ break;
+ case VT_UI8:
+ return &V_UI8(pvar);
+ break;
+#endif
+ case VT_INT:
+ return &V_INT(pvar);
+ break;
+ case VT_UINT:
+ return &V_UINT(pvar);
+ break;
+ case VT_CY:
+ return &V_CY(pvar);
+ break;
+ case VT_DATE:
+ return &V_DATE(pvar);
+ break;
+ case VT_BSTR:
+ return V_BSTR(pvar);
+ break;
+ case VT_DISPATCH:
+ return V_DISPATCH(pvar);
+ break;
+ case VT_ERROR:
+ return &V_ERROR(pvar);
+ break;
+ case VT_BOOL:
+ return &V_BOOL(pvar);
+ break;
+ case VT_UNKNOWN:
+ return V_UNKNOWN(pvar);
+ break;
+ case VT_ARRAY:
+ return &V_ARRAY(pvar);
+ break;
+ default:
+ return NULL;
+ break;
+ }
+}
+
+static void
+ole_set_safe_array(long n, SAFEARRAY *psa, LONG *pid, long *pub, VALUE val, long dim, VARTYPE vt)
+{
+ VALUE val1;
+ HRESULT hr = S_OK;
+ VARIANT var;
+ VOID *p = NULL;
+ long i = n;
+ while(i >= 0) {
+ val1 = ole_ary_m_entry(val, pid);
+ VariantInit(&var);
+ p = val2variant_ptr(val1, &var, vt);
+ if (is_all_index_under(pid, pub, dim) == Qtrue) {
+ if ((V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == NULL) ||
+ (V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) == NULL)) {
+ rb_raise(eWIN32OLERuntimeError, "element of array does not have IDispatch or IUnknown Interface");
+ }
+ hr = SafeArrayPutElement(psa, pid, p);
+ }
+ if (FAILED(hr)) {
+ ole_raise(hr, rb_eRuntimeError, "failed to SafeArrayPutElement");
+ }
+ pid[i] += 1;
+ if (pid[i] > pub[i]) {
+ pid[i] = 0;
+ i -= 1;
+ } else {
+ i = dim - 1;
+ }
+ }
+}
+
+static long
+dimension(VALUE val) {
+ long dim = 0;
+ long dim1 = 0;
+ long len = 0;
+ long i = 0;
+ if (RB_TYPE_P(val, T_ARRAY)) {
+ len = RARRAY_LEN(val);
+ for (i = 0; i < len; i++) {
+ dim1 = dimension(rb_ary_entry(val, i));
+ if (dim < dim1) {
+ dim = dim1;
+ }
+ }
+ dim += 1;
+ }
+ return dim;
+}
+
+static long
+ary_len_of_dim(VALUE ary, long dim) {
+ long ary_len = 0;
+ long ary_len1 = 0;
+ long len = 0;
+ long i = 0;
+ VALUE val;
+ if (dim == 0) {
+ if (RB_TYPE_P(ary, T_ARRAY)) {
+ ary_len = RARRAY_LEN(ary);
+ }
+ } else {
+ if (RB_TYPE_P(ary, T_ARRAY)) {
+ len = RARRAY_LEN(ary);
+ for (i = 0; i < len; i++) {
+ val = rb_ary_entry(ary, i);
+ ary_len1 = ary_len_of_dim(val, dim-1);
+ if (ary_len < ary_len1) {
+ ary_len = ary_len1;
+ }
+ }
+ }
+ }
+ return ary_len;
+}
+
+HRESULT
+ole_val_ary2variant_ary(VALUE val, VARIANT *var, VARTYPE vt)
+{
+ long dim = 0;
+ int i = 0;
+ HRESULT hr = S_OK;
+
+ SAFEARRAYBOUND *psab = NULL;
+ SAFEARRAY *psa = NULL;
+ long *pub;
+ LONG *pid;
+
+ Check_Type(val, T_ARRAY);
+
+ dim = dimension(val);
+
+ psab = ALLOC_N(SAFEARRAYBOUND, dim);
+ pub = ALLOC_N(long, dim);
+ pid = ALLOC_N(LONG, dim);
+
+ if(!psab || !pub || !pid) {
+ if(pub) free(pub);
+ if(psab) free(psab);
+ if(pid) free(pid);
+ rb_raise(rb_eRuntimeError, "memory allocation error");
+ }
+
+ for (i = 0; i < dim; i++) {
+ psab[i].cElements = ary_len_of_dim(val, i);
+ psab[i].lLbound = 0;
+ pub[i] = psab[i].cElements - 1;
+ pid[i] = 0;
+ }
+ /* Create and fill VARIANT array */
+ if ((vt & ~VT_BYREF) == VT_ARRAY) {
+ vt = (vt | VT_VARIANT);
+ }
+ psa = SafeArrayCreate((VARTYPE)(vt & VT_TYPEMASK), dim, psab);
+ if (psa == NULL)
+ hr = E_OUTOFMEMORY;
+ else
+ hr = SafeArrayLock(psa);
+ if (SUCCEEDED(hr)) {
+ ole_set_safe_array(dim-1, psa, pid, pub, val, dim, (VARTYPE)(vt & VT_TYPEMASK));
+ hr = SafeArrayUnlock(psa);
+ }
+
+ if(pub) free(pub);
+ if(psab) free(psab);
+ if(pid) free(pid);
+
+ if (SUCCEEDED(hr)) {
+ V_VT(var) = vt;
+ V_ARRAY(var) = psa;
+ }
+ else {
+ if (psa != NULL)
+ SafeArrayDestroy(psa);
+ }
+ return hr;
+}
+
+void
+ole_val2variant(VALUE val, VARIANT *var)
+{
+ struct oledata *pole = NULL;
+ if(rb_obj_is_kind_of(val, cWIN32OLE)) {
+ pole = oledata_get_struct(val);
+ OLE_ADDREF(pole->pDispatch);
+ V_VT(var) = VT_DISPATCH;
+ V_DISPATCH(var) = pole->pDispatch;
+ return;
+ }
+ if (rb_obj_is_kind_of(val, cWIN32OLE_VARIANT)) {
+ ole_variant2variant(val, var);
+ return;
+ }
+ if (rb_obj_is_kind_of(val, cWIN32OLE_RECORD)) {
+ ole_rec2variant(val, var);
+ return;
+ }
+ if (rb_obj_is_kind_of(val, rb_cTime)) {
+ V_VT(var) = VT_DATE;
+ V_DATE(var) = rbtime2vtdate(val);
+ return;
+ }
+ switch (TYPE(val)) {
+ case T_ARRAY:
+ ole_val_ary2variant_ary(val, var, VT_VARIANT|VT_ARRAY);
+ break;
+ case T_STRING:
+ V_VT(var) = VT_BSTR;
+ V_BSTR(var) = ole_vstr2wc(val);
+ break;
+ case T_FIXNUM:
+ V_VT(var) = VT_I4;
+ V_I4(var) = NUM2INT(val);
+ break;
+ case T_BIGNUM:
+ V_VT(var) = VT_R8;
+ V_R8(var) = rb_big2dbl(val);
+ break;
+ case T_FLOAT:
+ V_VT(var) = VT_R8;
+ V_R8(var) = NUM2DBL(val);
+ break;
+ case T_TRUE:
+ V_VT(var) = VT_BOOL;
+ V_BOOL(var) = VARIANT_TRUE;
+ break;
+ case T_FALSE:
+ V_VT(var) = VT_BOOL;
+ V_BOOL(var) = VARIANT_FALSE;
+ break;
+ case T_NIL:
+ if (g_nil_to == VT_ERROR) {
+ V_VT(var) = VT_ERROR;
+ V_ERROR(var) = DISP_E_PARAMNOTFOUND;
+ }else {
+ V_VT(var) = VT_EMPTY;
+ }
+ break;
+ default:
+ V_VT(var) = VT_DISPATCH;
+ V_DISPATCH(var) = val2dispatch(val);
+ break;
+ }
+}
+
+void
+ole_val2variant2(VALUE val, VARIANT *var)
+{
+ g_nil_to = VT_EMPTY;
+ ole_val2variant(val, var);
+ g_nil_to = VT_ERROR;
+}
+
+VALUE
+make_inspect(const char *class_name, VALUE detail)
+{
+ VALUE str;
+ str = rb_str_new2("#<");
+ rb_str_cat2(str, class_name);
+ rb_str_cat2(str, ":");
+ rb_str_concat(str, detail);
+ rb_str_cat2(str, ">");
+ return str;
+}
+
+VALUE
+default_inspect(VALUE self, const char *class_name)
+{
+ VALUE detail = rb_funcall(self, rb_intern("to_s"), 0);
+ return make_inspect(class_name, detail);
+}
+
+static VALUE
+ole_set_member(VALUE self, IDispatch *dispatch)
+{
+ struct oledata *pole = NULL;
+ pole = oledata_get_struct(self);
+ if (pole->pDispatch) {
+ OLE_RELEASE(pole->pDispatch);
+ pole->pDispatch = NULL;
+ }
+ pole->pDispatch = dispatch;
+ return self;
+}
+
+
+static VALUE
+fole_s_allocate(VALUE klass)
+{
+ struct oledata *pole;
+ VALUE obj;
+ ole_initialize();
+ obj = TypedData_Make_Struct(klass, struct oledata, &ole_datatype, pole);
+ pole->pDispatch = NULL;
+ return obj;
+}
+
+static VALUE
+create_win32ole_object(VALUE klass, IDispatch *pDispatch, int argc, VALUE *argv)
+{
+ VALUE obj = fole_s_allocate(klass);
+ ole_set_member(obj, pDispatch);
+ return obj;
+}
+
+static VALUE
+ary_new_dim(VALUE myary, LONG *pid, LONG *plb, LONG dim) {
+ long i;
+ VALUE obj = Qnil;
+ VALUE pobj = Qnil;
+ long *ids = ALLOC_N(long, dim);
+ if (!ids) {
+ rb_raise(rb_eRuntimeError, "memory allocation error");
+ }
+ for(i = 0; i < dim; i++) {
+ ids[i] = pid[i] - plb[i];
+ }
+ obj = myary;
+ pobj = myary;
+ for(i = 0; i < dim-1; i++) {
+ obj = rb_ary_entry(pobj, ids[i]);
+ if (obj == Qnil) {
+ rb_ary_store(pobj, ids[i], rb_ary_new());
+ }
+ obj = rb_ary_entry(pobj, ids[i]);
+ pobj = obj;
+ }
+ if (ids) free(ids);
+ return obj;
+}
+
+static void
+ary_store_dim(VALUE myary, LONG *pid, LONG *plb, LONG dim, VALUE val) {
+ long id = pid[dim - 1] - plb[dim - 1];
+ VALUE obj = ary_new_dim(myary, pid, plb, dim);
+ rb_ary_store(obj, id, val);
+}
+
+VALUE
+ole_variant2val(VARIANT *pvar)
+{
+ VALUE obj = Qnil;
+ VARTYPE vt = V_VT(pvar);
+ HRESULT hr;
+ while ( vt == (VT_BYREF | VT_VARIANT) ) {
+ pvar = V_VARIANTREF(pvar);
+ vt = V_VT(pvar);
+ }
+
+ if(V_ISARRAY(pvar)) {
+ VARTYPE vt_base = vt & VT_TYPEMASK;
+ SAFEARRAY *psa = V_ISBYREF(pvar) ? *V_ARRAYREF(pvar) : V_ARRAY(pvar);
+ UINT i = 0;
+ LONG *pid, *plb, *pub;
+ VARIANT variant;
+ VALUE val;
+ UINT dim = 0;
+ if (!psa) {
+ return obj;
+ }
+ dim = SafeArrayGetDim(psa);
+ pid = ALLOC_N(LONG, dim);
+ plb = ALLOC_N(LONG, dim);
+ pub = ALLOC_N(LONG, dim);
+
+ if(!pid || !plb || !pub) {
+ if(pid) free(pid);
+ if(plb) free(plb);
+ if(pub) free(pub);
+ rb_raise(rb_eRuntimeError, "memory allocation error");
+ }
+
+ for(i = 0; i < dim; ++i) {
+ SafeArrayGetLBound(psa, i+1, &plb[i]);
+ SafeArrayGetLBound(psa, i+1, &pid[i]);
+ SafeArrayGetUBound(psa, i+1, &pub[i]);
+ }
+ hr = SafeArrayLock(psa);
+ if (SUCCEEDED(hr)) {
+ obj = rb_ary_new();
+ i = 0;
+ VariantInit(&variant);
+ V_VT(&variant) = vt_base | VT_BYREF;
+ if (vt_base == VT_RECORD) {
+ hr = SafeArrayGetRecordInfo(psa, &V_RECORDINFO(&variant));
+ if (SUCCEEDED(hr)) {
+ V_VT(&variant) = VT_RECORD;
+ }
+ }
+ while (i < dim) {
+ ary_new_dim(obj, pid, plb, dim);
+ if (vt_base == VT_RECORD)
+ hr = SafeArrayPtrOfIndex(psa, pid, &V_RECORD(&variant));
+ else
+ hr = SafeArrayPtrOfIndex(psa, pid, &V_BYREF(&variant));
+ if (SUCCEEDED(hr)) {
+ val = ole_variant2val(&variant);
+ ary_store_dim(obj, pid, plb, dim, val);
+ }
+ for (i = 0; i < dim; ++i) {
+ if (++pid[i] <= pub[i])
+ break;
+ pid[i] = plb[i];
+ }
+ }
+ SafeArrayUnlock(psa);
+ }
+ if(pid) free(pid);
+ if(plb) free(plb);
+ if(pub) free(pub);
+ return obj;
+ }
+ switch(V_VT(pvar) & ~VT_BYREF){
+ case VT_EMPTY:
+ break;
+ case VT_NULL:
+ break;
+ case VT_I1:
+ if(V_ISBYREF(pvar))
+ obj = INT2NUM((long)*V_I1REF(pvar));
+ else
+ obj = INT2NUM((long)V_I1(pvar));
+ break;
+
+ case VT_UI1:
+ if(V_ISBYREF(pvar))
+ obj = INT2NUM((long)*V_UI1REF(pvar));
+ else
+ obj = INT2NUM((long)V_UI1(pvar));
+ break;
+
+ case VT_I2:
+ if(V_ISBYREF(pvar))
+ obj = INT2NUM((long)*V_I2REF(pvar));
+ else
+ obj = INT2NUM((long)V_I2(pvar));
+ break;
+
+ case VT_UI2:
+ if(V_ISBYREF(pvar))
+ obj = INT2NUM((long)*V_UI2REF(pvar));
+ else
+ obj = INT2NUM((long)V_UI2(pvar));
+ break;
+
+ case VT_I4:
+ if(V_ISBYREF(pvar))
+ obj = INT2NUM((long)*V_I4REF(pvar));
+ else
+ obj = INT2NUM((long)V_I4(pvar));
+ break;
+
+ case VT_UI4:
+ if(V_ISBYREF(pvar))
+ obj = INT2NUM((long)*V_UI4REF(pvar));
+ else
+ obj = INT2NUM((long)V_UI4(pvar));
+ break;
+
+ case VT_INT:
+ if(V_ISBYREF(pvar))
+ obj = INT2NUM((long)*V_INTREF(pvar));
+ else
+ obj = INT2NUM((long)V_INT(pvar));
+ break;
+
+ case VT_UINT:
+ if(V_ISBYREF(pvar))
+ obj = INT2NUM((long)*V_UINTREF(pvar));
+ else
+ obj = INT2NUM((long)V_UINT(pvar));
+ break;
+
+#if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
+ case VT_I8:
+ if(V_ISBYREF(pvar))
+#if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
+#ifdef V_I8REF
+ obj = I8_2_NUM(*V_I8REF(pvar));
+#endif
+#else
+ obj = Qnil;
+#endif
+ else
+ obj = I8_2_NUM(V_I8(pvar));
+ break;
+ case VT_UI8:
+ if(V_ISBYREF(pvar))
+#if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
+#ifdef V_UI8REF
+ obj = UI8_2_NUM(*V_UI8REF(pvar));
+#endif
+#else
+ obj = Qnil;
+#endif
+ else
+ obj = UI8_2_NUM(V_UI8(pvar));
+ break;
+#endif /* (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__) */
+
+ case VT_R4:
+ if(V_ISBYREF(pvar))
+ obj = rb_float_new(*V_R4REF(pvar));
+ else
+ obj = rb_float_new(V_R4(pvar));
+ break;
+
+ case VT_R8:
+ if(V_ISBYREF(pvar))
+ obj = rb_float_new(*V_R8REF(pvar));
+ else
+ obj = rb_float_new(V_R8(pvar));
+ break;
+
+ case VT_BSTR:
+ {
+ if(V_ISBYREF(pvar))
+ obj = ole_wc2vstr(*V_BSTRREF(pvar), FALSE);
+ else
+ obj = ole_wc2vstr(V_BSTR(pvar), FALSE);
+ break;
+ }
+
+ case VT_ERROR:
+ if(V_ISBYREF(pvar))
+ obj = INT2NUM(*V_ERRORREF(pvar));
+ else
+ obj = INT2NUM(V_ERROR(pvar));
+ break;
+
+ case VT_BOOL:
+ if (V_ISBYREF(pvar))
+ obj = (*V_BOOLREF(pvar) ? Qtrue : Qfalse);
+ else
+ obj = (V_BOOL(pvar) ? Qtrue : Qfalse);
+ break;
+
+ case VT_DISPATCH:
+ {
+ IDispatch *pDispatch;
+
+ if (V_ISBYREF(pvar))
+ pDispatch = *V_DISPATCHREF(pvar);
+ else
+ pDispatch = V_DISPATCH(pvar);
+
+ if (pDispatch != NULL ) {
+ OLE_ADDREF(pDispatch);
+ obj = create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);
+ }
+ break;
+ }
+
+ case VT_UNKNOWN:
+ {
+ /* get IDispatch interface from IUnknown interface */
+ IUnknown *punk;
+ IDispatch *pDispatch;
+ void *p;
+ HRESULT hr;
+
+ if (V_ISBYREF(pvar))
+ punk = *V_UNKNOWNREF(pvar);
+ else
+ punk = V_UNKNOWN(pvar);
+
+ if(punk != NULL) {
+ hr = punk->lpVtbl->QueryInterface(punk, &IID_IDispatch, &p);
+ if(SUCCEEDED(hr)) {
+ pDispatch = p;
+ obj = create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);
+ }
+ }
+ break;
+ }
+
+ case VT_DATE:
+ {
+ DATE date;
+ if(V_ISBYREF(pvar))
+ date = *V_DATEREF(pvar);
+ else
+ date = V_DATE(pvar);
+
+ obj = vtdate2rbtime(date);
+ break;
+ }
+
+ case VT_RECORD:
+ {
+ IRecordInfo *pri = V_RECORDINFO(pvar);
+ void *prec = V_RECORD(pvar);
+ obj = create_win32ole_record(pri, prec);
+ break;
+ }
+
+ case VT_CY:
+ default:
+ {
+ HRESULT hr;
+ VARIANT variant;
+ VariantInit(&variant);
+ hr = VariantChangeTypeEx(&variant, pvar,
+ cWIN32OLE_lcid, 0, VT_BSTR);
+ if (SUCCEEDED(hr) && V_VT(&variant) == VT_BSTR) {
+ obj = ole_wc2vstr(V_BSTR(&variant), FALSE);
+ }
+ VariantClear(&variant);
+ break;
+ }
+ }
+ return obj;
+}
+
+LONG
+reg_open_key(HKEY hkey, const char *name, HKEY *phkey)
+{
+ return RegOpenKeyEx(hkey, name, 0, KEY_READ, phkey);
+}
+
+LONG
+reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey)
+{
+ return reg_open_key(hkey, StringValuePtr(key), phkey);
+}
+
+VALUE
+reg_enum_key(HKEY hkey, DWORD i)
+{
+ char buf[BUFSIZ + 1];
+ DWORD size_buf = sizeof(buf);
+ FILETIME ft;
+ LONG err = RegEnumKeyEx(hkey, i, buf, &size_buf,
+ NULL, NULL, NULL, &ft);
+ if(err == ERROR_SUCCESS) {
+ buf[BUFSIZ] = '\0';
+ return rb_str_new2(buf);
+ }
+ return Qnil;
+}
+
+VALUE
+reg_get_val(HKEY hkey, const char *subkey)
+{
+ char *pbuf;
+ DWORD dwtype = 0;
+ DWORD size = 0;
+ VALUE val = Qnil;
+ LONG err = RegQueryValueEx(hkey, subkey, NULL, &dwtype, NULL, &size);
+
+ if (err == ERROR_SUCCESS) {
+ pbuf = ALLOC_N(char, size + 1);
+ err = RegQueryValueEx(hkey, subkey, NULL, &dwtype, (BYTE *)pbuf, &size);
+ if (err == ERROR_SUCCESS) {
+ pbuf[size] = '\0';
+ if (dwtype == REG_EXPAND_SZ) {
+ char* pbuf2 = (char *)pbuf;
+ DWORD len = ExpandEnvironmentStrings(pbuf2, NULL, 0);
+ pbuf = ALLOC_N(char, len + 1);
+ ExpandEnvironmentStrings(pbuf2, pbuf, len + 1);
+ free(pbuf2);
+ }
+ val = rb_str_new2((char *)pbuf);
+ }
+ free(pbuf);
+ }
+ return val;
+}
+
+VALUE
+reg_get_val2(HKEY hkey, const char *subkey)
+{
+ HKEY hsubkey;
+ LONG err;
+ VALUE val = Qnil;
+ err = RegOpenKeyEx(hkey, subkey, 0, KEY_READ, &hsubkey);
+ if (err == ERROR_SUCCESS) {
+ val = reg_get_val(hsubkey, NULL);
+ RegCloseKey(hsubkey);
+ }
+ if (val == Qnil) {
+ val = reg_get_val(hkey, subkey);
+ }
+ return val;
+}
+
+static void
+ole_const_load(ITypeLib *pTypeLib, VALUE klass, VALUE self)
+{
+ unsigned int count;
+ unsigned int index;
+ int iVar;
+ ITypeInfo *pTypeInfo;
+ TYPEATTR *pTypeAttr;
+ VARDESC *pVarDesc;
+ HRESULT hr;
+ unsigned int len;
+ BSTR bstr;
+ char *pName = NULL;
+ VALUE val;
+ VALUE constant;
+ ID id;
+ constant = rb_hash_new();
+ count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
+ for (index = 0; index < count; index++) {
+ hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, index, &pTypeInfo);
+ if (FAILED(hr))
+ continue;
+ hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
+ if(FAILED(hr)) {
+ OLE_RELEASE(pTypeInfo);
+ continue;
+ }
+ for(iVar = 0; iVar < pTypeAttr->cVars; iVar++) {
+ hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, iVar, &pVarDesc);
+ if(FAILED(hr))
+ continue;
+ if(pVarDesc->varkind == VAR_CONST &&
+ !(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN |
+ VARFLAG_FRESTRICTED |
+ VARFLAG_FNONBROWSABLE))) {
+ hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr,
+ 1, &len);
+ if(FAILED(hr) || len == 0 || !bstr)
+ continue;
+ pName = ole_wc2mb(bstr);
+ val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue));
+ *pName = toupper((int)*pName);
+ id = rb_intern(pName);
+ if (rb_is_const_id(id)) {
+ rb_define_const(klass, pName, val);
+ }
+ else {
+ rb_hash_aset(constant, rb_str_new2(pName), val);
+ }
+ SysFreeString(bstr);
+ if(pName) {
+ free(pName);
+ pName = NULL;
+ }
+ }
+ pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
+ }
+ pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr);
+ OLE_RELEASE(pTypeInfo);
+ }
+ rb_define_const(klass, "CONSTANTS", constant);
+}
+
+static HRESULT
+clsid_from_remote(VALUE host, VALUE com, CLSID *pclsid)
+{
+ HKEY hlm;
+ HKEY hpid;
+ VALUE subkey;
+ LONG err;
+ char clsid[100];
+ OLECHAR *pbuf;
+ DWORD len;
+ DWORD dwtype;
+ HRESULT hr = S_OK;
+ err = RegConnectRegistry(StringValuePtr(host), HKEY_LOCAL_MACHINE, &hlm);
+ if (err != ERROR_SUCCESS)
+ return HRESULT_FROM_WIN32(err);
+ subkey = rb_str_new2("SOFTWARE\\Classes\\");
+ rb_str_concat(subkey, com);
+ rb_str_cat2(subkey, "\\CLSID");
+ err = RegOpenKeyEx(hlm, StringValuePtr(subkey), 0, KEY_READ, &hpid);
+ if (err != ERROR_SUCCESS)
+ hr = HRESULT_FROM_WIN32(err);
+ else {
+ len = sizeof(clsid);
+ err = RegQueryValueEx(hpid, "", NULL, &dwtype, (BYTE *)clsid, &len);
+ if (err == ERROR_SUCCESS && dwtype == REG_SZ) {
+ pbuf = ole_mb2wc(clsid, -1);
+ hr = CLSIDFromString(pbuf, pclsid);
+ SysFreeString(pbuf);
+ }
+ else {
+ hr = HRESULT_FROM_WIN32(err);
+ }
+ RegCloseKey(hpid);
+ }
+ RegCloseKey(hlm);
+ return hr;
+}
+
+static VALUE
+ole_create_dcom(VALUE self, VALUE ole, VALUE host, VALUE others)
+{
+ HRESULT hr;
+ CLSID clsid;
+ OLECHAR *pbuf;
+
+ COSERVERINFO serverinfo;
+ MULTI_QI multi_qi;
+ DWORD clsctx = CLSCTX_REMOTE_SERVER;
+
+ if (!gole32)
+ gole32 = LoadLibrary("OLE32");
+ if (!gole32)
+ rb_raise(rb_eRuntimeError, "failed to load OLE32");
+ if (!gCoCreateInstanceEx)
+ gCoCreateInstanceEx = (FNCOCREATEINSTANCEEX*)
+ GetProcAddress(gole32, "CoCreateInstanceEx");
+ if (!gCoCreateInstanceEx)
+ rb_raise(rb_eRuntimeError, "CoCreateInstanceEx is not supported in this environment");
+
+ pbuf = ole_vstr2wc(ole);
+ hr = CLSIDFromProgID(pbuf, &clsid);
+ if (FAILED(hr))
+ hr = clsid_from_remote(host, ole, &clsid);
+ if (FAILED(hr))
+ hr = CLSIDFromString(pbuf, &clsid);
+ SysFreeString(pbuf);
+ if (FAILED(hr))
+ ole_raise(hr, eWIN32OLERuntimeError,
+ "unknown OLE server: `%s'",
+ StringValuePtr(ole));
+ memset(&serverinfo, 0, sizeof(COSERVERINFO));
+ serverinfo.pwszName = ole_vstr2wc(host);
+ memset(&multi_qi, 0, sizeof(MULTI_QI));
+ multi_qi.pIID = &IID_IDispatch;
+ hr = gCoCreateInstanceEx(&clsid, NULL, clsctx, &serverinfo, 1, &multi_qi);
+ SysFreeString(serverinfo.pwszName);
+ if (FAILED(hr))
+ ole_raise(hr, eWIN32OLERuntimeError,
+ "failed to create DCOM server `%s' in `%s'",
+ StringValuePtr(ole),
+ StringValuePtr(host));
+
+ ole_set_member(self, (IDispatch*)multi_qi.pItf);
+ return self;
+}
+
+static VALUE
+ole_bind_obj(VALUE moniker, int argc, VALUE *argv, VALUE self)
+{
+ IBindCtx *pBindCtx;
+ IMoniker *pMoniker;
+ IDispatch *pDispatch;
+ void *p;
+ HRESULT hr;
+ OLECHAR *pbuf;
+ ULONG eaten = 0;
+
+ ole_initialize();
+
+ hr = CreateBindCtx(0, &pBindCtx);
+ if(FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError,
+ "failed to create bind context");
+ }
+
+ pbuf = ole_vstr2wc(moniker);
+ hr = MkParseDisplayName(pBindCtx, pbuf, &eaten, &pMoniker);
+ SysFreeString(pbuf);
+ if(FAILED(hr)) {
+ OLE_RELEASE(pBindCtx);
+ ole_raise(hr, eWIN32OLERuntimeError,
+ "failed to parse display name of moniker `%s'",
+ StringValuePtr(moniker));
+ }
+ hr = pMoniker->lpVtbl->BindToObject(pMoniker, pBindCtx, NULL,
+ &IID_IDispatch, &p);
+ pDispatch = p;
+ OLE_RELEASE(pMoniker);
+ OLE_RELEASE(pBindCtx);
+
+ if(FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError,
+ "failed to bind moniker `%s'",
+ StringValuePtr(moniker));
+ }
+ return create_win32ole_object(self, pDispatch, argc, argv);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE.connect( ole ) --> aWIN32OLE
+ *
+ * Returns running OLE Automation object or WIN32OLE object from moniker.
+ * 1st argument should be OLE program id or class id or moniker.
+ *
+ * WIN32OLE.connect('Excel.Application') # => WIN32OLE object which represents running Excel.
+ */
+static VALUE
+fole_s_connect(int argc, VALUE *argv, VALUE self)
+{
+ VALUE svr_name;
+ VALUE others;
+ HRESULT hr;
+ CLSID clsid;
+ OLECHAR *pBuf;
+ IDispatch *pDispatch;
+ void *p;
+ IUnknown *pUnknown;
+
+ /* initialize to use OLE */
+ ole_initialize();
+
+ rb_scan_args(argc, argv, "1*", &svr_name, &others);
+ StringValue(svr_name);
+ if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name)) {
+ rb_raise(rb_eSecurityError, "insecure connection - `%s'",
+ StringValuePtr(svr_name));
+ }
+
+ /* get CLSID from OLE server name */
+ pBuf = ole_vstr2wc(svr_name);
+ hr = CLSIDFromProgID(pBuf, &clsid);
+ if(FAILED(hr)) {
+ hr = CLSIDFromString(pBuf, &clsid);
+ }
+ SysFreeString(pBuf);
+ if(FAILED(hr)) {
+ return ole_bind_obj(svr_name, argc, argv, self);
+ }
+
+ hr = GetActiveObject(&clsid, 0, &pUnknown);
+ if (FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError,
+ "OLE server `%s' not running", StringValuePtr(svr_name));
+ }
+ hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IDispatch, &p);
+ pDispatch = p;
+ if(FAILED(hr)) {
+ OLE_RELEASE(pUnknown);
+ ole_raise(hr, eWIN32OLERuntimeError,
+ "failed to create WIN32OLE server `%s'",
+ StringValuePtr(svr_name));
+ }
+
+ OLE_RELEASE(pUnknown);
+
+ return create_win32ole_object(self, pDispatch, argc, argv);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE.const_load( ole, mod = WIN32OLE)
+ *
+ * Defines the constants of OLE Automation server as mod's constants.
+ * The first argument is WIN32OLE object or type library name.
+ * If 2nd argument is omitted, the default is WIN32OLE.
+ * The first letter of Ruby's constant variable name is upper case,
+ * so constant variable name of WIN32OLE object is capitalized.
+ * For example, the 'xlTop' constant of Excel is changed to 'XlTop'
+ * in WIN32OLE.
+ * If the first letter of constant variable is not [A-Z], then
+ * the constant is defined as CONSTANTS hash element.
+ *
+ * module EXCEL_CONST
+ * end
+ * excel = WIN32OLE.new('Excel.Application')
+ * WIN32OLE.const_load(excel, EXCEL_CONST)
+ * puts EXCEL_CONST::XlTop # => -4160
+ * puts EXCEL_CONST::CONSTANTS['_xlDialogChartSourceData'] # => 541
+ *
+ * WIN32OLE.const_load(excel)
+ * puts WIN32OLE::XlTop # => -4160
+ *
+ * module MSO
+ * end
+ * WIN32OLE.const_load('Microsoft Office 9.0 Object Library', MSO)
+ * puts MSO::MsoLineSingle # => 1
+ */
+static VALUE
+fole_s_const_load(int argc, VALUE *argv, VALUE self)
+{
+ VALUE ole;
+ VALUE klass;
+ struct oledata *pole = NULL;
+ ITypeInfo *pTypeInfo;
+ ITypeLib *pTypeLib;
+ unsigned int index;
+ HRESULT hr;
+ OLECHAR *pBuf;
+ VALUE file;
+ LCID lcid = cWIN32OLE_lcid;
+
+ rb_scan_args(argc, argv, "11", &ole, &klass);
+ if (!RB_TYPE_P(klass, T_CLASS) &&
+ !RB_TYPE_P(klass, T_MODULE) &&
+ !RB_TYPE_P(klass, T_NIL)) {
+ rb_raise(rb_eTypeError, "2nd parameter must be Class or Module");
+ }
+ if (rb_obj_is_kind_of(ole, cWIN32OLE)) {
+ pole = oledata_get_struct(ole);
+ hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
+ 0, lcid, &pTypeInfo);
+ if(FAILED(hr)) {
+ ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
+ }
+ hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
+ if(FAILED(hr)) {
+ OLE_RELEASE(pTypeInfo);
+ ole_raise(hr, rb_eRuntimeError, "failed to GetContainingTypeLib");
+ }
+ OLE_RELEASE(pTypeInfo);
+ if(!RB_TYPE_P(klass, T_NIL)) {
+ ole_const_load(pTypeLib, klass, self);
+ }
+ else {
+ ole_const_load(pTypeLib, cWIN32OLE, self);
+ }
+ OLE_RELEASE(pTypeLib);
+ }
+ else if(RB_TYPE_P(ole, T_STRING)) {
+ file = typelib_file(ole);
+ if (file == Qnil) {
+ file = ole;
+ }
+ pBuf = ole_vstr2wc(file);
+ hr = LoadTypeLibEx(pBuf, REGKIND_NONE, &pTypeLib);
+ SysFreeString(pBuf);
+ if (FAILED(hr))
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx");
+ if(!RB_TYPE_P(klass, T_NIL)) {
+ ole_const_load(pTypeLib, klass, self);
+ }
+ else {
+ ole_const_load(pTypeLib, cWIN32OLE, self);
+ }
+ OLE_RELEASE(pTypeLib);
+ }
+ else {
+ rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE instance");
+ }
+ return Qnil;
+}
+
+static ULONG
+reference_count(struct oledata * pole)
+{
+ ULONG n = 0;
+ if(pole->pDispatch) {
+ OLE_ADDREF(pole->pDispatch);
+ n = OLE_RELEASE(pole->pDispatch);
+ }
+ return n;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE.ole_reference_count(aWIN32OLE) --> number
+ *
+ * Returns reference counter of Dispatch interface of WIN32OLE object.
+ * You should not use this method because this method
+ * exists only for debugging WIN32OLE.
+ */
+static VALUE
+fole_s_reference_count(VALUE self, VALUE obj)
+{
+ struct oledata * pole = NULL;
+ pole = oledata_get_struct(obj);
+ return INT2NUM(reference_count(pole));
+}
+
+/*
+ * call-seq:
+ * WIN32OLE.ole_free(aWIN32OLE) --> number
+ *
+ * Invokes Release method of Dispatch interface of WIN32OLE object.
+ * You should not use this method because this method
+ * exists only for debugging WIN32OLE.
+ * The return value is reference counter of OLE object.
+ */
+static VALUE
+fole_s_free(VALUE self, VALUE obj)
+{
+ ULONG n = 0;
+ struct oledata * pole = NULL;
+ pole = oledata_get_struct(obj);
+ if(pole->pDispatch) {
+ if (reference_count(pole) > 0) {
+ n = OLE_RELEASE(pole->pDispatch);
+ }
+ }
+ return INT2NUM(n);
+}
+
+static HWND
+ole_show_help(VALUE helpfile, VALUE helpcontext)
+{
+ FNHTMLHELP *pfnHtmlHelp;
+ HWND hwnd = 0;
+
+ if(!ghhctrl)
+ ghhctrl = LoadLibrary("HHCTRL.OCX");
+ if (!ghhctrl)
+ return hwnd;
+ pfnHtmlHelp = (FNHTMLHELP*)GetProcAddress(ghhctrl, "HtmlHelpA");
+ if (!pfnHtmlHelp)
+ return hwnd;
+ hwnd = pfnHtmlHelp(GetDesktopWindow(), StringValuePtr(helpfile),
+ 0x0f, NUM2INT(helpcontext));
+ if (hwnd == 0)
+ hwnd = pfnHtmlHelp(GetDesktopWindow(), StringValuePtr(helpfile),
+ 0, NUM2INT(helpcontext));
+ return hwnd;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE.ole_show_help(obj [,helpcontext])
+ *
+ * Displays helpfile. The 1st argument specifies WIN32OLE_TYPE
+ * object or WIN32OLE_METHOD object or helpfile.
+ *
+ * excel = WIN32OLE.new('Excel.Application')
+ * typeobj = excel.ole_type
+ * WIN32OLE.ole_show_help(typeobj)
+ */
+static VALUE
+fole_s_show_help(int argc, VALUE *argv, VALUE self)
+{
+ VALUE target;
+ VALUE helpcontext;
+ VALUE helpfile;
+ VALUE name;
+ HWND hwnd;
+ rb_scan_args(argc, argv, "11", &target, &helpcontext);
+ if (rb_obj_is_kind_of(target, cWIN32OLE_TYPE) ||
+ rb_obj_is_kind_of(target, cWIN32OLE_METHOD)) {
+ helpfile = rb_funcall(target, rb_intern("helpfile"), 0);
+ if(strlen(StringValuePtr(helpfile)) == 0) {
+ name = rb_ivar_get(target, rb_intern("name"));
+ rb_raise(rb_eRuntimeError, "no helpfile of `%s'",
+ StringValuePtr(name));
+ }
+ helpcontext = rb_funcall(target, rb_intern("helpcontext"), 0);
+ } else {
+ helpfile = target;
+ }
+ if (!RB_TYPE_P(helpfile, T_STRING)) {
+ rb_raise(rb_eTypeError, "1st parameter must be (String|WIN32OLE_TYPE|WIN32OLE_METHOD)");
+ }
+ hwnd = ole_show_help(helpfile, helpcontext);
+ if(hwnd == 0) {
+ rb_raise(rb_eRuntimeError, "failed to open help file `%s'",
+ StringValuePtr(helpfile));
+ }
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE.codepage
+ *
+ * Returns current codepage.
+ * WIN32OLE.codepage # => WIN32OLE::CP_ACP
+ */
+static VALUE
+fole_s_get_code_page(VALUE self)
+{
+ return INT2FIX(cWIN32OLE_cp);
+}
+
+static BOOL CALLBACK
+installed_code_page_proc(LPTSTR str) {
+ if (strtoul(str, NULL, 10) == g_cp_to_check) {
+ g_cp_installed = TRUE;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static BOOL
+code_page_installed(UINT cp)
+{
+ g_cp_installed = FALSE;
+ g_cp_to_check = cp;
+ EnumSystemCodePages(installed_code_page_proc, CP_INSTALLED);
+ return g_cp_installed;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE.codepage = CP
+ *
+ * Sets current codepage.
+ * The WIN32OLE.codepage is initialized according to
+ * Encoding.default_internal.
+ * If Encoding.default_internal is nil then WIN32OLE.codepage
+ * is initialized according to Encoding.default_external.
+ *
+ * WIN32OLE.codepage = WIN32OLE::CP_UTF8
+ * WIN32OLE.codepage = 65001
+ */
+static VALUE
+fole_s_set_code_page(VALUE self, VALUE vcp)
+{
+ UINT cp = FIX2INT(vcp);
+ set_ole_codepage(cp);
+ /*
+ * Should this method return old codepage?
+ */
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE.locale -> locale id.
+ *
+ * Returns current locale id (lcid). The default locale is
+ * WIN32OLE::LOCALE_SYSTEM_DEFAULT.
+ *
+ * lcid = WIN32OLE.locale
+ */
+static VALUE
+fole_s_get_locale(VALUE self)
+{
+ return INT2FIX(cWIN32OLE_lcid);
+}
+
+static BOOL
+CALLBACK installed_lcid_proc(LPTSTR str)
+{
+ if (strcmp(str, g_lcid_to_check) == 0) {
+ g_lcid_installed = TRUE;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static BOOL
+lcid_installed(LCID lcid)
+{
+ g_lcid_installed = FALSE;
+ snprintf(g_lcid_to_check, sizeof(g_lcid_to_check), "%08lx", (unsigned long)lcid);
+ EnumSystemLocales(installed_lcid_proc, LCID_INSTALLED);
+ return g_lcid_installed;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE.locale = lcid
+ *
+ * Sets current locale id (lcid).
+ *
+ * WIN32OLE.locale = 1033 # set locale English(U.S)
+ * obj = WIN32OLE_VARIANT.new("$100,000", WIN32OLE::VARIANT::VT_CY)
+ *
+ */
+static VALUE
+fole_s_set_locale(VALUE self, VALUE vlcid)
+{
+ LCID lcid = FIX2INT(vlcid);
+ if (lcid_installed(lcid)) {
+ cWIN32OLE_lcid = lcid;
+ } else {
+ switch (lcid) {
+ case LOCALE_SYSTEM_DEFAULT:
+ case LOCALE_USER_DEFAULT:
+ cWIN32OLE_lcid = lcid;
+ break;
+ default:
+ rb_raise(eWIN32OLERuntimeError, "not installed locale: %u", (unsigned int)lcid);
+ }
+ }
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE.create_guid
+ *
+ * Creates GUID.
+ * WIN32OLE.create_guid # => {1CB530F1-F6B1-404D-BCE6-1959BF91F4A8}
+ */
+static VALUE
+fole_s_create_guid(VALUE self)
+{
+ GUID guid;
+ HRESULT hr;
+ OLECHAR bstr[80];
+ int len = 0;
+ hr = CoCreateGuid(&guid);
+ if (FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to create GUID");
+ }
+ len = StringFromGUID2(&guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
+ if (len == 0) {
+ rb_raise(rb_eRuntimeError, "failed to create GUID(buffer over)");
+ }
+ return ole_wc2vstr(bstr, FALSE);
+}
+
+/*
+ * WIN32OLE.ole_initialize and WIN32OLE.ole_uninitialize
+ * are used in win32ole.rb to fix the issue bug #2618 (ruby-core:27634).
+ * You must not use these method.
+ */
+
+/* :nodoc: */
+static VALUE
+fole_s_ole_initialize(VALUE self)
+{
+ ole_initialize();
+ return Qnil;
+}
+
+/* :nodoc: */
+static VALUE
+fole_s_ole_uninitialize(VALUE self)
+{
+ ole_uninitialize();
+ return Qnil;
+}
+
+/*
+ * Document-class: WIN32OLE
+ *
+ * <code>WIN32OLE</code> objects represent OLE Automation object in Ruby.
+ *
+ * By using WIN32OLE, you can access OLE server like VBScript.
+ *
+ * Here is sample script.
+ *
+ * require 'win32ole'
+ *
+ * excel = WIN32OLE.new('Excel.Application')
+ * excel.visible = true
+ * workbook = excel.Workbooks.Add();
+ * worksheet = workbook.Worksheets(1);
+ * worksheet.Range("A1:D1").value = ["North","South","East","West"];
+ * worksheet.Range("A2:B2").value = [5.2, 10];
+ * worksheet.Range("C2").value = 8;
+ * worksheet.Range("D2").value = 20;
+ *
+ * range = worksheet.Range("A1:D2");
+ * range.select
+ * chart = workbook.Charts.Add;
+ *
+ * workbook.saved = true;
+ *
+ * excel.ActiveWorkbook.Close(0);
+ * excel.Quit();
+ *
+ * Unfortunately, Win32OLE doesn't support the argument passed by
+ * reference directly.
+ * Instead, Win32OLE provides WIN32OLE::ARGV or WIN32OLE_VARIANT object.
+ * If you want to get the result value of argument passed by reference,
+ * you can use WIN32OLE::ARGV or WIN32OLE_VARIANT.
+ *
+ * oleobj.method(arg1, arg2, refargv3)
+ * puts WIN32OLE::ARGV[2] # the value of refargv3 after called oleobj.method
+ *
+ * or
+ *
+ * refargv3 = WIN32OLE_VARIANT.new(XXX,
+ * WIN32OLE::VARIANT::VT_BYREF|WIN32OLE::VARIANT::VT_XXX)
+ * oleobj.method(arg1, arg2, refargv3)
+ * p refargv3.value # the value of refargv3 after called oleobj.method.
+ *
+ */
+
+/*
+ * call-seq:
+ * WIN32OLE.new(server, [host]) -> WIN32OLE object
+ *
+ * Returns a new WIN32OLE object(OLE Automation object).
+ * The first argument server specifies OLE Automation server.
+ * The first argument should be CLSID or PROGID.
+ * If second argument host specified, then returns OLE Automation
+ * object on host.
+ *
+ * WIN32OLE.new('Excel.Application') # => Excel OLE Automation WIN32OLE object.
+ * WIN32OLE.new('{00024500-0000-0000-C000-000000000046}') # => Excel OLE Automation WIN32OLE object.
+ */
+static VALUE
+fole_initialize(int argc, VALUE *argv, VALUE self)
+{
+ VALUE svr_name;
+ VALUE host;
+ VALUE others;
+ HRESULT hr;
+ CLSID clsid;
+ OLECHAR *pBuf;
+ IDispatch *pDispatch;
+ void *p;
+ rb_call_super(0, 0);
+ rb_scan_args(argc, argv, "11*", &svr_name, &host, &others);
+
+ StringValue(svr_name);
+ if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name)) {
+ rb_raise(rb_eSecurityError, "insecure object creation - `%s'",
+ StringValuePtr(svr_name));
+ }
+ if (!NIL_P(host)) {
+ StringValue(host);
+ if (rb_safe_level() > 0 && OBJ_TAINTED(host)) {
+ rb_raise(rb_eSecurityError, "insecure object creation - `%s'",
+ StringValuePtr(host));
+ }
+ return ole_create_dcom(self, svr_name, host, others);
+ }
+
+ /* get CLSID from OLE server name */
+ pBuf = ole_vstr2wc(svr_name);
+ hr = CLSIDFromProgID(pBuf, &clsid);
+ if(FAILED(hr)) {
+ hr = CLSIDFromString(pBuf, &clsid);
+ }
+ SysFreeString(pBuf);
+ if(FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError,
+ "unknown OLE server: `%s'",
+ StringValuePtr(svr_name));
+ }
+
+ /* get IDispatch interface */
+ hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
+ &IID_IDispatch, &p);
+ pDispatch = p;
+ if(FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError,
+ "failed to create WIN32OLE object from `%s'",
+ StringValuePtr(svr_name));
+ }
+
+ ole_set_member(self, pDispatch);
+ return self;
+}
+
+static int
+hash2named_arg(VALUE key, VALUE val, VALUE pop)
+{
+ struct oleparam* pOp = (struct oleparam *)pop;
+ unsigned int index, i;
+ index = pOp->dp.cNamedArgs;
+ /*---------------------------------------------
+ the data-type of key must be String or Symbol
+ -----------------------------------------------*/
+ if(!RB_TYPE_P(key, T_STRING) && !RB_TYPE_P(key, T_SYMBOL)) {
+ /* clear name of dispatch parameters */
+ for(i = 1; i < index + 1; i++) {
+ SysFreeString(pOp->pNamedArgs[i]);
+ }
+ /* clear dispatch parameters */
+ for(i = 0; i < index; i++ ) {
+ VariantClear(&(pOp->dp.rgvarg[i]));
+ }
+ /* raise an exception */
+ rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
+ }
+ if (RB_TYPE_P(key, T_SYMBOL)) {
+ key = rb_sym_to_s(key);
+ }
+
+ /* pNamedArgs[0] is <method name>, so "index + 1" */
+ pOp->pNamedArgs[index + 1] = ole_vstr2wc(key);
+
+ VariantInit(&(pOp->dp.rgvarg[index]));
+ ole_val2variant(val, &(pOp->dp.rgvarg[index]));
+
+ pOp->dp.cNamedArgs += 1;
+ return ST_CONTINUE;
+}
+
+static VALUE
+set_argv(VARIANTARG* realargs, unsigned int beg, unsigned int end)
+{
+ VALUE argv = rb_const_get(cWIN32OLE, rb_intern("ARGV"));
+
+ Check_Type(argv, T_ARRAY);
+ rb_ary_clear(argv);
+ while (end-- > beg) {
+ rb_ary_push(argv, ole_variant2val(&realargs[end]));
+ if (V_VT(&realargs[end]) != VT_RECORD) {
+ VariantClear(&realargs[end]);
+ }
+ }
+ return argv;
+}
+
+static VALUE
+ole_invoke(int argc, VALUE *argv, VALUE self, USHORT wFlags, BOOL is_bracket)
+{
+ LCID lcid = cWIN32OLE_lcid;
+ struct oledata *pole = NULL;
+ HRESULT hr;
+ VALUE cmd;
+ VALUE paramS;
+ VALUE param;
+ VALUE obj;
+ VALUE v;
+
+ BSTR wcmdname;
+
+ DISPID DispID;
+ DISPID* pDispID;
+ EXCEPINFO excepinfo;
+ VARIANT result;
+ VARIANTARG* realargs = NULL;
+ unsigned int argErr = 0;
+ unsigned int i;
+ unsigned int cNamedArgs;
+ int n;
+ struct oleparam op;
+ memset(&excepinfo, 0, sizeof(EXCEPINFO));
+
+ VariantInit(&result);
+
+ op.dp.rgvarg = NULL;
+ op.dp.rgdispidNamedArgs = NULL;
+ op.dp.cNamedArgs = 0;
+ op.dp.cArgs = 0;
+
+ rb_scan_args(argc, argv, "1*", &cmd, &paramS);
+ if(!RB_TYPE_P(cmd, T_STRING) && !RB_TYPE_P(cmd, T_SYMBOL) && !is_bracket) {
+ rb_raise(rb_eTypeError, "method is wrong type (expected String or Symbol)");
+ }
+ if (RB_TYPE_P(cmd, T_SYMBOL)) {
+ cmd = rb_sym_to_s(cmd);
+ }
+ pole = oledata_get_struct(self);
+ if(!pole->pDispatch) {
+ rb_raise(rb_eRuntimeError, "failed to get dispatch interface");
+ }
+ if (is_bracket) {
+ DispID = DISPID_VALUE;
+ argc += 1;
+ rb_ary_unshift(paramS, cmd);
+ } else {
+ wcmdname = ole_vstr2wc(cmd);
+ hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL,
+ &wcmdname, 1, lcid, &DispID);
+ SysFreeString(wcmdname);
+ if(FAILED(hr)) {
+ ole_raise(hr, rb_eNoMethodError,
+ "unknown property or method: `%s'",
+ StringValuePtr(cmd));
+ }
+ }
+
+ /* pick up last argument of method */
+ param = rb_ary_entry(paramS, argc-2);
+
+ op.dp.cNamedArgs = 0;
+
+ /* if last arg is hash object */
+ if(RB_TYPE_P(param, T_HASH)) {
+ /*------------------------------------------
+ hash object ==> named dispatch parameters
+ --------------------------------------------*/
+ cNamedArgs = rb_long2int(RHASH_SIZE(param));
+ op.dp.cArgs = cNamedArgs + argc - 2;
+ op.pNamedArgs = ALLOCA_N(OLECHAR*, cNamedArgs + 1);
+ op.dp.rgvarg = ALLOCA_N(VARIANTARG, op.dp.cArgs);
+
+ rb_hash_foreach(param, hash2named_arg, (VALUE)&op);
+
+ pDispID = ALLOCA_N(DISPID, cNamedArgs + 1);
+ op.pNamedArgs[0] = ole_vstr2wc(cmd);
+ hr = pole->pDispatch->lpVtbl->GetIDsOfNames(pole->pDispatch,
+ &IID_NULL,
+ op.pNamedArgs,
+ op.dp.cNamedArgs + 1,
+ lcid, pDispID);
+ for(i = 0; i < op.dp.cNamedArgs + 1; i++) {
+ SysFreeString(op.pNamedArgs[i]);
+ op.pNamedArgs[i] = NULL;
+ }
+ if(FAILED(hr)) {
+ /* clear dispatch parameters */
+ for(i = 0; i < op.dp.cArgs; i++ ) {
+ VariantClear(&op.dp.rgvarg[i]);
+ }
+ ole_raise(hr, eWIN32OLERuntimeError,
+ "failed to get named argument info: `%s'",
+ StringValuePtr(cmd));
+ }
+ op.dp.rgdispidNamedArgs = &(pDispID[1]);
+ }
+ else {
+ cNamedArgs = 0;
+ op.dp.cArgs = argc - 1;
+ op.pNamedArgs = ALLOCA_N(OLECHAR*, cNamedArgs + 1);
+ if (op.dp.cArgs > 0) {
+ op.dp.rgvarg = ALLOCA_N(VARIANTARG, op.dp.cArgs);
+ }
+ }
+ /*--------------------------------------
+ non hash args ==> dispatch parameters
+ ----------------------------------------*/
+ if(op.dp.cArgs > cNamedArgs) {
+ realargs = ALLOCA_N(VARIANTARG, op.dp.cArgs-cNamedArgs+1);
+ for(i = cNamedArgs; i < op.dp.cArgs; i++) {
+ n = op.dp.cArgs - i + cNamedArgs - 1;
+ VariantInit(&realargs[n]);
+ VariantInit(&op.dp.rgvarg[n]);
+ param = rb_ary_entry(paramS, i-cNamedArgs);
+ if (rb_obj_is_kind_of(param, cWIN32OLE_VARIANT)) {
+ ole_variant2variant(param, &op.dp.rgvarg[n]);
+ } else if (rb_obj_is_kind_of(param, cWIN32OLE_RECORD)) {
+ ole_val2variant(param, &realargs[n]);
+ op.dp.rgvarg[n] = realargs[n];
+ V_VT(&op.dp.rgvarg[n]) = VT_RECORD | VT_BYREF;
+ } else {
+ ole_val2variant(param, &realargs[n]);
+ V_VT(&op.dp.rgvarg[n]) = VT_VARIANT | VT_BYREF;
+ V_VARIANTREF(&op.dp.rgvarg[n]) = &realargs[n];
+ }
+ }
+ }
+ /* apparent you need to call propput, you need this */
+ if (wFlags & DISPATCH_PROPERTYPUT) {
+ if (op.dp.cArgs == 0)
+ ole_raise(ResultFromScode(E_INVALIDARG), eWIN32OLERuntimeError, "argument error");
+
+ op.dp.cNamedArgs = 1;
+ op.dp.rgdispidNamedArgs = ALLOCA_N( DISPID, 1 );
+ op.dp.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT;
+ }
+ hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
+ &IID_NULL, lcid, wFlags, &op.dp,
+ &result, &excepinfo, &argErr);
+
+ if (FAILED(hr)) {
+ /* retry to call args by value */
+ if(op.dp.cArgs >= cNamedArgs) {
+ for(i = cNamedArgs; i < op.dp.cArgs; i++) {
+ n = op.dp.cArgs - i + cNamedArgs - 1;
+ param = rb_ary_entry(paramS, i-cNamedArgs);
+ ole_val2variant(param, &op.dp.rgvarg[n]);
+ }
+ if (hr == DISP_E_EXCEPTION) {
+ ole_freeexceptinfo(&excepinfo);
+ }
+ memset(&excepinfo, 0, sizeof(EXCEPINFO));
+ VariantInit(&result);
+ hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
+ &IID_NULL, lcid, wFlags,
+ &op.dp, &result,
+ &excepinfo, &argErr);
+
+ /* mega kludge. if a method in WORD is called and we ask
+ * for a result when one is not returned then
+ * hResult == DISP_E_EXCEPTION. this only happens on
+ * functions whose DISPID > 0x8000 */
+ if ((hr == DISP_E_EXCEPTION || hr == DISP_E_MEMBERNOTFOUND) && DispID > 0x8000) {
+ if (hr == DISP_E_EXCEPTION) {
+ ole_freeexceptinfo(&excepinfo);
+ }
+ memset(&excepinfo, 0, sizeof(EXCEPINFO));
+ hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
+ &IID_NULL, lcid, wFlags,
+ &op.dp, NULL,
+ &excepinfo, &argErr);
+
+ }
+ for(i = cNamedArgs; i < op.dp.cArgs; i++) {
+ n = op.dp.cArgs - i + cNamedArgs - 1;
+ if (V_VT(&op.dp.rgvarg[n]) != VT_RECORD) {
+ VariantClear(&op.dp.rgvarg[n]);
+ }
+ }
+ }
+
+ if (FAILED(hr)) {
+ /* retry after converting nil to VT_EMPTY */
+ if (op.dp.cArgs > cNamedArgs) {
+ for(i = cNamedArgs; i < op.dp.cArgs; i++) {
+ n = op.dp.cArgs - i + cNamedArgs - 1;
+ param = rb_ary_entry(paramS, i-cNamedArgs);
+ ole_val2variant2(param, &op.dp.rgvarg[n]);
+ }
+ if (hr == DISP_E_EXCEPTION) {
+ ole_freeexceptinfo(&excepinfo);
+ }
+ memset(&excepinfo, 0, sizeof(EXCEPINFO));
+ VariantInit(&result);
+ hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
+ &IID_NULL, lcid, wFlags,
+ &op.dp, &result,
+ &excepinfo, &argErr);
+ for(i = cNamedArgs; i < op.dp.cArgs; i++) {
+ n = op.dp.cArgs - i + cNamedArgs - 1;
+ if (V_VT(&op.dp.rgvarg[n]) != VT_RECORD) {
+ VariantClear(&op.dp.rgvarg[n]);
+ }
+ }
+ }
+ }
+
+ }
+ /* clear dispatch parameter */
+ if(op.dp.cArgs > cNamedArgs) {
+ for(i = cNamedArgs; i < op.dp.cArgs; i++) {
+ n = op.dp.cArgs - i + cNamedArgs - 1;
+ param = rb_ary_entry(paramS, i-cNamedArgs);
+ if (rb_obj_is_kind_of(param, cWIN32OLE_VARIANT)) {
+ ole_val2variant(param, &realargs[n]);
+ } else if ( rb_obj_is_kind_of(param, cWIN32OLE_RECORD) &&
+ V_VT(&realargs[n]) == VT_RECORD ) {
+ olerecord_set_ivar(param, V_RECORDINFO(&realargs[n]), V_RECORD(&realargs[n]));
+ }
+ }
+ set_argv(realargs, cNamedArgs, op.dp.cArgs);
+ }
+ else {
+ for(i = 0; i < op.dp.cArgs; i++) {
+ VariantClear(&op.dp.rgvarg[i]);
+ }
+ }
+
+ if (FAILED(hr)) {
+ v = ole_excepinfo2msg(&excepinfo);
+ ole_raise(hr, eWIN32OLERuntimeError, "(in OLE method `%s': )%s",
+ StringValuePtr(cmd),
+ StringValuePtr(v));
+ }
+ obj = ole_variant2val(&result);
+ VariantClear(&result);
+ return obj;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#invoke(method, [arg1,...]) => return value of method.
+ *
+ * Runs OLE method.
+ * The first argument specifies the method name of OLE Automation object.
+ * The others specify argument of the <i>method</i>.
+ * If you can not execute <i>method</i> directly, then use this method instead.
+ *
+ * excel = WIN32OLE.new('Excel.Application')
+ * excel.invoke('Quit') # => same as excel.Quit
+ *
+ */
+static VALUE
+fole_invoke(int argc, VALUE *argv, VALUE self)
+{
+ return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
+}
+
+static VALUE
+ole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types, USHORT dispkind)
+{
+ HRESULT hr;
+ struct oledata *pole = NULL;
+ unsigned int argErr = 0;
+ EXCEPINFO excepinfo;
+ VARIANT result;
+ DISPPARAMS dispParams;
+ VARIANTARG* realargs = NULL;
+ int i, j;
+ VALUE obj = Qnil;
+ VALUE tp, param;
+ VALUE v;
+ VARTYPE vt;
+
+ Check_Type(args, T_ARRAY);
+ Check_Type(types, T_ARRAY);
+
+ memset(&excepinfo, 0, sizeof(EXCEPINFO));
+ memset(&dispParams, 0, sizeof(DISPPARAMS));
+ VariantInit(&result);
+ pole = oledata_get_struct(self);
+
+ dispParams.cArgs = RARRAY_LEN(args);
+ dispParams.rgvarg = ALLOCA_N(VARIANTARG, dispParams.cArgs);
+ realargs = ALLOCA_N(VARIANTARG, dispParams.cArgs);
+ for (i = 0, j = dispParams.cArgs - 1; i < (int)dispParams.cArgs; i++, j--)
+ {
+ VariantInit(&realargs[i]);
+ VariantInit(&dispParams.rgvarg[i]);
+ tp = rb_ary_entry(types, j);
+ vt = (VARTYPE)FIX2INT(tp);
+ V_VT(&dispParams.rgvarg[i]) = vt;
+ param = rb_ary_entry(args, j);
+ if (param == Qnil)
+ {
+
+ V_VT(&dispParams.rgvarg[i]) = V_VT(&realargs[i]) = VT_ERROR;
+ V_ERROR(&dispParams.rgvarg[i]) = V_ERROR(&realargs[i]) = DISP_E_PARAMNOTFOUND;
+ }
+ else
+ {
+ if (vt & VT_ARRAY)
+ {
+ int ent;
+ LPBYTE pb;
+ short* ps;
+ LPLONG pl;
+ VARIANT* pv;
+ CY *py;
+ VARTYPE v;
+ SAFEARRAYBOUND rgsabound[1];
+ Check_Type(param, T_ARRAY);
+ rgsabound[0].lLbound = 0;
+ rgsabound[0].cElements = RARRAY_LEN(param);
+ v = vt & ~(VT_ARRAY | VT_BYREF);
+ V_ARRAY(&realargs[i]) = SafeArrayCreate(v, 1, rgsabound);
+ V_VT(&realargs[i]) = VT_ARRAY | v;
+ SafeArrayLock(V_ARRAY(&realargs[i]));
+ pb = V_ARRAY(&realargs[i])->pvData;
+ ps = V_ARRAY(&realargs[i])->pvData;
+ pl = V_ARRAY(&realargs[i])->pvData;
+ py = V_ARRAY(&realargs[i])->pvData;
+ pv = V_ARRAY(&realargs[i])->pvData;
+ for (ent = 0; ent < (int)rgsabound[0].cElements; ent++)
+ {
+ VARIANT velem;
+ VALUE elem = rb_ary_entry(param, ent);
+ ole_val2variant(elem, &velem);
+ if (v != VT_VARIANT)
+ {
+ VariantChangeTypeEx(&velem, &velem,
+ cWIN32OLE_lcid, 0, v);
+ }
+ switch (v)
+ {
+ /* 128 bits */
+ case VT_VARIANT:
+ *pv++ = velem;
+ break;
+ /* 64 bits */
+ case VT_R8:
+ case VT_CY:
+ case VT_DATE:
+ *py++ = V_CY(&velem);
+ break;
+ /* 16 bits */
+ case VT_BOOL:
+ case VT_I2:
+ case VT_UI2:
+ *ps++ = V_I2(&velem);
+ break;
+ /* 8 bites */
+ case VT_UI1:
+ case VT_I1:
+ *pb++ = V_UI1(&velem);
+ break;
+ /* 32 bits */
+ default:
+ *pl++ = V_I4(&velem);
+ break;
+ }
+ }
+ SafeArrayUnlock(V_ARRAY(&realargs[i]));
+ }
+ else
+ {
+ ole_val2variant(param, &realargs[i]);
+ if ((vt & (~VT_BYREF)) != VT_VARIANT)
+ {
+ hr = VariantChangeTypeEx(&realargs[i], &realargs[i],
+ cWIN32OLE_lcid, 0,
+ (VARTYPE)(vt & (~VT_BYREF)));
+ if (hr != S_OK)
+ {
+ rb_raise(rb_eTypeError, "not valid value");
+ }
+ }
+ }
+ if ((vt & VT_BYREF) || vt == VT_VARIANT)
+ {
+ if (vt == VT_VARIANT)
+ V_VT(&dispParams.rgvarg[i]) = VT_VARIANT | VT_BYREF;
+ switch (vt & (~VT_BYREF))
+ {
+ /* 128 bits */
+ case VT_VARIANT:
+ V_VARIANTREF(&dispParams.rgvarg[i]) = &realargs[i];
+ break;
+ /* 64 bits */
+ case VT_R8:
+ case VT_CY:
+ case VT_DATE:
+ V_CYREF(&dispParams.rgvarg[i]) = &V_CY(&realargs[i]);
+ break;
+ /* 16 bits */
+ case VT_BOOL:
+ case VT_I2:
+ case VT_UI2:
+ V_I2REF(&dispParams.rgvarg[i]) = &V_I2(&realargs[i]);
+ break;
+ /* 8 bites */
+ case VT_UI1:
+ case VT_I1:
+ V_UI1REF(&dispParams.rgvarg[i]) = &V_UI1(&realargs[i]);
+ break;
+ /* 32 bits */
+ default:
+ V_I4REF(&dispParams.rgvarg[i]) = &V_I4(&realargs[i]);
+ break;
+ }
+ }
+ else
+ {
+ /* copy 64 bits of data */
+ V_CY(&dispParams.rgvarg[i]) = V_CY(&realargs[i]);
+ }
+ }
+ }
+
+ if (dispkind & DISPATCH_PROPERTYPUT) {
+ dispParams.cNamedArgs = 1;
+ dispParams.rgdispidNamedArgs = ALLOCA_N( DISPID, 1 );
+ dispParams.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT;
+ }
+
+ hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, NUM2INT(dispid),
+ &IID_NULL, cWIN32OLE_lcid,
+ dispkind,
+ &dispParams, &result,
+ &excepinfo, &argErr);
+
+ if (FAILED(hr)) {
+ v = ole_excepinfo2msg(&excepinfo);
+ ole_raise(hr, eWIN32OLERuntimeError, "(in OLE method `<dispatch id:%d>': )%s",
+ NUM2INT(dispid),
+ StringValuePtr(v));
+ }
+
+ /* clear dispatch parameter */
+ if(dispParams.cArgs > 0) {
+ set_argv(realargs, 0, dispParams.cArgs);
+ }
+
+ obj = ole_variant2val(&result);
+ VariantClear(&result);
+ return obj;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#_invoke(dispid, args, types)
+ *
+ * Runs the early binding method.
+ * The 1st argument specifies dispatch ID,
+ * the 2nd argument specifies the array of arguments,
+ * the 3rd argument specifies the array of the type of arguments.
+ *
+ * excel = WIN32OLE.new('Excel.Application')
+ * excel._invoke(302, [], []) # same effect as excel.Quit
+ */
+static VALUE
+fole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types)
+{
+ return ole_invoke2(self, dispid, args, types, DISPATCH_METHOD);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#_getproperty(dispid, args, types)
+ *
+ * Runs the early binding method to get property.
+ * The 1st argument specifies dispatch ID,
+ * the 2nd argument specifies the array of arguments,
+ * the 3rd argument specifies the array of the type of arguments.
+ *
+ * excel = WIN32OLE.new('Excel.Application')
+ * puts excel._getproperty(558, [], []) # same effect as puts excel.visible
+ */
+static VALUE
+fole_getproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
+{
+ return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYGET);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#_setproperty(dispid, args, types)
+ *
+ * Runs the early binding method to set property.
+ * The 1st argument specifies dispatch ID,
+ * the 2nd argument specifies the array of arguments,
+ * the 3rd argument specifies the array of the type of arguments.
+ *
+ * excel = WIN32OLE.new('Excel.Application')
+ * excel._setproperty(558, [true], [WIN32OLE::VARIANT::VT_BOOL]) # same effect as excel.visible = true
+ */
+static VALUE
+fole_setproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
+{
+ return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYPUT);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE[a1, a2, ...]=val
+ *
+ * Sets the value to WIN32OLE object specified by a1, a2, ...
+ *
+ * dict = WIN32OLE.new('Scripting.Dictionary')
+ * dict.add('ruby', 'RUBY')
+ * dict['ruby'] = 'Ruby'
+ * puts dict['ruby'] # => 'Ruby'
+ *
+ * Remark: You can not use this method to set the property value.
+ *
+ * excel = WIN32OLE.new('Excel.Application')
+ * # excel['Visible'] = true # This is error !!!
+ * excel.Visible = true # You should to use this style to set the property.
+ *
+ */
+static VALUE
+fole_setproperty_with_bracket(int argc, VALUE *argv, VALUE self)
+{
+ return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, TRUE);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE.setproperty('property', [arg1, arg2,...] val)
+ *
+ * Sets property of OLE object.
+ * When you want to set property with argument, you can use this method.
+ *
+ * excel = WIN32OLE.new('Excel.Application')
+ * excel.Visible = true
+ * book = excel.workbooks.add
+ * sheet = book.worksheets(1)
+ * sheet.setproperty('Cells', 1, 2, 10) # => The B1 cell value is 10.
+ */
+static VALUE
+fole_setproperty(int argc, VALUE *argv, VALUE self)
+{
+ return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, FALSE);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE[a1,a2,...]
+ *
+ * Returns the value of Collection specified by a1, a2,....
+ *
+ * dict = WIN32OLE.new('Scripting.Dictionary')
+ * dict.add('ruby', 'Ruby')
+ * puts dict['ruby'] # => 'Ruby' (same as `puts dict.item('ruby')')
+ *
+ * Remark: You can not use this method to get the property.
+ * excel = WIN32OLE.new('Excel.Application')
+ * # puts excel['Visible'] This is error !!!
+ * puts excel.Visible # You should to use this style to get the property.
+ *
+ */
+static VALUE
+fole_getproperty_with_bracket(int argc, VALUE *argv, VALUE self)
+{
+ return ole_invoke(argc, argv, self, DISPATCH_PROPERTYGET, TRUE);
+}
+
+static VALUE
+ole_propertyput(VALUE self, VALUE property, VALUE value)
+{
+ struct oledata *pole = NULL;
+ unsigned argErr;
+ unsigned int index;
+ HRESULT hr;
+ EXCEPINFO excepinfo;
+ DISPID dispID = DISPID_VALUE;
+ DISPID dispIDParam = DISPID_PROPERTYPUT;
+ USHORT wFlags = DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF;
+ DISPPARAMS dispParams;
+ VARIANTARG propertyValue[2];
+ OLECHAR* pBuf[1];
+ VALUE v;
+ LCID lcid = cWIN32OLE_lcid;
+ dispParams.rgdispidNamedArgs = &dispIDParam;
+ dispParams.rgvarg = propertyValue;
+ dispParams.cNamedArgs = 1;
+ dispParams.cArgs = 1;
+
+ VariantInit(&propertyValue[0]);
+ VariantInit(&propertyValue[1]);
+ memset(&excepinfo, 0, sizeof(excepinfo));
+
+ pole = oledata_get_struct(self);
+
+ /* get ID from property name */
+ pBuf[0] = ole_vstr2wc(property);
+ hr = pole->pDispatch->lpVtbl->GetIDsOfNames(pole->pDispatch, &IID_NULL,
+ pBuf, 1, lcid, &dispID);
+ SysFreeString(pBuf[0]);
+ pBuf[0] = NULL;
+
+ if(FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError,
+ "unknown property or method: `%s'",
+ StringValuePtr(property));
+ }
+ /* set property value */
+ ole_val2variant(value, &propertyValue[0]);
+ hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, dispID, &IID_NULL,
+ lcid, wFlags, &dispParams,
+ NULL, &excepinfo, &argErr);
+
+ for(index = 0; index < dispParams.cArgs; ++index) {
+ VariantClear(&propertyValue[index]);
+ }
+ if (FAILED(hr)) {
+ v = ole_excepinfo2msg(&excepinfo);
+ ole_raise(hr, eWIN32OLERuntimeError, "(in setting property `%s': )%s",
+ StringValuePtr(property),
+ StringValuePtr(v));
+ }
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#ole_free
+ *
+ * invokes Release method of Dispatch interface of WIN32OLE object.
+ * Usually, you do not need to call this method because Release method
+ * called automatically when WIN32OLE object garbaged.
+ *
+ */
+static VALUE
+fole_free(VALUE self)
+{
+ struct oledata *pole = NULL;
+ pole = oledata_get_struct(self);
+ OLE_FREE(pole->pDispatch);
+ pole->pDispatch = NULL;
+ return Qnil;
+}
+
+static VALUE
+ole_each_sub(VALUE pEnumV)
+{
+ VARIANT variant;
+ VALUE obj = Qnil;
+ IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV;
+ VariantInit(&variant);
+ while(pEnum->lpVtbl->Next(pEnum, 1, &variant, NULL) == S_OK) {
+ obj = ole_variant2val(&variant);
+ VariantClear(&variant);
+ VariantInit(&variant);
+ rb_yield(obj);
+ }
+ return Qnil;
+}
+
+static VALUE
+ole_ienum_free(VALUE pEnumV)
+{
+ IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV;
+ OLE_RELEASE(pEnum);
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#each {|i|...}
+ *
+ * Iterates over each item of OLE collection which has IEnumVARIANT interface.
+ *
+ * excel = WIN32OLE.new('Excel.Application')
+ * book = excel.workbooks.add
+ * sheets = book.worksheets(1)
+ * cells = sheets.cells("A1:A5")
+ * cells.each do |cell|
+ * cell.value = 10
+ * end
+ */
+static VALUE
+fole_each(VALUE self)
+{
+ LCID lcid = cWIN32OLE_lcid;
+
+ struct oledata *pole = NULL;
+
+ unsigned int argErr;
+ EXCEPINFO excepinfo;
+ DISPPARAMS dispParams;
+ VARIANT result;
+ HRESULT hr;
+ IEnumVARIANT *pEnum = NULL;
+ void *p;
+
+ RETURN_ENUMERATOR(self, 0, 0);
+
+ VariantInit(&result);
+ dispParams.rgvarg = NULL;
+ dispParams.rgdispidNamedArgs = NULL;
+ dispParams.cNamedArgs = 0;
+ dispParams.cArgs = 0;
+ memset(&excepinfo, 0, sizeof(excepinfo));
+
+ pole = oledata_get_struct(self);
+ hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DISPID_NEWENUM,
+ &IID_NULL, lcid,
+ DISPATCH_METHOD | DISPATCH_PROPERTYGET,
+ &dispParams, &result,
+ &excepinfo, &argErr);
+
+ if (FAILED(hr)) {
+ VariantClear(&result);
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to get IEnum Interface");
+ }
+
+ if (V_VT(&result) == VT_UNKNOWN) {
+ hr = V_UNKNOWN(&result)->lpVtbl->QueryInterface(V_UNKNOWN(&result),
+ &IID_IEnumVARIANT,
+ &p);
+ pEnum = p;
+ } else if (V_VT(&result) == VT_DISPATCH) {
+ hr = V_DISPATCH(&result)->lpVtbl->QueryInterface(V_DISPATCH(&result),
+ &IID_IEnumVARIANT,
+ &p);
+ pEnum = p;
+ }
+ if (FAILED(hr) || !pEnum) {
+ VariantClear(&result);
+ ole_raise(hr, rb_eRuntimeError, "failed to get IEnum Interface");
+ }
+
+ VariantClear(&result);
+ rb_ensure(ole_each_sub, (VALUE)pEnum, ole_ienum_free, (VALUE)pEnum);
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#method_missing(id [,arg1, arg2, ...])
+ *
+ * Calls WIN32OLE#invoke method.
+ */
+static VALUE
+fole_missing(int argc, VALUE *argv, VALUE self)
+{
+ ID id;
+ const char* mname;
+ size_t n;
+ rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
+ id = rb_to_id(argv[0]);
+ mname = rb_id2name(id);
+ if(!mname) {
+ rb_raise(rb_eRuntimeError, "fail: unknown method or property");
+ }
+ n = strlen(mname);
+#if SIZEOF_SIZE_T > SIZEOF_LONG
+ if (n >= LONG_MAX) {
+ rb_raise(rb_eRuntimeError, "too long method or property name");
+ }
+#endif
+ if(mname[n-1] == '=') {
+ rb_check_arity(argc, 2, 2);
+ argv[0] = rb_enc_str_new(mname, (long)(n-1), cWIN32OLE_enc);
+
+ return ole_propertyput(self, argv[0], argv[1]);
+ }
+ else {
+ argv[0] = rb_enc_str_new(mname, (long)n, cWIN32OLE_enc);
+ return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
+ }
+}
+
+static HRESULT
+typeinfo_from_ole(struct oledata *pole, ITypeInfo **ppti)
+{
+ ITypeInfo *pTypeInfo;
+ ITypeLib *pTypeLib;
+ BSTR bstr;
+ VALUE type;
+ UINT i;
+ UINT count;
+ LCID lcid = cWIN32OLE_lcid;
+ HRESULT hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
+ 0, lcid, &pTypeInfo);
+ if(FAILED(hr)) {
+ ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
+ }
+ hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo,
+ -1,
+ &bstr,
+ NULL, NULL, NULL);
+ type = WC2VSTR(bstr);
+ hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);
+ OLE_RELEASE(pTypeInfo);
+ if (FAILED(hr)) {
+ ole_raise(hr, rb_eRuntimeError, "failed to GetContainingTypeLib");
+ }
+ count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
+ for (i = 0; i < count; i++) {
+ hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
+ &bstr, NULL, NULL, NULL);
+ if (SUCCEEDED(hr) && rb_str_cmp(WC2VSTR(bstr), type) == 0) {
+ hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
+ if (SUCCEEDED(hr)) {
+ *ppti = pTypeInfo;
+ break;
+ }
+ }
+ }
+ OLE_RELEASE(pTypeLib);
+ return hr;
+}
+
+static VALUE
+ole_methods(VALUE self, int mask)
+{
+ ITypeInfo *pTypeInfo;
+ HRESULT hr;
+ VALUE methods;
+ struct oledata *pole = NULL;
+
+ pole = oledata_get_struct(self);
+ methods = rb_ary_new();
+
+ hr = typeinfo_from_ole(pole, &pTypeInfo);
+ if(FAILED(hr))
+ return methods;
+ rb_ary_concat(methods, ole_methods_from_typeinfo(pTypeInfo, mask));
+ OLE_RELEASE(pTypeInfo);
+ return methods;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#ole_methods
+ *
+ * Returns the array of WIN32OLE_METHOD object.
+ * The element is OLE method of WIN32OLE object.
+ *
+ * excel = WIN32OLE.new('Excel.Application')
+ * methods = excel.ole_methods
+ *
+ */
+static VALUE
+fole_methods(VALUE self)
+{
+ return ole_methods( self, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#ole_get_methods
+ *
+ * Returns the array of WIN32OLE_METHOD object .
+ * The element of the array is property (gettable) of WIN32OLE object.
+ *
+ * excel = WIN32OLE.new('Excel.Application')
+ * properties = excel.ole_get_methods
+ */
+static VALUE
+fole_get_methods(VALUE self)
+{
+ return ole_methods( self, INVOKE_PROPERTYGET);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#ole_put_methods
+ *
+ * Returns the array of WIN32OLE_METHOD object .
+ * The element of the array is property (settable) of WIN32OLE object.
+ *
+ * excel = WIN32OLE.new('Excel.Application')
+ * properties = excel.ole_put_methods
+ */
+static VALUE
+fole_put_methods(VALUE self)
+{
+ return ole_methods( self, INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#ole_func_methods
+ *
+ * Returns the array of WIN32OLE_METHOD object .
+ * The element of the array is property (settable) of WIN32OLE object.
+ *
+ * excel = WIN32OLE.new('Excel.Application')
+ * properties = excel.ole_func_methods
+ *
+ */
+static VALUE
+fole_func_methods(VALUE self)
+{
+ return ole_methods( self, INVOKE_FUNC);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#ole_type
+ *
+ * Returns WIN32OLE_TYPE object.
+ *
+ * excel = WIN32OLE.new('Excel.Application')
+ * tobj = excel.ole_type
+ */
+static VALUE
+fole_type(VALUE self)
+{
+ ITypeInfo *pTypeInfo;
+ HRESULT hr;
+ struct oledata *pole = NULL;
+ LCID lcid = cWIN32OLE_lcid;
+ VALUE type = Qnil;
+
+ pole = oledata_get_struct(self);
+
+ hr = pole->pDispatch->lpVtbl->GetTypeInfo( pole->pDispatch, 0, lcid, &pTypeInfo );
+ if(FAILED(hr)) {
+ ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
+ }
+ type = ole_type_from_itypeinfo(pTypeInfo);
+ OLE_RELEASE(pTypeInfo);
+ if (type == Qnil) {
+ rb_raise(rb_eRuntimeError, "failed to create WIN32OLE_TYPE obj from ITypeInfo");
+ }
+ return type;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#ole_typelib -> The WIN32OLE_TYPELIB object
+ *
+ * Returns the WIN32OLE_TYPELIB object. The object represents the
+ * type library which contains the WIN32OLE object.
+ *
+ * excel = WIN32OLE.new('Excel.Application')
+ * tlib = excel.ole_typelib
+ * puts tlib.name # -> 'Microsoft Excel 9.0 Object Library'
+ */
+static VALUE
+fole_typelib(VALUE self)
+{
+ struct oledata *pole = NULL;
+ HRESULT hr;
+ ITypeInfo *pTypeInfo;
+ LCID lcid = cWIN32OLE_lcid;
+ VALUE vtlib = Qnil;
+
+ pole = oledata_get_struct(self);
+ hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
+ 0, lcid, &pTypeInfo);
+ if(FAILED(hr)) {
+ ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
+ }
+ vtlib = ole_typelib_from_itypeinfo(pTypeInfo);
+ OLE_RELEASE(pTypeInfo);
+ if (vtlib == Qnil) {
+ rb_raise(rb_eRuntimeError, "failed to get type library info.");
+ }
+ return vtlib;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#ole_query_interface(iid) -> WIN32OLE object
+ *
+ * Returns WIN32OLE object for a specific dispatch or dual
+ * interface specified by iid.
+ *
+ * ie = WIN32OLE.new('InternetExplorer.Application')
+ * ie_web_app = ie.ole_query_interface('{0002DF05-0000-0000-C000-000000000046}') # => WIN32OLE object for dispinterface IWebBrowserApp
+ */
+static VALUE
+fole_query_interface(VALUE self, VALUE str_iid)
+{
+ HRESULT hr;
+ OLECHAR *pBuf;
+ IID iid;
+ struct oledata *pole = NULL;
+ IDispatch *pDispatch;
+ void *p;
+
+ pBuf = ole_vstr2wc(str_iid);
+ hr = CLSIDFromString(pBuf, &iid);
+ SysFreeString(pBuf);
+ if(FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError,
+ "invalid iid: `%s'",
+ StringValuePtr(str_iid));
+ }
+
+ pole = oledata_get_struct(self);
+ if(!pole->pDispatch) {
+ rb_raise(rb_eRuntimeError, "failed to get dispatch interface");
+ }
+
+ hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &iid,
+ &p);
+ if(FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError,
+ "failed to get interface `%s'",
+ StringValuePtr(str_iid));
+ }
+
+ pDispatch = p;
+ return create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#ole_respond_to?(method) -> true or false
+ *
+ * Returns true when OLE object has OLE method, otherwise returns false.
+ *
+ * ie = WIN32OLE.new('InternetExplorer.Application')
+ * ie.ole_respond_to?("gohome") => true
+ */
+static VALUE
+fole_respond_to(VALUE self, VALUE method)
+{
+ struct oledata *pole = NULL;
+ BSTR wcmdname;
+ DISPID DispID;
+ HRESULT hr;
+ if(!RB_TYPE_P(method, T_STRING) && !RB_TYPE_P(method, T_SYMBOL)) {
+ rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
+ }
+ if (RB_TYPE_P(method, T_SYMBOL)) {
+ method = rb_sym_to_s(method);
+ }
+ pole = oledata_get_struct(self);
+ wcmdname = ole_vstr2wc(method);
+ hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL,
+ &wcmdname, 1, cWIN32OLE_lcid, &DispID);
+ SysFreeString(wcmdname);
+ return SUCCEEDED(hr) ? Qtrue : Qfalse;
+}
+
+HRESULT
+ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile)
+{
+ HRESULT hr;
+ ITypeLib *pTypeLib;
+ UINT i;
+
+ hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);
+ if (FAILED(hr)) {
+ return hr;
+ }
+
+ hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
+ name, helpstr,
+ helpcontext, helpfile);
+ if (FAILED(hr)) {
+ OLE_RELEASE(pTypeLib);
+ return hr;
+ }
+ OLE_RELEASE(pTypeLib);
+ return hr;
+}
+
+static VALUE
+ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
+{
+ HRESULT hr;
+ BSTR bstr;
+ ITypeInfo *pRefTypeInfo;
+ VALUE type = Qnil;
+
+ hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
+ V_UNION1(pTypeDesc, hreftype),
+ &pRefTypeInfo);
+ if(FAILED(hr))
+ return Qnil;
+ hr = ole_docinfo_from_type(pRefTypeInfo, &bstr, NULL, NULL, NULL);
+ if(FAILED(hr)) {
+ OLE_RELEASE(pRefTypeInfo);
+ return Qnil;
+ }
+ OLE_RELEASE(pRefTypeInfo);
+ type = WC2VSTR(bstr);
+ if(typedetails != Qnil)
+ rb_ary_push(typedetails, type);
+ return type;
+}
+
+static VALUE
+ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
+{
+ TYPEDESC *p = pTypeDesc;
+ VALUE type = rb_str_new2("");
+
+ if (p->vt == VT_PTR || p->vt == VT_SAFEARRAY) {
+ p = V_UNION1(p, lptdesc);
+ type = ole_typedesc2val(pTypeInfo, p, typedetails);
+ }
+ return type;
+}
+
+VALUE
+ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
+{
+ VALUE str;
+ VALUE typestr = Qnil;
+ switch(pTypeDesc->vt) {
+ case VT_I2:
+ typestr = rb_str_new2("I2");
+ break;
+ case VT_I4:
+ typestr = rb_str_new2("I4");
+ break;
+ case VT_R4:
+ typestr = rb_str_new2("R4");
+ break;
+ case VT_R8:
+ typestr = rb_str_new2("R8");
+ break;
+ case VT_CY:
+ typestr = rb_str_new2("CY");
+ break;
+ case VT_DATE:
+ typestr = rb_str_new2("DATE");
+ break;
+ case VT_BSTR:
+ typestr = rb_str_new2("BSTR");
+ break;
+ case VT_BOOL:
+ typestr = rb_str_new2("BOOL");
+ break;
+ case VT_VARIANT:
+ typestr = rb_str_new2("VARIANT");
+ break;
+ case VT_DECIMAL:
+ typestr = rb_str_new2("DECIMAL");
+ break;
+ case VT_I1:
+ typestr = rb_str_new2("I1");
+ break;
+ case VT_UI1:
+ typestr = rb_str_new2("UI1");
+ break;
+ case VT_UI2:
+ typestr = rb_str_new2("UI2");
+ break;
+ case VT_UI4:
+ typestr = rb_str_new2("UI4");
+ break;
+#if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
+ case VT_I8:
+ typestr = rb_str_new2("I8");
+ break;
+ case VT_UI8:
+ typestr = rb_str_new2("UI8");
+ break;
+#endif
+ case VT_INT:
+ typestr = rb_str_new2("INT");
+ break;
+ case VT_UINT:
+ typestr = rb_str_new2("UINT");
+ break;
+ case VT_VOID:
+ typestr = rb_str_new2("VOID");
+ break;
+ case VT_HRESULT:
+ typestr = rb_str_new2("HRESULT");
+ break;
+ case VT_PTR:
+ typestr = rb_str_new2("PTR");
+ if(typedetails != Qnil)
+ rb_ary_push(typedetails, typestr);
+ return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails);
+ case VT_SAFEARRAY:
+ typestr = rb_str_new2("SAFEARRAY");
+ if(typedetails != Qnil)
+ rb_ary_push(typedetails, typestr);
+ return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails);
+ case VT_CARRAY:
+ typestr = rb_str_new2("CARRAY");
+ break;
+ case VT_USERDEFINED:
+ typestr = rb_str_new2("USERDEFINED");
+ if (typedetails != Qnil)
+ rb_ary_push(typedetails, typestr);
+ str = ole_usertype2val(pTypeInfo, pTypeDesc, typedetails);
+ if (str != Qnil) {
+ return str;
+ }
+ return typestr;
+ case VT_UNKNOWN:
+ typestr = rb_str_new2("UNKNOWN");
+ break;
+ case VT_DISPATCH:
+ typestr = rb_str_new2("DISPATCH");
+ break;
+ case VT_ERROR:
+ typestr = rb_str_new2("ERROR");
+ break;
+ case VT_LPWSTR:
+ typestr = rb_str_new2("LPWSTR");
+ break;
+ case VT_LPSTR:
+ typestr = rb_str_new2("LPSTR");
+ break;
+ case VT_RECORD:
+ typestr = rb_str_new2("RECORD");
+ break;
+ default:
+ typestr = rb_str_new2("Unknown Type ");
+ rb_str_concat(typestr, rb_fix2str(INT2FIX(pTypeDesc->vt), 10));
+ break;
+ }
+ if (typedetails != Qnil)
+ rb_ary_push(typedetails, typestr);
+ return typestr;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#ole_method_help(method)
+ *
+ * Returns WIN32OLE_METHOD object corresponding with method
+ * specified by 1st argument.
+ *
+ * excel = WIN32OLE.new('Excel.Application')
+ * method = excel.ole_method_help('Quit')
+ *
+ */
+static VALUE
+fole_method_help(VALUE self, VALUE cmdname)
+{
+ ITypeInfo *pTypeInfo;
+ HRESULT hr;
+ struct oledata *pole = NULL;
+ VALUE obj;
+
+ SafeStringValue(cmdname);
+ pole = oledata_get_struct(self);
+ hr = typeinfo_from_ole(pole, &pTypeInfo);
+ if(FAILED(hr))
+ ole_raise(hr, rb_eRuntimeError, "failed to get ITypeInfo");
+
+ obj = create_win32ole_method(pTypeInfo, cmdname);
+
+ OLE_RELEASE(pTypeInfo);
+ if (obj == Qnil)
+ rb_raise(eWIN32OLERuntimeError, "not found %s",
+ StringValuePtr(cmdname));
+ return obj;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE#ole_activex_initialize() -> Qnil
+ *
+ * Initialize WIN32OLE object(ActiveX Control) by calling
+ * IPersistMemory::InitNew.
+ *
+ * Before calling OLE method, some kind of the ActiveX controls
+ * created with MFC should be initialized by calling
+ * IPersistXXX::InitNew.
+ *
+ * If and only if you received the exception "HRESULT error code:
+ * 0x8000ffff catastrophic failure", try this method before
+ * invoking any ole_method.
+ *
+ * obj = WIN32OLE.new("ProgID_or_GUID_of_ActiveX_Control")
+ * obj.ole_activex_initialize
+ * obj.method(...)
+ *
+ */
+static VALUE
+fole_activex_initialize(VALUE self)
+{
+ struct oledata *pole = NULL;
+ IPersistMemory *pPersistMemory;
+ void *p;
+
+ HRESULT hr = S_OK;
+
+ pole = oledata_get_struct(self);
+
+ hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &IID_IPersistMemory, &p);
+ pPersistMemory = p;
+ if (SUCCEEDED(hr)) {
+ hr = pPersistMemory->lpVtbl->InitNew(pPersistMemory);
+ OLE_RELEASE(pPersistMemory);
+ if (SUCCEEDED(hr)) {
+ return Qnil;
+ }
+ }
+
+ if (FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError, "fail to initialize ActiveX control");
+ }
+
+ return Qnil;
+}
+
+HRESULT
+typelib_from_val(VALUE obj, ITypeLib **pTypeLib)
+{
+ LCID lcid = cWIN32OLE_lcid;
+ HRESULT hr;
+ struct oledata *pole = NULL;
+ unsigned int index;
+ ITypeInfo *pTypeInfo;
+ pole = oledata_get_struct(obj);
+ hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
+ 0, lcid, &pTypeInfo);
+ if (FAILED(hr)) {
+ return hr;
+ }
+ hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, pTypeLib, &index);
+ OLE_RELEASE(pTypeInfo);
+ return hr;
+}
+
+static void
+init_enc2cp(void)
+{
+ enc2cp_table = st_init_numtable();
+}
+
+static void
+free_enc2cp(void)
+{
+ st_free_table(enc2cp_table);
+}
+
+static void
+com_hash_free(void *ptr)
+{
+ st_table *tbl = ptr;
+ st_free_table(tbl);
+}
+
+static void
+com_hash_mark(void *ptr)
+{
+ st_table *tbl = ptr;
+ rb_mark_hash(tbl);
+}
+
+static size_t
+com_hash_size(const void *ptr)
+{
+ const st_table *tbl = ptr;
+ return tbl ? st_memsize(tbl) : 0;
+}
+
+void
+Init_win32ole(void)
+{
+ cWIN32OLE_lcid = LOCALE_SYSTEM_DEFAULT;
+ g_ole_initialized_init();
+
+ com_vtbl.QueryInterface = QueryInterface;
+ com_vtbl.AddRef = AddRef;
+ com_vtbl.Release = Release;
+ com_vtbl.GetTypeInfoCount = GetTypeInfoCount;
+ com_vtbl.GetTypeInfo = GetTypeInfo;
+ com_vtbl.GetIDsOfNames = GetIDsOfNames;
+ com_vtbl.Invoke = Invoke;
+
+ message_filter.QueryInterface = mf_QueryInterface;
+ message_filter.AddRef = mf_AddRef;
+ message_filter.Release = mf_Release;
+ message_filter.HandleInComingCall = mf_HandleInComingCall;
+ message_filter.RetryRejectedCall = mf_RetryRejectedCall;
+ message_filter.MessagePending = mf_MessagePending;
+
+ com_hash = TypedData_Wrap_Struct(rb_cData, &com_hash_datatype, st_init_numtable());
+ rb_gc_register_mark_object(com_hash);
+
+ cWIN32OLE = rb_define_class("WIN32OLE", rb_cObject);
+
+ rb_define_alloc_func(cWIN32OLE, fole_s_allocate);
+
+ rb_define_method(cWIN32OLE, "initialize", fole_initialize, -1);
+
+ rb_define_singleton_method(cWIN32OLE, "connect", fole_s_connect, -1);
+ rb_define_singleton_method(cWIN32OLE, "const_load", fole_s_const_load, -1);
+
+ rb_define_singleton_method(cWIN32OLE, "ole_free", fole_s_free, 1);
+ rb_define_singleton_method(cWIN32OLE, "ole_reference_count", fole_s_reference_count, 1);
+ rb_define_singleton_method(cWIN32OLE, "ole_show_help", fole_s_show_help, -1);
+ rb_define_singleton_method(cWIN32OLE, "codepage", fole_s_get_code_page, 0);
+ rb_define_singleton_method(cWIN32OLE, "codepage=", fole_s_set_code_page, 1);
+ rb_define_singleton_method(cWIN32OLE, "locale", fole_s_get_locale, 0);
+ rb_define_singleton_method(cWIN32OLE, "locale=", fole_s_set_locale, 1);
+ rb_define_singleton_method(cWIN32OLE, "create_guid", fole_s_create_guid, 0);
+ rb_define_singleton_method(cWIN32OLE, "ole_initialize", fole_s_ole_initialize, 0);
+ rb_define_singleton_method(cWIN32OLE, "ole_uninitialize", fole_s_ole_uninitialize, 0);
+
+ rb_define_method(cWIN32OLE, "invoke", fole_invoke, -1);
+ rb_define_method(cWIN32OLE, "[]", fole_getproperty_with_bracket, -1);
+ rb_define_method(cWIN32OLE, "_invoke", fole_invoke2, 3);
+ rb_define_method(cWIN32OLE, "_getproperty", fole_getproperty2, 3);
+ rb_define_method(cWIN32OLE, "_setproperty", fole_setproperty2, 3);
+
+ /* support propput method that takes an argument */
+ rb_define_method(cWIN32OLE, "[]=", fole_setproperty_with_bracket, -1);
+
+ rb_define_method(cWIN32OLE, "ole_free", fole_free, 0);
+
+ rb_define_method(cWIN32OLE, "each", fole_each, 0);
+ rb_define_method(cWIN32OLE, "method_missing", fole_missing, -1);
+
+ /* support setproperty method much like Perl ;-) */
+ rb_define_method(cWIN32OLE, "setproperty", fole_setproperty, -1);
+
+ rb_define_method(cWIN32OLE, "ole_methods", fole_methods, 0);
+ rb_define_method(cWIN32OLE, "ole_get_methods", fole_get_methods, 0);
+ rb_define_method(cWIN32OLE, "ole_put_methods", fole_put_methods, 0);
+ rb_define_method(cWIN32OLE, "ole_func_methods", fole_func_methods, 0);
+
+ rb_define_method(cWIN32OLE, "ole_method", fole_method_help, 1);
+ rb_define_alias(cWIN32OLE, "ole_method_help", "ole_method");
+ rb_define_method(cWIN32OLE, "ole_activex_initialize", fole_activex_initialize, 0);
+ rb_define_method(cWIN32OLE, "ole_type", fole_type, 0);
+ rb_define_alias(cWIN32OLE, "ole_obj_help", "ole_type");
+ rb_define_method(cWIN32OLE, "ole_typelib", fole_typelib, 0);
+ rb_define_method(cWIN32OLE, "ole_query_interface", fole_query_interface, 1);
+ rb_define_method(cWIN32OLE, "ole_respond_to?", fole_respond_to, 1);
+
+ /* Constants definition */
+
+ /*
+ * Version string of WIN32OLE.
+ */
+ rb_define_const(cWIN32OLE, "VERSION", rb_str_new2(WIN32OLE_VERSION));
+
+ /*
+ * After invoking OLE methods with reference arguments, you can access
+ * the value of arguments by using ARGV.
+ *
+ * If the method of OLE(COM) server written by C#.NET is following:
+ *
+ * void calcsum(int a, int b, out int c) {
+ * c = a + b;
+ * }
+ *
+ * then, the Ruby OLE(COM) client script to retrieve the value of
+ * argument c after invoking calcsum method is following:
+ *
+ * a = 10
+ * b = 20
+ * c = 0
+ * comserver.calcsum(a, b, c)
+ * p c # => 0
+ * p WIN32OLE::ARGV # => [10, 20, 30]
+ *
+ * You can use WIN32OLE_VARIANT object to retrieve the value of reference
+ * arguments instead of refering WIN32OLE::ARGV.
+ *
+ */
+ rb_define_const(cWIN32OLE, "ARGV", rb_ary_new());
+
+ /*
+ * 0: ANSI code page. See WIN32OLE.codepage and WIN32OLE.codepage=.
+ */
+ rb_define_const(cWIN32OLE, "CP_ACP", INT2FIX(CP_ACP));
+
+ /*
+ * 1: OEM code page. See WIN32OLE.codepage and WIN32OLE.codepage=.
+ */
+ rb_define_const(cWIN32OLE, "CP_OEMCP", INT2FIX(CP_OEMCP));
+
+ /*
+ * 2
+ */
+ rb_define_const(cWIN32OLE, "CP_MACCP", INT2FIX(CP_MACCP));
+
+ /*
+ * 3: current thread ANSI code page. See WIN32OLE.codepage and
+ * WIN32OLE.codepage=.
+ */
+ rb_define_const(cWIN32OLE, "CP_THREAD_ACP", INT2FIX(CP_THREAD_ACP));
+
+ /*
+ * 42: symbol code page. See WIN32OLE.codepage and WIN32OLE.codepage=.
+ */
+ rb_define_const(cWIN32OLE, "CP_SYMBOL", INT2FIX(CP_SYMBOL));
+
+ /*
+ * 65000: UTF-7 code page. See WIN32OLE.codepage and WIN32OLE.codepage=.
+ */
+ rb_define_const(cWIN32OLE, "CP_UTF7", INT2FIX(CP_UTF7));
+
+ /*
+ * 65001: UTF-8 code page. See WIN32OLE.codepage and WIN32OLE.codepage=.
+ */
+ rb_define_const(cWIN32OLE, "CP_UTF8", INT2FIX(CP_UTF8));
+
+ /*
+ * 0x0800: default locale for the operating system. See WIN32OLE.locale
+ * and WIN32OLE.locale=.
+ */
+ rb_define_const(cWIN32OLE, "LOCALE_SYSTEM_DEFAULT", INT2FIX(LOCALE_SYSTEM_DEFAULT));
+
+ /*
+ * 0x0400: default locale for the user or process. See WIN32OLE.locale
+ * and WIN32OLE.locale=.
+ */
+ rb_define_const(cWIN32OLE, "LOCALE_USER_DEFAULT", INT2FIX(LOCALE_USER_DEFAULT));
+
+ Init_win32ole_variant_m();
+ Init_win32ole_typelib();
+ Init_win32ole_type();
+ Init_win32ole_variable();
+ Init_win32ole_method();
+ Init_win32ole_param();
+ Init_win32ole_event();
+ Init_win32ole_variant();
+ Init_win32ole_record();
+ Init_win32ole_error();
+
+ init_enc2cp();
+ atexit((void (*)(void))free_enc2cp);
+ ole_init_cp();
+}
diff --git a/jni/ruby/ext/win32ole/win32ole.h b/jni/ruby/ext/win32ole/win32ole.h
new file mode 100644
index 0000000..d61f5e2
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole.h
@@ -0,0 +1,155 @@
+#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 NUM2LL
+#define NUM2UI8 NUM2ULL
+#else
+#define I8_2_NUM INT2NUM
+#define UI8_2_NUM UINT2NUM
+#define NUM2I8 NUM2INT
+#define NUM2UI8 NUM2UINT
+#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;
+};
+
+VALUE cWIN32OLE;
+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
diff --git a/jni/ruby/ext/win32ole/win32ole_error.c b/jni/ruby/ext/win32ole/win32ole_error.c
new file mode 100644
index 0000000..62e69b1
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_error.c
@@ -0,0 +1,83 @@
+#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));
+}
+
+void
+Init_win32ole_error(void)
+{
+ /*
+ * Document-class: WIN32OLERuntimeError
+ *
+ * Raised when OLE processing failed.
+ *
+ * EX:
+ *
+ * obj = WIN32OLE.new("NonExistProgID")
+ *
+ * raises the exception:
+ *
+ * WIN32OLERuntimeError: unknown OLE server: `NonExistProgID'
+ * HRESULT error code:0x800401f3
+ * Invalid class string
+ *
+ */
+ eWIN32OLERuntimeError = rb_define_class("WIN32OLERuntimeError", rb_eRuntimeError);
+}
diff --git a/jni/ruby/ext/win32ole/win32ole_error.h b/jni/ruby/ext/win32ole/win32ole_error.h
new file mode 100644
index 0000000..5359646
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_error.h
@@ -0,0 +1,8 @@
+#ifndef WIN32OLE_ERROR_H
+#define WIN32OLE_ERROR_H 1
+
+VALUE eWIN32OLERuntimeError;
+void ole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...);
+void Init_win32ole_error(void);
+
+#endif
diff --git a/jni/ruby/ext/win32ole/win32ole_event.c b/jni/ruby/ext/win32ole/win32ole_event.c
new file mode 100644
index 0000000..105308a
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_event.c
@@ -0,0 +1,1275 @@
+#include "win32ole.h"
+
+/*
+ * Document-class: WIN32OLE_EVENT
+ *
+ * <code>WIN32OLE_EVENT</code> objects controls OLE event.
+ */
+
+typedef struct {
+ struct IEventSinkVtbl * lpVtbl;
+} IEventSink, *PEVENTSINK;
+
+typedef struct IEventSinkVtbl IEventSinkVtbl;
+
+struct IEventSinkVtbl {
+ STDMETHOD(QueryInterface)(
+ PEVENTSINK,
+ REFIID,
+ LPVOID *);
+ STDMETHOD_(ULONG, AddRef)(PEVENTSINK);
+ STDMETHOD_(ULONG, Release)(PEVENTSINK);
+
+ STDMETHOD(GetTypeInfoCount)(
+ PEVENTSINK,
+ UINT *);
+ STDMETHOD(GetTypeInfo)(
+ PEVENTSINK,
+ UINT,
+ LCID,
+ ITypeInfo **);
+ STDMETHOD(GetIDsOfNames)(
+ PEVENTSINK,
+ REFIID,
+ OLECHAR **,
+ UINT,
+ LCID,
+ DISPID *);
+ STDMETHOD(Invoke)(
+ PEVENTSINK,
+ DISPID,
+ REFIID,
+ LCID,
+ WORD,
+ DISPPARAMS *,
+ VARIANT *,
+ EXCEPINFO *,
+ UINT *);
+};
+
+typedef struct tagIEVENTSINKOBJ {
+ IEventSinkVtbl *lpVtbl;
+ DWORD m_cRef;
+ IID m_iid;
+ long m_event_id;
+ ITypeInfo *pTypeInfo;
+}IEVENTSINKOBJ, *PIEVENTSINKOBJ;
+
+struct oleeventdata {
+ DWORD dwCookie;
+ IConnectionPoint *pConnectionPoint;
+ IDispatch *pDispatch;
+ long event_id;
+};
+
+static VALUE ary_ole_event;
+static ID id_events;
+
+VALUE cWIN32OLE_EVENT;
+
+static BOOL g_IsEventSinkVtblInitialized = FALSE;
+
+static IEventSinkVtbl vtEventSink;
+
+void EVENTSINK_Destructor(PIEVENTSINKOBJ);
+static void ole_val2ptr_variant(VALUE val, VARIANT *var);
+static void hash2ptr_dispparams(VALUE hash, ITypeInfo *pTypeInfo, DISPID dispid, DISPPARAMS *pdispparams);
+static VALUE hash2result(VALUE hash);
+static void ary2ptr_dispparams(VALUE ary, DISPPARAMS *pdispparams);
+static VALUE exec_callback(VALUE arg);
+static VALUE rescue_callback(VALUE arg);
+static HRESULT find_iid(VALUE ole, char *pitf, IID *piid, ITypeInfo **ppTypeInfo);
+static HRESULT find_coclass(ITypeInfo *pTypeInfo, TYPEATTR *pTypeAttr, ITypeInfo **pTypeInfo2, TYPEATTR **pTypeAttr2);
+static HRESULT find_default_source_from_typeinfo(ITypeInfo *pTypeInfo, TYPEATTR *pTypeAttr, ITypeInfo **ppTypeInfo);
+static HRESULT find_default_source(VALUE ole, IID *piid, ITypeInfo **ppTypeInfo);
+static long ole_search_event_at(VALUE ary, VALUE ev);
+static VALUE ole_search_event(VALUE ary, VALUE ev, BOOL *is_default);
+static VALUE ole_search_handler_method(VALUE handler, VALUE ev, BOOL *is_default_handler);
+static void ole_delete_event(VALUE ary, VALUE ev);
+static void oleevent_free(void *ptr);
+static size_t oleevent_size(const void *ptr);
+static VALUE fev_s_allocate(VALUE klass);
+static VALUE ev_advise(int argc, VALUE *argv, VALUE self);
+static VALUE fev_initialize(int argc, VALUE *argv, VALUE self);
+static void ole_msg_loop(void);
+static VALUE fev_s_msg_loop(VALUE klass);
+static void add_event_call_back(VALUE obj, VALUE event, VALUE data);
+static VALUE ev_on_event(int argc, VALUE *argv, VALUE self, VALUE is_ary_arg);
+static VALUE fev_on_event(int argc, VALUE *argv, VALUE self);
+static VALUE fev_on_event_with_outargs(int argc, VALUE *argv, VALUE self);
+static VALUE fev_off_event(int argc, VALUE *argv, VALUE self);
+static VALUE fev_unadvise(VALUE self);
+static VALUE fev_set_handler(VALUE self, VALUE val);
+static VALUE fev_get_handler(VALUE self);
+static VALUE evs_push(VALUE ev);
+static VALUE evs_delete(long i);
+static VALUE evs_entry(long i);
+static long evs_length(void);
+
+
+static const rb_data_type_t oleevent_datatype = {
+ "win32ole_event",
+ {NULL, oleevent_free, oleevent_size,},
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
+};
+
+STDMETHODIMP EVENTSINK_Invoke(
+ PEVENTSINK pEventSink,
+ DISPID dispid,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS *pdispparams,
+ VARIANT *pvarResult,
+ EXCEPINFO *pexcepinfo,
+ UINT *puArgErr
+ ) {
+
+ HRESULT hr;
+ BSTR bstr;
+ unsigned int count;
+ unsigned int i;
+ ITypeInfo *pTypeInfo;
+ VARIANT *pvar;
+ VALUE ary, obj, event, args, outargv, ev, result;
+ VALUE handler = Qnil;
+ VALUE arg[3];
+ VALUE mid;
+ VALUE is_outarg = Qfalse;
+ BOOL is_default_handler = FALSE;
+ int state;
+
+ PIEVENTSINKOBJ pEV = (PIEVENTSINKOBJ)pEventSink;
+ pTypeInfo = pEV->pTypeInfo;
+ obj = evs_entry(pEV->m_event_id);
+ if (!rb_obj_is_kind_of(obj, cWIN32OLE_EVENT)) {
+ return NOERROR;
+ }
+
+ ary = rb_ivar_get(obj, id_events);
+ if (NIL_P(ary) || !RB_TYPE_P(ary, T_ARRAY)) {
+ return NOERROR;
+ }
+ hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, dispid,
+ &bstr, 1, &count);
+ if (FAILED(hr)) {
+ return NOERROR;
+ }
+ ev = WC2VSTR(bstr);
+ event = ole_search_event(ary, ev, &is_default_handler);
+ if (RB_TYPE_P(event, T_ARRAY)) {
+ handler = rb_ary_entry(event, 0);
+ mid = rb_intern("call");
+ is_outarg = rb_ary_entry(event, 3);
+ } else {
+ handler = rb_ivar_get(obj, rb_intern("handler"));
+ if (handler == Qnil) {
+ return NOERROR;
+ }
+ mid = ole_search_handler_method(handler, ev, &is_default_handler);
+ }
+ if (handler == Qnil || mid == Qnil) {
+ return NOERROR;
+ }
+
+ args = rb_ary_new();
+ if (is_default_handler) {
+ rb_ary_push(args, ev);
+ }
+
+ /* make argument of event handler */
+ for (i = 0; i < pdispparams->cArgs; ++i) {
+ pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
+ rb_ary_push(args, ole_variant2val(pvar));
+ }
+ outargv = Qnil;
+ if (is_outarg == Qtrue) {
+ outargv = rb_ary_new();
+ rb_ary_push(args, outargv);
+ }
+
+ /*
+ * if exception raised in event callback,
+ * then you receive cfp consistency error.
+ * to avoid this error we use begin rescue end.
+ * and the exception raised then error message print
+ * and exit ruby process by Win32OLE itself.
+ */
+ arg[0] = handler;
+ arg[1] = mid;
+ arg[2] = args;
+ result = rb_protect(exec_callback, (VALUE)arg, &state);
+ if (state != 0) {
+ rescue_callback(Qnil);
+ }
+ if(RB_TYPE_P(result, T_HASH)) {
+ hash2ptr_dispparams(result, pTypeInfo, dispid, pdispparams);
+ result = hash2result(result);
+ }else if (is_outarg == Qtrue && RB_TYPE_P(outargv, T_ARRAY)) {
+ ary2ptr_dispparams(outargv, pdispparams);
+ }
+
+ if (pvarResult) {
+ VariantInit(pvarResult);
+ ole_val2variant(result, pvarResult);
+ }
+
+ return NOERROR;
+}
+
+STDMETHODIMP
+EVENTSINK_QueryInterface(
+ PEVENTSINK pEV,
+ REFIID iid,
+ LPVOID* ppv
+ ) {
+ if (IsEqualIID(iid, &IID_IUnknown) ||
+ IsEqualIID(iid, &IID_IDispatch) ||
+ IsEqualIID(iid, &((PIEVENTSINKOBJ)pEV)->m_iid)) {
+ *ppv = pEV;
+ }
+ else {
+ *ppv = NULL;
+ return E_NOINTERFACE;
+ }
+ ((LPUNKNOWN)*ppv)->lpVtbl->AddRef((LPUNKNOWN)*ppv);
+ return NOERROR;
+}
+
+STDMETHODIMP_(ULONG)
+EVENTSINK_AddRef(
+ PEVENTSINK pEV
+ ){
+ PIEVENTSINKOBJ pEVObj = (PIEVENTSINKOBJ)pEV;
+ return ++pEVObj->m_cRef;
+}
+
+STDMETHODIMP_(ULONG) EVENTSINK_Release(
+ PEVENTSINK pEV
+ ) {
+ PIEVENTSINKOBJ pEVObj = (PIEVENTSINKOBJ)pEV;
+ --pEVObj->m_cRef;
+ if(pEVObj->m_cRef != 0)
+ return pEVObj->m_cRef;
+ EVENTSINK_Destructor(pEVObj);
+ return 0;
+}
+
+STDMETHODIMP EVENTSINK_GetTypeInfoCount(
+ PEVENTSINK pEV,
+ UINT *pct
+ ) {
+ *pct = 0;
+ return NOERROR;
+}
+
+STDMETHODIMP EVENTSINK_GetTypeInfo(
+ PEVENTSINK pEV,
+ UINT info,
+ LCID lcid,
+ ITypeInfo **pInfo
+ ) {
+ *pInfo = NULL;
+ return DISP_E_BADINDEX;
+}
+
+STDMETHODIMP EVENTSINK_GetIDsOfNames(
+ PEVENTSINK pEventSink,
+ REFIID riid,
+ OLECHAR **szNames,
+ UINT cNames,
+ LCID lcid,
+ DISPID *pDispID
+ ) {
+ ITypeInfo *pTypeInfo;
+ PIEVENTSINKOBJ pEV = (PIEVENTSINKOBJ)pEventSink;
+ pTypeInfo = pEV->pTypeInfo;
+ if (pTypeInfo) {
+ return pTypeInfo->lpVtbl->GetIDsOfNames(pTypeInfo, szNames, cNames, pDispID);
+ }
+ return DISP_E_UNKNOWNNAME;
+}
+
+PIEVENTSINKOBJ
+EVENTSINK_Constructor(void)
+{
+ PIEVENTSINKOBJ pEv;
+ if (!g_IsEventSinkVtblInitialized) {
+ vtEventSink.QueryInterface=EVENTSINK_QueryInterface;
+ vtEventSink.AddRef = EVENTSINK_AddRef;
+ vtEventSink.Release = EVENTSINK_Release;
+ vtEventSink.Invoke = EVENTSINK_Invoke;
+ vtEventSink.GetIDsOfNames = EVENTSINK_GetIDsOfNames;
+ vtEventSink.GetTypeInfoCount = EVENTSINK_GetTypeInfoCount;
+ vtEventSink.GetTypeInfo = EVENTSINK_GetTypeInfo;
+
+ g_IsEventSinkVtblInitialized = TRUE;
+ }
+ pEv = ALLOC_N(IEVENTSINKOBJ, 1);
+ if(pEv == NULL) return NULL;
+ pEv->lpVtbl = &vtEventSink;
+ pEv->m_cRef = 0;
+ pEv->m_event_id = 0;
+ pEv->pTypeInfo = NULL;
+ return pEv;
+}
+
+void
+EVENTSINK_Destructor(
+ PIEVENTSINKOBJ pEVObj
+ ) {
+ if(pEVObj != NULL) {
+ OLE_RELEASE(pEVObj->pTypeInfo);
+ free(pEVObj);
+ pEVObj = NULL;
+ }
+}
+
+static void
+ole_val2ptr_variant(VALUE val, VARIANT *var)
+{
+ switch (TYPE(val)) {
+ case T_STRING:
+ if (V_VT(var) == (VT_BSTR | VT_BYREF)) {
+ *V_BSTRREF(var) = ole_vstr2wc(val);
+ }
+ break;
+ case T_FIXNUM:
+ switch(V_VT(var)) {
+ case (VT_UI1 | VT_BYREF) :
+ *V_UI1REF(var) = NUM2CHR(val);
+ break;
+ case (VT_I2 | VT_BYREF) :
+ *V_I2REF(var) = (short)NUM2INT(val);
+ break;
+ case (VT_I4 | VT_BYREF) :
+ *V_I4REF(var) = NUM2INT(val);
+ break;
+ case (VT_R4 | VT_BYREF) :
+ *V_R4REF(var) = (float)NUM2INT(val);
+ break;
+ case (VT_R8 | VT_BYREF) :
+ *V_R8REF(var) = NUM2INT(val);
+ break;
+ default:
+ break;
+ }
+ break;
+ case T_FLOAT:
+ switch(V_VT(var)) {
+ case (VT_I2 | VT_BYREF) :
+ *V_I2REF(var) = (short)NUM2INT(val);
+ break;
+ case (VT_I4 | VT_BYREF) :
+ *V_I4REF(var) = NUM2INT(val);
+ break;
+ case (VT_R4 | VT_BYREF) :
+ *V_R4REF(var) = (float)NUM2DBL(val);
+ break;
+ case (VT_R8 | VT_BYREF) :
+ *V_R8REF(var) = NUM2DBL(val);
+ break;
+ default:
+ break;
+ }
+ break;
+ case T_BIGNUM:
+ if (V_VT(var) == (VT_R8 | VT_BYREF)) {
+ *V_R8REF(var) = rb_big2dbl(val);
+ }
+ break;
+ case T_TRUE:
+ if (V_VT(var) == (VT_BOOL | VT_BYREF)) {
+ *V_BOOLREF(var) = VARIANT_TRUE;
+ }
+ break;
+ case T_FALSE:
+ if (V_VT(var) == (VT_BOOL | VT_BYREF)) {
+ *V_BOOLREF(var) = VARIANT_FALSE;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+hash2ptr_dispparams(VALUE hash, ITypeInfo *pTypeInfo, DISPID dispid, DISPPARAMS *pdispparams)
+{
+ BSTR *bstrs;
+ HRESULT hr;
+ UINT len, i;
+ VARIANT *pvar;
+ VALUE val;
+ VALUE key;
+ len = 0;
+ bstrs = ALLOCA_N(BSTR, pdispparams->cArgs + 1);
+ hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, dispid,
+ bstrs, pdispparams->cArgs + 1,
+ &len);
+ if (FAILED(hr))
+ return;
+
+ for (i = 0; i < len - 1; i++) {
+ key = WC2VSTR(bstrs[i + 1]);
+ val = rb_hash_aref(hash, INT2FIX(i));
+ if (val == Qnil)
+ val = rb_hash_aref(hash, key);
+ if (val == Qnil)
+ val = rb_hash_aref(hash, rb_str_intern(key));
+ pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
+ ole_val2ptr_variant(val, pvar);
+ }
+}
+
+static VALUE
+hash2result(VALUE hash)
+{
+ VALUE ret = Qnil;
+ ret = rb_hash_aref(hash, rb_str_new2("return"));
+ if (ret == Qnil)
+ ret = rb_hash_aref(hash, rb_str_intern(rb_str_new2("return")));
+ return ret;
+}
+
+static void
+ary2ptr_dispparams(VALUE ary, DISPPARAMS *pdispparams)
+{
+ int i;
+ VALUE v;
+ VARIANT *pvar;
+ for(i = 0; i < RARRAY_LEN(ary) && (unsigned int) i < pdispparams->cArgs; i++) {
+ v = rb_ary_entry(ary, i);
+ pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
+ ole_val2ptr_variant(v, pvar);
+ }
+}
+
+static VALUE
+exec_callback(VALUE arg)
+{
+ VALUE *parg = (VALUE *)arg;
+ VALUE handler = parg[0];
+ VALUE mid = parg[1];
+ VALUE args = parg[2];
+ return rb_apply(handler, mid, args);
+}
+
+static VALUE
+rescue_callback(VALUE arg)
+{
+
+ VALUE error;
+ VALUE e = rb_errinfo();
+ VALUE bt = rb_funcall(e, rb_intern("backtrace"), 0);
+ VALUE msg = rb_funcall(e, rb_intern("message"), 0);
+ bt = rb_ary_entry(bt, 0);
+ error = rb_sprintf("%"PRIsVALUE": %"PRIsVALUE" (%s)\n", bt, msg, rb_obj_classname(e));
+ rb_write_error(StringValuePtr(error));
+ rb_backtrace();
+ ruby_finalize();
+ exit(-1);
+
+ return Qnil;
+}
+
+static HRESULT
+find_iid(VALUE ole, char *pitf, IID *piid, ITypeInfo **ppTypeInfo)
+{
+ HRESULT hr;
+ IDispatch *pDispatch;
+ ITypeInfo *pTypeInfo;
+ ITypeLib *pTypeLib;
+ TYPEATTR *pTypeAttr;
+ HREFTYPE RefType;
+ ITypeInfo *pImplTypeInfo;
+ TYPEATTR *pImplTypeAttr;
+
+ struct oledata *pole = NULL;
+ unsigned int index;
+ unsigned int count;
+ int type;
+ BSTR bstr;
+ char *pstr;
+
+ BOOL is_found = FALSE;
+ LCID lcid = cWIN32OLE_lcid;
+
+ pole = oledata_get_struct(ole);
+
+ pDispatch = pole->pDispatch;
+
+ hr = pDispatch->lpVtbl->GetTypeInfo(pDispatch, 0, lcid, &pTypeInfo);
+ if (FAILED(hr))
+ return hr;
+
+ hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo,
+ &pTypeLib,
+ &index);
+ OLE_RELEASE(pTypeInfo);
+ if (FAILED(hr))
+ return hr;
+
+ if (!pitf) {
+ hr = pTypeLib->lpVtbl->GetTypeInfoOfGuid(pTypeLib,
+ piid,
+ ppTypeInfo);
+ OLE_RELEASE(pTypeLib);
+ return hr;
+ }
+ count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
+ for (index = 0; index < count; index++) {
+ hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib,
+ index,
+ &pTypeInfo);
+ if (FAILED(hr))
+ break;
+ hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
+
+ if(FAILED(hr)) {
+ OLE_RELEASE(pTypeInfo);
+ break;
+ }
+ if(pTypeAttr->typekind == TKIND_COCLASS) {
+ for (type = 0; type < pTypeAttr->cImplTypes; type++) {
+ hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,
+ type,
+ &RefType);
+ if (FAILED(hr))
+ break;
+ hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
+ RefType,
+ &pImplTypeInfo);
+ if (FAILED(hr))
+ break;
+
+ hr = pImplTypeInfo->lpVtbl->GetDocumentation(pImplTypeInfo,
+ -1,
+ &bstr,
+ NULL, NULL, NULL);
+ if (FAILED(hr)) {
+ OLE_RELEASE(pImplTypeInfo);
+ break;
+ }
+ pstr = ole_wc2mb(bstr);
+ if (strcmp(pitf, pstr) == 0) {
+ hr = pImplTypeInfo->lpVtbl->GetTypeAttr(pImplTypeInfo,
+ &pImplTypeAttr);
+ if (SUCCEEDED(hr)) {
+ is_found = TRUE;
+ *piid = pImplTypeAttr->guid;
+ if (ppTypeInfo) {
+ *ppTypeInfo = pImplTypeInfo;
+ (*ppTypeInfo)->lpVtbl->AddRef((*ppTypeInfo));
+ }
+ pImplTypeInfo->lpVtbl->ReleaseTypeAttr(pImplTypeInfo,
+ pImplTypeAttr);
+ }
+ }
+ free(pstr);
+ OLE_RELEASE(pImplTypeInfo);
+ if (is_found || FAILED(hr))
+ break;
+ }
+ }
+
+ OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
+ OLE_RELEASE(pTypeInfo);
+ if (is_found || FAILED(hr))
+ break;
+ }
+ OLE_RELEASE(pTypeLib);
+ if(!is_found)
+ return E_NOINTERFACE;
+ return hr;
+}
+
+static HRESULT
+find_coclass(
+ ITypeInfo *pTypeInfo,
+ TYPEATTR *pTypeAttr,
+ ITypeInfo **pCOTypeInfo,
+ TYPEATTR **pCOTypeAttr)
+{
+ HRESULT hr = E_NOINTERFACE;
+ ITypeLib *pTypeLib;
+ int count;
+ BOOL found = FALSE;
+ ITypeInfo *pTypeInfo2;
+ TYPEATTR *pTypeAttr2;
+ int flags;
+ int i,j;
+ HREFTYPE href;
+ ITypeInfo *pRefTypeInfo;
+ TYPEATTR *pRefTypeAttr;
+
+ hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, NULL);
+ if (FAILED(hr)) {
+ return hr;
+ }
+ count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
+ for (i = 0; i < count && !found; i++) {
+ hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo2);
+ if (FAILED(hr))
+ continue;
+ hr = OLE_GET_TYPEATTR(pTypeInfo2, &pTypeAttr2);
+ if (FAILED(hr)) {
+ OLE_RELEASE(pTypeInfo2);
+ continue;
+ }
+ if (pTypeAttr2->typekind != TKIND_COCLASS) {
+ OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2);
+ OLE_RELEASE(pTypeInfo2);
+ continue;
+ }
+ for (j = 0; j < pTypeAttr2->cImplTypes && !found; j++) {
+ hr = pTypeInfo2->lpVtbl->GetImplTypeFlags(pTypeInfo2, j, &flags);
+ if (FAILED(hr))
+ continue;
+ if (!(flags & IMPLTYPEFLAG_FDEFAULT))
+ continue;
+ hr = pTypeInfo2->lpVtbl->GetRefTypeOfImplType(pTypeInfo2, j, &href);
+ if (FAILED(hr))
+ continue;
+ hr = pTypeInfo2->lpVtbl->GetRefTypeInfo(pTypeInfo2, href, &pRefTypeInfo);
+ if (FAILED(hr))
+ continue;
+ hr = OLE_GET_TYPEATTR(pRefTypeInfo, &pRefTypeAttr);
+ if (FAILED(hr)) {
+ OLE_RELEASE(pRefTypeInfo);
+ continue;
+ }
+ if (IsEqualGUID(&(pTypeAttr->guid), &(pRefTypeAttr->guid))) {
+ found = TRUE;
+ }
+ }
+ if (!found) {
+ OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2);
+ OLE_RELEASE(pTypeInfo2);
+ }
+ }
+ OLE_RELEASE(pTypeLib);
+ if (found) {
+ *pCOTypeInfo = pTypeInfo2;
+ *pCOTypeAttr = pTypeAttr2;
+ hr = S_OK;
+ } else {
+ hr = E_NOINTERFACE;
+ }
+ return hr;
+}
+
+static HRESULT
+find_default_source_from_typeinfo(
+ ITypeInfo *pTypeInfo,
+ TYPEATTR *pTypeAttr,
+ ITypeInfo **ppTypeInfo)
+{
+ int i = 0;
+ HRESULT hr = E_NOINTERFACE;
+ int flags;
+ HREFTYPE hRefType;
+ /* Enumerate all implemented types of the COCLASS */
+ for (i = 0; i < pTypeAttr->cImplTypes; i++) {
+ hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags);
+ if (FAILED(hr))
+ continue;
+
+ /*
+ looking for the [default] [source]
+ we just hope that it is a dispinterface :-)
+ */
+ if ((flags & IMPLTYPEFLAG_FDEFAULT) &&
+ (flags & IMPLTYPEFLAG_FSOURCE)) {
+
+ hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,
+ i, &hRefType);
+ if (FAILED(hr))
+ continue;
+ hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
+ hRefType, ppTypeInfo);
+ if (SUCCEEDED(hr))
+ break;
+ }
+ }
+ return hr;
+}
+
+static HRESULT
+find_default_source(VALUE ole, IID *piid, ITypeInfo **ppTypeInfo)
+{
+ HRESULT hr;
+ IProvideClassInfo2 *pProvideClassInfo2;
+ IProvideClassInfo *pProvideClassInfo;
+ void *p;
+
+ IDispatch *pDispatch;
+ ITypeInfo *pTypeInfo;
+ ITypeInfo *pTypeInfo2 = NULL;
+ TYPEATTR *pTypeAttr;
+ TYPEATTR *pTypeAttr2 = NULL;
+
+ struct oledata *pole = NULL;
+
+ pole = oledata_get_struct(ole);
+ pDispatch = pole->pDispatch;
+ hr = pDispatch->lpVtbl->QueryInterface(pDispatch,
+ &IID_IProvideClassInfo2,
+ &p);
+ if (SUCCEEDED(hr)) {
+ pProvideClassInfo2 = p;
+ hr = pProvideClassInfo2->lpVtbl->GetGUID(pProvideClassInfo2,
+ GUIDKIND_DEFAULT_SOURCE_DISP_IID,
+ piid);
+ OLE_RELEASE(pProvideClassInfo2);
+ if (SUCCEEDED(hr)) {
+ hr = find_iid(ole, NULL, piid, ppTypeInfo);
+ }
+ }
+ if (SUCCEEDED(hr)) {
+ return hr;
+ }
+ hr = pDispatch->lpVtbl->QueryInterface(pDispatch,
+ &IID_IProvideClassInfo,
+ &p);
+ if (SUCCEEDED(hr)) {
+ pProvideClassInfo = p;
+ hr = pProvideClassInfo->lpVtbl->GetClassInfo(pProvideClassInfo,
+ &pTypeInfo);
+ OLE_RELEASE(pProvideClassInfo);
+ }
+ if (FAILED(hr)) {
+ hr = pDispatch->lpVtbl->GetTypeInfo(pDispatch, 0, cWIN32OLE_lcid, &pTypeInfo );
+ }
+ if (FAILED(hr))
+ return hr;
+ hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
+ if (FAILED(hr)) {
+ OLE_RELEASE(pTypeInfo);
+ return hr;
+ }
+
+ *ppTypeInfo = 0;
+ hr = find_default_source_from_typeinfo(pTypeInfo, pTypeAttr, ppTypeInfo);
+ if (!*ppTypeInfo) {
+ hr = find_coclass(pTypeInfo, pTypeAttr, &pTypeInfo2, &pTypeAttr2);
+ if (SUCCEEDED(hr)) {
+ hr = find_default_source_from_typeinfo(pTypeInfo2, pTypeAttr2, ppTypeInfo);
+ OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2);
+ OLE_RELEASE(pTypeInfo2);
+ }
+ }
+ OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
+ OLE_RELEASE(pTypeInfo);
+ /* Now that would be a bad surprise, if we didn't find it, wouldn't it? */
+ if (!*ppTypeInfo) {
+ if (SUCCEEDED(hr))
+ hr = E_UNEXPECTED;
+ return hr;
+ }
+
+ /* Determine IID of default source interface */
+ hr = (*ppTypeInfo)->lpVtbl->GetTypeAttr(*ppTypeInfo, &pTypeAttr);
+ if (SUCCEEDED(hr)) {
+ *piid = pTypeAttr->guid;
+ (*ppTypeInfo)->lpVtbl->ReleaseTypeAttr(*ppTypeInfo, pTypeAttr);
+ }
+ else
+ OLE_RELEASE(*ppTypeInfo);
+
+ return hr;
+}
+
+static long
+ole_search_event_at(VALUE ary, VALUE ev)
+{
+ VALUE event;
+ VALUE event_name;
+ long i, len;
+ long ret = -1;
+ len = RARRAY_LEN(ary);
+ for(i = 0; i < len; i++) {
+ event = rb_ary_entry(ary, i);
+ event_name = rb_ary_entry(event, 1);
+ if(NIL_P(event_name) && NIL_P(ev)) {
+ ret = i;
+ break;
+ }
+ else if (RB_TYPE_P(ev, T_STRING) &&
+ RB_TYPE_P(event_name, T_STRING) &&
+ rb_str_cmp(ev, event_name) == 0) {
+ ret = i;
+ break;
+ }
+ }
+ return ret;
+}
+
+static VALUE
+ole_search_event(VALUE ary, VALUE ev, BOOL *is_default)
+{
+ VALUE event;
+ VALUE def_event;
+ VALUE event_name;
+ int i, len;
+ *is_default = FALSE;
+ def_event = Qnil;
+ len = RARRAY_LEN(ary);
+ for(i = 0; i < len; i++) {
+ event = rb_ary_entry(ary, i);
+ event_name = rb_ary_entry(event, 1);
+ if(NIL_P(event_name)) {
+ *is_default = TRUE;
+ def_event = event;
+ }
+ else if (rb_str_cmp(ev, event_name) == 0) {
+ *is_default = FALSE;
+ return event;
+ }
+ }
+ return def_event;
+}
+
+static VALUE
+ole_search_handler_method(VALUE handler, VALUE ev, BOOL *is_default_handler)
+{
+ VALUE mid;
+
+ *is_default_handler = FALSE;
+ mid = rb_to_id(rb_sprintf("on%"PRIsVALUE, ev));
+ if (rb_respond_to(handler, mid)) {
+ return mid;
+ }
+ mid = rb_intern("method_missing");
+ if (rb_respond_to(handler, mid)) {
+ *is_default_handler = TRUE;
+ return mid;
+ }
+ return Qnil;
+}
+
+static void
+ole_delete_event(VALUE ary, VALUE ev)
+{
+ long at = -1;
+ at = ole_search_event_at(ary, ev);
+ if (at >= 0) {
+ rb_ary_delete_at(ary, at);
+ }
+}
+
+
+static void
+oleevent_free(void *ptr)
+{
+ struct oleeventdata *poleev = ptr;
+ if (poleev->pConnectionPoint) {
+ poleev->pConnectionPoint->lpVtbl->Unadvise(poleev->pConnectionPoint, poleev->dwCookie);
+ OLE_RELEASE(poleev->pConnectionPoint);
+ poleev->pConnectionPoint = NULL;
+ }
+ OLE_RELEASE(poleev->pDispatch);
+ free(poleev);
+}
+
+static size_t
+oleevent_size(const void *ptr)
+{
+ return ptr ? sizeof(struct oleeventdata) : 0;
+}
+
+static VALUE
+fev_s_allocate(VALUE klass)
+{
+ VALUE obj;
+ struct oleeventdata *poleev;
+ obj = TypedData_Make_Struct(klass, struct oleeventdata, &oleevent_datatype, poleev);
+ poleev->dwCookie = 0;
+ poleev->pConnectionPoint = NULL;
+ poleev->event_id = 0;
+ poleev->pDispatch = NULL;
+ return obj;
+}
+
+static VALUE
+ev_advise(int argc, VALUE *argv, VALUE self)
+{
+
+ VALUE ole, itf;
+ struct oledata *pole = NULL;
+ char *pitf;
+ HRESULT hr;
+ IID iid;
+ ITypeInfo *pTypeInfo = 0;
+ IDispatch *pDispatch;
+ IConnectionPointContainer *pContainer;
+ IConnectionPoint *pConnectionPoint;
+ IEVENTSINKOBJ *pIEV;
+ DWORD dwCookie;
+ struct oleeventdata *poleev;
+ void *p;
+
+ rb_scan_args(argc, argv, "11", &ole, &itf);
+
+ if (!rb_obj_is_kind_of(ole, cWIN32OLE)) {
+ rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE object");
+ }
+
+ if(!RB_TYPE_P(itf, T_NIL)) {
+ pitf = StringValuePtr(itf);
+ if (rb_safe_level() > 0 && OBJ_TAINTED(itf)) {
+ rb_raise(rb_eSecurityError, "insecure event creation - `%s'",
+ StringValuePtr(itf));
+ }
+ hr = find_iid(ole, pitf, &iid, &pTypeInfo);
+ }
+ else {
+ hr = find_default_source(ole, &iid, &pTypeInfo);
+ }
+ if (FAILED(hr)) {
+ ole_raise(hr, rb_eRuntimeError, "interface not found");
+ }
+
+ pole = oledata_get_struct(ole);
+ pDispatch = pole->pDispatch;
+ hr = pDispatch->lpVtbl->QueryInterface(pDispatch,
+ &IID_IConnectionPointContainer,
+ &p);
+ if (FAILED(hr)) {
+ OLE_RELEASE(pTypeInfo);
+ ole_raise(hr, rb_eRuntimeError,
+ "failed to query IConnectionPointContainer");
+ }
+ pContainer = p;
+
+ hr = pContainer->lpVtbl->FindConnectionPoint(pContainer,
+ &iid,
+ &pConnectionPoint);
+ OLE_RELEASE(pContainer);
+ if (FAILED(hr)) {
+ OLE_RELEASE(pTypeInfo);
+ ole_raise(hr, rb_eRuntimeError, "failed to query IConnectionPoint");
+ }
+ pIEV = EVENTSINK_Constructor();
+ pIEV->m_iid = iid;
+ hr = pConnectionPoint->lpVtbl->Advise(pConnectionPoint,
+ (IUnknown*)pIEV,
+ &dwCookie);
+ if (FAILED(hr)) {
+ ole_raise(hr, rb_eRuntimeError, "Advise Error");
+ }
+
+ TypedData_Get_Struct(self, struct oleeventdata, &oleevent_datatype, poleev);
+ pIEV->m_event_id = evs_length();
+ pIEV->pTypeInfo = pTypeInfo;
+ poleev->dwCookie = dwCookie;
+ poleev->pConnectionPoint = pConnectionPoint;
+ poleev->event_id = pIEV->m_event_id;
+ poleev->pDispatch = pDispatch;
+ OLE_ADDREF(pDispatch);
+
+ return self;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_EVENT.new(ole, event) #=> WIN32OLE_EVENT object.
+ *
+ * Returns OLE event object.
+ * The first argument specifies WIN32OLE object.
+ * The second argument specifies OLE event name.
+ * ie = WIN32OLE.new('InternetExplorer.Application')
+ * ev = WIN32OLE_EVENT.new(ie, 'DWebBrowserEvents')
+ */
+static VALUE
+fev_initialize(int argc, VALUE *argv, VALUE self)
+{
+ ev_advise(argc, argv, self);
+ evs_push(self);
+ rb_ivar_set(self, id_events, rb_ary_new());
+ fev_set_handler(self, Qnil);
+ return self;
+}
+
+static void
+ole_msg_loop(void)
+{
+ MSG msg;
+ while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_EVENT.message_loop
+ *
+ * Translates and dispatches Windows message.
+ */
+static VALUE
+fev_s_msg_loop(VALUE klass)
+{
+ ole_msg_loop();
+ return Qnil;
+}
+
+static void
+add_event_call_back(VALUE obj, VALUE event, VALUE data)
+{
+ VALUE events = rb_ivar_get(obj, id_events);
+ if (NIL_P(events) || !RB_TYPE_P(events, T_ARRAY)) {
+ events = rb_ary_new();
+ rb_ivar_set(obj, id_events, events);
+ }
+ ole_delete_event(events, event);
+ rb_ary_push(events, data);
+}
+
+static VALUE
+ev_on_event(int argc, VALUE *argv, VALUE self, VALUE is_ary_arg)
+{
+ struct oleeventdata *poleev;
+ VALUE event, args, data;
+ TypedData_Get_Struct(self, struct oleeventdata, &oleevent_datatype, poleev);
+ if (poleev->pConnectionPoint == NULL) {
+ rb_raise(eWIN32OLERuntimeError, "IConnectionPoint not found. You must call advise at first.");
+ }
+ rb_scan_args(argc, argv, "01*", &event, &args);
+ if(!NIL_P(event)) {
+ if(!RB_TYPE_P(event, T_STRING) && !RB_TYPE_P(event, T_SYMBOL)) {
+ rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
+ }
+ if (RB_TYPE_P(event, T_SYMBOL)) {
+ event = rb_sym_to_s(event);
+ }
+ }
+ data = rb_ary_new3(4, rb_block_proc(), event, args, is_ary_arg);
+ add_event_call_back(self, event, data);
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_EVENT#on_event([event]){...}
+ *
+ * Defines the callback event.
+ * If argument is omitted, this method defines the callback of all events.
+ * If you want to modify reference argument in callback, return hash in
+ * callback. If you want to return value to OLE server as result of callback
+ * use `return' or :return.
+ *
+ * ie = WIN32OLE.new('InternetExplorer.Application')
+ * ev = WIN32OLE_EVENT.new(ie)
+ * ev.on_event("NavigateComplete") {|url| puts url}
+ * ev.on_event() {|ev, *args| puts "#{ev} fired"}
+ *
+ * ev.on_event("BeforeNavigate2") {|*args|
+ * ...
+ * # set true to BeforeNavigate reference argument `Cancel'.
+ * # Cancel is 7-th argument of BeforeNavigate,
+ * # so you can use 6 as key of hash instead of 'Cancel'.
+ * # The argument is counted from 0.
+ * # The hash key of 0 means first argument.)
+ * {:Cancel => true} # or {'Cancel' => true} or {6 => true}
+ * }
+ *
+ * ev.on_event(...) {|*args|
+ * {:return => 1, :xxx => yyy}
+ * }
+ */
+static VALUE
+fev_on_event(int argc, VALUE *argv, VALUE self)
+{
+ return ev_on_event(argc, argv, self, Qfalse);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_EVENT#on_event_with_outargs([event]){...}
+ *
+ * Defines the callback of event.
+ * If you want modify argument in callback,
+ * you could use this method instead of WIN32OLE_EVENT#on_event.
+ *
+ * ie = WIN32OLE.new('InternetExplorer.Application')
+ * ev = WIN32OLE_EVENT.new(ie)
+ * ev.on_event_with_outargs('BeforeNavigate2') {|*args|
+ * args.last[6] = true
+ * }
+ */
+static VALUE
+fev_on_event_with_outargs(int argc, VALUE *argv, VALUE self)
+{
+ return ev_on_event(argc, argv, self, Qtrue);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_EVENT#off_event([event])
+ *
+ * removes the callback of event.
+ *
+ * ie = WIN32OLE.new('InternetExplorer.Application')
+ * ev = WIN32OLE_EVENT.new(ie)
+ * ev.on_event('BeforeNavigate2') {|*args|
+ * args.last[6] = true
+ * }
+ * ...
+ * ev.off_event('BeforeNavigate2')
+ * ...
+ */
+static VALUE
+fev_off_event(int argc, VALUE *argv, VALUE self)
+{
+ VALUE event = Qnil;
+ VALUE events;
+
+ rb_scan_args(argc, argv, "01", &event);
+ if(!NIL_P(event)) {
+ if(!RB_TYPE_P(event, T_STRING) && !RB_TYPE_P(event, T_SYMBOL)) {
+ rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
+ }
+ if (RB_TYPE_P(event, T_SYMBOL)) {
+ event = rb_sym_to_s(event);
+ }
+ }
+ events = rb_ivar_get(self, id_events);
+ if (NIL_P(events)) {
+ return Qnil;
+ }
+ ole_delete_event(events, event);
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_EVENT#unadvise -> nil
+ *
+ * disconnects OLE server. If this method called, then the WIN32OLE_EVENT object
+ * does not receive the OLE server event any more.
+ * This method is trial implementation.
+ *
+ * ie = WIN32OLE.new('InternetExplorer.Application')
+ * ev = WIN32OLE_EVENT.new(ie)
+ * ev.on_event() {...}
+ * ...
+ * ev.unadvise
+ *
+ */
+static VALUE
+fev_unadvise(VALUE self)
+{
+ struct oleeventdata *poleev;
+ TypedData_Get_Struct(self, struct oleeventdata, &oleevent_datatype, poleev);
+ if (poleev->pConnectionPoint) {
+ ole_msg_loop();
+ evs_delete(poleev->event_id);
+ poleev->pConnectionPoint->lpVtbl->Unadvise(poleev->pConnectionPoint, poleev->dwCookie);
+ OLE_RELEASE(poleev->pConnectionPoint);
+ poleev->pConnectionPoint = NULL;
+ }
+ OLE_FREE(poleev->pDispatch);
+ return Qnil;
+}
+
+static VALUE
+evs_push(VALUE ev)
+{
+ return rb_ary_push(ary_ole_event, ev);
+}
+
+static VALUE
+evs_delete(long i)
+{
+ rb_ary_store(ary_ole_event, i, Qnil);
+ return Qnil;
+}
+
+static VALUE
+evs_entry(long i)
+{
+ return rb_ary_entry(ary_ole_event, i);
+}
+
+static long
+evs_length(void)
+{
+ return RARRAY_LEN(ary_ole_event);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_EVENT#handler=
+ *
+ * sets event handler object. If handler object has onXXX
+ * method according to XXX event, then onXXX method is called
+ * when XXX event occurs.
+ *
+ * If handler object has method_missing and there is no
+ * method according to the event, then method_missing
+ * called and 1-st argument is event name.
+ *
+ * If handler object has onXXX method and there is block
+ * defined by WIN32OLE_EVENT#on_event('XXX'){},
+ * then block is executed but handler object method is not called
+ * when XXX event occurs.
+ *
+ * class Handler
+ * def onStatusTextChange(text)
+ * puts "StatusTextChanged"
+ * end
+ * def onPropertyChange(prop)
+ * puts "PropertyChanged"
+ * end
+ * def method_missing(ev, *arg)
+ * puts "other event #{ev}"
+ * end
+ * end
+ *
+ * handler = Handler.new
+ * ie = WIN32OLE.new('InternetExplorer.Application')
+ * ev = WIN32OLE_EVENT.new(ie)
+ * ev.on_event("StatusTextChange") {|*args|
+ * puts "this block executed."
+ * puts "handler.onStatusTextChange method is not called."
+ * }
+ * ev.handler = handler
+ *
+ */
+static VALUE
+fev_set_handler(VALUE self, VALUE val)
+{
+ return rb_ivar_set(self, rb_intern("handler"), val);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_EVENT#handler
+ *
+ * returns handler object.
+ *
+ */
+static VALUE
+fev_get_handler(VALUE self)
+{
+ return rb_ivar_get(self, rb_intern("handler"));
+}
+
+void
+Init_win32ole_event(void)
+{
+ ary_ole_event = rb_ary_new();
+ rb_gc_register_mark_object(ary_ole_event);
+ id_events = rb_intern("events");
+ cWIN32OLE_EVENT = rb_define_class("WIN32OLE_EVENT", rb_cObject);
+ rb_define_singleton_method(cWIN32OLE_EVENT, "message_loop", fev_s_msg_loop, 0);
+ rb_define_alloc_func(cWIN32OLE_EVENT, fev_s_allocate);
+ rb_define_method(cWIN32OLE_EVENT, "initialize", fev_initialize, -1);
+ rb_define_method(cWIN32OLE_EVENT, "on_event", fev_on_event, -1);
+ rb_define_method(cWIN32OLE_EVENT, "on_event_with_outargs", fev_on_event_with_outargs, -1);
+ rb_define_method(cWIN32OLE_EVENT, "off_event", fev_off_event, -1);
+ rb_define_method(cWIN32OLE_EVENT, "unadvise", fev_unadvise, 0);
+ rb_define_method(cWIN32OLE_EVENT, "handler=", fev_set_handler, 1);
+ rb_define_method(cWIN32OLE_EVENT, "handler", fev_get_handler, 0);
+}
diff --git a/jni/ruby/ext/win32ole/win32ole_event.h b/jni/ruby/ext/win32ole/win32ole_event.h
new file mode 100644
index 0000000..f1a5aa2
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_event.h
@@ -0,0 +1,6 @@
+#ifndef WIN32OLE_EVENT_H
+#define WIN32OLE_EVENT_H 1
+
+void Init_win32ole_event(void);
+
+#endif
diff --git a/jni/ruby/ext/win32ole/win32ole_method.c b/jni/ruby/ext/win32ole/win32ole_method.c
new file mode 100644
index 0000000..ba8cf78
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_method.c
@@ -0,0 +1,950 @@
+#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, eWIN32OLERuntimeError, "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, eWIN32OLERuntimeError, "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, eWIN32OLERuntimeError, "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, eWIN32OLERuntimeError, "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
+ *
+ * <code>WIN32OLE_METHOD</code> 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
+ * WIN32OLE_METHOD#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, eWIN32OLERuntimeError, "failed to GetFuncDesc");
+
+ type = ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), Qnil);
+ pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
+ return type;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_METHOD#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 = INT2FIX(pFuncDesc->elemdescFunc.tdesc.vt);
+ pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
+ return vvt;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_METHOD#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:
+ * WIN32OLE_METHOD#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 = 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((FIX2INT(invkind) & INVOKE_PROPERTYGET) &&
+ (FIX2INT(invkind) & INVOKE_PROPERTYPUT) ) {
+ type = rb_str_new2("PROPERTY");
+ } else if(FIX2INT(invkind) & INVOKE_PROPERTYGET) {
+ type = rb_str_new2("PROPERTYGET");
+ } else if(FIX2INT(invkind) & INVOKE_PROPERTYPUT) {
+ type = rb_str_new2("PROPERTYPUT");
+ } else if(FIX2INT(invkind) & INVOKE_PROPERTYPUTREF) {
+ type = rb_str_new2("PROPERTYPUTREF");
+ } else if(FIX2INT(invkind) & INVOKE_FUNC) {
+ type = rb_str_new2("FUNC");
+ }
+ return type;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_MTHOD#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:
+ * WIN32OLE_METHOD#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:
+ * WIN32OLE_METHOD#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:
+ * WIN32OLE_METHOD#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:
+ * WIN32OLE_METHOD#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:
+ * WIN32OLE_METHOD#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:
+ * WIN32OLE_METHOD#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 INT2FIX(helpcontext);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_METHOD#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 = INT2NUM(pFuncDesc->memid);
+ pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
+ return dispid;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_METHOD#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 = INT2FIX(pFuncDesc->oVft);
+ pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
+ return offset_vtbl;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_METHOD#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 = INT2FIX(pFuncDesc->cParams);
+ pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
+ return size_params;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_METHOD#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 = INT2FIX(pFuncDesc->cParamsOpt);
+ pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
+ return size_opt_params;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_METHOD#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:
+ * WIN32OLE_METHOD#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:
+ * WIN32OLE_METHOD#inspect -> String
+ *
+ * Returns the method name with class name.
+ *
+ */
+static VALUE
+folemethod_inspect(VALUE self)
+{
+ return default_inspect(self, "WIN32OLE_METHOD");
+}
+
+void Init_win32ole_method(void)
+{
+ cWIN32OLE_METHOD = rb_define_class("WIN32OLE_METHOD", rb_cObject);
+ 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);
+}
diff --git a/jni/ruby/ext/win32ole/win32ole_method.h b/jni/ruby/ext/win32ole/win32ole_method.h
new file mode 100644
index 0000000..ff2898e
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_method.h
@@ -0,0 +1,16 @@
+#ifndef WIN32OLE_METHOD_H
+#define WIN32OLE_METHOD_H 1
+
+struct olemethoddata {
+ ITypeInfo *pOwnerTypeInfo;
+ ITypeInfo *pTypeInfo;
+ UINT index;
+};
+
+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
diff --git a/jni/ruby/ext/win32ole/win32ole_param.c b/jni/ruby/ext/win32ole/win32ole_param.c
new file mode 100644
index 0000000..31cf853
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_param.c
@@ -0,0 +1,438 @@
+#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
+ *
+ * <code>WIN32OLE_PARAM</code> 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:
+ * WIN32OLE_PARAM.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 = FIX2INT(n);
+ return oleparam_ole_param(self, olemethod, idx);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_PARAM#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:
+ * WIN32OLE_PARAM#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:
+ * WIN32OLE_PARAM#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:
+ * WIN32OLE_PARAM#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:
+ * WIN32OLE#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:
+ * WIN32OLE_PARAM#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:
+ * WIN32OLE_PARAM#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:
+ * WIN32OLE_PARAM#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:
+ * WIN32OLE_PARAM#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("WIN32OLE_PARAM", rb_cObject);
+ 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);
+}
diff --git a/jni/ruby/ext/win32ole/win32ole_param.h b/jni/ruby/ext/win32ole/win32ole_param.h
new file mode 100644
index 0000000..7e2650c
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_param.h
@@ -0,0 +1,8 @@
+#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
+
diff --git a/jni/ruby/ext/win32ole/win32ole_record.c b/jni/ruby/ext/win32ole/win32ole_record.c
new file mode 100644
index 0000000..28d6238
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_record.c
@@ -0,0 +1,604 @@
+#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
+ *
+ * <code>WIN32OLE_RECORD</code> 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:
+ * WIN32OLE_RECORD.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_sym_to_s(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:
+ * WIN32OLE_RECORD#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:
+ * WIN32OLE_RECORD#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_sym_to_s(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:
+ * WIN32OLE_RECORD#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_sym_to_s(name);
+ }
+ return olerecord_ivar_get(self, sname);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_RECORD#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_sym_to_s(name);
+ }
+ return olerecord_ivar_set(self, sname, val);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_RECORD#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);
+}
+
+void
+Init_win32ole_record(void)
+{
+ cWIN32OLE_RECORD = rb_define_class("WIN32OLE_RECORD", rb_cObject);
+ 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);
+}
diff --git a/jni/ruby/ext/win32ole/win32ole_record.h b/jni/ruby/ext/win32ole/win32ole_record.h
new file mode 100644
index 0000000..ea431e9
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_record.h
@@ -0,0 +1,10 @@
+#ifndef WIN32OLE_RECORD_H
+#define WIN32OLE_RECORD_H 1
+
+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
diff --git a/jni/ruby/ext/win32ole/win32ole_type.c b/jni/ruby/ext/win32ole/win32ole_type.c
new file mode 100644
index 0000000..efcac88
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_type.c
@@ -0,0 +1,915 @@
+#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
+ *
+ * <code>WIN32OLE_TYPE</code> objects represent OLE type libarary 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:
+ * WIN32OLE_TYPE.ole_classes(typelib)
+ *
+ * Returns array of WIN32OLE_TYPE objects defined by the <i>typelib</i> type library.
+ * This method will be OBSOLETE. Use WIN32OLE_TYPELIB.new(typelib).ole_classes 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:
+ * WIN32OLE_TYPE.typelibs
+ *
+ * Returns array of type libraries.
+ * This method will be OBSOLETE. Use WIN32OLE_TYPELIB.typelibs.collect{|t| t.name} 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:
+ * WIN32OLE_TYPE.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:
+ * WIN32OLE_TYPE.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:
+ * WIN32OLE_TYPE#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:
+ * WIN32OLE_TYPE#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:
+ * WIN32OLE_TYPE#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:
+ * WIN32OLE_TYPE#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:
+ * WIN32OLE_TYPE#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 = INT2FIX(pTypeAttr->wMajorVerNum);
+ OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
+ return ver;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_TYPE#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 = INT2FIX(pTypeAttr->wMinorVerNum);
+ OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
+ return ver;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_TYPE#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 = INT2FIX(pTypeAttr->typekind);
+ OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
+ return typekind;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_TYPE#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:
+ * WIN32OLE_TYPE#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:
+ * WIN32OLE_TYPE#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:
+ * WIN32OLE_TYPE#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 INT2FIX(helpcontext);
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_TYPE#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:
+ * WIN32OLE_TYPE#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:
+ * WIN32OLE_TYPE#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:
+ * WIN32OLE_TYPE#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:
+ * WIN32OLE_TYPE#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:
+ * WIN32OLE_TYPE#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:
+ * WIN32OLE_TYPE#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:
+ * WIN32OLE_TYPE#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:
+ * WIN32OLE_TYPE#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");
+}
+
+void Init_win32ole_type(void)
+{
+ cWIN32OLE_TYPE = rb_define_class("WIN32OLE_TYPE", rb_cObject);
+ 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);
+}
diff --git a/jni/ruby/ext/win32ole/win32ole_type.h b/jni/ruby/ext/win32ole/win32ole_type.h
new file mode 100644
index 0000000..a26bf3e
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_type.h
@@ -0,0 +1,8 @@
+#ifndef WIN32OLE_TYPE_H
+#define WIN32OLE_TYPE_H 1
+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
diff --git a/jni/ruby/ext/win32ole/win32ole_typelib.c b/jni/ruby/ext/win32ole/win32ole_typelib.c
new file mode 100644
index 0000000..5a431d8
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_typelib.c
@@ -0,0 +1,846 @@
+#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
+ *
+ * <code>WIN32OLE_TYPELIB</code> objects represent OLE tyblib information.
+ */
+
+/*
+ * call-seq:
+ *
+ * WIN32OLE_TYPELIB.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:
+ * WIN32OLE_TYPELIB.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);
+ if (len < 1 || len > 3) {
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..3)", len);
+ }
+
+ 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:
+ * WIN32OLE_TYPELIB#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:
+ * WIN32OLE_TYPELIB#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:
+ * WIN32OLE_TYPELIB#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:
+ * WIN32OLE_TYPELIB#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 = INT2NUM(pTLibAttr->wMajorVerNum);
+ pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
+ return major;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_TYPELIB#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 = INT2NUM(pTLibAttr->wMinorVerNum);
+ pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
+ return minor;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_TYPELIB#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:
+ * WIN32OLE_TYPELIB#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
+ * WIN32OLERuntimeError 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:
+ * WIN32OLE_TYPELIB#library_name
+ *
+ * Returns library name.
+ * If the method fails to access library name, WIN32OLERuntimeError 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:
+ * WIN32OLE_TYPELIB#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:
+ * WIN32OLE_TYPELIB#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");
+}
+
+void
+Init_win32ole_typelib(void)
+{
+ cWIN32OLE_TYPELIB = rb_define_class("WIN32OLE_TYPELIB", rb_cObject);
+ 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);
+}
diff --git a/jni/ruby/ext/win32ole/win32ole_typelib.h b/jni/ruby/ext/win32ole/win32ole_typelib.h
new file mode 100644
index 0000000..9fc117f
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_typelib.h
@@ -0,0 +1,11 @@
+#ifndef WIN32OLE_TYPELIB_H
+#define WIN32OLE_TYPELIB_H 1
+
+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
diff --git a/jni/ruby/ext/win32ole/win32ole_variable.c b/jni/ruby/ext/win32ole/win32ole_variable.c
new file mode 100644
index 0000000..dd58382
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_variable.c
@@ -0,0 +1,380 @@
+#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
+ *
+ * <code>WIN32OLE_VARIABLE</code> 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:
+ * WIN32OLE_VARIABLE#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:
+ * WIN32OLE_VARIABLE#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:
+ * WIN32OLE_VARIABLE#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:
+ * WIN32OLE_VARIABLE#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:
+ * WIN32OLE_VARIABLE#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:
+ * WIN32OLE_VARIABLE#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 = INT2FIX(pVarDesc->varkind);
+ return kind;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_VARIABLE#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:
+ * WIN32OLE_VARIABLE#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);
+}
+
+void Init_win32ole_variable(void)
+{
+ cWIN32OLE_VARIABLE = rb_define_class("WIN32OLE_VARIABLE", rb_cObject);
+ 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");
+}
diff --git a/jni/ruby/ext/win32ole/win32ole_variable.h b/jni/ruby/ext/win32ole/win32ole_variable.h
new file mode 100644
index 0000000..704dc13
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_variable.h
@@ -0,0 +1,8 @@
+#ifndef WIN32OLE_VARIABLE_H
+#define WIN32OLE_VARIABLE_H 1
+
+VALUE cWIN32OLE_VARIABLE;
+VALUE create_win32ole_variable(ITypeInfo *pTypeInfo, UINT index, VALUE name);
+void Init_win32ole_variable(void);
+
+#endif
diff --git a/jni/ruby/ext/win32ole/win32ole_variant.c b/jni/ruby/ext/win32ole/win32ole_variant.c
new file mode 100644
index 0000000..1731ab7
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_variant.c
@@ -0,0 +1,734 @@
+#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 (_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 (TYPE(v) != T_FIXNUM && TYPE(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) = 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 (_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:
+ * WIN32OLE_VARIANT.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 = 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 = 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
+ *
+ * <code>WIN32OLE_VARIANT</code> 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 specfied 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:
+ * WIN32OLE_VARIANT.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);
+ if (len < 1 || len > 3) {
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..3)", len);
+ }
+ 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 = 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] = 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:
+ * WIN32OLE_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 indicies should be 0 or natural number and
+ * lower than or equal to max indicies.
+ * (This point is different with Ruby Array indicies.)
+ *
+ * obj = WIN32OLE_VARIANT.new([[1,2,3],[4,5,6]])
+ * p obj[0,0] # => 1
+ * p obj[1,0] # => 4
+ * p obj[2,0] # => WIN32OLERuntimeError
+ * p obj[0, -1] # => WIN32OLERuntimeError
+ *
+ */
+static VALUE
+folevariant_ary_aref(int argc, VALUE *argv, VALUE self)
+{
+ struct olevariantdata *pvar;
+ SAFEARRAY *psa;
+ VALUE val = Qnil;
+ VARIANT variant;
+ LONG *pid;
+ HRESULT hr;
+
+ TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar);
+ if (!V_ISARRAY(&(pvar->var))) {
+ rb_raise(eWIN32OLERuntimeError,
+ "`[]' is not available for this variant type object");
+ }
+ psa = get_locked_safe_array(self);
+ if (psa == NULL) {
+ return val;
+ }
+
+ pid = ary2safe_array_index(argc, argv, psa);
+
+ VariantInit(&variant);
+ V_VT(&variant) = (V_VT(&(pvar->var)) & ~VT_ARRAY) | VT_BYREF;
+ hr = SafeArrayPtrOfIndex(psa, pid, &V_BYREF(&variant));
+ if (FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to SafeArrayPtrOfIndex");
+ }
+ val = ole_variant2val(&variant);
+
+ unlock_safe_array(psa);
+ if (pid) free(pid);
+ return val;
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_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 indicies should be 0 or natural number and
+ * lower than or equal to max indicies.
+ * (This point is different with Ruby Array indicies.)
+ *
+ * obj = WIN32OLE_VARIANT.new([[1,2,3],[4,5,6]])
+ * obj[0,0] = 7
+ * obj[1,0] = 8
+ * p obj.value # => [[7,2,3], [8,5,6]]
+ * obj[2,0] = 9 # => WIN32OLERuntimeError
+ * obj[0, -1] = 9 # => WIN32OLERuntimeError
+ *
+ */
+static VALUE
+folevariant_ary_aset(int argc, VALUE *argv, VALUE self)
+{
+ struct olevariantdata *pvar;
+ SAFEARRAY *psa;
+ VARIANT var;
+ VARTYPE vt;
+ LONG *pid;
+ HRESULT hr;
+ VOID *p = NULL;
+
+ TypedData_Get_Struct(self, struct olevariantdata, &olevariant_datatype, pvar);
+ if (!V_ISARRAY(&(pvar->var))) {
+ rb_raise(eWIN32OLERuntimeError,
+ "`[]' is not available for this variant type object");
+ }
+ psa = get_locked_safe_array(self);
+ if (psa == NULL) {
+ rb_raise(rb_eRuntimeError, "failed to get SafeArray pointer");
+ }
+
+ pid = ary2safe_array_index(argc-1, argv, psa);
+
+ VariantInit(&var);
+ vt = (V_VT(&(pvar->var)) & ~VT_ARRAY);
+ p = val2variant_ptr(argv[argc-1], &var, vt);
+ if ((V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == NULL) ||
+ (V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) == NULL)) {
+ rb_raise(eWIN32OLERuntimeError, "argument does not have IDispatch or IUnknown Interface");
+ }
+ hr = SafeArrayPutElement(psa, pid, p);
+ if (FAILED(hr)) {
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to SafeArrayPutElement");
+ }
+
+ unlock_safe_array(psa);
+ if (pid) free(pid);
+ return argv[argc-1];
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_VARIANT.value #=> Ruby object.
+ *
+ * Returns Ruby object value from OLE variant.
+ * obj = WIN32OLE_VARIANT.new(1, WIN32OLE::VARIANT::VT_BSTR)
+ * obj.value # => "1" (not Fixnum 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:
+ * WIN32OLE_VARIANT.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 INT2FIX(V_VT(&pvar->var));
+}
+
+/*
+ * call-seq:
+ * WIN32OLE_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.
+ * Thie 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));
+}
+
+void
+Init_win32ole_variant(void)
+{
+ cWIN32OLE_VARIANT = rb_define_class("WIN32OLE_VARIANT", rb_cObject);
+ 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, INT2FIX(VT_EMPTY)));
+
+ /*
+ * represents VT_NULL OLE object.
+ */
+ rb_define_const(cWIN32OLE_VARIANT, "Null",
+ rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, 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, 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), INT2FIX(VT_ERROR)));
+}
diff --git a/jni/ruby/ext/win32ole/win32ole_variant.h b/jni/ruby/ext/win32ole/win32ole_variant.h
new file mode 100644
index 0000000..efe7ea8
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_variant.h
@@ -0,0 +1,9 @@
+#ifndef WIN32OLE_VARIANT_H
+#define WIN32OLE_VARIANT_H 1
+
+VALUE cWIN32OLE_VARIANT;
+void ole_variant2variant(VALUE val, VARIANT *var);
+void Init_win32ole_variant(void);
+
+#endif
+
diff --git a/jni/ruby/ext/win32ole/win32ole_variant_m.c b/jni/ruby/ext/win32ole/win32ole_variant_m.c
new file mode 100644
index 0000000..eb3b0b1
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_variant_m.c
@@ -0,0 +1,149 @@
+#include "win32ole.h"
+
+void Init_win32ole_variant_m(void)
+{
+ /*
+ * Document-module: WIN32OLE::VARIANT
+ *
+ * The WIN32OLE::VARIANT 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, "VARIANT");
+
+ /*
+ * represents VT_EMPTY type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_EMPTY", INT2FIX(VT_EMPTY));
+
+ /*
+ * represents VT_NULL type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_NULL", INT2FIX(VT_NULL));
+
+ /*
+ * represents VT_I2 type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_I2", INT2FIX(VT_I2));
+
+ /*
+ * represents VT_I4 type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_I4", INT2FIX(VT_I4));
+
+ /*
+ * represents VT_R4 type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_R4", INT2FIX(VT_R4));
+
+ /*
+ * represents VT_R8 type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_R8", INT2FIX(VT_R8));
+
+ /*
+ * represents VT_CY type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_CY", INT2FIX(VT_CY));
+
+ /*
+ * represents VT_DATE type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_DATE", INT2FIX(VT_DATE));
+
+ /*
+ * represents VT_BSTR type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_BSTR", INT2FIX(VT_BSTR));
+
+ /*
+ * represents VT_USERDEFINED type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_USERDEFINED", INT2FIX(VT_USERDEFINED));
+
+ /*
+ * represents VT_PTR type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_PTR", INT2FIX(VT_PTR));
+
+ /*
+ * represents VT_DISPATCH type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_DISPATCH", INT2FIX(VT_DISPATCH));
+
+ /*
+ * represents VT_ERROR type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_ERROR", INT2FIX(VT_ERROR));
+
+ /*
+ * represents VT_BOOL type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_BOOL", INT2FIX(VT_BOOL));
+
+ /*
+ * represents VT_VARIANT type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_VARIANT", INT2FIX(VT_VARIANT));
+
+ /*
+ * represents VT_UNKNOWN type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_UNKNOWN", INT2FIX(VT_UNKNOWN));
+
+ /*
+ * represents VT_I1 type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_I1", INT2FIX(VT_I1));
+
+ /*
+ * represents VT_UI1 type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_UI1", INT2FIX(VT_UI1));
+
+ /*
+ * represents VT_UI2 type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_UI2", INT2FIX(VT_UI2));
+
+ /*
+ * represents VT_UI4 type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_UI4", INT2FIX(VT_UI4));
+
+#if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
+ /*
+ * represents VT_I8 type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_I8", INT2FIX(VT_I8));
+
+ /*
+ * represents VT_UI8 type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_UI8", INT2FIX(VT_UI8));
+#endif
+
+ /*
+ * represents VT_INT type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_INT", INT2FIX(VT_INT));
+
+ /*
+ * represents VT_UINT type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_UINT", INT2FIX(VT_UINT));
+
+ /*
+ * represents VT_ARRAY type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_ARRAY", INT2FIX(VT_ARRAY));
+
+ /*
+ * represents VT_BYREF type constant.
+ */
+ rb_define_const(mWIN32OLE_VARIANT, "VT_BYREF", INT2FIX(VT_BYREF));
+
+}
diff --git a/jni/ruby/ext/win32ole/win32ole_variant_m.h b/jni/ruby/ext/win32ole/win32ole_variant_m.h
new file mode 100644
index 0000000..afbef30
--- /dev/null
+++ b/jni/ruby/ext/win32ole/win32ole_variant_m.h
@@ -0,0 +1,7 @@
+#ifndef WIN32OLE_VARIANT_M_H
+#define WIN32OLE_VARIANT_M_H 1
+
+VALUE mWIN32OLE_VARIANT;
+void Init_win32ole_variant_m(void);
+
+#endif