Created
August 5, 2009 20:08
-
-
Save jarib/162915 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c | |
index dc1b77d..51f6b58 100644 | |
--- a/ext/win32ole/win32ole.c | |
+++ b/ext/win32ole/win32ole.c | |
@@ -12,16 +12,22 @@ | |
*/ | |
/* | |
- $Date$ | |
modified for win32ole (ruby) by Masaki.Suketa <[email protected]> | |
*/ | |
-#include "ruby.h" | |
-#include "st.h" | |
+#include "ruby/ruby.h" | |
+#include "ruby/st.h" | |
+#include "ruby/encoding.h" | |
+#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) | |
@@ -54,6 +60,39 @@ | |
#define V_BOOL(X) V_UNION(X,boolVal) | |
#endif | |
+#ifndef V_I1REF | |
+#define V_I1REF(X) V_UNION(X, pcVal) | |
+#endif | |
+ | |
+#ifndef U_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 | |
+ | |
+/* | |
+ * 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 OLE_RELEASE(X) (X) ? ((X)->lpVtbl->Release(X)) : 0 | |
#define OLE_ADDREF(X) (X) ? ((X)->lpVtbl->AddRef(X)) : 0 | |
@@ -62,7 +101,7 @@ | |
#define OLE_RELEASE_TYPEATTR(X, Y) ((X)->lpVtbl->ReleaseTypeAttr((X), (Y))) | |
#define OLE_FREE(x) {\ | |
- if(gOLEInitialized == Qtrue) {\ | |
+ if(g_ole_initialized == TRUE) {\ | |
if(x) {\ | |
OLE_RELEASE(x);\ | |
(x) = 0;\ | |
@@ -77,15 +116,28 @@ | |
}\ | |
} | |
+#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 WC2VSTR(x) ole_wc2vstr((x), TRUE) | |
-#define WIN32OLE_VERSION "0.7.6" | |
+#define WIN32OLE_VERSION "1.3.9" | |
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); | |
typedef struct { | |
struct IEventSinkVtbl * lpVtbl; | |
} IEventSink, *PEVENTSINK; | |
@@ -132,35 +184,50 @@ typedef struct tagIEVENTSINKOBJ { | |
DWORD m_cRef; | |
IID m_iid; | |
int m_event_id; | |
- DWORD m_dwCookie; | |
- IConnectionPoint *pConnectionPoint; | |
ITypeInfo *pTypeInfo; | |
- int *ptr_freed; | |
}IEVENTSINKOBJ, *PIEVENTSINKOBJ; | |
VALUE cWIN32OLE; | |
+VALUE cWIN32OLE_TYPELIB; | |
VALUE cWIN32OLE_TYPE; | |
VALUE cWIN32OLE_VARIABLE; | |
VALUE cWIN32OLE_METHOD; | |
VALUE cWIN32OLE_PARAM; | |
VALUE cWIN32OLE_EVENT; | |
-VALUE eWIN32OLE_RUNTIME_ERROR; | |
+VALUE cWIN32OLE_VARIANT; | |
+VALUE eWIN32OLERuntimeError; | |
VALUE mWIN32OLE_VARIANT; | |
+VALUE cWIN32OLE_PROPERTY; | |
static VALUE ary_ole_event; | |
static ID id_events; | |
-static BOOL gOLEInitialized = Qfalse; | |
+static BOOL g_ole_initialized = 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 UINT cWIN32OLE_cp = CP_ACP; | |
+static LCID cWIN32OLE_lcid = LOCALE_SYSTEM_DEFAULT; | |
+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 oledata { | |
IDispatch *pDispatch; | |
}; | |
@@ -187,8 +254,9 @@ struct oleparamdata { | |
}; | |
struct oleeventdata { | |
- IEVENTSINKOBJ *pEvent; | |
- int freed; | |
+ DWORD dwCookie; | |
+ IConnectionPoint *pConnectionPoint; | |
+ long event_id; | |
}; | |
struct oleparam { | |
@@ -196,15 +264,308 @@ struct oleparam { | |
OLECHAR** pNamedArgs; | |
}; | |
-static VALUE folemethod_s_allocate _((VALUE)); | |
-static VALUE olemethod_set_member _((VALUE, ITypeInfo *, ITypeInfo *, int, VALUE)); | |
-static VALUE foletype_s_allocate _((VALUE)); | |
-static VALUE oletype_set_member _((VALUE, ITypeInfo *, VALUE)); | |
-static VALUE olemethod_from_typeinfo _((VALUE, ITypeInfo *, VALUE)); | |
-static HRESULT ole_docinfo_from_type _((ITypeInfo *, BSTR *, BSTR *, DWORD *, BSTR *)); | |
-static char *ole_wc2mb(LPWSTR); | |
-static VALUE ole_variant2val(VARIANT*); | |
-static void ole_val2variant(VALUE, VARIANT*); | |
+struct olevariantdata { | |
+ VARIANT realvar; | |
+ VARIANT var; | |
+}; | |
+ | |
+ | |
+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 void time2d(int hh, int mm, int ss, double *pv); | |
+static void d2time(double v, int *hh, int *mm, int *ss); | |
+static void civil2jd(int y, int m, int d, long *jd); | |
+static void jd2civil(long day, int *yy, int *mm, int *dd); | |
+static void double2time(double v, int *y, int *m, int *d, int *hh, int *mm, int *ss); | |
+static double time_object2date(VALUE tmobj); | |
+static VALUE date2time_str(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 char *ole_wc2mb(LPWSTR pw); | |
+static VALUE ole_hresult2msg(HRESULT hr); | |
+static void ole_freeexceptinfo(EXCEPINFO *pExInfo); | |
+static VALUE ole_excepinfo2msg(EXCEPINFO *pExInfo); | |
+static void ole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...); | |
+static void ole_initialize(); | |
+static void ole_msg_loop(); | |
+static void ole_free(struct oledata *pole); | |
+static void oletype_free(struct oletypedata *poletype); | |
+static void olemethod_free(struct olemethoddata *polemethod); | |
+static void olevariable_free(struct olevariabledata *polevar); | |
+static void oleparam_free(struct oleparamdata *pole); | |
+static LPWSTR ole_vstr2wc(VALUE vstr); | |
+static LPWSTR ole_mb2wc(char *pm, int len); | |
+static VALUE ole_wc2vstr(LPWSTR pw, BOOL isfree); | |
+static VALUE ole_ary_m_entry(VALUE val, long *pid); | |
+static void * get_ptr_of_variant(VARIANT *pvar); | |
+static VALUE is_all_index_under(long *pid, long *pub, long dim); | |
+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 HRESULT ole_val_ary2variant_ary(VALUE val, VARIANT *var, VARTYPE vt); | |
+static void ole_val2variant(VALUE val, VARIANT *var); | |
+static void ole_val2variant_ex(VALUE val, VARIANT *var, VARTYPE vt); | |
+static void ole_val2ptr_variant(VALUE val, VARIANT *var); | |
+static void ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vt); | |
+static void ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar); | |
+static void ole_val2variant2(VALUE val, VARIANT *var); | |
+static VALUE make_inspect(const char *class_name, VALUE detail); | |
+static VALUE default_inspect(VALUE self, const char *class_name); | |
+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 VALUE ole_variant2val(VARIANT *pvar); | |
+static LONG reg_open_key(HKEY hkey, const char *name, HKEY *phkey); | |
+static LONG reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey); | |
+static VALUE reg_enum_key(HKEY hkey, DWORD i); | |
+static VALUE reg_get_val(HKEY hkey, const char *subkey); | |
+static VALUE reg_get_typelib_file_path(HKEY hkey); | |
+static VALUE typelib_file_from_clsid(VALUE ole); | |
+static VALUE typelib_file_from_typelib(VALUE ole); | |
+static VALUE typelib_file(VALUE ole); | |
+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(int argc, VALUE *argv, VALUE self); | |
+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 VALUE ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes); | |
+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_initialize(int argc, VALUE *argv, VALUE self); | |
+static VALUE hash2named_arg(VALUE pair, struct oleparam* 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 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 ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask); | |
+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 ole_type_from_itypeinfo(ITypeInfo *pTypeInfo); | |
+static VALUE fole_type(VALUE self); | |
+static VALUE make_oletypelib_obj(VALUE guid, VALUE major_version, VALUE minor_version); | |
+static VALUE ole_typelib_from_itypelib(ITypeLib *pTypeLib); | |
+static VALUE ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo); | |
+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 HRESULT ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile); | |
+static VALUE ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails); | |
+static VALUE ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails); | |
+static VALUE ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails); | |
+static VALUE fole_method_help(VALUE self, VALUE cmdname); | |
+static VALUE fole_activex_initialize(VALUE self); | |
+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 foletype_s_allocate(VALUE klass); | |
+static VALUE oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name); | |
+static VALUE oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass); | |
+static VALUE oletypelib_set_member(VALUE self, VALUE typelib, VALUE guid, VALUE version); | |
+static VALUE foletypelib_s_typelibs(VALUE self); | |
+static VALUE make_version_str(VALUE major, VALUE minor); | |
+static VALUE oletypelib_search_registry2(VALUE self, VALUE args); | |
+static VALUE oletypelib_search_registry(VALUE self, VALUE typelib); | |
+static VALUE foletypelib_initialize(VALUE self, VALUE args); | |
+static VALUE foletypelib_guid(VALUE self); | |
+static VALUE foletypelib_name(VALUE self); | |
+static VALUE foletypelib_version(VALUE self); | |
+static VALUE foletypelib_major_version(VALUE self); | |
+static VALUE foletypelib_minor_version(VALUE self); | |
+static VALUE oletypelib_path(VALUE guid, VALUE version); | |
+static VALUE foletypelib_path(VALUE self); | |
+static void oletypelib2itypelib(VALUE self, ITypeLib **ppTypeLib); | |
+static VALUE foletypelib_visible(VALUE self); | |
+static VALUE foletypelib_library_name(VALUE self); | |
+static VALUE foletypelib_ole_types(VALUE self); | |
+static VALUE foletypelib_inspect(VALUE self); | |
+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 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 VALUE ole_variables(ITypeInfo *pTypeInfo); | |
+static VALUE foletype_variables(VALUE self); | |
+static VALUE foletype_methods(VALUE self); | |
+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 VALUE olemethod_set_member(VALUE self, ITypeInfo *pTypeInfo, ITypeInfo *pOwnerTypeInfo, int index, VALUE name); | |
+static VALUE folemethod_s_allocate(VALUE klass); | |
+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 VALUE 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 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 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 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 void ole_event_free(struct oleeventdata *poleev); | |
+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 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 VALUE evs_length(); | |
+static void olevariant_free(struct olevariantdata *pvar); | |
+static VALUE folevariant_s_allocate(VALUE klass); | |
+static VALUE folevariant_s_array(VALUE klass, VALUE dims, VALUE vvt); | |
+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 VOID * val2variant_ptr(VALUE val, VARIANT *var, VARTYPE vt); | |
+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 void init_enc2cp(); | |
+static void free_enc2cp(); | |
static HRESULT (STDMETHODCALLTYPE mf_QueryInterface)( | |
IMessageFilter __RPC_FAR * This, | |
@@ -369,7 +730,9 @@ static HRESULT ( STDMETHODCALLTYPE GetIDsOfNames )( | |
/* [in] */ LCID lcid, | |
/* [size_is][out] */ DISPID __RPC_FAR *rgDispId) | |
{ | |
+ /* | |
Win32OLEIDispatch* p = (Win32OLEIDispatch*)This; | |
+ */ | |
char* psz = ole_wc2mb(*rgszNames); // support only one method | |
*rgDispId = rb_intern(psz); | |
free(psz); | |
@@ -408,8 +771,7 @@ static /* [local] */ HRESULT ( STDMETHODCALLTYPE Invoke )( | |
} | |
static IDispatch* | |
-val2dispatch(val) | |
- VALUE val; | |
+val2dispatch(VALUE val) | |
{ | |
struct st_table *tbl = DATA_PTR(com_hash); | |
Win32OLEIDispatch* pdisp; | |
@@ -430,22 +792,18 @@ val2dispatch(val) | |
} | |
static void | |
-time2d(hh, mm, ss, pv) | |
- int hh, mm, ss; | |
- double *pv; | |
+time2d(int hh, int mm, int ss, double *pv) | |
{ | |
*pv = (hh * 60.0 * 60.0 + mm * 60.0 + ss) / 86400.0; | |
} | |
static void | |
-d2time(v, hh, mm, ss) | |
- double v; | |
- int *hh, *mm, *ss; | |
+d2time(double v, int *hh, int *mm, int *ss) | |
{ | |
double d_hh, d_mm, d_ss; | |
int i_hh, i_mm, i_ss; | |
- double d = v * 86400.0; | |
+ double d = fabs(v * 86400.0); | |
d_hh = d / 3600.0; | |
i_hh = (int)d_hh; | |
@@ -480,9 +838,7 @@ d2time(v, hh, mm, ss) | |
} | |
static void | |
-civil2jd(y, m, d, jd) | |
- int y, m, d; | |
- long *jd; | |
+civil2jd(int y, int m, int d, long *jd) | |
{ | |
long a, b; | |
if (m <= 2) { | |
@@ -497,9 +853,7 @@ civil2jd(y, m, d, jd) | |
} | |
static void | |
-jd2civil(day, yy, mm, dd) | |
- long day; | |
- int *yy, *mm, *dd; | |
+jd2civil(long day, int *yy, int *mm, int *dd) | |
{ | |
long x, a, b, c, d, e; | |
x = (long)(((double)day - 1867216.25) / 36524.25); | |
@@ -520,9 +874,7 @@ jd2civil(day, yy, mm, dd) | |
} | |
static void | |
-double2time(v, y, m, d, hh, mm, ss) | |
- double v; | |
- int *y, *m, *d, *hh, *mm, *ss; | |
+double2time(double v, int *y, int *m, int *d, int *hh, int *mm, int *ss) | |
{ | |
long day; | |
double t; | |
@@ -535,8 +887,7 @@ double2time(v, y, m, d, hh, mm, ss) | |
} | |
static double | |
-time_object2date(tmobj) | |
- VALUE tmobj; | |
+time_object2date(VALUE tmobj) | |
{ | |
long y, m, d, hh, mm, ss; | |
long day; | |
@@ -553,26 +904,243 @@ time_object2date(tmobj) | |
} | |
static VALUE | |
-date2time_str(date) | |
- double date; | |
+date2time_str(double date) | |
{ | |
int y, m, d, hh, mm, ss; | |
- char szTime[40]; | |
double2time(date, &y, &m, &d, &hh, &mm, &ss); | |
- sprintf(szTime, | |
- "%4.4d/%02.2d/%02.2d %02.2d:%02.2d:%02.2d", | |
+ return rb_sprintf( | |
+ "%04d/%02d/%02d %02d:%02d:%02d", | |
y, m, d, hh, mm, ss); | |
- return rb_str_new2(szTime); | |
} | |
-static void ole_val2variant(); | |
+#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", 51936); | |
+ 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(pw) | |
- LPWSTR pw; | |
+ole_wc2mb(LPWSTR pw) | |
{ | |
- int size; | |
LPSTR pm; | |
+ int 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_N(char, size + 1); | |
+ 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_N(char, size + 1); | |
@@ -587,8 +1155,7 @@ ole_wc2mb(pw) | |
} | |
static VALUE | |
-ole_hresult2msg(hr) | |
- HRESULT hr; | |
+ole_hresult2msg(HRESULT hr) | |
{ | |
VALUE msg = Qnil; | |
char *p_msg = NULL; | |
@@ -596,13 +1163,13 @@ ole_hresult2msg(hr) | |
DWORD dwCount; | |
char strhr[100]; | |
- sprintf(strhr, " HRESULT error code:0x%08lx\n ", hr); | |
+ 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, LOCALE_SYSTEM_DEFAULT, | |
+ NULL, hr, cWIN32OLE_lcid, | |
(LPTSTR)&p_msg, 0, NULL); | |
if (dwCount > 0) { | |
term = p_msg + strlen(p_msg); | |
@@ -621,8 +1188,7 @@ ole_hresult2msg(hr) | |
} | |
static void | |
-ole_freeexceptinfo(pExInfo) | |
- EXCEPINFO *pExInfo; | |
+ole_freeexceptinfo(EXCEPINFO *pExInfo) | |
{ | |
SysFreeString(pExInfo->bstrDescription); | |
SysFreeString(pExInfo->bstrSource); | |
@@ -630,8 +1196,7 @@ ole_freeexceptinfo(pExInfo) | |
} | |
static VALUE | |
-ole_excepinfo2msg(pExInfo) | |
- EXCEPINFO *pExInfo; | |
+ole_excepinfo2msg(EXCEPINFO *pExInfo) | |
{ | |
char error_code[40]; | |
char *pSource = NULL; | |
@@ -673,15 +1238,7 @@ ole_excepinfo2msg(pExInfo) | |
} | |
static void | |
-#ifdef HAVE_STDARG_PROTOTYPES | |
ole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...) | |
-#else | |
-ole_raise(hr, exc, fmt, va_alist) | |
- HRESULT hr; | |
- VALUE exc; | |
- const char *fmt; | |
- va_dcl | |
-#endif | |
{ | |
va_list args; | |
char buf[BUFSIZ]; | |
@@ -703,7 +1260,7 @@ void | |
ole_uninitialize() | |
{ | |
OleUninitialize(); | |
- gOLEInitialized = Qfalse; | |
+ g_ole_initialized = FALSE; | |
} | |
static void | |
@@ -711,12 +1268,12 @@ ole_initialize() | |
{ | |
HRESULT hr; | |
- if(gOLEInitialized == Qfalse) { | |
+ if(g_ole_initialized == FALSE) { | |
hr = OleInitialize(NULL); | |
if(FAILED(hr)) { | |
ole_raise(hr, rb_eRuntimeError, "fail: OLE initialize"); | |
} | |
- gOLEInitialized = Qtrue; | |
+ g_ole_initialized = TRUE; | |
/* | |
* In some situation, OleUninitialize does not work fine. ;-< | |
*/ | |
@@ -741,24 +1298,21 @@ ole_msg_loop() { | |
} | |
static void | |
-ole_free(pole) | |
- struct oledata *pole; | |
+ole_free(struct oledata *pole) | |
{ | |
OLE_FREE(pole->pDispatch); | |
free(pole); | |
} | |
static void | |
-oletype_free(poletype) | |
- struct oletypedata *poletype; | |
+oletype_free(struct oletypedata *poletype) | |
{ | |
OLE_FREE(poletype->pTypeInfo); | |
free(poletype); | |
} | |
static void | |
-olemethod_free(polemethod) | |
- struct olemethoddata *polemethod; | |
+olemethod_free(struct olemethoddata *polemethod) | |
{ | |
OLE_FREE(polemethod->pTypeInfo); | |
OLE_FREE(polemethod->pOwnerTypeInfo); | |
@@ -766,28 +1320,97 @@ olemethod_free(polemethod) | |
} | |
static void | |
-olevariable_free(polevar) | |
- struct olevariabledata *polevar; | |
+olevariable_free(struct olevariabledata *polevar) | |
{ | |
OLE_FREE(polevar->pTypeInfo); | |
free(polevar); | |
} | |
static void | |
-oleparam_free(pole) | |
- struct oleparamdata *pole; | |
+oleparam_free(struct oleparamdata *pole) | |
{ | |
OLE_FREE(pole->pTypeInfo); | |
free(pole); | |
} | |
+ | |
static LPWSTR | |
-ole_mb2wc(pm, len) | |
- char *pm; | |
- int len; | |
+ole_vstr2wc(VALUE vstr) | |
{ | |
- int size; | |
+ rb_encoding *enc; | |
+ int cp; | |
+ int size = 0; | |
LPWSTR pw; | |
+ st_data_t data; | |
+ enc = rb_enc_get(vstr); | |
+ | |
+ if (st_lookup(enc2cp_table, (st_data_t)enc, &data)) { | |
+ cp = 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; | |
+ int len = RSTRING_LEN(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) | |
+{ | |
+ int size = 0; | |
+ LPWSTR pw; | |
+ | |
+ if (conv_51932(cWIN32OLE_cp)) { | |
+#ifndef pIMultiLanguage | |
+ DWORD dw = 0; | |
+ int 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); | |
@@ -795,12 +1418,10 @@ ole_mb2wc(pm, len) | |
} | |
static VALUE | |
-ole_wc2vstr(pw, isfree) | |
- LPWSTR pw; | |
- BOOL isfree; | |
+ole_wc2vstr(LPWSTR pw, BOOL isfree) | |
{ | |
char *p = ole_wc2mb(pw); | |
- VALUE vstr = rb_str_new2(p); | |
+ VALUE vstr = rb_enc_str_new(p, strlen(p), cWIN32OLE_enc); | |
if(isfree) | |
SysFreeString(pw); | |
free(p); | |
@@ -808,9 +1429,7 @@ ole_wc2vstr(pw, isfree) | |
} | |
static VALUE | |
-ole_ary_m_entry(val, pid) | |
- VALUE val; | |
- long *pid; | |
+ole_ary_m_entry(VALUE val, long *pid) | |
{ | |
VALUE obj = Qnil; | |
int i = 0; | |
@@ -822,40 +1441,230 @@ ole_ary_m_entry(val, pid) | |
return obj; | |
} | |
+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 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; | |
+} | |
+ | |
static void | |
-ole_set_safe_array(n, psa, pid, pub, val, dim) | |
- long n; | |
- SAFEARRAY *psa; | |
- long *pid; | |
- long *pub; | |
- VALUE val; | |
- long dim; | |
+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; | |
- VariantInit(&var); | |
- if(n < 0) return; | |
- if(n == dim) { | |
+ VOID *p = NULL; | |
+ long i = n; | |
+ while(i >= 0) { | |
val1 = ole_ary_m_entry(val, pid); | |
- ole_val2variant(val1, &var); | |
- SafeArrayPutElement(psa, pid, &var); | |
+ 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 (TYPE(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 (TYPE(ary) == T_ARRAY) { | |
+ ary_len = RARRAY_LEN(ary); | |
+ } | |
+ } else { | |
+ if (TYPE(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; | |
+} | |
+ | |
+static 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, *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"); | |
} | |
- pid[n] += 1; | |
- if (pid[n] < pub[n]) { | |
- ole_set_safe_array(dim, psa, pid, pub, val, dim); | |
+ | |
+ 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 { | |
- pid[n] = 0; | |
- ole_set_safe_array(n-1, psa, pid, pub, val, dim); | |
+ if (psa != NULL) | |
+ SafeArrayDestroy(psa); | |
} | |
+ return hr; | |
} | |
static void | |
-ole_val2variant(val, var) | |
- VALUE val; | |
- VARIANT *var; | |
+ole_val2variant(VALUE val, VARIANT *var) | |
{ | |
struct oledata *pole; | |
+ struct olevariantdata *pvar; | |
if(rb_obj_is_kind_of(val, cWIN32OLE)) { | |
Data_Get_Struct(val, struct oledata, pole); | |
OLE_ADDREF(pole->pDispatch); | |
@@ -863,6 +1672,12 @@ ole_val2variant(val, var) | |
V_DISPATCH(var) = pole->pDispatch; | |
return; | |
} | |
+ if (rb_obj_is_kind_of(val, cWIN32OLE_VARIANT)) { | |
+ Data_Get_Struct(val, struct olevariantdata, pvar); | |
+ VariantCopy(var, &(pvar->var)); | |
+ return; | |
+ } | |
+ | |
if (rb_obj_is_kind_of(val, rb_cTime)) { | |
V_VT(var) = VT_DATE; | |
V_DATE(var) = time_object2date(val); | |
@@ -870,66 +1685,11 @@ ole_val2variant(val, var) | |
} | |
switch (TYPE(val)) { | |
case T_ARRAY: | |
- { | |
- VALUE val1; | |
- long dim = 0; | |
- int i = 0; | |
- | |
- HRESULT hr; | |
- SAFEARRAYBOUND *psab; | |
- SAFEARRAY *psa; | |
- long *pub, *pid; | |
- | |
- val1 = val; | |
- while(TYPE(val1) == T_ARRAY) { | |
- val1 = rb_ary_entry(val1, 0); | |
- dim += 1; | |
- } | |
- 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"); | |
- } | |
- val1 = val; | |
- i = 0; | |
- while(TYPE(val1) == T_ARRAY) { | |
- psab[i].cElements = RARRAY(val1)->len; | |
- psab[i].lLbound = 0; | |
- pub[i] = psab[i].cElements; | |
- pid[i] = 0; | |
- i ++; | |
- val1 = rb_ary_entry(val1, 0); | |
- } | |
- /* Create and fill VARIANT array */ | |
- psa = SafeArrayCreate(VT_VARIANT, 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-1); | |
- hr = SafeArrayUnlock(psa); | |
- } | |
- if(pub) free(pub); | |
- if(psab) free(psab); | |
- if(pid) free(pid); | |
- | |
- if (SUCCEEDED(hr)) { | |
- V_VT(var) = VT_VARIANT | VT_ARRAY; | |
- V_ARRAY(var) = psa; | |
- } | |
- else if (psa != NULL) | |
- SafeArrayDestroy(psa); | |
+ ole_val_ary2variant_ary(val, var, VT_VARIANT|VT_ARRAY); | |
break; | |
- } | |
case T_STRING: | |
V_VT(var) = VT_BSTR; | |
- V_BSTR(var) = ole_mb2wc(StringValuePtr(val), -1); | |
+ V_BSTR(var) = ole_vstr2wc(val); | |
break; | |
case T_FIXNUM: | |
V_VT(var) = VT_I4; | |
@@ -967,9 +1727,290 @@ ole_val2variant(val, var) | |
} | |
static void | |
-ole_val2variant2(val, var) | |
- VALUE val; | |
- VARIANT *var; | |
+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 | |
+} | |
+ | |
+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 | |
+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) | |
+ case VT_I8: | |
+ V_I8REF(var) = &V_I8(realvar); | |
+ break; | |
+ case VT_UI8: | |
+ V_UI8REF(var) = &V_UI8(realvar); | |
+ break; | |
+#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 void | |
+ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar) | |
+{ | |
+ HRESULT hr = S_OK; | |
+ | |
+ if (((vt & ~VT_BYREF) == (VT_ARRAY | VT_UI1)) && TYPE(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 (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_val2variant2(VALUE val, VARIANT *var) | |
{ | |
g_nil_to = VT_EMPTY; | |
ole_val2variant(val, var); | |
@@ -977,9 +2018,26 @@ ole_val2variant2(val, var) | |
} | |
static VALUE | |
-ole_set_member(self, dispatch) | |
- VALUE self; | |
- IDispatch * dispatch; | |
+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; | |
+} | |
+ | |
+static 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; | |
Data_Get_Struct(self, struct oledata, pole); | |
@@ -991,10 +2049,9 @@ ole_set_member(self, dispatch) | |
return self; | |
} | |
-static VALUE fole_s_allocate _((VALUE)); | |
+ | |
static VALUE | |
-fole_s_allocate(klass) | |
- VALUE klass; | |
+fole_s_allocate(VALUE klass) | |
{ | |
struct oledata *pole; | |
VALUE obj; | |
@@ -1005,11 +2062,7 @@ fole_s_allocate(klass) | |
} | |
static VALUE | |
-create_win32ole_object(klass, pDispatch, argc, argv) | |
- VALUE klass; | |
- IDispatch *pDispatch; | |
- int argc; | |
- VALUE *argv; | |
+create_win32ole_object(VALUE klass, IDispatch *pDispatch, int argc, VALUE *argv) | |
{ | |
VALUE obj = fole_s_allocate(klass); | |
ole_set_member(obj, pDispatch); | |
@@ -1017,8 +2070,40 @@ create_win32ole_object(klass, pDispatch, argc, argv) | |
} | |
static VALUE | |
-ole_variant2val(pvar) | |
- VARIANT *pvar; | |
+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); | |
+} | |
+ | |
+static VALUE | |
+ole_variant2val(VARIANT *pvar) | |
{ | |
VALUE obj = Qnil; | |
HRESULT hr; | |
@@ -1027,75 +2112,70 @@ ole_variant2val(pvar) | |
if(V_ISARRAY(pvar)) { | |
SAFEARRAY *psa = V_ISBYREF(pvar) ? *V_ARRAYREF(pvar) : V_ARRAY(pvar); | |
- long i; | |
- long *pID, *pLB, *pUB; | |
+ UINT i = 0; | |
+ long *pid, *plb, *pub; | |
VARIANT variant; | |
VALUE val; | |
- VALUE val2; | |
- int dim = 0; | |
- | |
+ UINT dim = 0; | |
if (!psa) { | |
return obj; | |
} | |
dim = SafeArrayGetDim(psa); | |
- | |
VariantInit(&variant); | |
V_VT(&variant) = (V_VT(pvar) & ~VT_ARRAY) | VT_BYREF; | |
- pID = ALLOC_N(long, dim); | |
- pLB = ALLOC_N(long, dim); | |
- pUB = ALLOC_N(long, dim); | |
+ 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); | |
+ if(!pid || !plb || !pub) { | |
+ if(pid) free(pid); | |
+ if(plb) free(plb); | |
+ if(pub) free(pub); | |
rb_raise(rb_eRuntimeError, "memory allocation error"); | |
} | |
- obj = Qnil; | |
- | |
for(i = 0; i < dim; ++i) { | |
- SafeArrayGetLBound(psa, i+1, &pLB[i]); | |
- SafeArrayGetLBound(psa, i+1, &pID[i]); | |
- SafeArrayGetUBound(psa, i+1, &pUB[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)) { | |
- val2 = rb_ary_new(); | |
- while (i >= 0) { | |
- hr = SafeArrayPtrOfIndex(psa, pID, &V_BYREF(&variant)); | |
- if (FAILED(hr)) | |
- break; | |
- | |
- val = ole_variant2val(&variant); | |
- rb_ary_push(val2, val); | |
- for (i = dim-1 ; i >= 0 ; --i) { | |
- if (++pID[i] <= pUB[i]) | |
+ obj = rb_ary_new(); | |
+ i = 0; | |
+ while (i < dim) { | |
+ ary_new_dim(obj, pid, plb, dim); | |
+ 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]; | |
- if (i > 0) { | |
- if (obj == Qnil) | |
- obj = rb_ary_new(); | |
- rb_ary_push(obj, val2); | |
- val2 = rb_ary_new(); | |
- } | |
+ pid[i] = plb[i]; | |
} | |
} | |
SafeArrayUnlock(psa); | |
} | |
- if(pID) free(pID); | |
- if(pLB) free(pLB); | |
- if(pUB) free(pUB); | |
- return (obj == Qnil) ? val2 : obj; | |
+ 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)); | |
@@ -1110,6 +2190,13 @@ ole_variant2val(pvar) | |
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)); | |
@@ -1117,6 +2204,50 @@ ole_variant2val(pvar) | |
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) | |
+ obj = I8_2_NUM(*V_I8REF(pvar)); | |
+#else | |
+ obj = Qnil; | |
+#endif | |
+ else | |
+ obj = I8_2_NUM(V_I8(pvar)); | |
+ break; | |
+ case VT_UI8: | |
+ if(V_ISBYREF(pvar)) | |
+#if (_MSC_VER >= 1300) | |
+ obj = UI8_2_NUM(*V_UI8REF(pvar)); | |
+#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)); | |
@@ -1133,13 +2264,10 @@ ole_variant2val(pvar) | |
case VT_BSTR: | |
{ | |
- char *p; | |
if(V_ISBYREF(pvar)) | |
- p = ole_wc2mb(*V_BSTRREF(pvar)); | |
+ obj = ole_wc2vstr(*V_BSTRREF(pvar), FALSE); | |
else | |
- p = ole_wc2mb(V_BSTR(pvar)); | |
- obj = rb_str_new2(p); | |
- if(p) free(p); | |
+ obj = ole_wc2vstr(V_BSTR(pvar), FALSE); | |
break; | |
} | |
@@ -1175,10 +2303,10 @@ ole_variant2val(pvar) | |
case VT_UNKNOWN: | |
{ | |
- | |
/* get IDispatch interface from IUnknown interface */ | |
IUnknown *punk; | |
IDispatch *pDispatch; | |
+ void *p; | |
HRESULT hr; | |
if (V_ISBYREF(pvar)) | |
@@ -1187,9 +2315,9 @@ ole_variant2val(pvar) | |
punk = V_UNKNOWN(pvar); | |
if(punk != NULL) { | |
- hr = punk->lpVtbl->QueryInterface(punk, &IID_IDispatch, | |
- (void **)&pDispatch); | |
+ hr = punk->lpVtbl->QueryInterface(punk, &IID_IDispatch, &p); | |
if(SUCCEEDED(hr)) { | |
+ pDispatch = p; | |
obj = create_win32ole_object(cWIN32OLE, pDispatch, 0, 0); | |
} | |
} | |
@@ -1214,11 +2342,9 @@ ole_variant2val(pvar) | |
VARIANT variant; | |
VariantInit(&variant); | |
hr = VariantChangeTypeEx(&variant, pvar, | |
- LOCALE_SYSTEM_DEFAULT, 0, VT_BSTR); | |
+ cWIN32OLE_lcid, 0, VT_BSTR); | |
if (SUCCEEDED(hr) && V_VT(&variant) == VT_BSTR) { | |
- char *p = ole_wc2mb(V_BSTR(&variant)); | |
- obj = rb_str_new2(p); | |
- if(p) free(p); | |
+ obj = ole_wc2vstr(V_BSTR(&variant), FALSE); | |
} | |
VariantClear(&variant); | |
break; | |
@@ -1227,30 +2353,23 @@ ole_variant2val(pvar) | |
return obj; | |
} | |
- | |
-static LONG reg_open_key(hkey, name, phkey) | |
- HKEY hkey; | |
- const char *name; | |
- HKEY *phkey; | |
+static LONG | |
+reg_open_key(HKEY hkey, const char *name, HKEY *phkey) | |
{ | |
return RegOpenKeyEx(hkey, name, 0, KEY_READ, phkey); | |
} | |
-static LONG reg_open_vkey(hkey, key, phkey) | |
- HKEY hkey; | |
- VALUE key; | |
- HKEY *phkey; | |
+static LONG | |
+reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey) | |
{ | |
return reg_open_key(hkey, StringValuePtr(key), phkey); | |
} | |
static VALUE | |
-reg_enum_key(hkey, i) | |
- HKEY hkey; | |
- DWORD i; | |
+reg_enum_key(HKEY hkey, DWORD i) | |
{ | |
char buf[BUFSIZ + 1]; | |
- DWORD size_buf = sizeof(buf) - 1; | |
+ DWORD size_buf = sizeof(buf); | |
FILETIME ft; | |
LONG err = RegEnumKeyEx(hkey, i, buf, &size_buf, | |
NULL, NULL, NULL, &ft); | |
@@ -1262,59 +2381,84 @@ reg_enum_key(hkey, i) | |
} | |
static VALUE | |
-reg_get_val(hkey, subkey) | |
- HKEY hkey; | |
- const char *subkey; | |
+reg_get_val(HKEY hkey, const char *subkey) | |
{ | |
- char buf[BUFSIZ + 1]; | |
- LONG size_buf = sizeof(buf) - 1; | |
- LONG err = RegQueryValue(hkey, subkey, buf, &size_buf); | |
+ char *pbuf; | |
+ DWORD dwtype = 0; | |
+ LONG size = 0; | |
+ VALUE val = Qnil; | |
+ LONG err = RegQueryValueEx(hkey, subkey, NULL, &dwtype, NULL, &size); | |
+ | |
if (err == ERROR_SUCCESS) { | |
- buf[BUFSIZ] = '\0'; | |
- return rb_str_new2(buf); | |
+ pbuf = ALLOC_N(char, size + 1); | |
+ err = RegQueryValueEx(hkey, subkey, NULL, &dwtype, pbuf, &size); | |
+ if (err == ERROR_SUCCESS) { | |
+ pbuf[size] = '\0'; | |
+ val = rb_str_new2(pbuf); | |
+ } | |
+ free(pbuf); | |
} | |
- return Qnil; | |
+ return val; | |
} | |
static VALUE | |
-typelib_file_from_clsid(ole) | |
- VALUE ole; | |
+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 VALUE | |
+reg_get_typelib_file_path(HKEY hkey) | |
+{ | |
+ VALUE path = Qnil; | |
+ path = reg_get_val2(hkey, "win32"); | |
+ if (path == Qnil) { | |
+ path = reg_get_val2(hkey, "win16"); | |
+ } | |
+ return path; | |
+} | |
+ | |
+static VALUE | |
+typelib_file_from_clsid(VALUE ole) | |
{ | |
- OLECHAR *pbuf; | |
- CLSID clsid; | |
- HRESULT hr; | |
HKEY hroot, hclsid; | |
LONG err; | |
VALUE typelib; | |
- VALUE vclsid; | |
- char *pclsid = NULL; | |
+ char path[MAX_PATH + 1]; | |
- pbuf = ole_mb2wc(StringValuePtr(ole), -1); | |
- hr = CLSIDFromProgID(pbuf, &clsid); | |
- SysFreeString(pbuf); | |
- if (FAILED(hr)) { | |
- return Qnil; | |
- } | |
- StringFromCLSID(&clsid, &pbuf); | |
- vclsid = WC2VSTR(pbuf); | |
err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hroot); | |
if (err != ERROR_SUCCESS) { | |
return Qnil; | |
} | |
- err = reg_open_key(hroot, StringValuePtr(vclsid), &hclsid); | |
+ err = reg_open_key(hroot, StringValuePtr(ole), &hclsid); | |
if (err != ERROR_SUCCESS) { | |
RegCloseKey(hroot); | |
return Qnil; | |
} | |
- typelib = reg_get_val(hclsid, "InprocServer32"); | |
+ 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; | |
} | |
static VALUE | |
-typelib_file_from_typelib(ole) | |
- VALUE ole; | |
+typelib_file_from_typelib(VALUE ole) | |
{ | |
HKEY htypelib, hclsid, hversion, hlang; | |
double fver; | |
@@ -1344,7 +2488,7 @@ typelib_file_from_typelib(ole) | |
if (ver == Qnil) | |
break; | |
err = reg_open_vkey(hclsid, ver, &hversion); | |
- if (err != ERROR_SUCCESS || fver > atof(StringValuePtr(ver))) | |
+ if (err != ERROR_SUCCESS || fver > atof(StringValuePtr(ver))) | |
continue; | |
fver = atof(StringValuePtr(ver)); | |
typelib = reg_get_val(hversion, NULL); | |
@@ -1357,7 +2501,7 @@ typelib_file_from_typelib(ole) | |
break; | |
err = reg_open_vkey(hversion, lang, &hlang); | |
if (err == ERROR_SUCCESS) { | |
- if ((file = reg_get_val(hlang, "win32")) != Qnil) | |
+ if ((file = reg_get_typelib_file_path(hlang)) != Qnil) | |
found = TRUE; | |
RegCloseKey(hlang); | |
} | |
@@ -1372,8 +2516,7 @@ typelib_file_from_typelib(ole) | |
} | |
static VALUE | |
-typelib_file(ole) | |
- VALUE ole; | |
+typelib_file(VALUE ole) | |
{ | |
VALUE file = typelib_file_from_clsid(ole); | |
if (file != Qnil) { | |
@@ -1383,10 +2526,7 @@ typelib_file(ole) | |
} | |
static void | |
-ole_const_load(pTypeLib, klass, self) | |
- ITypeLib *pTypeLib; | |
- VALUE klass; | |
- VALUE self; | |
+ole_const_load(ITypeLib *pTypeLib, VALUE klass, VALUE self) | |
{ | |
unsigned int count; | |
unsigned int index; | |
@@ -1449,10 +2589,7 @@ ole_const_load(pTypeLib, klass, self) | |
} | |
static HRESULT | |
-clsid_from_remote(host, com, pclsid) | |
- VALUE host; | |
- VALUE com; | |
- CLSID *pclsid; | |
+clsid_from_remote(VALUE host, VALUE com, CLSID *pclsid) | |
{ | |
HKEY hlm; | |
HKEY hpid; | |
@@ -1474,7 +2611,7 @@ clsid_from_remote(host, com, pclsid) | |
hr = HRESULT_FROM_WIN32(err); | |
else { | |
len = sizeof(clsid); | |
- err = RegQueryValueEx(hpid, "", NULL, &dwtype, clsid, &len); | |
+ err = RegQueryValueEx(hpid, (LPBYTE)"", NULL, &dwtype, clsid, &len); | |
if (err == ERROR_SUCCESS && dwtype == REG_SZ) { | |
pbuf = ole_mb2wc(clsid, -1); | |
hr = CLSIDFromString(pbuf, pclsid); | |
@@ -1490,10 +2627,7 @@ clsid_from_remote(host, com, pclsid) | |
} | |
static VALUE | |
-ole_create_dcom(argc, argv, self) | |
- int argc; | |
- VALUE *argv; | |
- VALUE self; | |
+ole_create_dcom(int argc, VALUE *argv, VALUE self) | |
{ | |
VALUE ole, host, others; | |
HRESULT hr; | |
@@ -1515,7 +2649,7 @@ ole_create_dcom(argc, argv, self) | |
rb_raise(rb_eRuntimeError, "CoCreateInstanceEx is not supported in this environment"); | |
rb_scan_args(argc, argv, "2*", &ole, &host, &others); | |
- pbuf = ole_mb2wc(StringValuePtr(ole), -1); | |
+ pbuf = ole_vstr2wc(ole); | |
hr = CLSIDFromProgID(pbuf, &clsid); | |
if (FAILED(hr)) | |
hr = clsid_from_remote(host, ole, &clsid); | |
@@ -1523,17 +2657,17 @@ ole_create_dcom(argc, argv, self) | |
hr = CLSIDFromString(pbuf, &clsid); | |
SysFreeString(pbuf); | |
if (FAILED(hr)) | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, | |
+ ole_raise(hr, eWIN32OLERuntimeError, | |
"unknown OLE server: `%s'", | |
StringValuePtr(ole)); | |
memset(&serverinfo, 0, sizeof(COSERVERINFO)); | |
- serverinfo.pwszName = ole_mb2wc(StringValuePtr(host), -1); | |
+ 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, eWIN32OLE_RUNTIME_ERROR, | |
+ ole_raise(hr, eWIN32OLERuntimeError, | |
"failed to create DCOM server `%s' in `%s'", | |
StringValuePtr(ole), | |
StringValuePtr(host)); | |
@@ -1543,15 +2677,12 @@ ole_create_dcom(argc, argv, self) | |
} | |
static VALUE | |
-ole_bind_obj(moniker, argc, argv, self) | |
- VALUE moniker; | |
- int argc; | |
- VALUE *argv; | |
- VALUE self; | |
+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; | |
@@ -1560,27 +2691,27 @@ ole_bind_obj(moniker, argc, argv, self) | |
hr = CreateBindCtx(0, &pBindCtx); | |
if(FAILED(hr)) { | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, | |
+ ole_raise(hr, eWIN32OLERuntimeError, | |
"failed to create bind context"); | |
} | |
- pbuf = ole_mb2wc(StringValuePtr(moniker), -1); | |
+ pbuf = ole_vstr2wc(moniker); | |
hr = MkParseDisplayName(pBindCtx, pbuf, &eaten, &pMoniker); | |
SysFreeString(pbuf); | |
if(FAILED(hr)) { | |
OLE_RELEASE(pBindCtx); | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, | |
+ ole_raise(hr, eWIN32OLERuntimeError, | |
"failed to parse display name of moniker `%s'", | |
StringValuePtr(moniker)); | |
} | |
hr = pMoniker->lpVtbl->BindToObject(pMoniker, pBindCtx, NULL, | |
- &IID_IDispatch, | |
- (void**)&pDispatch); | |
+ &IID_IDispatch, &p); | |
+ pDispatch = p; | |
OLE_RELEASE(pMoniker); | |
OLE_RELEASE(pBindCtx); | |
if(FAILED(hr)) { | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, | |
+ ole_raise(hr, eWIN32OLERuntimeError, | |
"failed to bind moniker `%s'", | |
StringValuePtr(moniker)); | |
} | |
@@ -1597,10 +2728,7 @@ ole_bind_obj(moniker, argc, argv, self) | |
* WIN32OLE.connect('Excel.Application') # => WIN32OLE object which represents running Excel. | |
*/ | |
static VALUE | |
-fole_s_connect(argc, argv, self) | |
- int argc; | |
- VALUE *argv; | |
- VALUE self; | |
+fole_s_connect(int argc, VALUE *argv, VALUE self) | |
{ | |
VALUE svr_name; | |
VALUE others; | |
@@ -1608,6 +2736,7 @@ fole_s_connect(argc, argv, self) | |
CLSID clsid; | |
OLECHAR *pBuf; | |
IDispatch *pDispatch; | |
+ void *p; | |
IUnknown *pUnknown; | |
rb_secure(4); | |
@@ -1615,13 +2744,14 @@ fole_s_connect(argc, argv, self) | |
ole_initialize(); | |
rb_scan_args(argc, argv, "1*", &svr_name, &others); | |
- if (ruby_safe_level > 0 && OBJ_TAINTED(svr_name)) { | |
+ Check_SafeStr(svr_name); | |
+ if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name)) { | |
rb_raise(rb_eSecurityError, "Insecure Object Connection - %s", | |
StringValuePtr(svr_name)); | |
} | |
/* get CLSID from OLE server name */ | |
- pBuf = ole_mb2wc(StringValuePtr(svr_name), -1); | |
+ pBuf = ole_vstr2wc(svr_name); | |
hr = CLSIDFromProgID(pBuf, &clsid); | |
if(FAILED(hr)) { | |
hr = CLSIDFromString(pBuf, &clsid); | |
@@ -1633,14 +2763,14 @@ fole_s_connect(argc, argv, self) | |
hr = GetActiveObject(&clsid, 0, &pUnknown); | |
if (FAILED(hr)) { | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, | |
+ ole_raise(hr, eWIN32OLERuntimeError, | |
"OLE server `%s' not running", StringValuePtr(svr_name)); | |
} | |
- hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IDispatch, | |
- (void **)&pDispatch); | |
+ hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IDispatch, &p); | |
+ pDispatch = p; | |
if(FAILED(hr)) { | |
OLE_RELEASE(pUnknown); | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, | |
+ ole_raise(hr, eWIN32OLERuntimeError, | |
"failed to create WIN32OLE server `%s'", | |
StringValuePtr(svr_name)); | |
} | |
@@ -1680,10 +2810,7 @@ fole_s_connect(argc, argv, self) | |
* puts MSO::MsoLineSingle # => 1 | |
*/ | |
static VALUE | |
-fole_s_const_load(argc, argv, self) | |
- int argc; | |
- VALUE *argv; | |
- VALUE self; | |
+fole_s_const_load(int argc, VALUE *argv, VALUE self) | |
{ | |
VALUE ole; | |
VALUE klass; | |
@@ -1694,7 +2821,7 @@ fole_s_const_load(argc, argv, self) | |
HRESULT hr; | |
OLECHAR *pBuf; | |
VALUE file; | |
- LCID lcid = LOCALE_SYSTEM_DEFAULT; | |
+ LCID lcid = cWIN32OLE_lcid; | |
rb_secure(4); | |
rb_scan_args(argc, argv, "11", &ole, &klass); | |
@@ -1729,11 +2856,11 @@ fole_s_const_load(argc, argv, self) | |
if (file == Qnil) { | |
file = ole; | |
} | |
- pBuf = ole_mb2wc(StringValuePtr(file), -1); | |
+ pBuf = ole_vstr2wc(file); | |
hr = LoadTypeLibEx(pBuf, REGKIND_NONE, &pTypeLib); | |
SysFreeString(pBuf); | |
if (FAILED(hr)) | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "failed to LoadTypeLibEx"); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx"); | |
if(TYPE(klass) != T_NIL) { | |
ole_const_load(pTypeLib, klass, self); | |
} | |
@@ -1749,9 +2876,7 @@ fole_s_const_load(argc, argv, self) | |
} | |
static VALUE | |
-ole_classes_from_typelib(pTypeLib, classes) | |
- ITypeLib *pTypeLib; | |
- VALUE classes; | |
+ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes) | |
{ | |
long count; | |
@@ -1783,8 +2908,7 @@ ole_classes_from_typelib(pTypeLib, classes) | |
} | |
static ULONG | |
-reference_count(pole) | |
- struct oledata * pole; | |
+reference_count(struct oledata * pole) | |
{ | |
ULONG n = 0; | |
if(pole->pDispatch) { | |
@@ -1803,9 +2927,7 @@ reference_count(pole) | |
* exists only for debugging WIN32OLE. | |
*/ | |
static VALUE | |
-fole_s_reference_count(self, obj) | |
- VALUE self; | |
- VALUE obj; | |
+fole_s_reference_count(VALUE self, VALUE obj) | |
{ | |
struct oledata * pole; | |
OLEData_Get_Struct(obj, pole); | |
@@ -1822,9 +2944,7 @@ fole_s_reference_count(self, obj) | |
* The return value is reference counter of OLE object. | |
*/ | |
static VALUE | |
-fole_s_free(self, obj) | |
- VALUE self; | |
- VALUE obj; | |
+fole_s_free(VALUE self, VALUE obj) | |
{ | |
ULONG n = 0; | |
struct oledata * pole; | |
@@ -1838,9 +2958,7 @@ fole_s_free(self, obj) | |
} | |
static HWND | |
-ole_show_help(helpfile, helpcontext) | |
- VALUE helpfile; | |
- VALUE helpcontext; | |
+ole_show_help(VALUE helpfile, VALUE helpcontext) | |
{ | |
FNHTMLHELP *pfnHtmlHelp; | |
HWND hwnd = 0; | |
@@ -1872,10 +2990,7 @@ ole_show_help(helpfile, helpcontext) | |
* WIN32OLE.ole_show_help(typeobj) | |
*/ | |
static VALUE | |
-fole_s_show_help(argc, argv, self) | |
- int argc; | |
- VALUE *argv; | |
- VALUE self; | |
+fole_s_show_help(int argc, VALUE *argv, VALUE self) | |
{ | |
VALUE target; | |
VALUE helpcontext; | |
@@ -1914,41 +3029,47 @@ fole_s_show_help(argc, argv, self) | |
* WIN32OLE.codepage # => WIN32OLE::CP_ACP | |
*/ | |
static VALUE | |
-fole_s_get_code_page(self) | |
- VALUE self; | |
+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. | |
+ * 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(self, vcp) | |
- VALUE self; | |
- VALUE vcp; | |
+fole_s_set_code_page(VALUE self, VALUE vcp) | |
{ | |
UINT cp = FIX2INT(vcp); | |
- | |
- 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; | |
- default: | |
- rb_raise(eWIN32OLE_RUNTIME_ERROR, "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"); | |
- break; | |
- } | |
- | |
+ set_ole_codepage(cp); | |
/* | |
* Should this method return old codepage? | |
*/ | |
@@ -1956,9 +3077,131 @@ fole_s_set_code_page(self, vcp) | |
} | |
/* | |
+ * call-seq: | |
+ * WIN32OLE.locale -> locale id. | |
+ * | |
+ * Returns current locale id (lcid). The default locale is | |
+ * 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", 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); | |
+} | |
+ | |
+/* | |
* 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. | |
+ * If you want to get the result value of argument passed by reference, | |
+ * you can use WIN32OLE::ARGV. | |
+ * | |
+ * oleobj.method(arg1, arg2, refargv3) | |
+ * puts WIN32OLE::ARGV[2] # the value of refargv3 after called oleobj.method | |
+ * | |
*/ | |
/* | |
@@ -1975,10 +3218,7 @@ fole_s_set_code_page(self, vcp) | |
* WIN32OLE.new('{00024500-0000-0000-C000-000000000046}') # => Excel OLE Automation WIN32OLE object. | |
*/ | |
static VALUE | |
-fole_initialize(argc, argv, self) | |
- int argc; | |
- VALUE *argv; | |
- VALUE self; | |
+fole_initialize(int argc, VALUE *argv, VALUE self) | |
{ | |
VALUE svr_name; | |
VALUE host; | |
@@ -1987,17 +3227,19 @@ fole_initialize(argc, argv, self) | |
CLSID clsid; | |
OLECHAR *pBuf; | |
IDispatch *pDispatch; | |
- | |
+ void *p; | |
rb_secure(4); | |
rb_call_super(0, 0); | |
rb_scan_args(argc, argv, "11*", &svr_name, &host, &others); | |
- if (ruby_safe_level > 0 && OBJ_TAINTED(svr_name)) { | |
+ Check_SafeStr(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)) { | |
- if (ruby_safe_level > 0 && OBJ_TAINTED(host)) { | |
+ Check_SafeStr(host); | |
+ if (rb_safe_level() > 0 && OBJ_TAINTED(host)) { | |
rb_raise(rb_eSecurityError, "Insecure Object Creation - %s", | |
StringValuePtr(svr_name)); | |
} | |
@@ -2005,45 +3247,44 @@ fole_initialize(argc, argv, self) | |
} | |
/* get CLSID from OLE server name */ | |
- pBuf = ole_mb2wc(StringValuePtr(svr_name), -1); | |
+ pBuf = ole_vstr2wc(svr_name); | |
hr = CLSIDFromProgID(pBuf, &clsid); | |
if(FAILED(hr)) { | |
hr = CLSIDFromString(pBuf, &clsid); | |
} | |
SysFreeString(pBuf); | |
if(FAILED(hr)) { | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, | |
+ 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, (void**)&pDispatch); | |
+ &IID_IDispatch, &p); | |
+ pDispatch = p; | |
if(FAILED(hr)) { | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, | |
+ ole_raise(hr, eWIN32OLERuntimeError, | |
"failed to create WIN32OLE object from `%s'", | |
StringValuePtr(svr_name)); | |
} | |
- | |
+ | |
ole_set_member(self, pDispatch); | |
return self; | |
} | |
static VALUE | |
-hash2named_arg(pair, pOp) | |
- VALUE pair; | |
- struct oleparam* pOp; | |
+hash2named_arg(VALUE pair, struct oleparam* pOp) | |
{ | |
unsigned int index, i; | |
VALUE key, value; | |
index = pOp->dp.cNamedArgs; | |
- /*------------------------------------- | |
- the data-type of key must be String | |
- ---------------------------------------*/ | |
+ /*--------------------------------------------- | |
+ the data-type of key must be String or Symbol | |
+ -----------------------------------------------*/ | |
key = rb_ary_entry(pair, 0); | |
- if(TYPE(key) != T_STRING) { | |
+ if(TYPE(key) != T_STRING && TYPE(key) != T_SYMBOL) { | |
/* clear name of dispatch parameters */ | |
for(i = 1; i < index + 1; i++) { | |
SysFreeString(pOp->pNamedArgs[i]); | |
@@ -2053,11 +3294,14 @@ hash2named_arg(pair, pOp) | |
VariantClear(&(pOp->dp.rgvarg[i])); | |
} | |
/* raise an exception */ | |
- Check_Type(key, T_STRING); | |
+ rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)"); | |
+ } | |
+ if (TYPE(key) == T_SYMBOL) { | |
+ key = rb_sym_to_s(key); | |
} | |
/* pNamedArgs[0] is <method name>, so "index + 1" */ | |
- pOp->pNamedArgs[index + 1] = ole_mb2wc(StringValuePtr(key), -1); | |
+ pOp->pNamedArgs[index + 1] = ole_vstr2wc(key); | |
value = rb_ary_entry(pair, 1); | |
VariantInit(&(pOp->dp.rgvarg[index])); | |
@@ -2068,9 +3312,7 @@ hash2named_arg(pair, pOp) | |
} | |
static VALUE | |
-set_argv(realargs, beg, end) | |
- VARIANTARG* realargs; | |
- unsigned int beg, end; | |
+set_argv(VARIANTARG* realargs, unsigned int beg, unsigned int end) | |
{ | |
VALUE argv = rb_const_get(cWIN32OLE, rb_intern("ARGV")); | |
@@ -2084,13 +3326,9 @@ set_argv(realargs, beg, end) | |
} | |
static VALUE | |
-ole_invoke(argc, argv, self, wFlags) | |
- int argc; | |
- VALUE *argv; | |
- VALUE self; | |
- USHORT wFlags; | |
+ole_invoke(int argc, VALUE *argv, VALUE self, USHORT wFlags, BOOL is_bracket) | |
{ | |
- LCID lcid = LOCALE_SYSTEM_DEFAULT; | |
+ LCID lcid = cWIN32OLE_lcid; | |
struct oledata *pole; | |
HRESULT hr; | |
VALUE cmd; | |
@@ -2111,6 +3349,7 @@ ole_invoke(argc, argv, self, wFlags) | |
unsigned int cNamedArgs; | |
int n; | |
struct oleparam op; | |
+ struct olevariantdata *pvar; | |
memset(&excepinfo, 0, sizeof(EXCEPINFO)); | |
VariantInit(&result); | |
@@ -2121,18 +3360,30 @@ ole_invoke(argc, argv, self, wFlags) | |
op.dp.cArgs = 0; | |
rb_scan_args(argc, argv, "1*", &cmd, ¶mS); | |
+ if(TYPE(cmd) != T_STRING && TYPE(cmd) != T_SYMBOL && !is_bracket) { | |
+ rb_raise(rb_eTypeError, "method is wrong type (expected String or Symbol)"); | |
+ } | |
+ if (TYPE(cmd) == T_SYMBOL) { | |
+ cmd = rb_sym_to_s(cmd); | |
+ } | |
OLEData_Get_Struct(self, pole); | |
if(!pole->pDispatch) { | |
rb_raise(rb_eRuntimeError, "failed to get dispatch interface"); | |
} | |
- wcmdname = ole_mb2wc(StringValuePtr(cmd), -1); | |
- hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL, | |
- &wcmdname, 1, lcid, &DispID); | |
- SysFreeString(wcmdname); | |
- if(FAILED(hr)) { | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, | |
- "unknown property or method `%s'", | |
- StringValuePtr(cmd)); | |
+ 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, eWIN32OLERuntimeError, | |
+ "unknown property or method: `%s'", | |
+ StringValuePtr(cmd)); | |
+ } | |
} | |
/* pick up last argument of method */ | |
@@ -2149,10 +3400,10 @@ ole_invoke(argc, argv, self, wFlags) | |
op.dp.cArgs = cNamedArgs + argc - 2; | |
op.pNamedArgs = ALLOCA_N(OLECHAR*, cNamedArgs + 1); | |
op.dp.rgvarg = ALLOCA_N(VARIANTARG, op.dp.cArgs); | |
- rb_iterate(rb_each, param, hash2named_arg, (VALUE)&op); | |
+ rb_block_call(param, rb_intern("each"), 0, 0, hash2named_arg, (VALUE)&op); | |
pDispID = ALLOCA_N(DISPID, cNamedArgs + 1); | |
- op.pNamedArgs[0] = ole_mb2wc(StringValuePtr(cmd), -1); | |
+ op.pNamedArgs[0] = ole_vstr2wc(cmd); | |
hr = pole->pDispatch->lpVtbl->GetIDsOfNames(pole->pDispatch, | |
&IID_NULL, | |
op.pNamedArgs, | |
@@ -2167,7 +3418,7 @@ ole_invoke(argc, argv, self, wFlags) | |
for(i = 0; i < op.dp.cArgs; i++ ) { | |
VariantClear(&op.dp.rgvarg[i]); | |
} | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, | |
+ ole_raise(hr, eWIN32OLERuntimeError, | |
"failed to get named argument info: `%s'", | |
StringValuePtr(cmd)); | |
} | |
@@ -2191,17 +3442,20 @@ ole_invoke(argc, argv, self, wFlags) | |
VariantInit(&realargs[n]); | |
VariantInit(&op.dp.rgvarg[n]); | |
param = rb_ary_entry(paramS, i-cNamedArgs); | |
- | |
- ole_val2variant(param, &realargs[n]); | |
- V_VT(&op.dp.rgvarg[n]) = VT_VARIANT | VT_BYREF; | |
- V_VARIANTREF(&op.dp.rgvarg[n]) = &realargs[n]; | |
- | |
+ if (rb_obj_is_kind_of(param, cWIN32OLE_VARIANT)) { | |
+ Data_Get_Struct(param, struct olevariantdata, pvar); | |
+ VariantCopy(&op.dp.rgvarg[n], &(pvar->var)); | |
+ } 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) | |
- return ResultFromScode(E_INVALIDARG); | |
+ ole_raise(ResultFromScode(E_INVALIDARG), eWIN32OLERuntimeError, "argument error"); | |
op.dp.cNamedArgs = 1; | |
op.dp.rgdispidNamedArgs = ALLOCA_N( DISPID, 1 ); | |
@@ -2211,6 +3465,7 @@ ole_invoke(argc, argv, self, wFlags) | |
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) { | |
@@ -2242,12 +3497,14 @@ ole_invoke(argc, argv, self, wFlags) | |
&IID_NULL, lcid, wFlags, | |
&op.dp, NULL, | |
&excepinfo, &argErr); | |
+ | |
} | |
for(i = cNamedArgs; i < op.dp.cArgs; i++) { | |
n = op.dp.cArgs - i + cNamedArgs - 1; | |
VariantClear(&op.dp.rgvarg[n]); | |
} | |
} | |
+ | |
if (FAILED(hr)) { | |
/* retry after converting nil to VT_EMPTY */ | |
if (op.dp.cArgs > cNamedArgs) { | |
@@ -2275,6 +3532,13 @@ ole_invoke(argc, argv, self, wFlags) | |
} | |
/* 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]); | |
+ } | |
+ } | |
set_argv(realargs, cNamedArgs, op.dp.cArgs); | |
} | |
else { | |
@@ -2285,8 +3549,9 @@ ole_invoke(argc, argv, self, wFlags) | |
if (FAILED(hr)) { | |
v = ole_excepinfo2msg(&excepinfo); | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "%s%s", | |
- StringValuePtr(cmd), StringValuePtr(v)); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "(in OLE method `%s': )%s", | |
+ StringValuePtr(cmd), | |
+ StringValuePtr(v)); | |
} | |
obj = ole_variant2val(&result); | |
VariantClear(&result); | |
@@ -2307,21 +3572,13 @@ ole_invoke(argc, argv, self, wFlags) | |
* | |
*/ | |
static VALUE | |
-fole_invoke(argc, argv, self) | |
- int argc; | |
- VALUE *argv; | |
- VALUE self; | |
+fole_invoke(int argc, VALUE *argv, VALUE self) | |
{ | |
- return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET); | |
+ return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE); | |
} | |
static VALUE | |
-ole_invoke2(self, dispid, args, types, dispkind) | |
- VALUE self; | |
- VALUE dispid; | |
- VALUE args; | |
- VALUE types; | |
- USHORT dispkind; | |
+ole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types, USHORT dispkind) | |
{ | |
HRESULT hr; | |
struct oledata *pole; | |
@@ -2344,7 +3601,7 @@ ole_invoke2(self, dispid, args, types, dispkind) | |
VariantInit(&result); | |
OLEData_Get_Struct(self, pole); | |
- dispParams.cArgs = RARRAY(args)->len; | |
+ 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--) | |
@@ -2375,7 +3632,7 @@ ole_invoke2(self, dispid, args, types, dispkind) | |
SAFEARRAYBOUND rgsabound[1]; | |
Check_Type(param, T_ARRAY); | |
rgsabound[0].lLbound = 0; | |
- rgsabound[0].cElements = RARRAY(param)->len; | |
+ 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; | |
@@ -2393,7 +3650,7 @@ ole_invoke2(self, dispid, args, types, dispkind) | |
if (v != VT_VARIANT) | |
{ | |
VariantChangeTypeEx(&velem, &velem, | |
- LOCALE_SYSTEM_DEFAULT, 0, v); | |
+ cWIN32OLE_lcid, 0, v); | |
} | |
switch (v) | |
{ | |
@@ -2432,7 +3689,7 @@ ole_invoke2(self, dispid, args, types, dispkind) | |
if ((vt & (~VT_BYREF)) != VT_VARIANT) | |
{ | |
hr = VariantChangeTypeEx(&realargs[i], &realargs[i], | |
- LOCALE_SYSTEM_DEFAULT, 0, | |
+ cWIN32OLE_lcid, 0, | |
(VARTYPE)(vt & (~VT_BYREF))); | |
if (hr != S_OK) | |
{ | |
@@ -2488,14 +3745,15 @@ ole_invoke2(self, dispid, args, types, dispkind) | |
} | |
hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, NUM2INT(dispid), | |
- &IID_NULL, LOCALE_SYSTEM_DEFAULT, | |
+ &IID_NULL, cWIN32OLE_lcid, | |
dispkind, | |
&dispParams, &result, | |
&excepinfo, &argErr); | |
if (FAILED(hr)) { | |
v = ole_excepinfo2msg(&excepinfo); | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "_invoke %s", | |
+ ole_raise(hr, eWIN32OLERuntimeError, "(in OLE method `<dispatch id:%d>': )%s", | |
+ NUM2INT(dispid), | |
StringValuePtr(v)); | |
} | |
@@ -2522,11 +3780,7 @@ ole_invoke2(self, dispid, args, types, dispkind) | |
* excel._invoke(302, [], []) # same effect as excel.Quit | |
*/ | |
static VALUE | |
-fole_invoke2(self, dispid, args, types) | |
- VALUE self; | |
- VALUE dispid; | |
- VALUE args; | |
- VALUE types; | |
+fole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types) | |
{ | |
return ole_invoke2(self, dispid, args, types, DISPATCH_METHOD); | |
} | |
@@ -2544,11 +3798,7 @@ fole_invoke2(self, dispid, args, types) | |
* puts excel._getproperty(558, [], []) # same effect as puts excel.visible | |
*/ | |
static VALUE | |
-fole_getproperty2(self, dispid, args, types) | |
- VALUE self; | |
- VALUE dispid; | |
- VALUE args; | |
- VALUE types; | |
+fole_getproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types) | |
{ | |
return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYGET); | |
} | |
@@ -2566,59 +3816,78 @@ fole_getproperty2(self, dispid, args, types) | |
* excel._setproperty(558, [true], [WIN32OLE::VARIANT::VT_BOOL]) # same effect as excel.visible = true | |
*/ | |
static VALUE | |
-fole_setproperty2(self, dispid, args, types) | |
- VALUE self; | |
- VALUE dispid; | |
- VALUE args; | |
- VALUE types; | |
+fole_setproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types) | |
{ | |
return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYPUT); | |
} | |
/* | |
* call-seq: | |
- * WIN32OLE['property']=val | |
+ * 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 | |
+ * 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(argc, argv, self) | |
- int argc; | |
- VALUE *argv; | |
- VALUE self; | |
+fole_setproperty(int argc, VALUE *argv, VALUE self) | |
{ | |
- return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT); | |
+ return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, FALSE); | |
} | |
/* | |
* call-seq: | |
- * WIN32OLE['property'] | |
+ * WIN32OLE[a1,a2,...] | |
* | |
- * Returns property of OLE object. | |
+ * 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'] # => false | |
+ * # puts excel['Visible'] This is error !!! | |
+ * puts excel.Visible # You should to use this style to get the property. | |
+ * | |
*/ | |
static VALUE | |
-fole_getproperty(argc, argv, self) | |
- int argc; | |
- VALUE *argv; | |
- VALUE self; | |
+fole_getproperty_with_bracket(int argc, VALUE *argv, VALUE self) | |
{ | |
- return ole_invoke(argc, argv, self, DISPATCH_PROPERTYGET); | |
+ return ole_invoke(argc, argv, self, DISPATCH_PROPERTYGET, TRUE); | |
} | |
static VALUE | |
-ole_propertyput(self, property, value) | |
- VALUE self, property, value; | |
+ole_propertyput(VALUE self, VALUE property, VALUE value) | |
{ | |
struct oledata *pole; | |
unsigned argErr; | |
@@ -2632,7 +3901,7 @@ ole_propertyput(self, property, value) | |
VARIANTARG propertyValue[2]; | |
OLECHAR* pBuf[1]; | |
VALUE v; | |
- LCID lcid = LOCALE_SYSTEM_DEFAULT; | |
+ LCID lcid = cWIN32OLE_lcid; | |
dispParams.rgdispidNamedArgs = &dispIDParam; | |
dispParams.rgvarg = propertyValue; | |
dispParams.cNamedArgs = 1; | |
@@ -2645,14 +3914,14 @@ ole_propertyput(self, property, value) | |
OLEData_Get_Struct(self, pole); | |
/* get ID from property name */ | |
- pBuf[0] = ole_mb2wc(StringValuePtr(property), -1); | |
+ 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, eWIN32OLE_RUNTIME_ERROR, | |
+ ole_raise(hr, eWIN32OLERuntimeError, | |
"unknown property or method: `%s'", | |
StringValuePtr(property)); | |
} | |
@@ -2667,7 +3936,9 @@ ole_propertyput(self, property, value) | |
} | |
if (FAILED(hr)) { | |
v = ole_excepinfo2msg(&excepinfo); | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, StringValuePtr(v)); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "(in setting property `%s': )%s", | |
+ StringValuePtr(property), | |
+ StringValuePtr(v)); | |
} | |
return Qnil; | |
} | |
@@ -2682,8 +3953,7 @@ ole_propertyput(self, property, value) | |
* | |
*/ | |
static VALUE | |
-fole_free(self) | |
- VALUE self; | |
+fole_free(VALUE self) | |
{ | |
struct oledata *pole; | |
rb_secure(4); | |
@@ -2694,8 +3964,7 @@ fole_free(self) | |
} | |
static VALUE | |
-ole_each_sub(pEnumV) | |
- VALUE pEnumV; | |
+ole_each_sub(VALUE pEnumV) | |
{ | |
VARIANT variant; | |
VALUE obj = Qnil; | |
@@ -2711,8 +3980,7 @@ ole_each_sub(pEnumV) | |
} | |
static VALUE | |
-ole_ienum_free(pEnumV) | |
- VALUE pEnumV; | |
+ole_ienum_free(VALUE pEnumV) | |
{ | |
IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV; | |
OLE_RELEASE(pEnum); | |
@@ -2734,10 +4002,9 @@ ole_ienum_free(pEnumV) | |
* end | |
*/ | |
static VALUE | |
-fole_each(self) | |
- VALUE self; | |
+fole_each(VALUE self) | |
{ | |
- LCID lcid = LOCALE_SYSTEM_DEFAULT; | |
+ LCID lcid = cWIN32OLE_lcid; | |
struct oledata *pole; | |
@@ -2747,6 +4014,9 @@ fole_each(self) | |
VARIANT result; | |
HRESULT hr; | |
IEnumVARIANT *pEnum = NULL; | |
+ void *p; | |
+ | |
+ RETURN_ENUMERATOR(self, 0, 0); | |
VariantInit(&result); | |
dispParams.rgvarg = NULL; | |
@@ -2764,17 +4034,20 @@ fole_each(self) | |
if (FAILED(hr)) { | |
VariantClear(&result); | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "failed to get IEnum Interface"); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to get IEnum Interface"); | |
} | |
- if (V_VT(&result) == VT_UNKNOWN) | |
+ if (V_VT(&result) == VT_UNKNOWN) { | |
hr = V_UNKNOWN(&result)->lpVtbl->QueryInterface(V_UNKNOWN(&result), | |
&IID_IEnumVARIANT, | |
- (void**)&pEnum); | |
- else if (V_VT(&result) == VT_DISPATCH) | |
+ &p); | |
+ pEnum = p; | |
+ } else if (V_VT(&result) == VT_DISPATCH) { | |
hr = V_DISPATCH(&result)->lpVtbl->QueryInterface(V_DISPATCH(&result), | |
&IID_IEnumVARIANT, | |
- (void**)&pEnum); | |
+ &p); | |
+ pEnum = p; | |
+ } | |
if (FAILED(hr) || !pEnum) { | |
VariantClear(&result); | |
ole_raise(hr, rb_eRuntimeError, "failed to get IEnum Interface"); | |
@@ -2792,13 +4065,10 @@ fole_each(self) | |
* Calls WIN32OLE#invoke method. | |
*/ | |
static VALUE | |
-fole_missing(argc, argv, self) | |
- int argc; | |
- VALUE *argv; | |
- VALUE self; | |
+fole_missing(int argc, VALUE *argv, VALUE self) | |
{ | |
ID id; | |
- char* mname; | |
+ const char* mname; | |
int n; | |
id = rb_to_id(argv[0]); | |
mname = rb_id2name(id); | |
@@ -2807,22 +4077,18 @@ fole_missing(argc, argv, self) | |
} | |
n = strlen(mname); | |
if(mname[n-1] == '=') { | |
- argv[0] = rb_str_new(mname, n-1); | |
+ argv[0] = rb_enc_str_new(mname, n-1, cWIN32OLE_enc); | |
return ole_propertyput(self, argv[0], argv[1]); | |
} | |
else { | |
- argv[0] = rb_str_new2(mname); | |
- return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET); | |
+ argv[0] = rb_enc_str_new(mname, n, cWIN32OLE_enc); | |
+ return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE); | |
} | |
} | |
static VALUE | |
-ole_method_sub(self, pOwnerTypeInfo, pTypeInfo, name) | |
- VALUE self; | |
- ITypeInfo *pOwnerTypeInfo; | |
- ITypeInfo *pTypeInfo; | |
- VALUE name; | |
+ole_method_sub(VALUE self, ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE name) | |
{ | |
HRESULT hr; | |
TYPEATTR *pTypeAttr; | |
@@ -2833,7 +4099,7 @@ ole_method_sub(self, pOwnerTypeInfo, pTypeInfo, name) | |
VALUE method = Qnil; | |
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); | |
if (FAILED(hr)) { | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "failed to GetTypeAttr"); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr"); | |
} | |
for(i = 0; i < pTypeAttr->cFuncs && method == Qnil; i++) { | |
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc); | |
@@ -2859,10 +4125,7 @@ ole_method_sub(self, pOwnerTypeInfo, pTypeInfo, name) | |
} | |
static VALUE | |
-olemethod_from_typeinfo(self, pTypeInfo, name) | |
- VALUE self; | |
- ITypeInfo *pTypeInfo; | |
- VALUE name; | |
+olemethod_from_typeinfo(VALUE self, ITypeInfo *pTypeInfo, VALUE name) | |
{ | |
HRESULT hr; | |
TYPEATTR *pTypeAttr; | |
@@ -2872,7 +4135,7 @@ olemethod_from_typeinfo(self, pTypeInfo, name) | |
VALUE method = Qnil; | |
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); | |
if (FAILED(hr)) { | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "failed to GetTypeAttr"); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr"); | |
} | |
method = ole_method_sub(self, 0, pTypeInfo, name); | |
if (method != Qnil) { | |
@@ -2893,11 +4156,7 @@ olemethod_from_typeinfo(self, pTypeInfo, name) | |
} | |
static VALUE | |
-ole_methods_sub(pOwnerTypeInfo, pTypeInfo, methods, mask) | |
- ITypeInfo *pOwnerTypeInfo; | |
- ITypeInfo *pTypeInfo; | |
- VALUE methods; | |
- int mask; | |
+ole_methods_sub(ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE methods, int mask) | |
{ | |
HRESULT hr; | |
TYPEATTR *pTypeAttr; | |
@@ -2908,7 +4167,7 @@ ole_methods_sub(pOwnerTypeInfo, pTypeInfo, methods, mask) | |
WORD i; | |
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); | |
if (FAILED(hr)) { | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "failed to GetTypeAttr"); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr"); | |
} | |
for(i = 0; i < pTypeAttr->cFuncs; i++) { | |
pstr = NULL; | |
@@ -2937,9 +4196,7 @@ ole_methods_sub(pOwnerTypeInfo, pTypeInfo, methods, mask) | |
} | |
static VALUE | |
-ole_methods_from_typeinfo(pTypeInfo, mask) | |
- ITypeInfo *pTypeInfo; | |
- int mask; | |
+ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask) | |
{ | |
HRESULT hr; | |
TYPEATTR *pTypeAttr; | |
@@ -2949,7 +4206,7 @@ ole_methods_from_typeinfo(pTypeInfo, mask) | |
VALUE methods = rb_ary_new(); | |
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); | |
if (FAILED(hr)) { | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "failed to GetTypeAttr"); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr"); | |
} | |
ole_methods_sub(0, pTypeInfo, methods, mask); | |
@@ -2968,9 +4225,7 @@ ole_methods_from_typeinfo(pTypeInfo, mask) | |
} | |
static HRESULT | |
-typeinfo_from_ole(pole, ppti) | |
- struct oledata *pole; | |
- ITypeInfo **ppti; | |
+typeinfo_from_ole(struct oledata *pole, ITypeInfo **ppti) | |
{ | |
ITypeInfo *pTypeInfo; | |
ITypeLib *pTypeLib; | |
@@ -2978,7 +4233,7 @@ typeinfo_from_ole(pole, ppti) | |
VALUE type; | |
UINT i; | |
UINT count; | |
- LCID lcid = LOCALE_SYSTEM_DEFAULT; | |
+ LCID lcid = cWIN32OLE_lcid; | |
HRESULT hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch, | |
0, lcid, &pTypeInfo); | |
if(FAILED(hr)) { | |
@@ -3011,9 +4266,7 @@ typeinfo_from_ole(pole, ppti) | |
} | |
static VALUE | |
-ole_methods(self,mask) | |
- VALUE self; | |
- int mask; | |
+ole_methods(VALUE self, int mask) | |
{ | |
ITypeInfo *pTypeInfo; | |
HRESULT hr; | |
@@ -3043,8 +4296,7 @@ ole_methods(self,mask) | |
* | |
*/ | |
static VALUE | |
-fole_methods( self ) | |
- VALUE self; | |
+fole_methods(VALUE self) | |
{ | |
return ole_methods( self, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF); | |
} | |
@@ -3060,8 +4312,7 @@ fole_methods( self ) | |
* properties = excel.ole_get_methods | |
*/ | |
static VALUE | |
-fole_get_methods( self ) | |
- VALUE self; | |
+fole_get_methods(VALUE self) | |
{ | |
return ole_methods( self, INVOKE_PROPERTYGET); | |
} | |
@@ -3077,10 +4328,9 @@ fole_get_methods( self ) | |
* properties = excel.ole_put_methods | |
*/ | |
static VALUE | |
-fole_put_methods( self ) | |
- VALUE self; | |
+fole_put_methods(VALUE self) | |
{ | |
- return ole_methods( self, INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF); | |
+ return ole_methods( self, INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF); | |
} | |
/* | |
@@ -3088,39 +4338,58 @@ fole_put_methods( self ) | |
* WIN32OLE#ole_func_methods | |
* | |
* Returns the array of WIN32OLE_METHOD object . | |
- * The element of the array is functional method of WIN32OLE 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( self ) | |
- VALUE self; | |
+fole_func_methods(VALUE self) | |
{ | |
return ole_methods( self, INVOKE_FUNC); | |
} | |
+static 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 = foletype_s_allocate(cWIN32OLE_TYPE); | |
+ oletype_set_member(type, pTypeInfo, WC2VSTR(bstr)); | |
+ return type; | |
+} | |
+ | |
/* | |
* call-seq: | |
- * WIN32OLE#ole_obj_help | |
+ * WIN32OLE#ole_type | |
* | |
* Returns WIN32OLE_TYPE object. | |
* | |
* excel = WIN32OLE.new('Excel.Application') | |
- * tobj = excel.ole_obj_help | |
+ * tobj = excel.ole_type | |
*/ | |
static VALUE | |
-fole_obj_help( self ) | |
- VALUE self; | |
+fole_type(VALUE self) | |
{ | |
- unsigned int index; | |
ITypeInfo *pTypeInfo; | |
- ITypeLib *pTypeLib; | |
HRESULT hr; | |
struct oledata *pole; | |
- BSTR bstr; | |
- LCID lcid = LOCALE_SYSTEM_DEFAULT; | |
+ LCID lcid = cWIN32OLE_lcid; | |
VALUE type = Qnil; | |
OLEData_Get_Struct(self, pole); | |
@@ -3129,30 +4398,182 @@ fole_obj_help( self ) | |
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"); | |
+ type = ole_type_from_itypeinfo(pTypeInfo); | |
+ OLE_RELEASE(pTypeInfo); | |
+ if (type == Qnil) { | |
+ rb_raise(rb_eRuntimeError, "failed to create WIN32OLE_TYPE obj from ITypeInfo"); | |
} | |
- hr = pTypeLib->lpVtbl->GetDocumentation( pTypeLib, index, | |
- &bstr, NULL, NULL, NULL); | |
- if (SUCCEEDED(hr)) { | |
- type = foletype_s_allocate(cWIN32OLE_TYPE); | |
- oletype_set_member(type, pTypeInfo, WC2VSTR(bstr)); | |
+ return type; | |
+} | |
+ | |
+static VALUE | |
+make_oletypelib_obj(VALUE guid, VALUE major_version, VALUE minor_version) | |
+{ | |
+ VALUE args = rb_ary_new(); | |
+ rb_ary_push(args, guid); | |
+ rb_ary_push(args, major_version); | |
+ rb_ary_push(args, minor_version); | |
+ return rb_apply(cWIN32OLE_TYPELIB, rb_intern("new"), args); | |
+} | |
+ | |
+static VALUE | |
+ole_typelib_from_itypelib(ITypeLib *pTypeLib) | |
+{ | |
+ TLIBATTR *pTLibAttr; | |
+ OLECHAR bstr[80]; | |
+ VALUE guid = Qnil; | |
+ VALUE major; | |
+ VALUE minor; | |
+ int len = 0; | |
+ HRESULT hr = S_OK; | |
+ hr = pTypeLib->lpVtbl->GetLibAttr(pTypeLib, &pTLibAttr); | |
+ if (FAILED(hr)) { | |
+ return Qnil; | |
} | |
+ len = StringFromGUID2(&pTLibAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR)); | |
+ if (len > 3) { | |
+ guid = ole_wc2vstr(bstr, FALSE); | |
+ } | |
+ major = INT2NUM(pTLibAttr->wMajorVerNum); | |
+ minor = INT2NUM(pTLibAttr->wMinorVerNum); | |
+ pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr); | |
+ if (guid == Qnil) { | |
+ return Qnil; | |
+ } | |
+ return make_oletypelib_obj(guid, major, minor); | |
+} | |
+ | |
+ | |
+static 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 = ole_typelib_from_itypelib(pTypeLib); | |
OLE_RELEASE(pTypeLib); | |
+ return retval; | |
+} | |
+ | |
+/* | |
+ * 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; | |
+ HRESULT hr; | |
+ ITypeInfo *pTypeInfo; | |
+ LCID lcid = cWIN32OLE_lcid; | |
+ VALUE vtlib = Qnil; | |
+ | |
+ OLEData_Get_Struct(self, pole); | |
+ 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; | |
+} | |
- return type; | |
+/* | |
+ * 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; | |
+ 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)); | |
+ } | |
+ | |
+ OLEData_Get_Struct(self, pole); | |
+ 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; | |
+ BSTR wcmdname; | |
+ DISPID DispID; | |
+ HRESULT hr; | |
+ rb_secure(4); | |
+ if(TYPE(method) != T_STRING && TYPE(method) != T_SYMBOL) { | |
+ rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)"); | |
+ } | |
+ if (TYPE(method) == T_SYMBOL) { | |
+ method = rb_sym_to_s(method); | |
+ } | |
+ OLEData_Get_Struct(self, pole); | |
+ 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; | |
} | |
static HRESULT | |
-ole_docinfo_from_type(pTypeInfo, name, helpstr, helpcontext, helpfile) | |
- ITypeInfo *pTypeInfo; | |
- BSTR *name; | |
- BSTR *helpstr; | |
- DWORD *helpcontext; | |
- BSTR *helpfile; | |
+ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile) | |
{ | |
HRESULT hr; | |
ITypeLib *pTypeLib; | |
@@ -3175,10 +4596,7 @@ ole_docinfo_from_type(pTypeInfo, name, helpstr, helpcontext, helpfile) | |
} | |
static VALUE | |
-ole_usertype2val(pTypeInfo, pTypeDesc, typedetails) | |
- ITypeInfo *pTypeInfo; | |
- TYPEDESC *pTypeDesc; | |
- VALUE typedetails; | |
+ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails) | |
{ | |
HRESULT hr; | |
BSTR bstr; | |
@@ -3202,146 +4620,132 @@ ole_usertype2val(pTypeInfo, pTypeDesc, typedetails) | |
return type; | |
} | |
-static VALUE ole_typedesc2val(); | |
static VALUE | |
-ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails) | |
- ITypeInfo *pTypeInfo; | |
- TYPEDESC *pTypeDesc; | |
- VALUE typedetails; | |
+ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails) | |
{ | |
TYPEDESC *p = pTypeDesc; | |
VALUE type = rb_str_new2(""); | |
- while(p->vt == VT_PTR || p->vt == VT_SAFEARRAY) { | |
+ | |
+ if (p->vt == VT_PTR || p->vt == VT_SAFEARRAY) { | |
p = V_UNION1(p, lptdesc); | |
- if(strlen(StringValuePtr(type)) == 0) { | |
- type = ole_typedesc2val(pTypeInfo, p, typedetails); | |
- } else { | |
- rb_str_cat(type, ",", 1); | |
- rb_str_concat(type, ole_typedesc2val(pTypeInfo, p, typedetails)); | |
- } | |
+ type = ole_typedesc2val(pTypeInfo, p, typedetails); | |
} | |
return type; | |
} | |
static VALUE | |
-ole_typedesc2val(pTypeInfo, pTypeDesc, typedetails) | |
- ITypeInfo *pTypeInfo; | |
- TYPEDESC *pTypeDesc; | |
- VALUE typedetails; | |
+ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails) | |
{ | |
VALUE str; | |
+ VALUE typestr = Qnil; | |
switch(pTypeDesc->vt) { | |
case VT_I2: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("I2")); | |
- return rb_str_new2("I2"); | |
+ typestr = rb_str_new2("I2"); | |
+ break; | |
case VT_I4: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("I4")); | |
- return rb_str_new2("I4"); | |
+ typestr = rb_str_new2("I4"); | |
+ break; | |
case VT_R4: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("R4")); | |
- return rb_str_new2("R4"); | |
+ typestr = rb_str_new2("R4"); | |
+ break; | |
case VT_R8: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("R8")); | |
- return rb_str_new2("R8"); | |
+ typestr = rb_str_new2("R8"); | |
+ break; | |
case VT_CY: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("CY")); | |
- return rb_str_new2("CY"); | |
+ typestr = rb_str_new2("CY"); | |
+ break; | |
case VT_DATE: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("DATE")); | |
- return rb_str_new2("DATE"); | |
+ typestr = rb_str_new2("DATE"); | |
+ break; | |
case VT_BSTR: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("BSTR")); | |
- return rb_str_new2("BSTR"); | |
+ typestr = rb_str_new2("BSTR"); | |
+ break; | |
case VT_BOOL: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("BOOL")); | |
- return rb_str_new2("BOOL"); | |
+ typestr = rb_str_new2("BOOL"); | |
+ break; | |
case VT_VARIANT: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("VARIANT")); | |
- return rb_str_new2("VARIANT"); | |
+ typestr = rb_str_new2("VARIANT"); | |
+ break; | |
case VT_DECIMAL: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("DECIMAL")); | |
- return rb_str_new2("DECIMAL"); | |
+ typestr = rb_str_new2("DECIMAL"); | |
+ break; | |
case VT_I1: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("I1")); | |
- return rb_str_new2("I1"); | |
+ typestr = rb_str_new2("I1"); | |
+ break; | |
case VT_UI1: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("UI1")); | |
- return rb_str_new2("UI1"); | |
+ typestr = rb_str_new2("UI1"); | |
+ break; | |
case VT_UI2: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("UI2")); | |
- return rb_str_new2("UI2"); | |
+ typestr = rb_str_new2("UI2"); | |
+ break; | |
case VT_UI4: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("UI4")); | |
- return rb_str_new2("UI4"); | |
+ typestr = rb_str_new2("UI4"); | |
+ break; | |
+#if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__) | |
case VT_I8: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("I8")); | |
- return rb_str_new2("I8"); | |
+ typestr = rb_str_new2("I8"); | |
+ break; | |
case VT_UI8: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("UI8")); | |
- return rb_str_new2("UI8"); | |
+ typestr = rb_str_new2("UI8"); | |
+ break; | |
+#endif | |
case VT_INT: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("INT")); | |
- return rb_str_new2("INT"); | |
+ typestr = rb_str_new2("INT"); | |
+ break; | |
case VT_UINT: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("UINT")); | |
- return rb_str_new2("UINT"); | |
+ typestr = rb_str_new2("UINT"); | |
+ break; | |
case VT_VOID: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("VOID")); | |
- return rb_str_new2("VOID"); | |
+ typestr = rb_str_new2("VOID"); | |
+ break; | |
case VT_HRESULT: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("HRESULT")); | |
- return rb_str_new2("HRESULT"); | |
+ typestr = rb_str_new2("HRESULT"); | |
+ break; | |
case VT_PTR: | |
+ typestr = rb_str_new2("PTR"); | |
if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("PTR")); | |
+ 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, rb_str_new2("SAFEARRAY")); | |
+ rb_ary_push(typedetails, typestr); | |
return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails); | |
case VT_CARRAY: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("CARRAY")); | |
- return rb_str_new2("CARRAY"); | |
+ typestr = rb_str_new2("CARRAY"); | |
+ break; | |
case VT_USERDEFINED: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("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 rb_str_new2("USERDEFINED"); | |
+ return typestr; | |
case VT_UNKNOWN: | |
- return rb_str_new2("UNKNOWN"); | |
+ typestr = rb_str_new2("UNKNOWN"); | |
+ break; | |
case VT_DISPATCH: | |
- if(typedetails != Qnil) | |
- rb_ary_push(typedetails, rb_str_new2("DISPATCH")); | |
- return rb_str_new2("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; | |
default: | |
- str = rb_str_new2("Unknown Type "); | |
- rb_str_concat(str, rb_fix2str(INT2FIX(pTypeDesc->vt), 10)); | |
- return str; | |
+ 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; | |
} | |
/* | |
@@ -3356,15 +4760,12 @@ ole_typedesc2val(pTypeInfo, pTypeDesc, typedetails) | |
* | |
*/ | |
static VALUE | |
-fole_method_help( self, cmdname ) | |
- VALUE self; | |
- VALUE cmdname; | |
+fole_method_help(VALUE self, VALUE cmdname) | |
{ | |
ITypeInfo *pTypeInfo; | |
HRESULT hr; | |
struct oledata *pole; | |
VALUE method, obj; | |
- LCID lcid = LOCALE_SYSTEM_DEFAULT; | |
Check_SafeStr(cmdname); | |
OLEData_Get_Struct(self, pole); | |
@@ -3375,45 +4776,78 @@ fole_method_help( self, cmdname ) | |
obj = olemethod_from_typeinfo(method, pTypeInfo, cmdname); | |
OLE_RELEASE(pTypeInfo); | |
if (obj == Qnil) | |
- rb_raise(eWIN32OLE_RUNTIME_ERROR, "not found %s", | |
+ 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; | |
+ IPersistMemory *pPersistMemory; | |
+ void *p; | |
+ | |
+ HRESULT hr = S_OK; | |
+ | |
+ OLEData_Get_Struct(self, pole); | |
+ | |
+ 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; | |
+} | |
+ | |
+/* | |
* 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(self, typelib) | |
- VALUE self; | |
- VALUE typelib; | |
+foletype_s_ole_classes(VALUE self, VALUE typelib) | |
{ | |
- VALUE file, classes; | |
- OLECHAR * pbuf; | |
- ITypeLib *pTypeLib; | |
- HRESULT hr; | |
+ VALUE obj; | |
- rb_secure(4); | |
- classes = rb_ary_new(); | |
- if(TYPE(typelib) == T_STRING) { | |
- file = typelib_file(typelib); | |
- if (file == Qnil) { | |
- file = typelib; | |
- } | |
- pbuf = ole_mb2wc(StringValuePtr(file), -1); | |
- hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib); | |
- if (FAILED(hr)) | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "failed to LoadTypeLibEx"); | |
- SysFreeString(pbuf); | |
- ole_classes_from_typelib(pTypeLib, classes); | |
- OLE_RELEASE(pTypeLib); | |
- } else { | |
- rb_raise(rb_eTypeError, "1st argument should be TypeLib string"); | |
- } | |
- return classes; | |
+ /* | |
+ 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); | |
} | |
/* | |
@@ -3421,48 +4855,18 @@ foletype_s_ole_classes(self, typelib) | |
* 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(self) | |
- VALUE self; | |
+foletype_s_typelibs(VALUE self) | |
{ | |
- HKEY htypelib, hclsid; | |
- double fversion; | |
- DWORD i, j; | |
- LONG err; | |
- VALUE clsid; | |
- VALUE ver; | |
- VALUE v = Qnil; | |
- VALUE typelibs = rb_ary_new(); | |
- | |
- err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib); | |
- if(err != ERROR_SUCCESS) { | |
- return typelibs; | |
- } | |
- for(i = 0; ; i++) { | |
- clsid = reg_enum_key(htypelib, i); | |
- if (clsid == Qnil) | |
- break; | |
- err = reg_open_vkey(htypelib, clsid, &hclsid); | |
- if (err != ERROR_SUCCESS) | |
- continue; | |
- fversion = 0; | |
- for(j = 0; ; j++) { | |
- ver = reg_enum_key(hclsid, j); | |
- if (ver == Qnil) | |
- break; | |
- if (fversion > atof(StringValuePtr(ver))) | |
- continue; | |
- fversion = atof(StringValuePtr(ver)); | |
- if ( (v = reg_get_val(hclsid, StringValuePtr(ver))) != Qnil ) { | |
- rb_ary_push(typelibs, v); | |
- } | |
- } | |
- RegCloseKey(hclsid); | |
- } | |
- RegCloseKey(htypelib); | |
- return typelibs; | |
+ /* | |
+ 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}"); | |
} | |
/* | |
@@ -3472,8 +4876,7 @@ foletype_s_typelibs(self) | |
* Returns array of ProgID. | |
*/ | |
static VALUE | |
-foletype_s_progids(self) | |
- VALUE self; | |
+foletype_s_progids(VALUE self) | |
{ | |
HKEY hclsids, hclsid; | |
DWORD i; | |
@@ -3493,9 +4896,9 @@ foletype_s_progids(self) | |
err = reg_open_vkey(hclsids, clsid, &hclsid); | |
if (err != ERROR_SUCCESS) | |
continue; | |
- if ((v = reg_get_val(hclsid, "ProgID")) != Qnil) | |
+ if ((v = reg_get_val2(hclsid, "ProgID")) != Qnil) | |
rb_ary_push(progids, v); | |
- if ((v = reg_get_val(hclsid, "VersionIndependentProgID")) != Qnil) | |
+ if ((v = reg_get_val2(hclsid, "VersionIndependentProgID")) != Qnil) | |
rb_ary_push(progids, v); | |
RegCloseKey(hclsid); | |
} | |
@@ -3504,8 +4907,7 @@ foletype_s_progids(self) | |
} | |
static VALUE | |
-foletype_s_allocate(klass) | |
- VALUE klass; | |
+foletype_s_allocate(VALUE klass) | |
{ | |
struct oletypedata *poletype; | |
VALUE obj; | |
@@ -3516,10 +4918,7 @@ foletype_s_allocate(klass) | |
} | |
static VALUE | |
-oletype_set_member(self, pTypeInfo, name) | |
- VALUE self; | |
- ITypeInfo *pTypeInfo; | |
- VALUE name; | |
+oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name) | |
{ | |
struct oletypedata *ptype; | |
Data_Get_Struct(self, struct oletypedata, ptype); | |
@@ -3530,10 +4929,7 @@ oletype_set_member(self, pTypeInfo, name) | |
} | |
static VALUE | |
-oleclass_from_typelib(self, pTypeLib, oleclass) | |
- VALUE self; | |
- ITypeLib *pTypeLib; | |
- VALUE oleclass; | |
+oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass) | |
{ | |
long count; | |
@@ -3565,6 +4961,528 @@ oleclass_from_typelib(self, pTypeLib, oleclass) | |
} | |
/* | |
+ * Document-class: WIN32OLE_TYPELIB | |
+ * | |
+ * <code>WIN32OLE_TYPELIB</code> objects represent OLE tyblib information. | |
+ */ | |
+ | |
+ | |
+static VALUE | |
+oletypelib_set_member(VALUE self, VALUE typelib, VALUE guid, VALUE version) | |
+{ | |
+ rb_ivar_set(self, rb_intern("name"), typelib); | |
+ rb_ivar_set(self, rb_intern("guid"), guid); | |
+ rb_ivar_set(self, rb_intern("version"), version); | |
+ return self; | |
+} | |
+ | |
+/* | |
+ * 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; | |
+ | |
+ 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 ) { | |
+ typelib = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("allocate"), 0); | |
+ oletypelib_set_member(typelib, name, guid, version); | |
+ rb_ary_push(typelibs, typelib); | |
+ } | |
+ } | |
+ RegCloseKey(hguid); | |
+ } | |
+ RegCloseKey(htypelib); | |
+ return typelibs; | |
+} | |
+ | |
+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; | |
+} | |
+ | |
+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; | |
+ | |
+ 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) { | |
+ found = Qtrue; | |
+ oletypelib_set_member(self, typelib, guid, version); | |
+ } | |
+ return found; | |
+} | |
+ | |
+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; | |
+ | |
+ 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) { | |
+ oletypelib_set_member(self, typelib, guid, ver); | |
+ found = Qtrue; | |
+ } | |
+ RegCloseKey(hversion); | |
+ } | |
+ RegCloseKey(hguid); | |
+ } | |
+ RegCloseKey(htypelib); | |
+ 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; | |
+ VALUE retval; | |
+ 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); | |
+ | |
+ Check_SafeStr(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)) { | |
+ retval = ole_typelib_from_itypelib(pTypeLib); | |
+ OLE_RELEASE(pTypeLib); | |
+ if (retval != Qnil) { | |
+ found = Qtrue; | |
+ oletypelib_set_member(self, | |
+ rb_ivar_get(retval, rb_intern("name")), | |
+ rb_ivar_get(retval, rb_intern("guid")), | |
+ rb_ivar_get(retval, rb_intern("version"))); | |
+ } | |
+ } | |
+ } | |
+ | |
+ 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) | |
+{ | |
+ return rb_ivar_get(self, rb_intern("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) | |
+{ | |
+ return rb_ivar_get(self, rb_intern("name")); | |
+} | |
+ | |
+/* | |
+ * call-seq: | |
+ * WIN32OLE_TYPELIB#version -> The type library version. | |
+ * | |
+ * 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) | |
+{ | |
+ VALUE ver = rb_ivar_get(self, rb_intern("version")); | |
+ return rb_Float(ver); | |
+} | |
+ | |
+/* | |
+ * 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) | |
+{ | |
+ VALUE ver = rb_ivar_get(self, rb_intern("version")); | |
+ VALUE ary = rb_str_split(ver, "."); | |
+ return rb_Integer(rb_ary_entry(ary, 0)); | |
+} | |
+ | |
+/* | |
+ * 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) | |
+{ | |
+ VALUE ver = rb_ivar_get(self, rb_intern("version")); | |
+ VALUE ary = rb_str_split(ver, "."); | |
+ return rb_Integer(rb_ary_entry(ary, 1)); | |
+} | |
+ | |
+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; | |
+} | |
+ | |
+/* | |
+ * 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) | |
+{ | |
+ VALUE guid = rb_ivar_get(self, rb_intern("guid")); | |
+ VALUE version = rb_ivar_get(self, rb_intern("version")); | |
+ return oletypelib_path(guid, version); | |
+} | |
+ | |
+static void | |
+oletypelib2itypelib(VALUE self, ITypeLib **ppTypeLib) | |
+{ | |
+ VALUE path = Qnil; | |
+ OLECHAR *pbuf; | |
+ HRESULT hr = S_OK; | |
+ path = rb_funcall(self, rb_intern("path"), 0); | |
+ if (path != Qnil) { | |
+ pbuf = ole_vstr2wc(path); | |
+ hr = LoadTypeLibEx(pbuf, REGKIND_NONE, ppTypeLib); | |
+ SysFreeString(pbuf); | |
+ if (FAILED(hr)) | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx from `%s'", | |
+ StringValuePtr(path)); | |
+ } else { | |
+ rb_raise(eWIN32OLERuntimeError, "failed to get type library 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) | |
+{ | |
+ HRESULT hr; | |
+ ITypeLib *pTypeLib = NULL; | |
+ VALUE visible = Qtrue; | |
+ TLIBATTR *pTLibAttr; | |
+ | |
+ oletypelib2itypelib(self, &pTypeLib); | |
+ | |
+ hr = pTypeLib->lpVtbl->GetLibAttr(pTypeLib, &pTLibAttr); | |
+ if (FAILED(hr)) { | |
+ OLE_RELEASE(pTypeLib); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to get TLIBATTR information"); | |
+ } | |
+ if ((pTLibAttr->wLibFlags == 0) || | |
+ (pTLibAttr->wLibFlags & LIBFLAG_FRESTRICTED) || | |
+ (pTLibAttr->wLibFlags & LIBFLAG_FHIDDEN)) { | |
+ visible = Qfalse; | |
+ } | |
+ pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr); | |
+ OLE_RELEASE(pTypeLib); | |
+ 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; | |
+ | |
+ oletypelib2itypelib(self, &pTypeLib); | |
+ hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1, | |
+ &bstr, NULL, NULL, NULL); | |
+ if (FAILED(hr)) { | |
+ OLE_RELEASE(pTypeLib); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to get library name"); | |
+ } | |
+ OLE_RELEASE(pTypeLib); | |
+ libname = WC2VSTR(bstr); | |
+ return libname; | |
+} | |
+ | |
+ | |
+/* | |
+ * 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(); | |
+ oletypelib2itypelib(self, &pTypeLib); | |
+ ole_types_from_typelib(pTypeLib, classes); | |
+ OLE_RELEASE(pTypeLib); | |
+ 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"); | |
+} | |
+ | |
+/* | |
* Document-class: WIN32OLE_TYPE | |
* | |
* <code>WIN32OLE_TYPE</code> objects represent OLE type libarary information. | |
@@ -3582,10 +5500,7 @@ oleclass_from_typelib(self, pTypeLib, oleclass) | |
* # => WIN32OLE_TYPE object of Application class of Excel. | |
*/ | |
static VALUE | |
-foletype_initialize(self, typelib, oleclass) | |
- VALUE self; | |
- VALUE typelib; | |
- VALUE oleclass; | |
+foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass) | |
{ | |
VALUE file; | |
OLECHAR * pbuf; | |
@@ -3598,14 +5513,14 @@ foletype_initialize(self, typelib, oleclass) | |
if (file == Qnil) { | |
file = typelib; | |
} | |
- pbuf = ole_mb2wc(StringValuePtr(file), -1); | |
+ pbuf = ole_vstr2wc(file); | |
hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib); | |
if (FAILED(hr)) | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "failed to LoadTypeLibEx"); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx"); | |
SysFreeString(pbuf); | |
if (oleclass_from_typelib(self, pTypeLib, oleclass) == Qfalse) { | |
OLE_RELEASE(pTypeLib); | |
- rb_raise(eWIN32OLE_RUNTIME_ERROR, "not found `%s` in `%s`", | |
+ rb_raise(eWIN32OLERuntimeError, "not found `%s` in `%s`", | |
StringValuePtr(oleclass), StringValuePtr(typelib)); | |
} | |
OLE_RELEASE(pTypeLib); | |
@@ -3621,15 +5536,13 @@ foletype_initialize(self, typelib, oleclass) | |
* puts tobj.name # => Application | |
*/ | |
static VALUE | |
-foletype_name(self) | |
- VALUE self; | |
+foletype_name(VALUE self) | |
{ | |
return rb_ivar_get(self, rb_intern("name")); | |
} | |
static VALUE | |
-ole_ole_type(pTypeInfo) | |
- ITypeInfo *pTypeInfo; | |
+ole_ole_type(ITypeInfo *pTypeInfo) | |
{ | |
HRESULT hr; | |
TYPEATTR *pTypeAttr; | |
@@ -3683,8 +5596,7 @@ ole_ole_type(pTypeInfo) | |
* puts tobj.ole_type # => Class | |
*/ | |
static VALUE | |
-foletype_ole_type(self) | |
- VALUE self; | |
+foletype_ole_type(VALUE self) | |
{ | |
struct oletypedata *ptype; | |
Data_Get_Struct(self, struct oletypedata, ptype); | |
@@ -3692,8 +5604,7 @@ foletype_ole_type(self) | |
} | |
static VALUE | |
-ole_type_guid(pTypeInfo) | |
- ITypeInfo *pTypeInfo; | |
+ole_type_guid(ITypeInfo *pTypeInfo) | |
{ | |
HRESULT hr; | |
TYPEATTR *pTypeAttr; | |
@@ -3720,8 +5631,7 @@ ole_type_guid(pTypeInfo) | |
* puts tobj.guid # => {00024500-0000-0000-C000-000000000046} | |
*/ | |
static VALUE | |
-foletype_guid(self) | |
- VALUE self; | |
+foletype_guid(VALUE self) | |
{ | |
struct oletypedata *ptype; | |
Data_Get_Struct(self, struct oletypedata, ptype); | |
@@ -3729,8 +5639,7 @@ foletype_guid(self) | |
} | |
static VALUE | |
-ole_type_progid(pTypeInfo) | |
- ITypeInfo *pTypeInfo; | |
+ole_type_progid(ITypeInfo *pTypeInfo) | |
{ | |
HRESULT hr; | |
TYPEATTR *pTypeAttr; | |
@@ -3740,7 +5649,7 @@ ole_type_progid(pTypeInfo) | |
if (FAILED(hr)) | |
return progid; | |
hr = ProgIDFromCLSID(&pTypeAttr->guid, &pbuf); | |
- if (SUCCEEDED(hr)) { | |
+ if (SUCCEEDED(hr)) { | |
progid = ole_wc2vstr(pbuf, FALSE); | |
CoTaskMemFree(pbuf); | |
} | |
@@ -3757,8 +5666,7 @@ ole_type_progid(pTypeInfo) | |
* puts tobj.progid # => Excel.Application.9 | |
*/ | |
static VALUE | |
-foletype_progid(self) | |
- VALUE self; | |
+foletype_progid(VALUE self) | |
{ | |
struct oletypedata *ptype; | |
Data_Get_Struct(self, struct oletypedata, ptype); | |
@@ -3767,8 +5675,7 @@ foletype_progid(self) | |
static VALUE | |
-ole_type_visible(pTypeInfo) | |
- ITypeInfo *pTypeInfo; | |
+ole_type_visible(ITypeInfo *pTypeInfo) | |
{ | |
HRESULT hr; | |
TYPEATTR *pTypeAttr; | |
@@ -3794,8 +5701,7 @@ ole_type_visible(pTypeInfo) | |
* puts tobj.visible # => true | |
*/ | |
static VALUE | |
-foletype_visible(self) | |
- VALUE self; | |
+foletype_visible(VALUE self) | |
{ | |
struct oletypedata *ptype; | |
Data_Get_Struct(self, struct oletypedata, ptype); | |
@@ -3803,15 +5709,14 @@ foletype_visible(self) | |
} | |
static VALUE | |
-ole_type_major_version(pTypeInfo) | |
- ITypeInfo *pTypeInfo; | |
+ole_type_major_version(ITypeInfo *pTypeInfo) | |
{ | |
VALUE ver; | |
TYPEATTR *pTypeAttr; | |
HRESULT hr; | |
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); | |
if (FAILED(hr)) | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "failed to GetTypeAttr"); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr"); | |
ver = INT2FIX(pTypeAttr->wMajorVerNum); | |
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); | |
return ver; | |
@@ -3826,8 +5731,7 @@ ole_type_major_version(pTypeInfo) | |
* puts tobj.major_version # => 8 | |
*/ | |
static VALUE | |
-foletype_major_version(self) | |
- VALUE self; | |
+foletype_major_version(VALUE self) | |
{ | |
struct oletypedata *ptype; | |
Data_Get_Struct(self, struct oletypedata, ptype); | |
@@ -3835,15 +5739,14 @@ foletype_major_version(self) | |
} | |
static VALUE | |
-ole_type_minor_version(pTypeInfo) | |
- ITypeInfo *pTypeInfo; | |
+ole_type_minor_version(ITypeInfo *pTypeInfo) | |
{ | |
VALUE ver; | |
TYPEATTR *pTypeAttr; | |
HRESULT hr; | |
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); | |
if (FAILED(hr)) | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "failed to GetTypeAttr"); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr"); | |
ver = INT2FIX(pTypeAttr->wMinorVerNum); | |
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); | |
return ver; | |
@@ -3858,8 +5761,7 @@ ole_type_minor_version(pTypeInfo) | |
* puts tobj.minor_version # => 2 | |
*/ | |
static VALUE | |
-foletype_minor_version(self) | |
- VALUE self; | |
+foletype_minor_version(VALUE self) | |
{ | |
struct oletypedata *ptype; | |
Data_Get_Struct(self, struct oletypedata, ptype); | |
@@ -3867,15 +5769,14 @@ foletype_minor_version(self) | |
} | |
static VALUE | |
-ole_type_typekind(pTypeInfo) | |
- ITypeInfo *pTypeInfo; | |
+ole_type_typekind(ITypeInfo *pTypeInfo) | |
{ | |
VALUE typekind; | |
TYPEATTR *pTypeAttr; | |
HRESULT hr; | |
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); | |
if (FAILED(hr)) | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "failed to GetTypeAttr"); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr"); | |
typekind = INT2FIX(pTypeAttr->typekind); | |
OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr); | |
return typekind; | |
@@ -3891,8 +5792,7 @@ ole_type_typekind(pTypeInfo) | |
* | |
*/ | |
static VALUE | |
-foletype_typekind(self) | |
- VALUE self; | |
+foletype_typekind(VALUE self) | |
{ | |
struct oletypedata *ptype; | |
Data_Get_Struct(self, struct oletypedata, ptype); | |
@@ -3900,8 +5800,7 @@ foletype_typekind(self) | |
} | |
static VALUE | |
-ole_type_helpstring(pTypeInfo) | |
- ITypeInfo *pTypeInfo; | |
+ole_type_helpstring(ITypeInfo *pTypeInfo) | |
{ | |
HRESULT hr; | |
BSTR bhelpstr; | |
@@ -3921,8 +5820,7 @@ ole_type_helpstring(pTypeInfo) | |
* puts tobj.helpstring # => Web Browser interface | |
*/ | |
static VALUE | |
-foletype_helpstring(self) | |
- VALUE self; | |
+foletype_helpstring(VALUE self) | |
{ | |
struct oletypedata *ptype; | |
Data_Get_Struct(self, struct oletypedata, ptype); | |
@@ -3930,8 +5828,7 @@ foletype_helpstring(self) | |
} | |
static VALUE | |
-ole_type_src_type(pTypeInfo) | |
- ITypeInfo *pTypeInfo; | |
+ole_type_src_type(ITypeInfo *pTypeInfo) | |
{ | |
HRESULT hr; | |
TYPEATTR *pTypeAttr; | |
@@ -3958,8 +5855,7 @@ ole_type_src_type(pTypeInfo) | |
* | |
*/ | |
static VALUE | |
-foletype_src_type(self) | |
- VALUE self; | |
+foletype_src_type(VALUE self) | |
{ | |
struct oletypedata *ptype; | |
Data_Get_Struct(self, struct oletypedata, ptype); | |
@@ -3967,8 +5863,7 @@ foletype_src_type(self) | |
} | |
static VALUE | |
-ole_type_helpfile(pTypeInfo) | |
- ITypeInfo *pTypeInfo; | |
+ole_type_helpfile(ITypeInfo *pTypeInfo) | |
{ | |
HRESULT hr; | |
BSTR bhelpfile; | |
@@ -3989,8 +5884,7 @@ ole_type_helpfile(pTypeInfo) | |
* | |
*/ | |
static VALUE | |
-foletype_helpfile(self) | |
- VALUE self; | |
+foletype_helpfile(VALUE self) | |
{ | |
struct oletypedata *ptype; | |
Data_Get_Struct(self, struct oletypedata, ptype); | |
@@ -3998,8 +5892,7 @@ foletype_helpfile(self) | |
} | |
static VALUE | |
-ole_type_helpcontext(pTypeInfo) | |
- ITypeInfo *pTypeInfo; | |
+ole_type_helpcontext(ITypeInfo *pTypeInfo) | |
{ | |
HRESULT hr; | |
DWORD helpcontext; | |
@@ -4019,17 +5912,158 @@ ole_type_helpcontext(pTypeInfo) | |
* puts tobj.helpfile # => 131185 | |
*/ | |
static VALUE | |
-foletype_helpcontext(self) | |
- VALUE self; | |
+foletype_helpcontext(VALUE self) | |
{ | |
struct oletypedata *ptype; | |
Data_Get_Struct(self, struct oletypedata, ptype); | |
return ole_type_helpcontext(ptype->pTypeInfo); | |
} | |
+/* | |
+ * 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) | |
+{ | |
+ struct oletypedata *ptype; | |
+ Data_Get_Struct(self, struct oletypedata, ptype); | |
+ return ole_typelib_from_itypeinfo(ptype->pTypeInfo); | |
+} | |
+ | |
static VALUE | |
-ole_variables(pTypeInfo) | |
- ITypeInfo *pTypeInfo; | |
+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) | |
+{ | |
+ struct oletypedata *ptype; | |
+ Data_Get_Struct(self, struct oletypedata, ptype); | |
+ return ole_type_impl_ole_types(ptype->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) | |
+{ | |
+ struct oletypedata *ptype; | |
+ Data_Get_Struct(self, struct oletypedata, ptype); | |
+ return ole_type_impl_ole_types(ptype->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) | |
+{ | |
+ struct oletypedata *ptype; | |
+ Data_Get_Struct(self, struct oletypedata, ptype); | |
+ return ole_type_impl_ole_types(ptype->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) | |
+{ | |
+ struct oletypedata *ptype; | |
+ Data_Get_Struct(self, struct oletypedata, ptype); | |
+ return ole_type_impl_ole_types(ptype->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"); | |
+} | |
+ | |
+static VALUE | |
+ole_variables(ITypeInfo *pTypeInfo) | |
{ | |
HRESULT hr; | |
TYPEATTR *pTypeAttr; | |
@@ -4043,7 +6077,7 @@ ole_variables(pTypeInfo) | |
VALUE variables = rb_ary_new(); | |
hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr); | |
if (FAILED(hr)) { | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "failed to GetTypeAttr"); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr"); | |
} | |
for(i = 0; i < pTypeAttr->cVars; i++) { | |
@@ -4093,8 +6127,7 @@ ole_variables(pTypeInfo) | |
* | |
*/ | |
static VALUE | |
-foletype_variables(self) | |
- VALUE self; | |
+foletype_variables(VALUE self) | |
{ | |
struct oletypedata *ptype; | |
Data_Get_Struct(self, struct oletypedata, ptype); | |
@@ -4114,10 +6147,7 @@ foletype_variables(self) | |
* # => ['Activate', 'Copy', 'Delete',....] | |
*/ | |
static VALUE | |
-foletype_methods(argc, argv, self) | |
- int argc; | |
- VALUE *argv; | |
- VALUE self; | |
+foletype_methods(VALUE self) | |
{ | |
struct oletypedata *ptype; | |
Data_Get_Struct(self, struct oletypedata, ptype); | |
@@ -4151,23 +6181,20 @@ foletype_methods(argc, argv, self) | |
* | |
*/ | |
static VALUE | |
-folevariable_name(self) | |
- VALUE self; | |
+folevariable_name(VALUE self) | |
{ | |
return rb_ivar_get(self, rb_intern("name")); | |
} | |
static VALUE | |
-ole_variable_ole_type(pTypeInfo, var_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT var_index; | |
+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, eWIN32OLE_RUNTIME_ERROR, "failed to GetVarDesc"); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc"); | |
type = ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), Qnil); | |
pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); | |
return type; | |
@@ -4194,8 +6221,7 @@ ole_variable_ole_type(pTypeInfo, var_index) | |
* | |
*/ | |
static VALUE | |
-folevariable_ole_type(self) | |
- VALUE self; | |
+folevariable_ole_type(VALUE self) | |
{ | |
struct olevariabledata *pvar; | |
Data_Get_Struct(self, struct olevariabledata, pvar); | |
@@ -4203,16 +6229,14 @@ folevariable_ole_type(self) | |
} | |
static VALUE | |
-ole_variable_ole_type_detail(pTypeInfo, var_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT var_index; | |
+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, eWIN32OLE_RUNTIME_ERROR, "failed to GetVarDesc"); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc"); | |
ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), type); | |
pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc); | |
return type; | |
@@ -4231,8 +6255,7 @@ ole_variable_ole_type_detail(pTypeInfo, var_index) | |
* | |
*/ | |
static VALUE | |
-folevariable_ole_type_detail(self) | |
- VALUE self; | |
+folevariable_ole_type_detail(VALUE self) | |
{ | |
struct olevariabledata *pvar; | |
Data_Get_Struct(self, struct olevariabledata, pvar); | |
@@ -4240,9 +6263,7 @@ folevariable_ole_type_detail(self) | |
} | |
static VALUE | |
-ole_variable_value(pTypeInfo, var_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT var_index; | |
+ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index) | |
{ | |
VARDESC *pVarDesc; | |
HRESULT hr; | |
@@ -4266,7 +6287,7 @@ ole_variable_value(pTypeInfo, var_index) | |
* tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType') | |
* variables = tobj.variables | |
* variables.each do |variable| | |
- * puts "#{variable.name} = #{variable.value}" | |
+ * puts "#{variable.name} #{variable.value}" | |
* end | |
* | |
* The result of above script is following: | |
@@ -4278,8 +6299,7 @@ ole_variable_value(pTypeInfo, var_index) | |
* | |
*/ | |
static VALUE | |
-folevariable_value(self) | |
- VALUE self; | |
+folevariable_value(VALUE self) | |
{ | |
struct olevariabledata *pvar; | |
Data_Get_Struct(self, struct olevariabledata, pvar); | |
@@ -4287,9 +6307,7 @@ folevariable_value(self) | |
} | |
static VALUE | |
-ole_variable_visible(pTypeInfo, var_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT var_index; | |
+ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index) | |
{ | |
VARDESC *pVarDesc; | |
HRESULT hr; | |
@@ -4327,8 +6345,7 @@ ole_variable_visible(pTypeInfo, var_index) | |
* | |
*/ | |
static VALUE | |
-folevariable_visible(self) | |
- VALUE self; | |
+folevariable_visible(VALUE self) | |
{ | |
struct olevariabledata *pvar; | |
Data_Get_Struct(self, struct olevariabledata, pvar); | |
@@ -4336,9 +6353,7 @@ folevariable_visible(self) | |
} | |
static VALUE | |
-ole_variable_kind(pTypeInfo, var_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT var_index; | |
+ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index) | |
{ | |
VARDESC *pVarDesc; | |
HRESULT hr; | |
@@ -4386,8 +6401,7 @@ ole_variable_kind(pTypeInfo, var_index) | |
* xlWorksheet CONSTANT | |
*/ | |
static VALUE | |
-folevariable_variable_kind(self) | |
- VALUE self; | |
+folevariable_variable_kind(VALUE self) | |
{ | |
struct olevariabledata *pvar; | |
Data_Get_Struct(self, struct olevariabledata, pvar); | |
@@ -4395,9 +6409,7 @@ folevariable_variable_kind(self) | |
} | |
static VALUE | |
-ole_variable_varkind(pTypeInfo, var_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT var_index; | |
+ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index) | |
{ | |
VARDESC *pVarDesc; | |
HRESULT hr; | |
@@ -4429,8 +6441,7 @@ ole_variable_varkind(pTypeInfo, var_index) | |
* xlWorksheet 2 | |
*/ | |
static VALUE | |
-folevariable_varkind(self) | |
- VALUE self; | |
+folevariable_varkind(VALUE self) | |
{ | |
struct olevariabledata *pvar; | |
Data_Get_Struct(self, struct olevariabledata, pvar); | |
@@ -4438,18 +6449,29 @@ folevariable_varkind(self) | |
} | |
/* | |
+ * call-seq: | |
+ * WIN32OLE_VARIABLE#inspect -> String | |
+ * | |
+ * Returns the OLE variable name and the value with class name. | |
+ * | |
+ */ | |
+static VALUE | |
+folevariable_inspect(VALUE self) | |
+{ | |
+ VALUE detail = rb_funcall(self, rb_intern("to_s"), 0); | |
+ rb_str_cat2(detail, "="); | |
+ rb_str_concat(detail, rb_funcall(rb_funcall(self, rb_intern("value"), 0), rb_intern("inspect"), 0)); | |
+ return make_inspect("WIN32OLE_VARIABLE", detail); | |
+} | |
+ | |
+/* | |
* Document-class: WIN32OLE_METHOD | |
* | |
* <code>WIN32OLE_METHOD</code> objects represent OLE method information. | |
*/ | |
static VALUE | |
-olemethod_set_member(self, pTypeInfo, pOwnerTypeInfo, index, name) | |
- VALUE self; | |
- ITypeInfo *pTypeInfo; | |
- ITypeInfo *pOwnerTypeInfo; | |
- int index; | |
- VALUE name; | |
+olemethod_set_member(VALUE self, ITypeInfo *pTypeInfo, ITypeInfo *pOwnerTypeInfo, int index, VALUE name) | |
{ | |
struct olemethoddata *pmethod; | |
Data_Get_Struct(self, struct olemethoddata, pmethod); | |
@@ -4463,8 +6485,7 @@ olemethod_set_member(self, pTypeInfo, pOwnerTypeInfo, index, name) | |
} | |
static VALUE | |
-folemethod_s_allocate(klass) | |
- VALUE klass; | |
+folemethod_s_allocate(VALUE klass) | |
{ | |
struct olemethoddata *pmethod; | |
VALUE obj; | |
@@ -4491,10 +6512,7 @@ folemethod_s_allocate(klass) | |
* method = WIN32OLE_METHOD.new(tobj, 'SaveAs') | |
*/ | |
static VALUE | |
-folemethod_initialize(self, oletype, method) | |
- VALUE self; | |
- VALUE oletype; | |
- VALUE method; | |
+folemethod_initialize(VALUE self, VALUE oletype, VALUE method) | |
{ | |
struct oletypedata *ptype; | |
VALUE obj = Qnil; | |
@@ -4503,7 +6521,7 @@ folemethod_initialize(self, oletype, method) | |
Data_Get_Struct(oletype, struct oletypedata, ptype); | |
obj = olemethod_from_typeinfo(self, ptype->pTypeInfo, method); | |
if (obj == Qnil) { | |
- rb_raise(eWIN32OLE_RUNTIME_ERROR, "not found %s", | |
+ rb_raise(eWIN32OLERuntimeError, "not found %s", | |
StringValuePtr(method)); | |
} | |
} | |
@@ -4525,16 +6543,13 @@ folemethod_initialize(self, oletype, method) | |
* | |
*/ | |
static VALUE | |
-folemethod_name(self) | |
- VALUE self; | |
+folemethod_name(VALUE self) | |
{ | |
return rb_ivar_get(self, rb_intern("name")); | |
} | |
static VALUE | |
-ole_method_return_type(pTypeInfo, method_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
+ole_method_return_type(ITypeInfo *pTypeInfo, UINT method_index) | |
{ | |
FUNCDESC *pFuncDesc; | |
HRESULT hr; | |
@@ -4542,7 +6557,7 @@ ole_method_return_type(pTypeInfo, method_index) | |
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); | |
if (FAILED(hr)) | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "failed to GetFuncDesc"); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc"); | |
type = ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), Qnil); | |
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); | |
@@ -4560,8 +6575,7 @@ ole_method_return_type(pTypeInfo, method_index) | |
* | |
*/ | |
static VALUE | |
-folemethod_return_type(self) | |
- VALUE self; | |
+folemethod_return_type(VALUE self) | |
{ | |
struct olemethoddata *pmethod; | |
Data_Get_Struct(self, struct olemethoddata, pmethod); | |
@@ -4569,21 +6583,19 @@ folemethod_return_type(self) | |
} | |
static VALUE | |
-ole_method_return_vtype(pTypeInfo, method_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
+ole_method_return_vtype(ITypeInfo *pTypeInfo, UINT method_index) | |
{ | |
FUNCDESC *pFuncDesc; | |
HRESULT hr; | |
- VALUE vt; | |
+ VALUE vvt; | |
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); | |
if (FAILED(hr)) | |
- ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "failed to GetFuncDesc"); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc"); | |
- vt = INT2FIX(pFuncDesc->elemdescFunc.tdesc.vt); | |
+ vvt = INT2FIX(pFuncDesc->elemdescFunc.tdesc.vt); | |
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); | |
- return vt; | |
+ return vvt; | |
} | |
/* | |
@@ -4597,8 +6609,7 @@ ole_method_return_vtype(pTypeInfo, method_index) | |
* | |
*/ | |
static VALUE | |
-folemethod_return_vtype(self) | |
- VALUE self; | |
+folemethod_return_vtype(VALUE self) | |
{ | |
struct olemethoddata *pmethod; | |
Data_Get_Struct(self, struct olemethoddata, pmethod); | |
@@ -4606,9 +6617,7 @@ folemethod_return_vtype(self) | |
} | |
static VALUE | |
-ole_method_return_type_detail(pTypeInfo, method_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
+ole_method_return_type_detail(ITypeInfo *pTypeInfo, UINT method_index) | |
{ | |
FUNCDESC *pFuncDesc; | |
HRESULT hr; | |
@@ -4634,8 +6643,7 @@ ole_method_return_type_detail(pTypeInfo, method_index) | |
* p method.return_type_detail # => ["PTR", "USERDEFINED", "Workbook"] | |
*/ | |
static VALUE | |
-folemethod_return_type_detail(self) | |
- VALUE self; | |
+folemethod_return_type_detail(VALUE self) | |
{ | |
struct olemethoddata *pmethod; | |
Data_Get_Struct(self, struct olemethoddata, pmethod); | |
@@ -4643,25 +6651,21 @@ folemethod_return_type_detail(self) | |
} | |
static VALUE | |
-ole_method_invkind(pTypeInfo, method_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
+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, eWIN32OLE_RUNTIME_ERROR, "failed to GetFuncDesc"); | |
+ ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc"); | |
invkind = INT2FIX(pFuncDesc->invkind); | |
pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc); | |
return invkind; | |
} | |
static VALUE | |
-ole_method_invoke_kind(pTypeInfo, method_index) | |
- ITypeInfo *pTypeInfo; | |
- WORD method_index; | |
+ole_method_invoke_kind(ITypeInfo *pTypeInfo, UINT method_index) | |
{ | |
VALUE type = rb_str_new2("UNKNOWN"); | |
VALUE invkind = ole_method_invkind(pTypeInfo, method_index); | |
@@ -4691,8 +6695,7 @@ ole_method_invoke_kind(pTypeInfo, method_index) | |
* | |
*/ | |
static VALUE | |
-folemethod_invkind(self) | |
- VALUE self; | |
+folemethod_invkind(VALUE self) | |
{ | |
struct olemethoddata *pmethod; | |
Data_Get_Struct(self, struct olemethoddata, pmethod); | |
@@ -4711,8 +6714,7 @@ folemethod_invkind(self) | |
* puts method.invoke_kind # => "FUNC" | |
*/ | |
static VALUE | |
-folemethod_invoke_kind(self) | |
- VALUE self; | |
+folemethod_invoke_kind(VALUE self) | |
{ | |
struct olemethoddata *pmethod; | |
Data_Get_Struct(self, struct olemethoddata, pmethod); | |
@@ -4720,9 +6722,7 @@ folemethod_invoke_kind(self) | |
} | |
static VALUE | |
-ole_method_visible(pTypeInfo, method_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
+ole_method_visible(ITypeInfo *pTypeInfo, UINT method_index) | |
{ | |
FUNCDESC *pFuncDesc; | |
HRESULT hr; | |
@@ -4751,8 +6751,7 @@ ole_method_visible(pTypeInfo, method_index) | |
* puts method.visible? # => true | |
*/ | |
static VALUE | |
-folemethod_visible(self) | |
- VALUE self; | |
+folemethod_visible(VALUE self) | |
{ | |
struct olemethoddata *pmethod; | |
Data_Get_Struct(self, struct olemethoddata, pmethod); | |
@@ -4760,10 +6759,7 @@ folemethod_visible(self) | |
} | |
static VALUE | |
-ole_method_event(pTypeInfo, method_index, method_name) | |
- ITypeInfo *pTypeInfo; | |
- WORD method_index; | |
- VALUE method_name; | |
+ole_method_event(ITypeInfo *pTypeInfo, UINT method_index, VALUE method_name) | |
{ | |
TYPEATTR *pTypeAttr; | |
HRESULT hr; | |
@@ -4837,8 +6833,7 @@ ole_method_event(pTypeInfo, method_index, method_name) | |
* | |
*/ | |
static VALUE | |
-folemethod_event(self) | |
- VALUE self; | |
+folemethod_event(VALUE self) | |
{ | |
struct olemethoddata *pmethod; | |
Data_Get_Struct(self, struct olemethoddata, pmethod); | |
@@ -4859,8 +6854,7 @@ folemethod_event(self) | |
* puts method.event_interface # => WorkbookEvents | |
*/ | |
static VALUE | |
-folemethod_event_interface(self) | |
- VALUE self; | |
+folemethod_event_interface(VALUE self) | |
{ | |
BSTR name; | |
struct olemethoddata *pmethod; | |
@@ -4875,14 +6869,14 @@ folemethod_event_interface(self) | |
} | |
static VALUE | |
-ole_method_docinfo_from_type(pTypeInfo, method_index, name, helpstr, | |
- helpcontext, helpfile) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
- BSTR *name; | |
- BSTR *helpstr; | |
- DWORD *helpcontext; | |
- BSTR *helpfile; | |
+ole_method_docinfo_from_type( | |
+ ITypeInfo *pTypeInfo, | |
+ UINT method_index, | |
+ BSTR *name, | |
+ BSTR *helpstr, | |
+ DWORD *helpcontext, | |
+ BSTR *helpfile | |
+ ) | |
{ | |
FUNCDESC *pFuncDesc; | |
HRESULT hr; | |
@@ -4897,9 +6891,7 @@ ole_method_docinfo_from_type(pTypeInfo, method_index, name, helpstr, | |
} | |
static VALUE | |
-ole_method_helpstring(pTypeInfo, method_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
+ole_method_helpstring(ITypeInfo *pTypeInfo, UINT method_index) | |
{ | |
HRESULT hr; | |
BSTR bhelpstring; | |
@@ -4922,8 +6914,7 @@ ole_method_helpstring(pTypeInfo, method_index) | |
* | |
*/ | |
static VALUE | |
-folemethod_helpstring(self) | |
- VALUE self; | |
+folemethod_helpstring(VALUE self) | |
{ | |
struct olemethoddata *pmethod; | |
Data_Get_Struct(self, struct olemethoddata, pmethod); | |
@@ -4931,9 +6922,7 @@ folemethod_helpstring(self) | |
} | |
static VALUE | |
-ole_method_helpfile(pTypeInfo, method_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
+ole_method_helpfile(ITypeInfo *pTypeInfo, UINT method_index) | |
{ | |
HRESULT hr; | |
BSTR bhelpfile; | |
@@ -4955,8 +6944,7 @@ ole_method_helpfile(pTypeInfo, method_index) | |
* puts method.helpfile # => C:\...\VBAXL9.CHM | |
*/ | |
static VALUE | |
-folemethod_helpfile(self) | |
- VALUE self; | |
+folemethod_helpfile(VALUE self) | |
{ | |
struct olemethoddata *pmethod; | |
Data_Get_Struct(self, struct olemethoddata, pmethod); | |
@@ -4965,9 +6953,7 @@ folemethod_helpfile(self) | |
} | |
static VALUE | |
-ole_method_helpcontext(pTypeInfo, method_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
+ole_method_helpcontext(ITypeInfo *pTypeInfo, UINT method_index) | |
{ | |
HRESULT hr; | |
DWORD helpcontext = 0; | |
@@ -4988,8 +6974,7 @@ ole_method_helpcontext(pTypeInfo, method_index) | |
* puts method.helpcontext # => 65717 | |
*/ | |
static VALUE | |
-folemethod_helpcontext(self) | |
- VALUE self; | |
+folemethod_helpcontext(VALUE self) | |
{ | |
struct olemethoddata *pmethod; | |
Data_Get_Struct(self, struct olemethoddata, pmethod); | |
@@ -4997,9 +6982,7 @@ folemethod_helpcontext(self) | |
} | |
static VALUE | |
-ole_method_dispid(pTypeInfo, method_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
+ole_method_dispid(ITypeInfo *pTypeInfo, UINT method_index) | |
{ | |
FUNCDESC *pFuncDesc; | |
HRESULT hr; | |
@@ -5022,8 +7005,7 @@ ole_method_dispid(pTypeInfo, method_index) | |
* puts method.dispid # => 181 | |
*/ | |
static VALUE | |
-folemethod_dispid(self) | |
- VALUE self; | |
+folemethod_dispid(VALUE self) | |
{ | |
struct olemethoddata *pmethod; | |
Data_Get_Struct(self, struct olemethoddata, pmethod); | |
@@ -5031,9 +7013,7 @@ folemethod_dispid(self) | |
} | |
static VALUE | |
-ole_method_offset_vtbl(pTypeInfo, method_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
+ole_method_offset_vtbl(ITypeInfo *pTypeInfo, UINT method_index) | |
{ | |
FUNCDESC *pFuncDesc; | |
HRESULT hr; | |
@@ -5056,8 +7036,7 @@ ole_method_offset_vtbl(pTypeInfo, method_index) | |
* puts method.offset_vtbl # => 40 | |
*/ | |
static VALUE | |
-folemethod_offset_vtbl(self) | |
- VALUE self; | |
+folemethod_offset_vtbl(VALUE self) | |
{ | |
struct olemethoddata *pmethod; | |
Data_Get_Struct(self, struct olemethoddata, pmethod); | |
@@ -5065,9 +7044,7 @@ folemethod_offset_vtbl(self) | |
} | |
static VALUE | |
-ole_method_size_params(pTypeInfo, method_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
+ole_method_size_params(ITypeInfo *pTypeInfo, UINT method_index) | |
{ | |
FUNCDESC *pFuncDesc; | |
HRESULT hr; | |
@@ -5091,8 +7068,7 @@ ole_method_size_params(pTypeInfo, method_index) | |
* | |
*/ | |
static VALUE | |
-folemethod_size_params(self) | |
- VALUE self; | |
+folemethod_size_params(VALUE self) | |
{ | |
struct olemethoddata *pmethod; | |
Data_Get_Struct(self, struct olemethoddata, pmethod); | |
@@ -5100,9 +7076,7 @@ folemethod_size_params(self) | |
} | |
static VALUE | |
-ole_method_size_opt_params(pTypeInfo, method_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
+ole_method_size_opt_params(ITypeInfo *pTypeInfo, UINT method_index) | |
{ | |
FUNCDESC *pFuncDesc; | |
HRESULT hr; | |
@@ -5125,8 +7099,7 @@ ole_method_size_opt_params(pTypeInfo, method_index) | |
* puts method.size_opt_params # => 4 | |
*/ | |
static VALUE | |
-folemethod_size_opt_params(self) | |
- VALUE self; | |
+folemethod_size_opt_params(VALUE self) | |
{ | |
struct olemethoddata *pmethod; | |
Data_Get_Struct(self, struct olemethoddata, pmethod); | |
@@ -5134,9 +7107,7 @@ folemethod_size_opt_params(self) | |
} | |
static VALUE | |
-ole_method_params(pTypeInfo, method_index) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
+ole_method_params(ITypeInfo *pTypeInfo, UINT method_index) | |
{ | |
FUNCDESC *pFuncDesc; | |
HRESULT hr; | |
@@ -5175,6 +7146,7 @@ ole_method_params(pTypeInfo, method_index) | |
return params; | |
} | |
+ | |
/* | |
* call-seq: | |
* WIN32OLE_METHOD#params | |
@@ -5188,8 +7160,7 @@ ole_method_params(pTypeInfo, method_index) | |
* TextVisualLayout] | |
*/ | |
static VALUE | |
-folemethod_params(self) | |
- VALUE self; | |
+folemethod_params(VALUE self) | |
{ | |
struct olemethoddata *pmethod; | |
Data_Get_Struct(self, struct olemethoddata, pmethod); | |
@@ -5197,6 +7168,19 @@ folemethod_params(self) | |
} | |
/* | |
+ * 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"); | |
+} | |
+ | |
+/* | |
* Document-class: WIN32OLE_PARAM | |
* | |
* <code>WIN32OLE_PARAM</code> objects represent param information of | |
@@ -5214,21 +7198,17 @@ folemethod_params(self) | |
* puts param1.name # => Filename | |
*/ | |
static VALUE | |
-foleparam_name(self) | |
- VALUE self; | |
+foleparam_name(VALUE self) | |
{ | |
return rb_ivar_get(self, rb_intern("name")); | |
} | |
static VALUE | |
-ole_param_ole_type(pTypeInfo, method_index, index) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
- UINT index; | |
+ole_param_ole_type(ITypeInfo *pTypeInfo, UINT method_index, UINT index) | |
{ | |
FUNCDESC *pFuncDesc; | |
HRESULT hr; | |
- VALUE type = rb_str_new2("UNKNOWN"); | |
+ VALUE type = rb_str_new2("unknown type"); | |
hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc); | |
if (FAILED(hr)) | |
return type; | |
@@ -5249,8 +7229,7 @@ ole_param_ole_type(pTypeInfo, method_index, index) | |
* puts param1.ole_type # => VARIANT | |
*/ | |
static VALUE | |
-foleparam_ole_type(self) | |
- VALUE self; | |
+foleparam_ole_type(VALUE self) | |
{ | |
struct oleparamdata *pparam; | |
Data_Get_Struct(self, struct oleparamdata, pparam); | |
@@ -5259,10 +7238,7 @@ foleparam_ole_type(self) | |
} | |
static VALUE | |
-ole_param_ole_type_detail(pTypeInfo, method_index, index) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
- UINT index; | |
+ole_param_ole_type_detail(ITypeInfo *pTypeInfo, UINT method_index, UINT index) | |
{ | |
FUNCDESC *pFuncDesc; | |
HRESULT hr; | |
@@ -5287,8 +7263,7 @@ ole_param_ole_type_detail(pTypeInfo, method_index, index) | |
* p param1.ole_type_detail # => ["PTR", "USERDEFINED", "Range"] | |
*/ | |
static VALUE | |
-foleparam_ole_type_detail(self) | |
- VALUE self; | |
+foleparam_ole_type_detail(VALUE self) | |
{ | |
struct oleparamdata *pparam; | |
Data_Get_Struct(self, struct oleparamdata, pparam); | |
@@ -5297,11 +7272,7 @@ foleparam_ole_type_detail(self) | |
} | |
static VALUE | |
-ole_param_flag_mask(pTypeInfo, method_index, index, mask) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
- UINT index; | |
- USHORT mask; | |
+ole_param_flag_mask(ITypeInfo *pTypeInfo, UINT method_index, UINT index, USHORT mask) | |
{ | |
FUNCDESC *pFuncDesc; | |
HRESULT hr; | |
@@ -5325,8 +7296,7 @@ ole_param_flag_mask(pTypeInfo, method_index, index, mask) | |
* param1 = method.params[0] | |
* puts param1.input? # => true | |
*/ | |
-static VALUE foleparam_input(self) | |
- VALUE self; | |
+static VALUE foleparam_input(VALUE self) | |
{ | |
struct oleparamdata *pparam; | |
Data_Get_Struct(self, struct oleparamdata, pparam); | |
@@ -5353,8 +7323,7 @@ static VALUE foleparam_input(self) | |
* Headers false | |
* Processed true | |
*/ | |
-static VALUE foleparam_output(self) | |
- VALUE self; | |
+static VALUE foleparam_output(VALUE self) | |
{ | |
struct oleparamdata *pparam; | |
Data_Get_Struct(self, struct oleparamdata, pparam); | |
@@ -5372,8 +7341,7 @@ static VALUE foleparam_output(self) | |
* param1 = method.params[0] | |
* puts "#{param1.name} #{param1.optional?}" # => Filename true | |
*/ | |
-static VALUE foleparam_optional(self) | |
- VALUE self; | |
+static VALUE foleparam_optional(VALUE self) | |
{ | |
struct oleparamdata *pparam; | |
Data_Get_Struct(self, struct oleparamdata, pparam); | |
@@ -5392,8 +7360,7 @@ static VALUE foleparam_optional(self) | |
* param = method.params[0] | |
* puts "#{param.name} #{param.retval?}" # => name true | |
*/ | |
-static VALUE foleparam_retval(self) | |
- VALUE self; | |
+static VALUE foleparam_retval(VALUE self) | |
{ | |
struct oleparamdata *pparam; | |
Data_Get_Struct(self, struct oleparamdata, pparam); | |
@@ -5402,10 +7369,7 @@ static VALUE foleparam_retval(self) | |
} | |
static VALUE | |
-ole_param_default(pTypeInfo, method_index, index) | |
- ITypeInfo *pTypeInfo; | |
- UINT method_index; | |
- UINT index; | |
+ole_param_default(ITypeInfo *pTypeInfo, UINT method_index, UINT index) | |
{ | |
FUNCDESC *pFuncDesc; | |
ELEMDESC *pElemDesc; | |
@@ -5456,8 +7420,7 @@ ole_param_default(pTypeInfo, method_index, index) | |
* TextCodepage | |
* TextVisualLayout | |
*/ | |
-static VALUE foleparam_default(self) | |
- VALUE self; | |
+static VALUE foleparam_default(VALUE self) | |
{ | |
struct oleparamdata *pparam; | |
Data_Get_Struct(self, struct oleparamdata, pparam); | |
@@ -5465,7 +7428,26 @@ static VALUE foleparam_default(self) | |
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_funcall(defval, rb_intern("inspect"), 0)); | |
+ } | |
+ return make_inspect("WIN32OLE_PARAM", detail); | |
+} | |
+ | |
/* | |
* Document-class: WIN32OLE_EVENT | |
* | |
@@ -5534,20 +7516,24 @@ STDMETHODIMP EVENTSINK_GetTypeInfo( | |
} | |
STDMETHODIMP EVENTSINK_GetIDsOfNames( | |
- PEVENTSINK pEV, | |
+ 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; | |
} | |
static long | |
-ole_search_event_at(ary, ev) | |
- VALUE ary; | |
- VALUE ev; | |
+ole_search_event_at(VALUE ary, VALUE ev) | |
{ | |
VALUE event; | |
VALUE def_event; | |
@@ -5555,7 +7541,7 @@ ole_search_event_at(ary, ev) | |
long i, len; | |
long ret = -1; | |
def_event = Qnil; | |
- len = RARRAY(ary)->len; | |
+ len = RARRAY_LEN(ary); | |
for(i = 0; i < len; i++) { | |
event = rb_ary_entry(ary, i); | |
event_name = rb_ary_entry(event, 1); | |
@@ -5574,18 +7560,15 @@ ole_search_event_at(ary, ev) | |
} | |
static VALUE | |
-ole_search_event(ary, ev, is_default) | |
- VALUE ary; | |
- VALUE ev; | |
- BOOL *is_default; | |
+ole_search_event(VALUE ary, VALUE ev, BOOL *is_default) | |
{ | |
VALUE event; | |
VALUE def_event; | |
VALUE event_name; | |
- long i, len; | |
+ int i, len; | |
*is_default = FALSE; | |
def_event = Qnil; | |
- len = RARRAY(ary)->len; | |
+ len = RARRAY_LEN(ary); | |
for(i = 0; i < len; i++) { | |
event = rb_ary_entry(ary, i); | |
event_name = rb_ary_entry(event, 1); | |
@@ -5600,92 +7583,114 @@ ole_search_event(ary, ev, is_default) | |
} | |
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%s", StringValuePtr(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 | |
-val2ptr_variant(val, var) | |
- VALUE val; | |
- VARIANT *var; | |
+ole_delete_event(VALUE ary, VALUE ev) | |
{ | |
- switch (TYPE(val)) { | |
- case T_STRING: | |
- if (V_VT(var) == (VT_BSTR | VT_BYREF)) { | |
- *V_BSTRREF(var) = ole_mb2wc(StringValuePtr(val), -1); | |
- } | |
- 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; | |
+ long at = -1; | |
+ at = ole_search_event_at(ary, ev); | |
+ if (at >= 0) { | |
+ rb_ary_delete_at(ary, at); | |
+ } | |
+} | |
+ | |
+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(ary, pdispparams) | |
- VALUE ary; | |
- DISPPARAMS *pdispparams; | |
+ary2ptr_dispparams(VALUE ary, DISPPARAMS *pdispparams) | |
{ | |
int i; | |
VALUE v; | |
VARIANT *pvar; | |
- for(i = 0; i < RARRAY(ary)->len && (unsigned int) i < pdispparams->cArgs; i++) { | |
+ 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]; | |
- val2ptr_variant(v, pvar); | |
+ 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("%s: %s (%s)\n", StringValuePtr(bt), StringValuePtr(msg), rb_obj_classname(e)); | |
+ rb_write_error(StringValuePtr(error)); | |
+ rb_backtrace(); | |
+ ruby_finalize(); | |
+ exit(-1); | |
+ | |
+ return Qnil; | |
+} | |
+ | |
STDMETHODIMP EVENTSINK_Invoke( | |
PEVENTSINK pEventSink, | |
DISPID dispid, | |
@@ -5704,13 +7709,17 @@ STDMETHODIMP EVENTSINK_Invoke( | |
unsigned int i; | |
ITypeInfo *pTypeInfo; | |
VARIANT *pvar; | |
- VALUE ary, obj, event, handler, args, argv, ev, result; | |
+ 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 = rb_ary_entry(ary_ole_event, pEV->m_event_id); | |
+ obj = evs_entry(pEV->m_event_id); | |
if (!rb_obj_is_kind_of(obj, cWIN32OLE_EVENT)) { | |
return NOERROR; | |
} | |
@@ -5726,9 +7735,21 @@ STDMETHODIMP EVENTSINK_Invoke( | |
} | |
ev = WC2VSTR(bstr); | |
event = ole_search_event(ary, ev, &is_default_handler); | |
- if (NIL_P(event)) { | |
- return NOERROR; | |
+ if (TYPE(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); | |
@@ -5739,16 +7760,31 @@ STDMETHODIMP EVENTSINK_Invoke( | |
pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1]; | |
rb_ary_push(args, ole_variant2val(pvar)); | |
} | |
- handler = rb_ary_entry(event, 0); | |
+ outargv = Qnil; | |
+ if (is_outarg == Qtrue) { | |
+ outargv = rb_ary_new(); | |
+ rb_ary_push(args, outargv); | |
+ } | |
- if (rb_ary_entry(event, 3) == Qtrue) { | |
- argv = rb_ary_new(); | |
- rb_ary_push(args, argv); | |
- result = rb_apply(handler, rb_intern("call"), args); | |
- ary2ptr_dispparams(argv, pdispparams); | |
+ /* | |
+ * 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); | |
} | |
- else { | |
- result = rb_apply(handler, rb_intern("call"), args); | |
+ if(TYPE(result) == T_HASH) { | |
+ hash2ptr_dispparams(result, pTypeInfo, dispid, pdispparams); | |
+ result = hash2result(result); | |
+ }else if (is_outarg == Qtrue && TYPE(outargv) == T_ARRAY) { | |
+ ary2ptr_dispparams(outargv, pdispparams); | |
} | |
if (pvarResult) { | |
@@ -5777,10 +7813,7 @@ EVENTSINK_Constructor() { | |
pEv->lpVtbl = &vtEventSink; | |
pEv->m_cRef = 0; | |
pEv->m_event_id = 0; | |
- pEv->m_dwCookie = 0; | |
- pEv->pConnectionPoint = NULL; | |
pEv->pTypeInfo = NULL; | |
- pEv->ptr_freed = NULL; | |
return pEv; | |
} | |
@@ -5788,17 +7821,14 @@ void EVENTSINK_Destructor( | |
PIEVENTSINKOBJ pEVObj | |
) { | |
if(pEVObj != NULL) { | |
- *(pEVObj->ptr_freed) = 1; | |
+ OLE_RELEASE(pEVObj->pTypeInfo); | |
free(pEVObj); | |
+ pEVObj = NULL; | |
} | |
} | |
static HRESULT | |
-find_iid(ole, pitf, piid, ppTypeInfo) | |
- VALUE ole; | |
- char *pitf; | |
- IID *piid; | |
- ITypeInfo **ppTypeInfo; | |
+find_iid(VALUE ole, char *pitf, IID *piid, ITypeInfo **ppTypeInfo) | |
{ | |
HRESULT hr; | |
IDispatch *pDispatch; | |
@@ -5817,7 +7847,7 @@ find_iid(ole, pitf, piid, ppTypeInfo) | |
char *pstr; | |
BOOL is_found = FALSE; | |
- LCID lcid = LOCALE_SYSTEM_DEFAULT; | |
+ LCID lcid = cWIN32OLE_lcid; | |
OLEData_Get_Struct(ole, pole); | |
@@ -5908,22 +7938,130 @@ find_iid(ole, pitf, piid, ppTypeInfo) | |
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(ole, piid, ppTypeInfo) | |
- VALUE ole; | |
- IID *piid; | |
- ITypeInfo **ppTypeInfo; | |
+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; | |
- int i; | |
- int iFlags; | |
- HREFTYPE hRefType; | |
+ TYPEATTR *pTypeAttr2 = NULL; | |
struct oledata *pole; | |
@@ -5931,58 +8069,52 @@ find_default_source(ole, piid, ppTypeInfo) | |
pDispatch = pole->pDispatch; | |
hr = pDispatch->lpVtbl->QueryInterface(pDispatch, | |
&IID_IProvideClassInfo2, | |
- (void**)&pProvideClassInfo2); | |
+ &p); | |
if (SUCCEEDED(hr)) { | |
+ pProvideClassInfo2 = p; | |
hr = pProvideClassInfo2->lpVtbl->GetGUID(pProvideClassInfo2, | |
GUIDKIND_DEFAULT_SOURCE_DISP_IID, | |
piid); | |
OLE_RELEASE(pProvideClassInfo2); | |
- return find_iid(ole, NULL, piid, ppTypeInfo); | |
+ if (SUCCEEDED(hr)) { | |
+ hr = find_iid(ole, NULL, piid, ppTypeInfo); | |
+ } | |
+ } | |
+ if (SUCCEEDED(hr)) { | |
+ return hr; | |
} | |
hr = pDispatch->lpVtbl->QueryInterface(pDispatch, | |
&IID_IProvideClassInfo, | |
- (void**)&pProvideClassInfo); | |
- if (FAILED(hr)) | |
- return hr; | |
- | |
- hr = pProvideClassInfo->lpVtbl->GetClassInfo(pProvideClassInfo, | |
- &pTypeInfo); | |
- OLE_RELEASE(pProvideClassInfo); | |
+ &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; | |
} | |
- /* Enumerate all implemented types of the COCLASS */ | |
- for (i = 0; i < pTypeAttr->cImplTypes; i++) { | |
- hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &iFlags); | |
- if (FAILED(hr)) | |
- continue; | |
- | |
- /* | |
- looking for the [default] [source] | |
- we just hope that it is a dispinterface :-) | |
- */ | |
- if ((iFlags & IMPLTYPEFLAG_FDEFAULT) && | |
- (iFlags & IMPLTYPEFLAG_FSOURCE)) { | |
- hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, | |
- i, &hRefType); | |
- if (FAILED(hr)) | |
- continue; | |
- hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, | |
- hRefType, ppTypeInfo); | |
- if (SUCCEEDED(hr)) | |
- break; | |
- } | |
+ *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)) | |
@@ -6004,72 +8136,45 @@ find_default_source(ole, piid, ppTypeInfo) | |
} | |
static void | |
-ole_event_free(poleev) | |
- struct oleeventdata *poleev; | |
+ole_event_free(struct oleeventdata *poleev) | |
{ | |
- ITypeInfo *pti = NULL; | |
- IConnectionPoint *pcp = NULL; | |
- | |
- if (poleev->freed == 1) { | |
- /* | |
- * this return create memory leak. | |
- * but poleev->pEvent->pConnectionPoint shoul'd not be freed | |
- * until poleev-> freed == 0. | |
- */ | |
- return; | |
- } | |
- if(poleev->pEvent) { | |
- pti = poleev->pEvent->pTypeInfo; | |
- if(pti) OLE_RELEASE(pti); | |
- pcp = poleev->pEvent->pConnectionPoint; | |
- if(pcp) { | |
- pcp->lpVtbl->Unadvise(pcp, poleev->pEvent->m_dwCookie); | |
- OLE_RELEASE(pcp); | |
- } | |
- free(poleev); | |
+ if (poleev->pConnectionPoint) { | |
+ poleev->pConnectionPoint->lpVtbl->Unadvise(poleev->pConnectionPoint, poleev->dwCookie); | |
+ OLE_RELEASE(poleev->pConnectionPoint); | |
+ poleev->pConnectionPoint = NULL; | |
} | |
+ free(poleev); | |
} | |
-static VALUE fev_s_allocate _((VALUE)); | |
static VALUE | |
-fev_s_allocate(klass) | |
- VALUE klass; | |
+fev_s_allocate(VALUE klass) | |
{ | |
VALUE obj; | |
struct oleeventdata *poleev; | |
obj = Data_Make_Struct(klass,struct oleeventdata,0,ole_event_free,poleev); | |
- poleev->pEvent = NULL; | |
+ poleev->dwCookie = 0; | |
+ poleev->pConnectionPoint = NULL; | |
+ poleev->event_id = 0; | |
return obj; | |
} | |
-/* | |
- * 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(argc, argv, self) | |
- int argc; | |
- VALUE *argv; | |
- VALUE self; | |
+ev_advise(int argc, VALUE *argv, VALUE self) | |
{ | |
+ | |
VALUE ole, itf; | |
struct oledata *pole; | |
char *pitf; | |
HRESULT hr; | |
IID iid; | |
- ITypeInfo *pTypeInfo; | |
+ ITypeInfo *pTypeInfo = 0; | |
IDispatch *pDispatch; | |
IConnectionPointContainer *pContainer; | |
IConnectionPoint *pConnectionPoint; | |
IEVENTSINKOBJ *pIEV; | |
- DWORD dwCookie = 0; | |
+ DWORD dwCookie; | |
struct oleeventdata *poleev; | |
+ void *p; | |
rb_secure(4); | |
rb_scan_args(argc, argv, "11", &ole, &itf); | |
@@ -6079,7 +8184,7 @@ fev_initialize(argc, argv, self) | |
} | |
if(TYPE(itf) != T_NIL) { | |
- if (ruby_safe_level > 0 && OBJ_TAINTED(itf)) { | |
+ if (rb_safe_level() > 0 && OBJ_TAINTED(itf)) { | |
rb_raise(rb_eSecurityError, "Insecure Event Creation - %s", | |
StringValuePtr(itf)); | |
} | |
@@ -6098,12 +8203,13 @@ fev_initialize(argc, argv, self) | |
pDispatch = pole->pDispatch; | |
hr = pDispatch->lpVtbl->QueryInterface(pDispatch, | |
&IID_IConnectionPointContainer, | |
- (void**)&pContainer); | |
+ &p); | |
if (FAILED(hr)) { | |
OLE_RELEASE(pTypeInfo); | |
ole_raise(hr, rb_eRuntimeError, | |
"failed to query IConnectionPointContainer"); | |
} | |
+ pContainer = p; | |
hr = pContainer->lpVtbl->FindConnectionPoint(pContainer, | |
&iid, | |
@@ -6123,15 +8229,33 @@ fev_initialize(argc, argv, self) | |
} | |
Data_Get_Struct(self, struct oleeventdata, poleev); | |
- poleev->pEvent = pIEV; | |
- poleev->pEvent->m_event_id | |
- = NUM2INT(rb_funcall(ary_ole_event, rb_intern("length"), 0)); | |
- poleev->pEvent->pConnectionPoint = pConnectionPoint; | |
- poleev->pEvent->pTypeInfo = pTypeInfo; | |
- poleev->pEvent->m_dwCookie = dwCookie; | |
- poleev->freed = 0; | |
- poleev->pEvent->ptr_freed = &(poleev->freed); | |
- rb_ary_push(ary_ole_event, self); | |
+ pIEV->m_event_id | |
+ = NUM2INT(evs_length()); | |
+ pIEV->pTypeInfo = pTypeInfo; | |
+ poleev->dwCookie = dwCookie; | |
+ poleev->pConnectionPoint = pConnectionPoint; | |
+ poleev->event_id = pIEV->m_event_id; | |
+ | |
+ 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; | |
} | |
@@ -6142,8 +8266,7 @@ fev_initialize(argc, argv, self) | |
* Translates and dispatches Windows message. | |
*/ | |
static VALUE | |
-fev_s_msg_loop(klass) | |
- VALUE klass; | |
+fev_s_msg_loop(VALUE klass) | |
{ | |
ole_msg_loop(); | |
return Qnil; | |
@@ -6151,35 +8274,34 @@ fev_s_msg_loop(klass) | |
static void | |
-add_event_call_back(obj, event, data) | |
- VALUE obj; | |
- VALUE event; | |
- VALUE data; | |
+add_event_call_back(VALUE obj, VALUE event, VALUE data) | |
{ | |
- long at; | |
VALUE events = rb_ivar_get(obj, id_events); | |
if (NIL_P(events) || TYPE(events) != T_ARRAY) { | |
events = rb_ary_new(); | |
rb_ivar_set(obj, id_events, events); | |
} | |
- at = ole_search_event_at(events, event); | |
- if (at > -1) { | |
- rb_ary_delete_at(events, at); | |
- } | |
+ ole_delete_event(events, event); | |
rb_ary_push(events, data); | |
} | |
static VALUE | |
-ev_on_event(argc, argv, self, is_ary_arg) | |
- int argc; | |
- VALUE *argv; | |
- VALUE self; | |
- VALUE is_ary_arg; | |
+ev_on_event(int argc, VALUE *argv, VALUE self, VALUE is_ary_arg) | |
{ | |
+ struct oleeventdata *poleev; | |
VALUE event, args, data; | |
+ Data_Get_Struct(self, struct oleeventdata, 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)) { | |
- Check_SafeStr(event); | |
+ if(TYPE(event) != T_STRING && TYPE(event) != T_SYMBOL) { | |
+ rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)"); | |
+ } | |
+ if (TYPE(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); | |
@@ -6192,15 +8314,31 @@ ev_on_event(argc, argv, self, is_ary_arg) | |
* | |
* 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, 'DWebBrowserEvents') | |
+ * 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(argc, argv, self) | |
- int argc; | |
- VALUE *argv; | |
- VALUE self; | |
+fev_on_event(int argc, VALUE *argv, VALUE self) | |
{ | |
return ev_on_event(argc, argv, self, Qfalse); | |
} | |
@@ -6211,26 +8349,619 @@ fev_on_event(argc, argv, self) | |
* | |
* Defines the callback of event. | |
* If you want modify argument in callback, | |
- * you should use this method instead of WIN32OLE_EVENT#on_event. | |
+ * 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(argc, argv, self) | |
- int argc; | |
- VALUE *argv; | |
- VALUE self; | |
+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_secure(4); | |
+ rb_scan_args(argc, argv, "01", &event); | |
+ if(!NIL_P(event)) { | |
+ if(TYPE(event) != T_STRING && TYPE(event) != T_SYMBOL) { | |
+ rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)"); | |
+ } | |
+ if (TYPE(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; | |
+ Data_Get_Struct(self, struct oleeventdata, 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; | |
+ } | |
+ 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 VALUE | |
+evs_length() | |
+{ | |
+ return rb_funcall(ary_ole_event, rb_intern("length"), 0); | |
+} | |
+ | |
+/* | |
+ * 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")); | |
+} | |
+ | |
+static void | |
+olevariant_free(struct olevariantdata *pvar) | |
+{ | |
+ VariantClear(&(pvar->realvar)); | |
+ VariantClear(&(pvar->var)); | |
+ free(pvar); | |
+} | |
+ | |
+static VALUE | |
+folevariant_s_allocate(VALUE klass) | |
+{ | |
+ struct olevariantdata *pvar; | |
+ VALUE obj; | |
+ ole_initialize(); | |
+ obj = Data_Make_Struct(klass,struct olevariantdata,0,olevariant_free,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); | |
+ | |
+ Data_Get_Struct(obj, struct olevariantdata, 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; | |
+} | |
+ | |
+/* | |
+ * 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); | |
+ | |
+ 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: | |
+ 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)); | |
+ } | |
+ } | |
+ | |
+ Data_Get_Struct(self, struct olevariantdata, pvar); | |
+ if (len == 1) { | |
+ ole_val2variant(val, &(pvar->var)); | |
+ } else { | |
+ vvt = rb_ary_entry(args, 1); | |
+ vt = NUM2INT(vvt); | |
+ ole_val2olevariantdata(val, vt, pvar); | |
+ } | |
+ vt = V_VT(&pvar->var); | |
+ return self; | |
+} | |
+ | |
+static SAFEARRAY * | |
+get_locked_safe_array(VALUE val) | |
+{ | |
+ struct olevariantdata *pvar; | |
+ SAFEARRAY *psa = NULL; | |
+ HRESULT hr; | |
+ Data_Get_Struct(val, struct olevariantdata, 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; | |
+ | |
+ Data_Get_Struct(self, struct olevariantdata, 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; | |
+} | |
+ | |
+static 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; | |
+} | |
+ | |
+/* | |
+ * 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; | |
+ | |
+ Data_Get_Struct(self, struct olevariantdata, 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; | |
+ Data_Get_Struct(self, struct olevariantdata, 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; | |
+ Data_Get_Struct(self, struct olevariantdata, 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; | |
+ Data_Get_Struct(self, struct olevariantdata, pvar); | |
+ vt = V_VT(&(pvar->var)); | |
+ if (V_ISARRAY(&(pvar->var)) && ((vt & ~VT_BYREF) != (VT_UI1|VT_ARRAY) || TYPE(val) != T_STRING)) { | |
+ rb_raise(eWIN32OLERuntimeError, | |
+ "`value=' is not available for this variant type object"); | |
+ } | |
+ ole_val2olevariantdata(val, vt, pvar); | |
+ return Qnil; | |
+} | |
+ | |
+static void | |
+init_enc2cp() | |
+{ | |
+ enc2cp_table = st_init_numtable(); | |
+} | |
+ | |
+static void | |
+free_enc2cp() | |
+{ | |
+ st_free_table(enc2cp_table); | |
+} | |
void | |
Init_win32ole() | |
{ | |
- rb_global_variable(&ary_ole_event); | |
ary_ole_event = rb_ary_new(); | |
+ rb_gc_register_mark_object(ary_ole_event); | |
id_events = rb_intern("events"); | |
- rb_global_variable(&com_hash); | |
com_vtbl.QueryInterface = QueryInterface; | |
com_vtbl.AddRef = AddRef; | |
com_vtbl.Release = Release; | |
@@ -6245,8 +8976,9 @@ Init_win32ole() | |
message_filter.HandleInComingCall = mf_HandleInComingCall; | |
message_filter.RetryRejectedCall = mf_RetryRejectedCall; | |
message_filter.MessagePending = mf_MessagePending; | |
- | |
+ | |
com_hash = Data_Wrap_Struct(rb_cData, rb_mark_hash, st_free_table, st_init_numtable()); | |
+ rb_gc_register_mark_object(com_hash); | |
cWIN32OLE = rb_define_class("WIN32OLE", rb_cObject); | |
@@ -6262,16 +8994,18 @@ Init_win32ole() | |
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_method(cWIN32OLE, "invoke", fole_invoke, -1); | |
- rb_define_method(cWIN32OLE, "[]", fole_getproperty, -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, -1); | |
+ rb_define_method(cWIN32OLE, "[]=", fole_setproperty_with_bracket, -1); | |
rb_define_method(cWIN32OLE, "ole_free", fole_free, 0); | |
@@ -6288,19 +9022,30 @@ Init_win32ole() | |
rb_define_method(cWIN32OLE, "ole_method", fole_method_help, 1); | |
rb_define_alias(cWIN32OLE, "ole_method_help", "ole_method"); | |
- rb_define_method(cWIN32OLE, "ole_obj_help", fole_obj_help, 0); | |
+ 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); | |
rb_define_const(cWIN32OLE, "VERSION", rb_str_new2(WIN32OLE_VERSION)); | |
rb_define_const(cWIN32OLE, "ARGV", rb_ary_new()); | |
- rb_define_const(cWIN32OLE, "CP_ACP" ,INT2FIX(CP_ACP)); | |
- rb_define_const(cWIN32OLE, "CP_OEMCP" ,INT2FIX(CP_OEMCP)); | |
- rb_define_const(cWIN32OLE, "CP_MACCP" ,INT2FIX(CP_MACCP)); | |
- rb_define_const(cWIN32OLE, "CP_THREAD_ACP",INT2FIX(CP_THREAD_ACP)); | |
- rb_define_const(cWIN32OLE, "CP_SYMBOL" ,INT2FIX(CP_SYMBOL)); | |
- rb_define_const(cWIN32OLE, "CP_UTF7" ,INT2FIX(CP_UTF7)); | |
- rb_define_const(cWIN32OLE, "CP_UTF8" ,INT2FIX(CP_UTF8)); | |
+ | |
+ rb_define_const(cWIN32OLE, "CP_ACP", INT2FIX(CP_ACP)); | |
+ rb_define_const(cWIN32OLE, "CP_OEMCP", INT2FIX(CP_OEMCP)); | |
+ rb_define_const(cWIN32OLE, "CP_MACCP", INT2FIX(CP_MACCP)); | |
+ rb_define_const(cWIN32OLE, "CP_THREAD_ACP", INT2FIX(CP_THREAD_ACP)); | |
+ rb_define_const(cWIN32OLE, "CP_SYMBOL", INT2FIX(CP_SYMBOL)); | |
+ rb_define_const(cWIN32OLE, "CP_UTF7", INT2FIX(CP_UTF7)); | |
+ rb_define_const(cWIN32OLE, "CP_UTF8", INT2FIX(CP_UTF8)); | |
+ | |
+ rb_define_const(cWIN32OLE, "LOCALE_SYSTEM_DEFAULT", INT2FIX(LOCALE_SYSTEM_DEFAULT)); | |
+ rb_define_const(cWIN32OLE, "LOCALE_USER_DEFAULT", INT2FIX(LOCALE_USER_DEFAULT)); | |
mWIN32OLE_VARIANT = rb_define_module_under(cWIN32OLE, "VARIANT"); | |
+ rb_define_const(mWIN32OLE_VARIANT, "VT_EMPTY", INT2FIX(VT_EMPTY)); | |
+ rb_define_const(mWIN32OLE_VARIANT, "VT_NULL", INT2FIX(VT_NULL)); | |
rb_define_const(mWIN32OLE_VARIANT, "VT_I2", INT2FIX(VT_I2)); | |
rb_define_const(mWIN32OLE_VARIANT, "VT_I4", INT2FIX(VT_I4)); | |
rb_define_const(mWIN32OLE_VARIANT, "VT_R4", INT2FIX(VT_R4)); | |
@@ -6319,10 +9064,30 @@ Init_win32ole() | |
rb_define_const(mWIN32OLE_VARIANT, "VT_UI1", INT2FIX(VT_UI1)); | |
rb_define_const(mWIN32OLE_VARIANT, "VT_UI2", INT2FIX(VT_UI2)); | |
rb_define_const(mWIN32OLE_VARIANT, "VT_UI4", INT2FIX(VT_UI4)); | |
+#if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__) | |
+ rb_define_const(mWIN32OLE_VARIANT, "VT_I8", INT2FIX(VT_I8)); | |
+ rb_define_const(mWIN32OLE_VARIANT, "VT_UI8", INT2FIX(VT_UI8)); | |
+#endif | |
rb_define_const(mWIN32OLE_VARIANT, "VT_INT", INT2FIX(VT_INT)); | |
rb_define_const(mWIN32OLE_VARIANT, "VT_UINT", INT2FIX(VT_UINT)); | |
rb_define_const(mWIN32OLE_VARIANT, "VT_ARRAY", INT2FIX(VT_ARRAY)); | |
rb_define_const(mWIN32OLE_VARIANT, "VT_BYREF", INT2FIX(VT_BYREF)); | |
+ | |
+ cWIN32OLE_TYPELIB = rb_define_class("WIN32OLE_TYPELIB", rb_cObject); | |
+ rb_define_singleton_method(cWIN32OLE_TYPELIB, "typelibs", foletypelib_s_typelibs, 0); | |
+ 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); | |
cWIN32OLE_TYPE = rb_define_class("WIN32OLE_TYPE", rb_cObject); | |
rb_define_singleton_method(cWIN32OLE_TYPE, "ole_classes", foletype_s_ole_classes, 1); | |
@@ -6336,7 +9101,6 @@ Init_win32ole() | |
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); | |
@@ -6345,7 +9109,13 @@ Init_win32ole() | |
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, -1); | |
+ 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); | |
cWIN32OLE_VARIABLE = rb_define_class("WIN32OLE_VARIABLE", rb_cObject); | |
rb_define_method(cWIN32OLE_VARIABLE, "name", folevariable_name, 0); | |
@@ -6355,12 +9125,12 @@ Init_win32ole() | |
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"); | |
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); | |
@@ -6379,6 +9149,7 @@ Init_win32ole() | |
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); | |
cWIN32OLE_PARAM = rb_define_class("WIN32OLE_PARAM", rb_cObject); | |
rb_define_method(cWIN32OLE_PARAM, "name", foleparam_name, 0); | |
@@ -6390,14 +9161,35 @@ Init_win32ole() | |
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); | |
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_singleton_method(cWIN32OLE_EVENT, "message_loop", fev_s_msg_loop, 0); | |
- | |
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); | |
- eWIN32OLE_RUNTIME_ERROR = rb_define_class("WIN32OLERuntimeError", rb_eRuntimeError); | |
+ 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); | |
+ | |
+ 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); | |
+ rb_define_const(cWIN32OLE_VARIANT, "Empty", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_EMPTY))); | |
+ rb_define_const(cWIN32OLE_VARIANT, "Null", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_NULL))); | |
+ rb_define_const(cWIN32OLE_VARIANT, "Nothing", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_DISPATCH))); | |
+ | |
+ eWIN32OLERuntimeError = rb_define_class("WIN32OLERuntimeError", rb_eRuntimeError); | |
+ | |
+ init_enc2cp(); | |
+ atexit((void (*)(void))free_enc2cp); | |
+ ole_init_cp(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment