2 * (c) 1995 Microsoft Corporation. All rights reserved.
3 * Developed by ActiveWare Internet Corp., http://www.ActiveWare.com
5 * Other modifications Copyright (c) 1997, 1998 by Gurusamy Sarathy
6 * <gsar@umich.edu> and Jan Dubois <jan.dubois@ibm.net>
8 * You may distribute under the terms of either the GNU General Public
9 * License or the Artistic License, as specified in the README file
10 * of the Perl distribution.
15 modified for win32ole (ruby) by Masaki.Suketa <masaki.suketa@nifty.ne.jp>
18 #include "ruby/ruby.h"
20 #include "ruby/encoding.h"
28 #ifdef HAVE_STDARG_PROTOTYPES
30 #define va_init_list(a,b) va_start(a,b)
33 #define va_init_list(a,b) va_start(a)
37 #define DOUT fprintf(stderr,"[%d]\n",__LINE__)
38 #define DOUTS(x) fprintf(stderr,"[%d]:" #x "=%s\n",__LINE__,x)
39 #define DOUTMSG(x) fprintf(stderr, "[%d]:" #x "\n",__LINE__)
40 #define DOUTI(x) fprintf(stderr, "[%ld]:" #x "=%d\n",__LINE__,x)
41 #define DOUTD(x) fprintf(stderr, "[%d]:" #x "=%f\n",__LINE__,x)
43 #if defined NONAMELESSUNION && __GNUC__
44 #define V_UNION1(X, Y) ((X)->u.Y)
46 #define V_UNION1(X, Y) ((X)->Y)
49 #if defined NONAMELESSUNION && __GNUC__
51 #define V_UNION(X,Y) ((X)->n1.n2.n3.Y)
54 #define V_VT(X) ((X)->n1.n2.vt)
57 #define V_BOOL(X) V_UNION(X,boolVal)
61 #define V_I1REF(X) V_UNION(X, pcVal)
65 #define V_UI2REF(X) V_UNION(X, puiVal)
69 #define V_INT(X) V_UNION(X, intVal)
73 #define V_INTREF(X) V_UNION(X, pintVal)
77 #define V_UINT(X) V_UNION(X, uintVal)
81 #define V_UINTREF(X) V_UNION(X, puintVal)
84 #define OLE_RELEASE(X) (X) ? ((X)->lpVtbl->Release(X)) : 0
86 #define OLE_ADDREF(X) (X) ? ((X)->lpVtbl->AddRef(X)) : 0
88 #define OLE_GET_TYPEATTR(X, Y) ((X)->lpVtbl->GetTypeAttr((X), (Y)))
89 #define OLE_RELEASE_TYPEATTR(X, Y) ((X)->lpVtbl->ReleaseTypeAttr((X), (Y)))
91 #define OLE_FREE(x) {\
92 if(g_ole_initialized == TRUE) {\
100 #define OLEData_Get_Struct(obj, pole) {\
101 Data_Get_Struct(obj, struct oledata, pole);\
102 if(!pole->pDispatch) {\
103 rb_raise(rb_eRuntimeError, "failed to get Dispatch Interface");\
107 #ifdef HAVE_LONG_LONG
108 #define I8_2_NUM LL2NUM
109 #define UI8_2_NUM ULL2NUM
110 #define NUM2I8 NUM2LL
111 #define NUM2UI8 NUM2ULL
113 #define I8_2_NUM INT2NUM
114 #define UI8_2_NUM UINT2NUM
115 #define NUM2I8 NUM2INT
116 #define NUM2UI8 NUM2UINT
119 #define WC2VSTR(x) ole_wc2vstr((x), TRUE)
121 #define WIN32OLE_VERSION "1.3.1"
123 typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX
)
124 (REFCLSID
, IUnknown
*, DWORD
, COSERVERINFO
*, DWORD
, MULTI_QI
*);
126 typedef HWND (WINAPI FNHTMLHELP
)(HWND hwndCaller
, LPCSTR pszFile
,
127 UINT uCommand
, DWORD dwData
);
128 typedef BOOL (FNENUMSYSEMCODEPAGES
) (CODEPAGE_ENUMPROC
, DWORD
);
130 struct IEventSinkVtbl
* lpVtbl
;
131 } IEventSink
, *PEVENTSINK
;
133 typedef struct IEventSinkVtbl IEventSinkVtbl
;
135 struct IEventSinkVtbl
{
136 STDMETHOD(QueryInterface
)(
140 STDMETHOD_(ULONG
, AddRef
)(PEVENTSINK
);
141 STDMETHOD_(ULONG
, Release
)(PEVENTSINK
);
143 STDMETHOD(GetTypeInfoCount
)(
146 STDMETHOD(GetTypeInfo
)(
151 STDMETHOD(GetIDsOfNames
)(
170 typedef struct tagIEVENTSINKOBJ
{
171 IEventSinkVtbl
*lpVtbl
;
175 ITypeInfo
*pTypeInfo
;
176 }IEVENTSINKOBJ
, *PIEVENTSINKOBJ
;
179 VALUE cWIN32OLE_TYPELIB
;
180 VALUE cWIN32OLE_TYPE
;
181 VALUE cWIN32OLE_VARIABLE
;
182 VALUE cWIN32OLE_METHOD
;
183 VALUE cWIN32OLE_PARAM
;
184 VALUE cWIN32OLE_EVENT
;
185 VALUE cWIN32OLE_VARIANT
;
186 VALUE eWIN32OLERuntimeError
;
187 VALUE mWIN32OLE_VARIANT
;
188 VALUE cWIN32OLE_PROPERTY
;
190 static VALUE ary_ole_event
;
192 static BOOL g_ole_initialized
= FALSE
;
193 static BOOL g_cp_installed
= FALSE
;
194 static BOOL g_lcid_installed
= FALSE
;
195 static HINSTANCE ghhctrl
= NULL
;
196 static HINSTANCE gole32
= NULL
;
197 static FNCOCREATEINSTANCEEX
*gCoCreateInstanceEx
= NULL
;
198 static VALUE com_hash
;
199 static IDispatchVtbl com_vtbl
;
200 static UINT cWIN32OLE_cp
= CP_ACP
;
201 static LCID cWIN32OLE_lcid
= LOCALE_SYSTEM_DEFAULT
;
202 static rb_encoding
*cWIN32OLE_enc
;
203 static UINT g_cp_to_check
= CP_ACP
;
204 static char g_lcid_to_check
[8 + 1];
205 static VARTYPE g_nil_to
= VT_ERROR
;
206 static st_table
*enc2cp_table
;
207 static IMessageFilterVtbl message_filter
;
208 static IMessageFilter imessage_filter
= { &message_filter
};
209 static IMessageFilter
* previous_filter
;
212 IDispatch
*pDispatch
;
216 ITypeInfo
*pTypeInfo
;
219 struct olemethoddata
{
220 ITypeInfo
*pOwnerTypeInfo
;
221 ITypeInfo
*pTypeInfo
;
225 struct olevariabledata
{
226 ITypeInfo
*pTypeInfo
;
230 struct oleparamdata
{
231 ITypeInfo
*pTypeInfo
;
236 struct oleeventdata
{
238 IConnectionPoint
*pConnectionPoint
;
244 OLECHAR
** pNamedArgs
;
247 struct olevariantdata
{
253 static HRESULT ( STDMETHODCALLTYPE QueryInterface
)(IDispatch __RPC_FAR
*, REFIID riid
, void __RPC_FAR
*__RPC_FAR
*ppvObject
);
254 static ULONG ( STDMETHODCALLTYPE AddRef
)(IDispatch __RPC_FAR
* This
);
255 static ULONG ( STDMETHODCALLTYPE Release
)(IDispatch __RPC_FAR
* This
);
256 static HRESULT ( STDMETHODCALLTYPE GetTypeInfoCount
)(IDispatch __RPC_FAR
* This
, UINT __RPC_FAR
*pctinfo
);
257 static HRESULT ( STDMETHODCALLTYPE GetTypeInfo
)(IDispatch __RPC_FAR
* This
, UINT iTInfo
, LCID lcid
, ITypeInfo __RPC_FAR
*__RPC_FAR
*ppTInfo
);
258 static HRESULT ( STDMETHODCALLTYPE GetIDsOfNames
)(IDispatch __RPC_FAR
* This
, REFIID riid
, LPOLESTR __RPC_FAR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID __RPC_FAR
*rgDispId
);
259 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
);
260 static IDispatch
* val2dispatch(VALUE val
);
261 static void time2d(int hh
, int mm
, int ss
, double *pv
);
262 static void d2time(double v
, int *hh
, int *mm
, int *ss
);
263 static void civil2jd(int y
, int m
, int d
, long *jd
);
264 static void jd2civil(long day
, int *yy
, int *mm
, int *dd
);
265 static void double2time(double v
, int *y
, int *m
, int *d
, int *hh
, int *mm
, int *ss
);
266 static double time_object2date(VALUE tmobj
);
267 static VALUE
date2time_str(double date
);
268 static rb_encoding
*ole_cp2encoding(UINT cp
);
269 static UINT
ole_encoding2cp(rb_encoding
*enc
);
270 static UINT
ole_init_cp();
271 static char *ole_wc2mb(LPWSTR pw
);
272 static VALUE
ole_hresult2msg(HRESULT hr
);
273 static void ole_freeexceptinfo(EXCEPINFO
*pExInfo
);
274 static VALUE
ole_excepinfo2msg(EXCEPINFO
*pExInfo
);
275 static void ole_raise(HRESULT hr
, VALUE ecs
, const char *fmt
, ...);
276 static void ole_initialize();
277 static void ole_msg_loop();
278 static void ole_free(struct oledata
*pole
);
279 static void oletype_free(struct oletypedata
*poletype
);
280 static void olemethod_free(struct olemethoddata
*polemethod
);
281 static void olevariable_free(struct olevariabledata
*polevar
);
282 static void oleparam_free(struct oleparamdata
*pole
);
283 static LPWSTR
ole_vstr2wc(VALUE vstr
);
284 static LPWSTR
ole_mb2wc(char *pm
, int len
);
285 static VALUE
ole_wc2vstr(LPWSTR pw
, BOOL isfree
);
286 static VALUE
ole_ary_m_entry(VALUE val
, long *pid
);
287 static void * get_ptr_of_variant(VARIANT
*pvar
);
288 static VALUE
is_all_index_under(long *pid
, long *pub
, long dim
);
289 static void ole_set_safe_array(long n
, SAFEARRAY
*psa
, long *pid
, long *pub
, VALUE val
, long dim
, VARTYPE vt
);
290 static long dimension(VALUE val
);
291 static long ary_len_of_dim(VALUE ary
, long dim
);
292 static HRESULT
ole_val_ary2variant_ary(VALUE val
, VARIANT
*var
, VARTYPE vt
);
293 static void ole_val2variant(VALUE val
, VARIANT
*var
);
294 static void ole_val2variant_ex(VALUE val
, VARIANT
*var
, VARTYPE vt
);
295 static void ole_val2ptr_variant(VALUE val
, VARIANT
*var
);
296 static void ole_set_byref(VARIANT
*realvar
, VARIANT
*var
, VARTYPE vt
);
297 static void ole_val2olevariantdata(VALUE val
, VARTYPE vt
, struct olevariantdata
*pvar
);
298 static void ole_val2variant2(VALUE val
, VARIANT
*var
);
299 static VALUE
make_inspect(const char *class_name
, VALUE detail
);
300 static VALUE
default_inspect(VALUE self
, const char *class_name
);
301 static VALUE
ole_set_member(VALUE self
, IDispatch
*dispatch
);
302 static VALUE
fole_s_allocate(VALUE klass
);
303 static VALUE
create_win32ole_object(VALUE klass
, IDispatch
*pDispatch
, int argc
, VALUE
*argv
);
304 static VALUE
ary_new_dim(VALUE myary
, long *pid
, long *plb
, long dim
);
305 static void ary_store_dim(VALUE myary
, long *pid
, long *plb
, long dim
, VALUE val
);
306 static VALUE
ole_variant2val(VARIANT
*pvar
);
307 static LONG
reg_open_key(HKEY hkey
, const char *name
, HKEY
*phkey
);
308 static LONG
reg_open_vkey(HKEY hkey
, VALUE key
, HKEY
*phkey
);
309 static VALUE
reg_enum_key(HKEY hkey
, DWORD i
);
310 static VALUE
reg_get_val(HKEY hkey
, const char *subkey
);
311 static VALUE
reg_get_typelib_file_path(HKEY hkey
);
312 static VALUE
typelib_file_from_clsid(VALUE ole
);
313 static VALUE
typelib_file_from_typelib(VALUE ole
);
314 static VALUE
typelib_file(VALUE ole
);
315 static void ole_const_load(ITypeLib
*pTypeLib
, VALUE klass
, VALUE self
);
316 static HRESULT
clsid_from_remote(VALUE host
, VALUE com
, CLSID
*pclsid
);
317 static VALUE
ole_create_dcom(int argc
, VALUE
*argv
, VALUE self
);
318 static VALUE
ole_bind_obj(VALUE moniker
, int argc
, VALUE
*argv
, VALUE self
);
319 static VALUE
fole_s_connect(int argc
, VALUE
*argv
, VALUE self
);
320 static VALUE
fole_s_const_load(int argc
, VALUE
*argv
, VALUE self
);
321 static VALUE
ole_types_from_typelib(ITypeLib
*pTypeLib
, VALUE classes
);
322 static ULONG
reference_count(struct oledata
* pole
);
323 static VALUE
fole_s_reference_count(VALUE self
, VALUE obj
);
324 static VALUE
fole_s_free(VALUE self
, VALUE obj
);
325 static HWND
ole_show_help(VALUE helpfile
, VALUE helpcontext
);
326 static VALUE
fole_s_show_help(int argc
, VALUE
*argv
, VALUE self
);
327 static VALUE
fole_s_get_code_page(VALUE self
);
328 static BOOL CALLBACK
installed_code_page_proc(LPTSTR str
);
329 static BOOL
code_page_installed(UINT cp
);
330 static VALUE
fole_s_set_code_page(VALUE self
, VALUE vcp
);
331 static VALUE
fole_s_get_locale(VALUE self
);
332 static BOOL CALLBACK
installed_lcid_proc(LPTSTR str
);
333 static BOOL
lcid_installed(LCID lcid
);
334 static VALUE
fole_s_set_locale(VALUE self
, VALUE vlcid
);
335 static VALUE
fole_s_create_guid(VALUE self
);
336 static VALUE
fole_initialize(int argc
, VALUE
*argv
, VALUE self
);
337 static VALUE
hash2named_arg(VALUE pair
, struct oleparam
* pOp
);
338 static VALUE
set_argv(VARIANTARG
* realargs
, unsigned int beg
, unsigned int end
);
339 static VALUE
ole_invoke(int argc
, VALUE
*argv
, VALUE self
, USHORT wFlags
, BOOL is_bracket
);
340 static VALUE
fole_invoke(int argc
, VALUE
*argv
, VALUE self
);
341 static VALUE
ole_invoke2(VALUE self
, VALUE dispid
, VALUE args
, VALUE types
, USHORT dispkind
);
342 static VALUE
fole_invoke2(VALUE self
, VALUE dispid
, VALUE args
, VALUE types
);
343 static VALUE
fole_getproperty2(VALUE self
, VALUE dispid
, VALUE args
, VALUE types
);
344 static VALUE
fole_setproperty2(VALUE self
, VALUE dispid
, VALUE args
, VALUE types
);
345 static VALUE
fole_setproperty_with_bracket(int argc
, VALUE
*argv
, VALUE self
);
346 static VALUE
fole_setproperty(int argc
, VALUE
*argv
, VALUE self
);
347 static VALUE
fole_getproperty_with_bracket(int argc
, VALUE
*argv
, VALUE self
);
348 static VALUE
ole_propertyput(VALUE self
, VALUE property
, VALUE value
);
349 static VALUE
fole_free(VALUE self
);
350 static VALUE
ole_each_sub(VALUE pEnumV
);
351 static VALUE
ole_ienum_free(VALUE pEnumV
);
352 static VALUE
fole_each(VALUE self
);
353 static VALUE
fole_missing(int argc
, VALUE
*argv
, VALUE self
);
354 static VALUE
ole_method_sub(VALUE self
, ITypeInfo
*pOwnerTypeInfo
, ITypeInfo
*pTypeInfo
, VALUE name
);
355 static VALUE
olemethod_from_typeinfo(VALUE self
, ITypeInfo
*pTypeInfo
, VALUE name
);
356 static VALUE
ole_methods_sub(ITypeInfo
*pOwnerTypeInfo
, ITypeInfo
*pTypeInfo
, VALUE methods
, int mask
);
357 static VALUE
ole_methods_from_typeinfo(ITypeInfo
*pTypeInfo
, int mask
);
358 static HRESULT
typeinfo_from_ole(struct oledata
*pole
, ITypeInfo
**ppti
);
359 static VALUE
ole_methods(VALUE self
, int mask
);
360 static VALUE
fole_methods(VALUE self
);
361 static VALUE
fole_get_methods(VALUE self
);
362 static VALUE
fole_put_methods(VALUE self
);
363 static VALUE
fole_func_methods(VALUE self
);
364 static VALUE
ole_type_from_itypeinfo(ITypeInfo
*pTypeInfo
);
365 static VALUE
fole_type(VALUE self
);
366 static VALUE
make_oletypelib_obj(VALUE guid
, VALUE major_version
, VALUE minor_version
);
367 static VALUE
ole_typelib_from_itypelib(ITypeLib
*pTypeLib
);
368 static VALUE
ole_typelib_from_itypeinfo(ITypeInfo
*pTypeInfo
);
369 static VALUE
fole_typelib(VALUE self
);
370 static VALUE
fole_query_interface(VALUE self
, VALUE str_iid
);
371 static VALUE
fole_respond_to(VALUE self
, VALUE method
);
372 static HRESULT
ole_docinfo_from_type(ITypeInfo
*pTypeInfo
, BSTR
*name
, BSTR
*helpstr
, DWORD
*helpcontext
, BSTR
*helpfile
);
373 static VALUE
ole_usertype2val(ITypeInfo
*pTypeInfo
, TYPEDESC
*pTypeDesc
, VALUE typedetails
);
374 static VALUE
ole_ptrtype2val(ITypeInfo
*pTypeInfo
, TYPEDESC
*pTypeDesc
, VALUE typedetails
);
375 static VALUE
ole_typedesc2val(ITypeInfo
*pTypeInfo
, TYPEDESC
*pTypeDesc
, VALUE typedetails
);
376 static VALUE
fole_method_help(VALUE self
, VALUE cmdname
);
377 static VALUE
fole_activex_initialize(VALUE self
);
378 static VALUE
foletype_s_ole_classes(VALUE self
, VALUE typelib
);
379 static VALUE
foletype_s_typelibs(VALUE self
);
380 static VALUE
foletype_s_progids(VALUE self
);
381 static VALUE
foletype_s_allocate(VALUE klass
);
382 static VALUE
oletype_set_member(VALUE self
, ITypeInfo
*pTypeInfo
, VALUE name
);
383 static VALUE
oleclass_from_typelib(VALUE self
, ITypeLib
*pTypeLib
, VALUE oleclass
);
384 static VALUE
oletypelib_set_member(VALUE self
, VALUE typelib
, VALUE guid
, VALUE version
);
385 static VALUE
foletypelib_s_typelibs(VALUE self
);
386 static VALUE
make_version_str(VALUE major
, VALUE minor
);
387 static VALUE
oletypelib_search_registry2(VALUE self
, VALUE args
);
388 static VALUE
oletypelib_search_registry(VALUE self
, VALUE typelib
);
389 static VALUE
foletypelib_initialize(VALUE self
, VALUE args
);
390 static VALUE
foletypelib_guid(VALUE self
);
391 static VALUE
foletypelib_name(VALUE self
);
392 static VALUE
foletypelib_version(VALUE self
);
393 static VALUE
foletypelib_major_version(VALUE self
);
394 static VALUE
foletypelib_minor_version(VALUE self
);
395 static VALUE
oletypelib_path(VALUE guid
, VALUE version
);
396 static VALUE
foletypelib_path(VALUE self
);
397 static void oletypelib2itypelib(VALUE self
, ITypeLib
**ppTypeLib
);
398 static VALUE
foletypelib_visible(VALUE self
);
399 static VALUE
foletypelib_library_name(VALUE self
);
400 static VALUE
foletypelib_ole_types(VALUE self
);
401 static VALUE
foletypelib_inspect(VALUE self
);
402 static VALUE
foletype_initialize(VALUE self
, VALUE typelib
, VALUE oleclass
);
403 static VALUE
foletype_name(VALUE self
);
404 static VALUE
ole_ole_type(ITypeInfo
*pTypeInfo
);
405 static VALUE
foletype_ole_type(VALUE self
);
406 static VALUE
ole_type_guid(ITypeInfo
*pTypeInfo
);
407 static VALUE
foletype_guid(VALUE self
);
408 static VALUE
ole_type_progid(ITypeInfo
*pTypeInfo
);
409 static VALUE
foletype_progid(VALUE self
);
410 static VALUE
ole_type_visible(ITypeInfo
*pTypeInfo
);
411 static VALUE
foletype_visible(VALUE self
);
412 static VALUE
ole_type_major_version(ITypeInfo
*pTypeInfo
);
413 static VALUE
foletype_major_version(VALUE self
);
414 static VALUE
ole_type_minor_version(ITypeInfo
*pTypeInfo
);
415 static VALUE
foletype_minor_version(VALUE self
);
416 static VALUE
ole_type_typekind(ITypeInfo
*pTypeInfo
);
417 static VALUE
foletype_typekind(VALUE self
);
418 static VALUE
ole_type_helpstring(ITypeInfo
*pTypeInfo
);
419 static VALUE
foletype_helpstring(VALUE self
);
420 static VALUE
ole_type_src_type(ITypeInfo
*pTypeInfo
);
421 static VALUE
foletype_src_type(VALUE self
);
422 static VALUE
ole_type_helpfile(ITypeInfo
*pTypeInfo
);
423 static VALUE
foletype_helpfile(VALUE self
);
424 static VALUE
ole_type_helpcontext(ITypeInfo
*pTypeInfo
);
425 static VALUE
foletype_helpcontext(VALUE self
);
426 static VALUE
foletype_ole_typelib(VALUE self
);
427 static VALUE
ole_type_impl_ole_types(ITypeInfo
*pTypeInfo
, int implflags
);
428 static VALUE
foletype_impl_ole_types(VALUE self
);
429 static VALUE
foletype_source_ole_types(VALUE self
);
430 static VALUE
foletype_default_event_sources(VALUE self
);
431 static VALUE
foletype_default_ole_types(VALUE self
);
432 static VALUE
foletype_inspect(VALUE self
);
433 static VALUE
ole_variables(ITypeInfo
*pTypeInfo
);
434 static VALUE
foletype_variables(VALUE self
);
435 static VALUE
foletype_methods(VALUE self
);
436 static VALUE
folevariable_name(VALUE self
);
437 static VALUE
ole_variable_ole_type(ITypeInfo
*pTypeInfo
, UINT var_index
);
438 static VALUE
folevariable_ole_type(VALUE self
);
439 static VALUE
ole_variable_ole_type_detail(ITypeInfo
*pTypeInfo
, UINT var_index
);
440 static VALUE
folevariable_ole_type_detail(VALUE self
);
441 static VALUE
ole_variable_value(ITypeInfo
*pTypeInfo
, UINT var_index
);
442 static VALUE
folevariable_value(VALUE self
);
443 static VALUE
ole_variable_visible(ITypeInfo
*pTypeInfo
, UINT var_index
);
444 static VALUE
folevariable_visible(VALUE self
);
445 static VALUE
ole_variable_kind(ITypeInfo
*pTypeInfo
, UINT var_index
);
446 static VALUE
folevariable_variable_kind(VALUE self
);
447 static VALUE
ole_variable_varkind(ITypeInfo
*pTypeInfo
, UINT var_index
);
448 static VALUE
folevariable_varkind(VALUE self
);
449 static VALUE
folevariable_inspect(VALUE self
);
450 static VALUE
olemethod_set_member(VALUE self
, ITypeInfo
*pTypeInfo
, ITypeInfo
*pOwnerTypeInfo
, int index
, VALUE name
);
451 static VALUE
folemethod_s_allocate(VALUE klass
);
452 static VALUE
folemethod_initialize(VALUE self
, VALUE oletype
, VALUE method
);
453 static VALUE
folemethod_name(VALUE self
);
454 static VALUE
ole_method_return_type(ITypeInfo
*pTypeInfo
, UINT method_index
);
455 static VALUE
folemethod_return_type(VALUE self
);
456 static VALUE
ole_method_return_vtype(ITypeInfo
*pTypeInfo
, UINT method_index
);
457 static VALUE
folemethod_return_vtype(VALUE self
);
458 static VALUE
ole_method_return_type_detail(ITypeInfo
*pTypeInfo
, UINT method_index
);
459 static VALUE
folemethod_return_type_detail(VALUE self
);
460 static VALUE
ole_method_invkind(ITypeInfo
*pTypeInfo
, UINT method_index
);
461 static VALUE
ole_method_invoke_kind(ITypeInfo
*pTypeInfo
, UINT method_index
);
462 static VALUE
folemethod_invkind(VALUE self
);
463 static VALUE
folemethod_invoke_kind(VALUE self
);
464 static VALUE
ole_method_visible(ITypeInfo
*pTypeInfo
, UINT method_index
);
465 static VALUE
folemethod_visible(VALUE self
);
466 static VALUE
ole_method_event(ITypeInfo
*pTypeInfo
, UINT method_index
, VALUE method_name
);
467 static VALUE
folemethod_event(VALUE self
);
468 static VALUE
folemethod_event_interface(VALUE self
);
469 static VALUE
ole_method_docinfo_from_type(ITypeInfo
*pTypeInfo
, UINT method_index
, BSTR
*name
, BSTR
*helpstr
, DWORD
*helpcontext
, BSTR
*helpfile
);
470 static VALUE
ole_method_helpstring(ITypeInfo
*pTypeInfo
, UINT method_index
);
471 static VALUE
folemethod_helpstring(VALUE self
);
472 static VALUE
ole_method_helpfile(ITypeInfo
*pTypeInfo
, UINT method_index
);
473 static VALUE
folemethod_helpfile(VALUE self
);
474 static VALUE
ole_method_helpcontext(ITypeInfo
*pTypeInfo
, UINT method_index
);
475 static VALUE
folemethod_helpcontext(VALUE self
);
476 static VALUE
ole_method_dispid(ITypeInfo
*pTypeInfo
, UINT method_index
);
477 static VALUE
folemethod_dispid(VALUE self
);
478 static VALUE
ole_method_offset_vtbl(ITypeInfo
*pTypeInfo
, UINT method_index
);
479 static VALUE
folemethod_offset_vtbl(VALUE self
);
480 static VALUE
ole_method_size_params(ITypeInfo
*pTypeInfo
, UINT method_index
);
481 static VALUE
folemethod_size_params(VALUE self
);
482 static VALUE
ole_method_size_opt_params(ITypeInfo
*pTypeInfo
, UINT method_index
);
483 static VALUE
folemethod_size_opt_params(VALUE self
);
484 static VALUE
ole_method_params(ITypeInfo
*pTypeInfo
, UINT method_index
);
485 static VALUE
folemethod_params(VALUE self
);
486 static VALUE
folemethod_inspect(VALUE self
);
487 static VALUE
foleparam_name(VALUE self
);
488 static VALUE
ole_param_ole_type(ITypeInfo
*pTypeInfo
, UINT method_index
, UINT index
);
489 static VALUE
foleparam_ole_type(VALUE self
);
490 static VALUE
ole_param_ole_type_detail(ITypeInfo
*pTypeInfo
, UINT method_index
, UINT index
);
491 static VALUE
foleparam_ole_type_detail(VALUE self
);
492 static VALUE
ole_param_flag_mask(ITypeInfo
*pTypeInfo
, UINT method_index
, UINT index
, USHORT mask
);
493 static VALUE
foleparam_input(VALUE self
);
494 static VALUE
foleparam_output(VALUE self
);
495 static VALUE
foleparam_optional(VALUE self
);
496 static VALUE
foleparam_retval(VALUE self
);
497 static VALUE
ole_param_default(ITypeInfo
*pTypeInfo
, UINT method_index
, UINT index
);
498 static VALUE
foleparam_default(VALUE self
);
499 static VALUE
foleparam_inspect(VALUE self
);
500 static long ole_search_event_at(VALUE ary
, VALUE ev
);
501 static VALUE
ole_search_event(VALUE ary
, VALUE ev
, BOOL
*is_default
);
502 static VALUE
ole_search_handler_method(VALUE handler
, VALUE ev
, BOOL
*is_default_handler
);
503 static void ole_delete_event(VALUE ary
, VALUE ev
);
504 static void hash2ptr_dispparams(VALUE hash
, ITypeInfo
*pTypeInfo
, DISPID dispid
, DISPPARAMS
*pdispparams
);
505 static VALUE
hash2result(VALUE hash
);
506 static void ary2ptr_dispparams(VALUE ary
, DISPPARAMS
*pdispparams
);
507 static VALUE
exec_callback(VALUE arg
);
508 static VALUE
rescue_callback(VALUE arg
);
509 static HRESULT
find_iid(VALUE ole
, char *pitf
, IID
*piid
, ITypeInfo
**ppTypeInfo
);
510 static HRESULT
find_coclass(ITypeInfo
*pTypeInfo
, TYPEATTR
*pTypeAttr
, ITypeInfo
**pTypeInfo2
, TYPEATTR
**pTypeAttr2
);
511 static HRESULT
find_default_source_from_typeinfo(ITypeInfo
*pTypeInfo
, TYPEATTR
*pTypeAttr
, ITypeInfo
**ppTypeInfo
);
512 static HRESULT
find_default_source(VALUE ole
, IID
*piid
, ITypeInfo
**ppTypeInfo
);
513 static void ole_event_free(struct oleeventdata
*poleev
);
514 static VALUE
fev_s_allocate(VALUE klass
);
515 static VALUE
ev_advise(int argc
, VALUE
*argv
, VALUE self
);
516 static VALUE
fev_initialize(int argc
, VALUE
*argv
, VALUE self
);
517 static VALUE
fev_s_msg_loop(VALUE klass
);
518 static void add_event_call_back(VALUE obj
, VALUE event
, VALUE data
);
519 static VALUE
ev_on_event(int argc
, VALUE
*argv
, VALUE self
, VALUE is_ary_arg
);
520 static VALUE
fev_on_event(int argc
, VALUE
*argv
, VALUE self
);
521 static VALUE
fev_on_event_with_outargs(int argc
, VALUE
*argv
, VALUE self
);
522 static VALUE
fev_off_event(int argc
, VALUE
*argv
, VALUE self
);
523 static VALUE
fev_unadvise(VALUE self
);
524 static VALUE
fev_set_handler(VALUE self
, VALUE val
);
525 static VALUE
fev_get_handler(VALUE self
);
526 static VALUE
evs_push(VALUE ev
);
527 static VALUE
evs_delete(long i
);
528 static VALUE
evs_entry(long i
);
529 static VALUE
evs_length();
530 static void olevariant_free(struct olevariantdata
*pvar
);
531 static VALUE
folevariant_s_allocate(VALUE klass
);
532 static VALUE
folevariant_s_array(VALUE klass
, VALUE dims
, VALUE vvt
);
533 static VALUE
folevariant_initialize(VALUE self
, VALUE args
);
534 static long *ary2safe_array_index(int ary_size
, VALUE
*ary
, SAFEARRAY
*psa
);
535 static void unlock_safe_array(SAFEARRAY
*psa
);
536 static SAFEARRAY
*get_locked_safe_array(VALUE val
);
537 static VALUE
folevariant_ary_aref(int argc
, VALUE
*argv
, VALUE self
);
538 static VOID
* val2variant_ptr(VALUE val
, VARIANT
*var
, VARTYPE vt
);
539 static VALUE
folevariant_ary_aset(int argc
, VALUE
*argv
, VALUE self
);
540 static VALUE
folevariant_value(VALUE self
);
541 static VALUE
folevariant_vartype(VALUE self
);
542 static VALUE
folevariant_set_value(VALUE self
, VALUE val
);
543 static void init_enc2cp();
544 static void free_enc2cp();
546 static HRESULT (STDMETHODCALLTYPE mf_QueryInterface
)(
547 IMessageFilter __RPC_FAR
* This
,
548 /* [in] */ REFIID riid
,
549 /* [iid_is][out] */ void __RPC_FAR
*__RPC_FAR
*ppvObject
)
551 if (MEMCMP(riid
, &IID_IUnknown
, GUID
, 1) == 0
552 || MEMCMP(riid
, &IID_IMessageFilter
, GUID
, 1) == 0)
554 *ppvObject
= &message_filter
;
557 return E_NOINTERFACE
;
560 static ULONG (STDMETHODCALLTYPE mf_AddRef
)(
561 IMessageFilter __RPC_FAR
* This
)
566 static ULONG (STDMETHODCALLTYPE mf_Release
)(
567 IMessageFilter __RPC_FAR
* This
)
572 static DWORD (STDMETHODCALLTYPE mf_HandleInComingCall
)(
573 IMessageFilter __RPC_FAR
* pThis
,
574 DWORD dwCallType
, //Type of incoming call
575 HTASK threadIDCaller
, //Task handle calling this task
576 DWORD dwTickCount
, //Elapsed tick count
577 LPINTERFACEINFO lpInterfaceInfo
//Pointer to INTERFACEINFO structure
580 #ifdef DEBUG_MESSAGEFILTER
581 printf("incoming %08X, %08X, %d\n", dwCallType
, threadIDCaller
, dwTickCount
);
587 case CALLTYPE_TOPLEVEL_CALLPENDING
:
588 case CALLTYPE_ASYNC_CALLPENDING
:
589 if (rb_during_gc()) {
590 return SERVERCALL_RETRYLATER
;
596 if (previous_filter
) {
597 return previous_filter
->lpVtbl
->HandleInComingCall(previous_filter
,
603 return SERVERCALL_ISHANDLED
;
606 static DWORD (STDMETHODCALLTYPE mf_RetryRejectedCall
)(
607 IMessageFilter
* pThis
,
608 HTASK threadIDCallee
, //Server task handle
609 DWORD dwTickCount
, //Elapsed tick count
610 DWORD dwRejectType
//Returned rejection message
613 if (previous_filter
) {
614 return previous_filter
->lpVtbl
->RetryRejectedCall(previous_filter
,
622 static DWORD (STDMETHODCALLTYPE mf_MessagePending
)(
623 IMessageFilter
* pThis
,
624 HTASK threadIDCallee
, //Called applications task handle
625 DWORD dwTickCount
, //Elapsed tick count
626 DWORD dwPendingType
//Call type
629 if (rb_during_gc()) {
630 return PENDINGMSG_WAITNOPROCESS
;
632 if (previous_filter
) {
633 return previous_filter
->lpVtbl
->MessagePending(previous_filter
,
638 return PENDINGMSG_WAITNOPROCESS
;
641 typedef struct _Win32OLEIDispatch
648 static HRESULT ( STDMETHODCALLTYPE QueryInterface
)(
649 IDispatch __RPC_FAR
* This
,
650 /* [in] */ REFIID riid
,
651 /* [iid_is][out] */ void __RPC_FAR
*__RPC_FAR
*ppvObject
)
653 if (MEMCMP(riid
, &IID_IUnknown
, GUID
, 1) == 0
654 || MEMCMP(riid
, &IID_IDispatch
, GUID
, 1) == 0)
656 Win32OLEIDispatch
* p
= (Win32OLEIDispatch
*)This
;
661 return E_NOINTERFACE
;
664 static ULONG ( STDMETHODCALLTYPE AddRef
)(
665 IDispatch __RPC_FAR
* This
)
667 Win32OLEIDispatch
* p
= (Win32OLEIDispatch
*)This
;
668 return ++(p
->refcount
);
671 static ULONG ( STDMETHODCALLTYPE Release
)(
672 IDispatch __RPC_FAR
* This
)
674 Win32OLEIDispatch
* p
= (Win32OLEIDispatch
*)This
;
675 ULONG u
= --(p
->refcount
);
677 st_data_t key
= p
->obj
;
678 st_delete(DATA_PTR(com_hash
), &key
, 0);
684 static HRESULT ( STDMETHODCALLTYPE GetTypeInfoCount
)(
685 IDispatch __RPC_FAR
* This
,
686 /* [out] */ UINT __RPC_FAR
*pctinfo
)
691 static HRESULT ( STDMETHODCALLTYPE GetTypeInfo
)(
692 IDispatch __RPC_FAR
* This
,
693 /* [in] */ UINT iTInfo
,
694 /* [in] */ LCID lcid
,
695 /* [out] */ ITypeInfo __RPC_FAR
*__RPC_FAR
*ppTInfo
)
701 static HRESULT ( STDMETHODCALLTYPE GetIDsOfNames
)(
702 IDispatch __RPC_FAR
* This
,
703 /* [in] */ REFIID riid
,
704 /* [size_is][in] */ LPOLESTR __RPC_FAR
*rgszNames
,
705 /* [in] */ UINT cNames
,
706 /* [in] */ LCID lcid
,
707 /* [size_is][out] */ DISPID __RPC_FAR
*rgDispId
)
710 Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
712 char* psz
= ole_wc2mb(*rgszNames
); // support only one method
713 *rgDispId
= rb_intern(psz
);
718 static /* [local] */ HRESULT ( STDMETHODCALLTYPE Invoke
)(
719 IDispatch __RPC_FAR
* This
,
720 /* [in] */ DISPID dispIdMember
,
721 /* [in] */ REFIID riid
,
722 /* [in] */ LCID lcid
,
723 /* [in] */ WORD wFlags
,
724 /* [out][in] */ DISPPARAMS __RPC_FAR
*pDispParams
,
725 /* [out] */ VARIANT __RPC_FAR
*pVarResult
,
726 /* [out] */ EXCEPINFO __RPC_FAR
*pExcepInfo
,
727 /* [out] */ UINT __RPC_FAR
*puArgErr
)
731 int args
= pDispParams
->cArgs
;
732 Win32OLEIDispatch
* p
= (Win32OLEIDispatch
*)This
;
733 VALUE
* parg
= ALLOCA_N(VALUE
, args
);
734 for (i
= 0; i
< args
; i
++) {
735 *(parg
+ i
) = ole_variant2val(&pDispParams
->rgvarg
[args
- i
- 1]);
737 if (dispIdMember
== DISPID_VALUE
) {
738 if (wFlags
== DISPATCH_METHOD
) {
739 dispIdMember
= rb_intern("call");
740 } else if (wFlags
& DISPATCH_PROPERTYGET
) {
741 dispIdMember
= rb_intern("value");
744 v
= rb_funcall2(p
->obj
, dispIdMember
, args
, parg
);
745 ole_val2variant(v
, pVarResult
);
750 val2dispatch(VALUE val
)
752 struct st_table
*tbl
= DATA_PTR(com_hash
);
753 Win32OLEIDispatch
* pdisp
;
756 if (st_lookup(tbl
, val
, &data
)) {
757 pdisp
= (Win32OLEIDispatch
*)(data
& ~FIXNUM_FLAG
);
761 pdisp
= ALLOC(Win32OLEIDispatch
);
762 pdisp
->dispatch
.lpVtbl
= &com_vtbl
;
765 st_insert(tbl
, val
, (VALUE
)pdisp
| FIXNUM_FLAG
);
767 return &pdisp
->dispatch
;
771 time2d(int hh
, int mm
, int ss
, double *pv
)
773 *pv
= (hh
* 60.0 * 60.0 + mm
* 60.0 + ss
) / 86400.0;
777 d2time(double v
, int *hh
, int *mm
, int *ss
)
779 double d_hh
, d_mm
, d_ss
;
780 int i_hh
, i_mm
, i_ss
;
782 double d
= fabs(v
* 86400.0);
787 d
= d
- i_hh
* 3600.0;
796 i_ss
= (int)d_ss
/ 10;
817 civil2jd(int y
, int m
, int d
, long *jd
)
824 a
= (long)(y
/ 100.0);
825 b
= 2 - a
+ (long)(a
/ 4.0);
826 *jd
= (long)(365.25 * (double)(y
+ 4716))
827 + (long)(30.6001 * (m
+ 1))
832 jd2civil(long day
, int *yy
, int *mm
, int *dd
)
834 long x
, a
, b
, c
, d
, e
;
835 x
= (long)(((double)day
- 1867216.25) / 36524.25);
836 a
= day
+ 1 + x
- (long)(x
/ 4.0);
838 c
= (long)(((double)b
-122.1) /365.25);
839 d
= (long)(365.25 * c
);
840 e
= (long)((double)(b
- d
) / 30.6001);
841 *dd
= b
- d
- (long)(30.6001 * e
);
853 double2time(double v
, int *y
, int *m
, int *d
, int *hh
, int *mm
, int *ss
)
860 jd2civil(2415019 + day
, y
, m
, d
);
862 d2time(t
, hh
, mm
, ss
);
866 time_object2date(VALUE tmobj
)
868 long y
, m
, d
, hh
, mm
, ss
;
871 y
= FIX2INT(rb_funcall(tmobj
, rb_intern("year"), 0));
872 m
= FIX2INT(rb_funcall(tmobj
, rb_intern("month"), 0));
873 d
= FIX2INT(rb_funcall(tmobj
, rb_intern("mday"), 0));
874 hh
= FIX2INT(rb_funcall(tmobj
, rb_intern("hour"), 0));
875 mm
= FIX2INT(rb_funcall(tmobj
, rb_intern("min"), 0));
876 ss
= FIX2INT(rb_funcall(tmobj
, rb_intern("sec"), 0));
877 civil2jd(y
, m
, d
, &day
);
878 time2d(hh
, mm
, ss
, &t
);
879 return t
+ day
- 2415019;
883 date2time_str(double date
)
885 int y
, m
, d
, hh
, mm
, ss
;
886 double2time(date
, &y
, &m
, &d
, &hh
, &mm
, &ss
);
888 "%04d/%02d/%02d %02d:%02d:%02d",
889 y
, m
, d
, hh
, mm
, ss
);
892 #define ENC_MACHING_CP(enc,encname,cp) if(strcasecmp(rb_enc_name((enc)),(encname)) == 0) return cp
894 static UINT
ole_encoding2cp(rb_encoding
*enc
)
897 * Is there any better solution to convert
898 * Ruby encoding to Windows codepage???
900 ENC_MACHING_CP(enc
, "Big5", 950);
901 ENC_MACHING_CP(enc
, "CP51932", 51932);
902 ENC_MACHING_CP(enc
, "CP850", 850);
903 ENC_MACHING_CP(enc
, "CP852", 852);
904 ENC_MACHING_CP(enc
, "CP855", 855);
905 ENC_MACHING_CP(enc
, "CP949", 949);
906 ENC_MACHING_CP(enc
, "EUC-JP", 20932);
907 ENC_MACHING_CP(enc
, "EUC-KR", 51949);
908 ENC_MACHING_CP(enc
, "EUC-TW", 51950);
909 ENC_MACHING_CP(enc
, "GB18030", 54936);
910 ENC_MACHING_CP(enc
, "GB2312", 51936);
911 ENC_MACHING_CP(enc
, "GBK", 936);
912 ENC_MACHING_CP(enc
, "IBM437", 437);
913 ENC_MACHING_CP(enc
, "IBM737", 737);
914 ENC_MACHING_CP(enc
, "IBM775", 775);
915 ENC_MACHING_CP(enc
, "IBM852", 852);
916 ENC_MACHING_CP(enc
, "IBM855", 855);
917 ENC_MACHING_CP(enc
, "IBM857", 857);
918 ENC_MACHING_CP(enc
, "IBM860", 860);
919 ENC_MACHING_CP(enc
, "IBM861", 861);
920 ENC_MACHING_CP(enc
, "IBM862", 862);
921 ENC_MACHING_CP(enc
, "IBM863", 863);
922 ENC_MACHING_CP(enc
, "IBM864", 864);
923 ENC_MACHING_CP(enc
, "IBM865", 865);
924 ENC_MACHING_CP(enc
, "IBM866", 866);
925 ENC_MACHING_CP(enc
, "IBM869", 869);
926 ENC_MACHING_CP(enc
, "ISO-2022-JP", 50220);
927 ENC_MACHING_CP(enc
, "ISO-8859-1", 28591);
928 ENC_MACHING_CP(enc
, "ISO-8859-15", 28605);
929 ENC_MACHING_CP(enc
, "ISO-8859-2", 28592);
930 ENC_MACHING_CP(enc
, "ISO-8859-3", 28593);
931 ENC_MACHING_CP(enc
, "ISO-8859-4", 28594);
932 ENC_MACHING_CP(enc
, "ISO-8859-5", 28595);
933 ENC_MACHING_CP(enc
, "ISO-8859-6", 28596);
934 ENC_MACHING_CP(enc
, "ISO-8859-7", 28597);
935 ENC_MACHING_CP(enc
, "ISO-8859-8", 28598);
936 ENC_MACHING_CP(enc
, "ISO-8859-9", 28599);
937 ENC_MACHING_CP(enc
, "KOI8-R", 20866);
938 ENC_MACHING_CP(enc
, "KOI8-U", 21866);
939 ENC_MACHING_CP(enc
, "Shift_JIS", 932);
940 ENC_MACHING_CP(enc
, "UTF-16BE", 1201);
941 ENC_MACHING_CP(enc
, "UTF-16LE", 1200);
942 ENC_MACHING_CP(enc
, "UTF-7", 65000);
943 ENC_MACHING_CP(enc
, "UTF-8", 65001);
944 ENC_MACHING_CP(enc
, "Windows-1250", 1250);
945 ENC_MACHING_CP(enc
, "Windows-1251", 1251);
946 ENC_MACHING_CP(enc
, "Windows-1252", 1252);
947 ENC_MACHING_CP(enc
, "Windows-1253", 1253);
948 ENC_MACHING_CP(enc
, "Windows-1254", 1254);
949 ENC_MACHING_CP(enc
, "Windows-1255", 1255);
950 ENC_MACHING_CP(enc
, "Windows-1256", 1256);
951 ENC_MACHING_CP(enc
, "Windows-1257", 1257);
952 ENC_MACHING_CP(enc
, "Windows-1258", 1258);
953 ENC_MACHING_CP(enc
, "Windows-31J", 932);
954 ENC_MACHING_CP(enc
, "Windows-874", 874);
955 ENC_MACHING_CP(enc
, "eucJP-ms", 20932);
964 encdef
= rb_default_external_encoding();
965 cp
= ole_encoding2cp(encdef
);
966 if (code_page_installed(cp
)) {
976 WCHAR UnicodeDefaultChar
;
978 char CodePageName
[MAX_PATH
];
982 ole_cp2encoding(UINT cp
)
984 static BOOL (*pGetCPInfoEx
)(UINT
, DWORD
, struct myCPINFOEX
*) = NULL
;
985 struct myCPINFOEX
* buf
;
990 if (!code_page_installed(cp
)) {
1000 if (!pGetCPInfoEx
) {
1001 pGetCPInfoEx
= (BOOL (*)(UINT
, DWORD
, struct myCPINFOEX
*))
1002 GetProcAddress(GetModuleHandle("kernel32"), "GetCPInfoEx");
1003 if (!pGetCPInfoEx
) {
1004 pGetCPInfoEx
= (void*)-1;
1007 buf
= ALLOCA_N(struct myCPINFOEX
, 1);
1008 ZeroMemory(buf
, sizeof(struct myCPINFOEX
));
1009 if (pGetCPInfoEx
== (void*)-1 || !pGetCPInfoEx(cp
, 0, buf
)) {
1010 rb_raise(eWIN32OLERuntimeError
, "cannot map codepage to encoding.");
1011 break; /* never reach here */
1021 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.");
1026 enc_name
= rb_sprintf("CP%d", cp
);
1027 idx
= rb_enc_find_index(enc_cstr
= StringValueCStr(enc_name
));
1029 idx
= rb_define_dummy_encoding(enc_cstr
);
1030 return rb_enc_from_index(idx
);
1034 ole_wc2mb(LPWSTR pw
)
1038 size
= WideCharToMultiByte(cWIN32OLE_cp
, 0, pw
, -1, NULL
, 0, NULL
, NULL
);
1040 pm
= ALLOC_N(char, size
+ 1);
1041 WideCharToMultiByte(cWIN32OLE_cp
, 0, pw
, -1, pm
, size
, NULL
, NULL
);
1045 pm
= ALLOC_N(char, 1);
1052 ole_hresult2msg(HRESULT hr
)
1060 sprintf(strhr
, " HRESULT error code:0x%08x\n ", (unsigned)hr
);
1061 msg
= rb_str_new2(strhr
);
1063 dwCount
= FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
1064 FORMAT_MESSAGE_FROM_SYSTEM
|
1065 FORMAT_MESSAGE_IGNORE_INSERTS
,
1066 NULL
, hr
, cWIN32OLE_lcid
,
1067 (LPTSTR
)&p_msg
, 0, NULL
);
1069 term
= p_msg
+ strlen(p_msg
);
1070 while (p_msg
< term
) {
1072 if (*term
== '\r' || *term
== '\n')
1076 if (p_msg
[0] != '\0') {
1077 rb_str_cat2(msg
, p_msg
);
1085 ole_freeexceptinfo(EXCEPINFO
*pExInfo
)
1087 SysFreeString(pExInfo
->bstrDescription
);
1088 SysFreeString(pExInfo
->bstrSource
);
1089 SysFreeString(pExInfo
->bstrHelpFile
);
1093 ole_excepinfo2msg(EXCEPINFO
*pExInfo
)
1095 char error_code
[40];
1096 char *pSource
= NULL
;
1097 char *pDescription
= NULL
;
1099 if(pExInfo
->pfnDeferredFillIn
!= NULL
) {
1100 (*pExInfo
->pfnDeferredFillIn
)(pExInfo
);
1102 if (pExInfo
->bstrSource
!= NULL
) {
1103 pSource
= ole_wc2mb(pExInfo
->bstrSource
);
1105 if (pExInfo
->bstrDescription
!= NULL
) {
1106 pDescription
= ole_wc2mb(pExInfo
->bstrDescription
);
1108 if(pExInfo
->wCode
== 0) {
1109 sprintf(error_code
, "\n OLE error code:%lX in ", pExInfo
->scode
);
1112 sprintf(error_code
, "\n OLE error code:%u in ", pExInfo
->wCode
);
1114 error_msg
= rb_str_new2(error_code
);
1115 if(pSource
!= NULL
) {
1116 rb_str_cat(error_msg
, pSource
, strlen(pSource
));
1119 rb_str_cat(error_msg
, "<Unknown>", 9);
1121 rb_str_cat2(error_msg
, "\n ");
1122 if(pDescription
!= NULL
) {
1123 rb_str_cat2(error_msg
, pDescription
);
1126 rb_str_cat2(error_msg
, "<No Description>");
1128 if(pSource
) free(pSource
);
1129 if(pDescription
) free(pDescription
);
1130 ole_freeexceptinfo(pExInfo
);
1135 ole_raise(HRESULT hr
, VALUE ecs
, const char *fmt
, ...)
1140 va_init_list(args
, fmt
);
1141 vsnprintf(buf
, BUFSIZ
, fmt
, args
);
1144 err_msg
= ole_hresult2msg(hr
);
1145 if(err_msg
!= Qnil
) {
1146 rb_raise(ecs
, "%s\n%s", buf
, StringValuePtr(err_msg
));
1149 rb_raise(ecs
, "%s", buf
);
1157 g_ole_initialized
= FALSE
;
1165 if(g_ole_initialized
== FALSE
) {
1166 hr
= OleInitialize(NULL
);
1168 ole_raise(hr
, rb_eRuntimeError
, "fail: OLE initialize");
1170 g_ole_initialized
= TRUE
;
1172 * In some situation, OleUninitialize does not work fine. ;-<
1175 atexit((void (*)(void))ole_uninitialize);
1177 hr
= CoRegisterMessageFilter(&imessage_filter
, &previous_filter
);
1179 previous_filter
= NULL
;
1180 ole_raise(hr
, rb_eRuntimeError
, "fail: install OLE MessageFilter");
1188 while(PeekMessage(&msg
,NULL
,0,0,PM_REMOVE
)) {
1189 TranslateMessage(&msg
);
1190 DispatchMessage(&msg
);
1195 ole_free(struct oledata
*pole
)
1197 OLE_FREE(pole
->pDispatch
);
1202 oletype_free(struct oletypedata
*poletype
)
1204 OLE_FREE(poletype
->pTypeInfo
);
1209 olemethod_free(struct olemethoddata
*polemethod
)
1211 OLE_FREE(polemethod
->pTypeInfo
);
1212 OLE_FREE(polemethod
->pOwnerTypeInfo
);
1217 olevariable_free(struct olevariabledata
*polevar
)
1219 OLE_FREE(polevar
->pTypeInfo
);
1224 oleparam_free(struct oleparamdata
*pole
)
1226 OLE_FREE(pole
->pTypeInfo
);
1231 ole_vstr2wc(VALUE vstr
)
1238 enc
= rb_enc_get(vstr
);
1239 if (st_lookup(enc2cp_table
, (st_data_t
)enc
, &data
)) {
1242 cp
= ole_encoding2cp(enc
);
1243 if (code_page_installed(cp
) ||
1247 cp
== CP_THREAD_ACP
||
1251 st_insert(enc2cp_table
, (st_data_t
)enc
, (st_data_t
)cp
);
1253 rb_raise(eWIN32OLERuntimeError
, "not installed Windows codepage(%d) according to `%s'", cp
, rb_enc_name(enc
));
1256 size
= MultiByteToWideChar(cp
, 0, StringValuePtr(vstr
), -1, NULL
, 0);
1257 pw
= SysAllocStringLen(NULL
, size
- 1);
1258 MultiByteToWideChar(cp
, 0, StringValuePtr(vstr
), -1, pw
, size
);
1263 ole_mb2wc(char *pm
, int len
)
1267 size
= MultiByteToWideChar(cWIN32OLE_cp
, 0, pm
, len
, NULL
, 0);
1268 pw
= SysAllocStringLen(NULL
, size
- 1);
1269 MultiByteToWideChar(cWIN32OLE_cp
, 0, pm
, len
, pw
, size
);
1274 ole_wc2vstr(LPWSTR pw
, BOOL isfree
)
1276 char *p
= ole_wc2mb(pw
);
1277 VALUE vstr
= rb_enc_str_new(p
, strlen(p
), cWIN32OLE_enc
);
1285 ole_ary_m_entry(VALUE val
, long *pid
)
1290 while(TYPE(obj
) == T_ARRAY
) {
1291 obj
= rb_ary_entry(obj
, pid
[i
]);
1298 get_ptr_of_variant(VARIANT
*pvar
)
1300 switch(V_VT(pvar
)) {
1302 return &V_UI1(pvar
);
1308 return &V_UI2(pvar
);
1314 return &V_UI4(pvar
);
1322 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
1327 return &V_UI8(pvar
);
1331 return &V_INT(pvar
);
1334 return &V_UINT(pvar
);
1340 return &V_DATE(pvar
);
1343 return V_BSTR(pvar
);
1346 return V_DISPATCH(pvar
);
1349 return &V_ERROR(pvar
);
1352 return &V_BOOL(pvar
);
1355 return V_UNKNOWN(pvar
);
1358 return &V_ARRAY(pvar
);
1367 is_all_index_under(long *pid
, long *pub
, long dim
)
1370 for (i
= 0; i
< dim
; i
++) {
1371 if (pid
[i
] > pub
[i
]) {
1379 ole_set_safe_array(long n
, SAFEARRAY
*psa
, long *pid
, long *pub
, VALUE val
, long dim
, VARTYPE vt
)
1387 val1
= ole_ary_m_entry(val
, pid
);
1389 p
= val2variant_ptr(val1
, &var
, vt
);
1390 if (is_all_index_under(pid
, pub
, dim
) == Qtrue
) {
1391 if ((V_VT(&var
) == VT_DISPATCH
&& V_DISPATCH(&var
) == NULL
) ||
1392 (V_VT(&var
) == VT_UNKNOWN
&& V_UNKNOWN(&var
) == NULL
)) {
1393 rb_raise(eWIN32OLERuntimeError
, "element of array does not have IDispatch or IUnknown Interface");
1395 hr
= SafeArrayPutElement(psa
, pid
, p
);
1398 ole_raise(hr
, rb_eRuntimeError
, "failed to SafeArrayPutElement");
1401 if (pid
[i
] > pub
[i
]) {
1411 dimension(VALUE val
) {
1416 if (TYPE(val
) == T_ARRAY
) {
1417 len
= RARRAY_LEN(val
);
1418 for (i
= 0; i
< len
; i
++) {
1419 dim1
= dimension(rb_ary_entry(val
, i
));
1430 ary_len_of_dim(VALUE ary
, long dim
) {
1437 if (TYPE(ary
) == T_ARRAY
) {
1438 ary_len
= RARRAY_LEN(ary
);
1441 if (TYPE(ary
) == T_ARRAY
) {
1442 len
= RARRAY_LEN(ary
);
1443 for (i
= 0; i
< len
; i
++) {
1444 val
= rb_ary_entry(ary
, i
);
1445 ary_len1
= ary_len_of_dim(val
, dim
-1);
1446 if (ary_len
< ary_len1
) {
1456 ole_val_ary2variant_ary(VALUE val
, VARIANT
*var
, VARTYPE vt
)
1462 SAFEARRAYBOUND
*psab
= NULL
;
1463 SAFEARRAY
*psa
= NULL
;
1466 Check_Type(val
, T_ARRAY
);
1468 dim
= dimension(val
);
1470 psab
= ALLOC_N(SAFEARRAYBOUND
, dim
);
1471 pub
= ALLOC_N(long, dim
);
1472 pid
= ALLOC_N(long, dim
);
1474 if(!psab
|| !pub
|| !pid
) {
1476 if(psab
) free(psab
);
1478 rb_raise(rb_eRuntimeError
, "memory allocation error");
1481 for (i
= 0; i
< dim
; i
++) {
1482 psab
[i
].cElements
= ary_len_of_dim(val
, i
);
1483 psab
[i
].lLbound
= 0;
1484 pub
[i
] = psab
[i
].cElements
- 1;
1487 /* Create and fill VARIANT array */
1488 if ((vt
& ~VT_BYREF
) == VT_ARRAY
) {
1489 vt
= (vt
| VT_VARIANT
);
1491 psa
= SafeArrayCreate((VARTYPE
)(vt
& VT_TYPEMASK
), dim
, psab
);
1495 hr
= SafeArrayLock(psa
);
1496 if (SUCCEEDED(hr
)) {
1497 ole_set_safe_array(dim
-1, psa
, pid
, pub
, val
, dim
, (VARTYPE
)(vt
& VT_TYPEMASK
));
1498 hr
= SafeArrayUnlock(psa
);
1502 if(psab
) free(psab
);
1505 if (SUCCEEDED(hr
)) {
1511 SafeArrayDestroy(psa
);
1517 ole_val2variant(VALUE val
, VARIANT
*var
)
1519 struct oledata
*pole
;
1520 struct olevariantdata
*pvar
;
1521 if(rb_obj_is_kind_of(val
, cWIN32OLE
)) {
1522 Data_Get_Struct(val
, struct oledata
, pole
);
1523 OLE_ADDREF(pole
->pDispatch
);
1524 V_VT(var
) = VT_DISPATCH
;
1525 V_DISPATCH(var
) = pole
->pDispatch
;
1528 if (rb_obj_is_kind_of(val
, cWIN32OLE_VARIANT
)) {
1529 Data_Get_Struct(val
, struct olevariantdata
, pvar
);
1530 VariantCopy(var
, &(pvar
->var
));
1534 if (rb_obj_is_kind_of(val
, rb_cTime
)) {
1535 V_VT(var
) = VT_DATE
;
1536 V_DATE(var
) = time_object2date(val
);
1539 switch (TYPE(val
)) {
1541 ole_val_ary2variant_ary(val
, var
, VT_VARIANT
|VT_ARRAY
);
1544 V_VT(var
) = VT_BSTR
;
1545 V_BSTR(var
) = ole_vstr2wc(val
);
1549 V_I4(var
) = NUM2INT(val
);
1553 V_R8(var
) = rb_big2dbl(val
);
1557 V_R8(var
) = NUM2DBL(val
);
1560 V_VT(var
) = VT_BOOL
;
1561 V_BOOL(var
) = VARIANT_TRUE
;
1564 V_VT(var
) = VT_BOOL
;
1565 V_BOOL(var
) = VARIANT_FALSE
;
1568 if (g_nil_to
== VT_ERROR
) {
1569 V_VT(var
) = VT_ERROR
;
1570 V_ERROR(var
) = DISP_E_PARAMNOTFOUND
;
1572 V_VT(var
) = VT_EMPTY
;
1576 V_VT(var
) = VT_DISPATCH
;
1577 V_DISPATCH(var
) = val2dispatch(val
);
1583 ole_val2variant_ex(VALUE val
, VARIANT
*var
, VARTYPE vt
)
1586 if (vt
== VT_VARIANT
) {
1587 ole_val2variant2(val
, var
);
1589 V_VT(var
) = (vt
& ~VT_BYREF
);
1590 if (V_VT(var
) == VT_DISPATCH
) {
1591 V_DISPATCH(var
) = NULL
;
1592 } else if (V_VT(var
) == VT_UNKNOWN
) {
1593 V_UNKNOWN(var
) = NULL
;
1598 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
1599 switch(vt
& ~VT_BYREF
) {
1602 V_I8(var
) = NUM2I8 (val
);
1606 V_UI8(var
) = NUM2UI8(val
);
1609 ole_val2variant2(val
, var
);
1612 #else /* (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__) */
1613 ole_val2variant2(val
, var
);
1618 ole_val2ptr_variant(VALUE val
, VARIANT
*var
)
1620 switch (TYPE(val
)) {
1622 if (V_VT(var
) == (VT_BSTR
| VT_BYREF
)) {
1623 *V_BSTRREF(var
) = ole_vstr2wc(val
);
1628 case (VT_UI1
| VT_BYREF
) :
1629 *V_UI1REF(var
) = NUM2CHR(val
);
1631 case (VT_I2
| VT_BYREF
) :
1632 *V_I2REF(var
) = (short)NUM2INT(val
);
1634 case (VT_I4
| VT_BYREF
) :
1635 *V_I4REF(var
) = NUM2INT(val
);
1637 case (VT_R4
| VT_BYREF
) :
1638 *V_R4REF(var
) = (float)NUM2INT(val
);
1640 case (VT_R8
| VT_BYREF
) :
1641 *V_R8REF(var
) = NUM2INT(val
);
1649 case (VT_I2
| VT_BYREF
) :
1650 *V_I2REF(var
) = (short)NUM2INT(val
);
1652 case (VT_I4
| VT_BYREF
) :
1653 *V_I4REF(var
) = NUM2INT(val
);
1655 case (VT_R4
| VT_BYREF
) :
1656 *V_R4REF(var
) = (float)NUM2DBL(val
);
1658 case (VT_R8
| VT_BYREF
) :
1659 *V_R8REF(var
) = NUM2DBL(val
);
1666 if (V_VT(var
) == (VT_R8
| VT_BYREF
)) {
1667 *V_R8REF(var
) = rb_big2dbl(val
);
1671 if (V_VT(var
) == (VT_BOOL
| VT_BYREF
)) {
1672 *V_BOOLREF(var
) = VARIANT_TRUE
;
1676 if (V_VT(var
) == (VT_BOOL
| VT_BYREF
)) {
1677 *V_BOOLREF(var
) = VARIANT_FALSE
;
1686 ole_set_byref(VARIANT
*realvar
, VARIANT
*var
, VARTYPE vt
)
1689 if (vt
== (VT_VARIANT
|VT_BYREF
)) {
1690 V_VARIANTREF(var
) = realvar
;
1692 if (V_VT(realvar
) != (vt
& ~VT_BYREF
)) {
1693 rb_raise(eWIN32OLERuntimeError
, "variant type mismatch");
1695 switch(vt
& ~VT_BYREF
) {
1697 V_I1REF(var
) = &V_I1(realvar
);
1700 V_UI1REF(var
) = &V_UI1(realvar
);
1703 V_I2REF(var
) = &V_I2(realvar
);
1706 V_UI2REF(var
) = &V_UI2(realvar
);
1709 V_I4REF(var
) = &V_I4(realvar
);
1712 V_UI4REF(var
) = &V_UI4(realvar
);
1715 V_R4REF(var
) = &V_R4(realvar
);
1718 V_R8REF(var
) = &V_R8(realvar
);
1721 #if (_MSC_VER >= 1300)
1723 V_I8REF(var
) = &V_I8(realvar
);
1726 V_UI8REF(var
) = &V_UI8(realvar
);
1730 V_INTREF(var
) = &V_INT(realvar
);
1734 V_UINTREF(var
) = &V_UINT(realvar
);
1738 V_CYREF(var
) = &V_CY(realvar
);
1741 V_DATEREF(var
) = &V_DATE(realvar
);
1744 V_BSTRREF(var
) = &V_BSTR(realvar
);
1747 V_DISPATCHREF(var
) = &V_DISPATCH(realvar
);
1750 V_ERRORREF(var
) = &V_ERROR(realvar
);
1753 V_BOOLREF(var
) = &V_BOOL(realvar
);
1756 V_UNKNOWNREF(var
) = &V_UNKNOWN(realvar
);
1759 V_ARRAYREF(var
) = &V_ARRAY(realvar
);
1762 rb_raise(eWIN32OLERuntimeError
, "unknown type specified(setting BYREF):%d", vt
);
1769 ole_val2olevariantdata(VALUE val
, VARTYPE vt
, struct olevariantdata
*pvar
)
1773 if (((vt
& ~VT_BYREF
) == (VT_ARRAY
| VT_UI1
)) && TYPE(val
) == T_STRING
) {
1774 long len
= RSTRING_LEN(val
);
1776 SAFEARRAY
*p
= NULL
;
1777 SAFEARRAY
*psa
= SafeArrayCreateVector(VT_UI1
, 0, len
);
1779 rb_raise(rb_eRuntimeError
, "fail to SafeArrayCreateVector");
1781 hr
= SafeArrayAccessData(psa
, &pdest
);
1782 if (SUCCEEDED(hr
)) {
1783 memcpy(pdest
, RSTRING_PTR(val
), len
);
1784 SafeArrayUnaccessData(psa
);
1785 V_VT(&(pvar
->realvar
)) = (vt
& ~VT_BYREF
);
1786 p
= V_ARRAY(&(pvar
->realvar
));
1788 SafeArrayDestroy(p
);
1790 V_ARRAY(&(pvar
->realvar
)) = psa
;
1791 if (vt
& VT_BYREF
) {
1792 V_VT(&(pvar
->var
)) = vt
;
1793 V_ARRAYREF(&(pvar
->var
)) = &(V_ARRAY(&(pvar
->realvar
)));
1795 hr
= VariantCopy(&(pvar
->var
), &(pvar
->realvar
));
1799 SafeArrayDestroy(psa
);
1801 } else if (vt
& VT_ARRAY
) {
1803 V_VT(&(pvar
->var
)) = vt
;
1804 if (vt
& VT_BYREF
) {
1805 V_ARRAYREF(&(pvar
->var
)) = &(V_ARRAY(&(pvar
->realvar
)));
1808 hr
= ole_val_ary2variant_ary(val
, &(pvar
->realvar
), (VARTYPE
)(vt
& ~VT_BYREF
));
1809 if (SUCCEEDED(hr
)) {
1810 if (vt
& VT_BYREF
) {
1811 V_VT(&(pvar
->var
)) = vt
;
1812 V_ARRAYREF(&(pvar
->var
)) = &(V_ARRAY(&(pvar
->realvar
)));
1814 hr
= VariantCopy(&(pvar
->var
), &(pvar
->realvar
));
1818 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
1819 } else if ( (vt
& ~VT_BYREF
) == VT_I8
|| (vt
& ~VT_BYREF
) == VT_UI8
) {
1820 ole_val2variant_ex(val
, &(pvar
->realvar
), (vt
& ~VT_BYREF
));
1821 ole_val2variant_ex(val
, &(pvar
->var
), (vt
& ~VT_BYREF
));
1822 V_VT(&(pvar
->var
)) = vt
;
1823 if (vt
& VT_BYREF
) {
1824 ole_set_byref(&(pvar
->realvar
), &(pvar
->var
), vt
);
1829 V_VT(&(pvar
->var
)) = vt
;
1830 if (vt
== (VT_BYREF
| VT_VARIANT
)) {
1831 ole_set_byref(&(pvar
->realvar
), &(pvar
->var
), vt
);
1833 V_VT(&(pvar
->realvar
)) = vt
& ~VT_BYREF
;
1834 if (vt
& VT_BYREF
) {
1835 ole_set_byref(&(pvar
->realvar
), &(pvar
->var
), vt
);
1839 ole_val2variant_ex(val
, &(pvar
->realvar
), (VARTYPE
)(vt
& ~VT_BYREF
));
1840 if (vt
== (VT_BYREF
| VT_VARIANT
)) {
1841 ole_set_byref(&(pvar
->realvar
), &(pvar
->var
), vt
);
1842 } else if (vt
& VT_BYREF
) {
1843 if ( (vt
& ~VT_BYREF
) != V_VT(&(pvar
->realvar
))) {
1844 hr
= VariantChangeTypeEx(&(pvar
->realvar
), &(pvar
->realvar
),
1845 cWIN32OLE_lcid
, 0, (VARTYPE
)(vt
& ~VT_BYREF
));
1847 if (SUCCEEDED(hr
)) {
1848 ole_set_byref(&(pvar
->realvar
), &(pvar
->var
), vt
);
1851 if (vt
== V_VT(&(pvar
->realvar
))) {
1852 hr
= VariantCopy(&(pvar
->var
), &(pvar
->realvar
));
1854 hr
= VariantChangeTypeEx(&(pvar
->var
), &(pvar
->realvar
),
1855 cWIN32OLE_lcid
, 0, vt
);
1861 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to change type");
1866 ole_val2variant2(VALUE val
, VARIANT
*var
)
1868 g_nil_to
= VT_EMPTY
;
1869 ole_val2variant(val
, var
);
1870 g_nil_to
= VT_ERROR
;
1874 make_inspect(const char *class_name
, VALUE detail
)
1877 str
= rb_str_new2("#<");
1878 rb_str_cat2(str
, class_name
);
1879 rb_str_cat2(str
, ":");
1880 rb_str_concat(str
, detail
);
1881 rb_str_cat2(str
, ">");
1886 default_inspect(VALUE self
, const char *class_name
)
1888 VALUE detail
= rb_funcall(self
, rb_intern("to_s"), 0);
1889 return make_inspect(class_name
, detail
);
1893 ole_set_member(VALUE self
, IDispatch
*dispatch
)
1895 struct oledata
*pole
;
1896 Data_Get_Struct(self
, struct oledata
, pole
);
1897 if (pole
->pDispatch
) {
1898 OLE_RELEASE(pole
->pDispatch
);
1899 pole
->pDispatch
= NULL
;
1901 pole
->pDispatch
= dispatch
;
1907 fole_s_allocate(VALUE klass
)
1909 struct oledata
*pole
;
1912 obj
= Data_Make_Struct(klass
,struct oledata
,0,ole_free
,pole
);
1913 pole
->pDispatch
= NULL
;
1918 create_win32ole_object(VALUE klass
, IDispatch
*pDispatch
, int argc
, VALUE
*argv
)
1920 VALUE obj
= fole_s_allocate(klass
);
1921 ole_set_member(obj
, pDispatch
);
1926 ary_new_dim(VALUE myary
, long *pid
, long *plb
, long dim
) {
1930 long *ids
= ALLOC_N(long, dim
);
1932 rb_raise(rb_eRuntimeError
, "memory allocation error");
1934 for(i
= 0; i
< dim
; i
++) {
1935 ids
[i
] = pid
[i
] - plb
[i
];
1939 for(i
= 0; i
< dim
-1; i
++) {
1940 obj
= rb_ary_entry(pobj
, ids
[i
]);
1942 rb_ary_store(pobj
, ids
[i
], rb_ary_new());
1944 obj
= rb_ary_entry(pobj
, ids
[i
]);
1952 ary_store_dim(VALUE myary
, long *pid
, long *plb
, long dim
, VALUE val
) {
1953 long id
= pid
[dim
- 1] - plb
[dim
- 1];
1954 VALUE obj
= ary_new_dim(myary
, pid
, plb
, dim
);
1955 rb_ary_store(obj
, id
, val
);
1959 ole_variant2val(VARIANT
*pvar
)
1963 while ( V_VT(pvar
) == (VT_BYREF
| VT_VARIANT
) )
1964 pvar
= V_VARIANTREF(pvar
);
1966 if(V_ISARRAY(pvar
)) {
1967 SAFEARRAY
*psa
= V_ISBYREF(pvar
) ? *V_ARRAYREF(pvar
) : V_ARRAY(pvar
);
1969 long *pid
, *plb
, *pub
;
1976 dim
= SafeArrayGetDim(psa
);
1977 VariantInit(&variant
);
1978 V_VT(&variant
) = (V_VT(pvar
) & ~VT_ARRAY
) | VT_BYREF
;
1980 pid
= ALLOC_N(long, dim
);
1981 plb
= ALLOC_N(long, dim
);
1982 pub
= ALLOC_N(long, dim
);
1984 if(!pid
|| !plb
|| !pub
) {
1988 rb_raise(rb_eRuntimeError
, "memory allocation error");
1991 for(i
= 0; i
< dim
; ++i
) {
1992 SafeArrayGetLBound(psa
, i
+1, &plb
[i
]);
1993 SafeArrayGetLBound(psa
, i
+1, &pid
[i
]);
1994 SafeArrayGetUBound(psa
, i
+1, &pub
[i
]);
1996 hr
= SafeArrayLock(psa
);
1997 if (SUCCEEDED(hr
)) {
2001 ary_new_dim(obj
, pid
, plb
, dim
);
2002 hr
= SafeArrayPtrOfIndex(psa
, pid
, &V_BYREF(&variant
));
2003 if (SUCCEEDED(hr
)) {
2004 val
= ole_variant2val(&variant
);
2005 ary_store_dim(obj
, pid
, plb
, dim
, val
);
2007 for (i
= 0; i
< dim
; ++i
) {
2008 if (++pid
[i
] <= pub
[i
])
2013 SafeArrayUnlock(psa
);
2020 switch(V_VT(pvar
) & ~VT_BYREF
){
2027 obj
= INT2NUM((long)*V_I1REF(pvar
));
2029 obj
= INT2NUM((long)V_I1(pvar
));
2034 obj
= INT2NUM((long)*V_UI1REF(pvar
));
2036 obj
= INT2NUM((long)V_UI1(pvar
));
2041 obj
= INT2NUM((long)*V_I2REF(pvar
));
2043 obj
= INT2NUM((long)V_I2(pvar
));
2048 obj
= INT2NUM((long)*V_UI2REF(pvar
));
2050 obj
= INT2NUM((long)V_UI2(pvar
));
2055 obj
= INT2NUM((long)*V_I4REF(pvar
));
2057 obj
= INT2NUM((long)V_I4(pvar
));
2062 obj
= INT2NUM((long)*V_UI4REF(pvar
));
2064 obj
= INT2NUM((long)V_UI4(pvar
));
2069 obj
= INT2NUM((long)*V_INTREF(pvar
));
2071 obj
= INT2NUM((long)V_INT(pvar
));
2076 obj
= INT2NUM((long)*V_UINTREF(pvar
));
2078 obj
= INT2NUM((long)V_UINT(pvar
));
2081 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
2084 #if (_MSC_VER >= 1300)
2085 obj
= I8_2_NUM(*V_I8REF(pvar
));
2090 obj
= I8_2_NUM(V_I8(pvar
));
2094 #if (_MSC_VER >= 1300)
2095 obj
= UI8_2_NUM(*V_UI8REF(pvar
));
2100 obj
= UI8_2_NUM(V_UI8(pvar
));
2102 #endif /* (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__) */
2106 obj
= rb_float_new(*V_R4REF(pvar
));
2108 obj
= rb_float_new(V_R4(pvar
));
2113 obj
= rb_float_new(*V_R8REF(pvar
));
2115 obj
= rb_float_new(V_R8(pvar
));
2121 obj
= ole_wc2vstr(*V_BSTRREF(pvar
), FALSE
);
2123 obj
= ole_wc2vstr(V_BSTR(pvar
), FALSE
);
2129 obj
= INT2NUM(*V_ERRORREF(pvar
));
2131 obj
= INT2NUM(V_ERROR(pvar
));
2135 if (V_ISBYREF(pvar
))
2136 obj
= (*V_BOOLREF(pvar
) ? Qtrue
: Qfalse
);
2138 obj
= (V_BOOL(pvar
) ? Qtrue
: Qfalse
);
2143 IDispatch
*pDispatch
;
2145 if (V_ISBYREF(pvar
))
2146 pDispatch
= *V_DISPATCHREF(pvar
);
2148 pDispatch
= V_DISPATCH(pvar
);
2150 if (pDispatch
!= NULL
) {
2151 OLE_ADDREF(pDispatch
);
2152 obj
= create_win32ole_object(cWIN32OLE
, pDispatch
, 0, 0);
2159 /* get IDispatch interface from IUnknown interface */
2161 IDispatch
*pDispatch
;
2165 if (V_ISBYREF(pvar
))
2166 punk
= *V_UNKNOWNREF(pvar
);
2168 punk
= V_UNKNOWN(pvar
);
2171 hr
= punk
->lpVtbl
->QueryInterface(punk
, &IID_IDispatch
, &p
);
2174 obj
= create_win32ole_object(cWIN32OLE
, pDispatch
, 0, 0);
2184 date
= *V_DATEREF(pvar
);
2186 date
= V_DATE(pvar
);
2188 obj
= date2time_str(date
);
2196 VariantInit(&variant
);
2197 hr
= VariantChangeTypeEx(&variant
, pvar
,
2198 cWIN32OLE_lcid
, 0, VT_BSTR
);
2199 if (SUCCEEDED(hr
) && V_VT(&variant
) == VT_BSTR
) {
2200 obj
= ole_wc2vstr(V_BSTR(&variant
), FALSE
);
2202 VariantClear(&variant
);
2210 reg_open_key(HKEY hkey
, const char *name
, HKEY
*phkey
)
2212 return RegOpenKeyEx(hkey
, name
, 0, KEY_READ
, phkey
);
2216 reg_open_vkey(HKEY hkey
, VALUE key
, HKEY
*phkey
)
2218 return reg_open_key(hkey
, StringValuePtr(key
), phkey
);
2222 reg_enum_key(HKEY hkey
, DWORD i
)
2224 char buf
[BUFSIZ
+ 1];
2225 DWORD size_buf
= sizeof(buf
);
2227 LONG err
= RegEnumKeyEx(hkey
, i
, buf
, &size_buf
,
2228 NULL
, NULL
, NULL
, &ft
);
2229 if(err
== ERROR_SUCCESS
) {
2231 return rb_str_new2(buf
);
2237 reg_get_val(HKEY hkey
, const char *subkey
)
2243 LONG err
= RegQueryValueEx(hkey
, subkey
, NULL
, &dwtype
, NULL
, &size
);
2245 if (err
== ERROR_SUCCESS
) {
2246 pbuf
= ALLOC_N(char, size
+ 1);
2247 err
= RegQueryValueEx(hkey
, subkey
, NULL
, &dwtype
, pbuf
, &size
);
2248 if (err
== ERROR_SUCCESS
) {
2250 val
= rb_str_new2(pbuf
);
2258 reg_get_val2(HKEY hkey
, const char *subkey
)
2263 err
= RegOpenKeyEx(hkey
, subkey
, 0, KEY_READ
, &hsubkey
);
2264 if (err
== ERROR_SUCCESS
) {
2265 val
= reg_get_val(hsubkey
, NULL
);
2266 RegCloseKey(hsubkey
);
2269 val
= reg_get_val(hkey
, subkey
);
2275 reg_get_typelib_file_path(HKEY hkey
)
2278 path
= reg_get_val2(hkey
, "win32");
2280 path
= reg_get_val2(hkey
, "win16");
2286 typelib_file_from_clsid(VALUE ole
)
2291 char path
[MAX_PATH
+ 1];
2293 err
= reg_open_key(HKEY_CLASSES_ROOT
, "CLSID", &hroot
);
2294 if (err
!= ERROR_SUCCESS
) {
2297 err
= reg_open_key(hroot
, StringValuePtr(ole
), &hclsid
);
2298 if (err
!= ERROR_SUCCESS
) {
2302 typelib
= reg_get_val2(hclsid
, "InprocServer32");
2304 RegCloseKey(hclsid
);
2305 if (typelib
!= Qnil
) {
2306 ExpandEnvironmentStrings(StringValuePtr(typelib
), path
, sizeof(path
));
2307 path
[MAX_PATH
] = '\0';
2308 typelib
= rb_str_new2(path
);
2314 typelib_file_from_typelib(VALUE ole
)
2316 HKEY htypelib
, hclsid
, hversion
, hlang
;
2327 err
= reg_open_key(HKEY_CLASSES_ROOT
, "TypeLib", &htypelib
);
2328 if(err
!= ERROR_SUCCESS
) {
2331 for(i
= 0; !found
; i
++) {
2332 clsid
= reg_enum_key(htypelib
, i
);
2335 err
= reg_open_vkey(htypelib
, clsid
, &hclsid
);
2336 if (err
!= ERROR_SUCCESS
)
2339 for(j
= 0; !found
; j
++) {
2340 ver
= reg_enum_key(hclsid
, j
);
2343 err
= reg_open_vkey(hclsid
, ver
, &hversion
);
2344 if (err
!= ERROR_SUCCESS
|| fver
> atof(StringValuePtr(ver
)))
2346 fver
= atof(StringValuePtr(ver
));
2347 typelib
= reg_get_val(hversion
, NULL
);
2348 if (typelib
== Qnil
)
2350 if (rb_str_cmp(typelib
, ole
) == 0) {
2351 for(k
= 0; !found
; k
++) {
2352 lang
= reg_enum_key(hversion
, k
);
2355 err
= reg_open_vkey(hversion
, lang
, &hlang
);
2356 if (err
== ERROR_SUCCESS
) {
2357 if ((file
= reg_get_typelib_file_path(hlang
)) != Qnil
)
2363 RegCloseKey(hversion
);
2365 RegCloseKey(hclsid
);
2367 RegCloseKey(htypelib
);
2372 typelib_file(VALUE ole
)
2374 VALUE file
= typelib_file_from_clsid(ole
);
2378 return typelib_file_from_typelib(ole
);
2382 ole_const_load(ITypeLib
*pTypeLib
, VALUE klass
, VALUE self
)
2387 ITypeInfo
*pTypeInfo
;
2388 TYPEATTR
*pTypeAttr
;
2397 constant
= rb_hash_new();
2398 count
= pTypeLib
->lpVtbl
->GetTypeInfoCount(pTypeLib
);
2399 for (index
= 0; index
< count
; index
++) {
2400 hr
= pTypeLib
->lpVtbl
->GetTypeInfo(pTypeLib
, index
, &pTypeInfo
);
2403 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
2405 OLE_RELEASE(pTypeInfo
);
2408 for(iVar
= 0; iVar
< pTypeAttr
->cVars
; iVar
++) {
2409 hr
= pTypeInfo
->lpVtbl
->GetVarDesc(pTypeInfo
, iVar
, &pVarDesc
);
2412 if(pVarDesc
->varkind
== VAR_CONST
&&
2413 !(pVarDesc
->wVarFlags
& (VARFLAG_FHIDDEN
|
2414 VARFLAG_FRESTRICTED
|
2415 VARFLAG_FNONBROWSABLE
))) {
2416 hr
= pTypeInfo
->lpVtbl
->GetNames(pTypeInfo
, pVarDesc
->memid
, &bstr
,
2418 if(FAILED(hr
) || len
== 0 || !bstr
)
2420 pName
= ole_wc2mb(bstr
);
2421 val
= ole_variant2val(V_UNION1(pVarDesc
, lpvarValue
));
2422 *pName
= toupper(*pName
);
2423 id
= rb_intern(pName
);
2424 if (rb_is_const_id(id
)) {
2425 rb_define_const(klass
, pName
, val
);
2428 rb_hash_aset(constant
, rb_str_new2(pName
), val
);
2430 SysFreeString(bstr
);
2436 pTypeInfo
->lpVtbl
->ReleaseVarDesc(pTypeInfo
, pVarDesc
);
2438 pTypeInfo
->lpVtbl
->ReleaseTypeAttr(pTypeInfo
, pTypeAttr
);
2439 OLE_RELEASE(pTypeInfo
);
2441 rb_define_const(klass
, "CONSTANTS", constant
);
2445 clsid_from_remote(VALUE host
, VALUE com
, CLSID
*pclsid
)
2456 err
= RegConnectRegistry(StringValuePtr(host
), HKEY_LOCAL_MACHINE
, &hlm
);
2457 if (err
!= ERROR_SUCCESS
)
2458 return HRESULT_FROM_WIN32(err
);
2459 subkey
= rb_str_new2("SOFTWARE\\Classes\\");
2460 rb_str_concat(subkey
, com
);
2461 rb_str_cat2(subkey
, "\\CLSID");
2462 err
= RegOpenKeyEx(hlm
, StringValuePtr(subkey
), 0, KEY_READ
, &hpid
);
2463 if (err
!= ERROR_SUCCESS
)
2464 hr
= HRESULT_FROM_WIN32(err
);
2466 len
= sizeof(clsid
);
2467 err
= RegQueryValueEx(hpid
, (LPBYTE
)"", NULL
, &dwtype
, clsid
, &len
);
2468 if (err
== ERROR_SUCCESS
&& dwtype
== REG_SZ
) {
2469 pbuf
= ole_mb2wc(clsid
, -1);
2470 hr
= CLSIDFromString(pbuf
, pclsid
);
2471 SysFreeString(pbuf
);
2474 hr
= HRESULT_FROM_WIN32(err
);
2483 ole_create_dcom(int argc
, VALUE
*argv
, VALUE self
)
2485 VALUE ole
, host
, others
;
2490 COSERVERINFO serverinfo
;
2492 DWORD clsctx
= CLSCTX_REMOTE_SERVER
;
2495 gole32
= LoadLibrary("OLE32");
2497 rb_raise(rb_eRuntimeError
, "failed to load OLE32");
2498 if (!gCoCreateInstanceEx
)
2499 gCoCreateInstanceEx
= (FNCOCREATEINSTANCEEX
*)
2500 GetProcAddress(gole32
, "CoCreateInstanceEx");
2501 if (!gCoCreateInstanceEx
)
2502 rb_raise(rb_eRuntimeError
, "CoCreateInstanceEx is not supported in this environment");
2503 rb_scan_args(argc
, argv
, "2*", &ole
, &host
, &others
);
2505 pbuf
= ole_vstr2wc(ole
);
2506 hr
= CLSIDFromProgID(pbuf
, &clsid
);
2508 hr
= clsid_from_remote(host
, ole
, &clsid
);
2510 hr
= CLSIDFromString(pbuf
, &clsid
);
2511 SysFreeString(pbuf
);
2513 ole_raise(hr
, eWIN32OLERuntimeError
,
2514 "unknown OLE server: `%s'",
2515 StringValuePtr(ole
));
2516 memset(&serverinfo
, 0, sizeof(COSERVERINFO
));
2517 serverinfo
.pwszName
= ole_vstr2wc(host
);
2518 memset(&multi_qi
, 0, sizeof(MULTI_QI
));
2519 multi_qi
.pIID
= &IID_IDispatch
;
2520 hr
= gCoCreateInstanceEx(&clsid
, NULL
, clsctx
, &serverinfo
, 1, &multi_qi
);
2521 SysFreeString(serverinfo
.pwszName
);
2523 ole_raise(hr
, eWIN32OLERuntimeError
,
2524 "failed to create DCOM server `%s' in `%s'",
2525 StringValuePtr(ole
),
2526 StringValuePtr(host
));
2528 ole_set_member(self
, (IDispatch
*)multi_qi
.pItf
);
2533 ole_bind_obj(VALUE moniker
, int argc
, VALUE
*argv
, VALUE self
)
2537 IDispatch
*pDispatch
;
2545 hr
= CreateBindCtx(0, &pBindCtx
);
2547 ole_raise(hr
, eWIN32OLERuntimeError
,
2548 "failed to create bind context");
2551 pbuf
= ole_vstr2wc(moniker
);
2552 hr
= MkParseDisplayName(pBindCtx
, pbuf
, &eaten
, &pMoniker
);
2553 SysFreeString(pbuf
);
2555 OLE_RELEASE(pBindCtx
);
2556 ole_raise(hr
, eWIN32OLERuntimeError
,
2557 "failed to parse display name of moniker `%s'",
2558 StringValuePtr(moniker
));
2560 hr
= pMoniker
->lpVtbl
->BindToObject(pMoniker
, pBindCtx
, NULL
,
2561 &IID_IDispatch
, &p
);
2563 OLE_RELEASE(pMoniker
);
2564 OLE_RELEASE(pBindCtx
);
2567 ole_raise(hr
, eWIN32OLERuntimeError
,
2568 "failed to bind moniker `%s'",
2569 StringValuePtr(moniker
));
2571 return create_win32ole_object(self
, pDispatch
, argc
, argv
);
2576 * WIN32OLE.connect( ole ) --> aWIN32OLE
2578 * Returns running OLE Automation object or WIN32OLE object from moniker.
2579 * 1st argument should be OLE program id or class id or moniker.
2581 * WIN32OLE.connect('Excel.Application') # => WIN32OLE object which represents running Excel.
2584 fole_s_connect(int argc
, VALUE
*argv
, VALUE self
)
2591 IDispatch
*pDispatch
;
2596 /* initialize to use OLE */
2599 rb_scan_args(argc
, argv
, "1*", &svr_name
, &others
);
2600 if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name
)) {
2601 rb_raise(rb_eSecurityError
, "Insecure Object Connection - %s",
2602 StringValuePtr(svr_name
));
2605 /* get CLSID from OLE server name */
2606 pBuf
= ole_vstr2wc(svr_name
);
2607 hr
= CLSIDFromProgID(pBuf
, &clsid
);
2609 hr
= CLSIDFromString(pBuf
, &clsid
);
2611 SysFreeString(pBuf
);
2613 return ole_bind_obj(svr_name
, argc
, argv
, self
);
2616 hr
= GetActiveObject(&clsid
, 0, &pUnknown
);
2618 ole_raise(hr
, eWIN32OLERuntimeError
,
2619 "OLE server `%s' not running", StringValuePtr(svr_name
));
2621 hr
= pUnknown
->lpVtbl
->QueryInterface(pUnknown
, &IID_IDispatch
, &p
);
2624 OLE_RELEASE(pUnknown
);
2625 ole_raise(hr
, eWIN32OLERuntimeError
,
2626 "failed to create WIN32OLE server `%s'",
2627 StringValuePtr(svr_name
));
2630 OLE_RELEASE(pUnknown
);
2632 return create_win32ole_object(self
, pDispatch
, argc
, argv
);
2637 * WIN32OLE.const_load( ole, mod = WIN32OLE)
2639 * Defines the constants of OLE Automation server as mod's constants.
2640 * The first argument is WIN32OLE object or type library name.
2641 * If 2nd argument is omitted, the default is WIN32OLE.
2642 * The first letter of Ruby's constant variable name is upper case,
2643 * so constant variable name of WIN32OLE object is capitalized.
2644 * For example, the 'xlTop' constant of Excel is changed to 'XlTop'
2646 * If the first letter of constant variabl is not [A-Z], then
2647 * the constant is defined as CONSTANTS hash element.
2649 * module EXCEL_CONST
2651 * excel = WIN32OLE.new('Excel.Application')
2652 * WIN32OLE.const_load(excel, EXCEL_CONST)
2653 * puts EXCEL_CONST::XlTop # => -4160
2654 * puts EXCEL_CONST::CONSTANTS['_xlDialogChartSourceData'] # => 541
2656 * WIN32OLE.const_load(excel)
2657 * puts WIN32OLE::XlTop # => -4160
2661 * WIN32OLE.const_load('Microsoft Office 9.0 Object Library', MSO)
2662 * puts MSO::MsoLineSingle # => 1
2665 fole_s_const_load(int argc
, VALUE
*argv
, VALUE self
)
2669 struct oledata
*pole
;
2670 ITypeInfo
*pTypeInfo
;
2676 LCID lcid
= cWIN32OLE_lcid
;
2679 rb_scan_args(argc
, argv
, "11", &ole
, &klass
);
2680 if (TYPE(klass
) != T_CLASS
&&
2681 TYPE(klass
) != T_MODULE
&&
2682 TYPE(klass
) != T_NIL
) {
2683 rb_raise(rb_eTypeError
, "2nd parameter must be Class or Module");
2685 if (rb_obj_is_kind_of(ole
, cWIN32OLE
)) {
2686 OLEData_Get_Struct(ole
, pole
);
2687 hr
= pole
->pDispatch
->lpVtbl
->GetTypeInfo(pole
->pDispatch
,
2688 0, lcid
, &pTypeInfo
);
2690 ole_raise(hr
, rb_eRuntimeError
, "failed to GetTypeInfo");
2692 hr
= pTypeInfo
->lpVtbl
->GetContainingTypeLib(pTypeInfo
, &pTypeLib
, &index
);
2694 OLE_RELEASE(pTypeInfo
);
2695 ole_raise(hr
, rb_eRuntimeError
, "failed to GetContainingTypeLib");
2697 OLE_RELEASE(pTypeInfo
);
2698 if(TYPE(klass
) != T_NIL
) {
2699 ole_const_load(pTypeLib
, klass
, self
);
2702 ole_const_load(pTypeLib
, cWIN32OLE
, self
);
2704 OLE_RELEASE(pTypeLib
);
2706 else if(TYPE(ole
) == T_STRING
) {
2707 file
= typelib_file(ole
);
2711 pBuf
= ole_vstr2wc(file
);
2712 hr
= LoadTypeLibEx(pBuf
, REGKIND_NONE
, &pTypeLib
);
2713 SysFreeString(pBuf
);
2715 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to LoadTypeLibEx");
2716 if(TYPE(klass
) != T_NIL
) {
2717 ole_const_load(pTypeLib
, klass
, self
);
2720 ole_const_load(pTypeLib
, cWIN32OLE
, self
);
2722 OLE_RELEASE(pTypeLib
);
2725 rb_raise(rb_eTypeError
, "1st parameter must be WIN32OLE instance");
2731 ole_types_from_typelib(ITypeLib
*pTypeLib
, VALUE classes
)
2738 ITypeInfo
*pTypeInfo
;
2742 count
= pTypeLib
->lpVtbl
->GetTypeInfoCount(pTypeLib
);
2743 for (i
= 0; i
< count
; i
++) {
2744 hr
= pTypeLib
->lpVtbl
->GetDocumentation(pTypeLib
, i
,
2745 &bstr
, NULL
, NULL
, NULL
);
2749 hr
= pTypeLib
->lpVtbl
->GetTypeInfo(pTypeLib
, i
, &pTypeInfo
);
2753 type
= foletype_s_allocate(cWIN32OLE_TYPE
);
2754 oletype_set_member(type
, pTypeInfo
, WC2VSTR(bstr
));
2756 rb_ary_push(classes
, type
);
2757 OLE_RELEASE(pTypeInfo
);
2763 reference_count(struct oledata
* pole
)
2766 if(pole
->pDispatch
) {
2767 OLE_ADDREF(pole
->pDispatch
);
2768 n
= OLE_RELEASE(pole
->pDispatch
);
2775 * WIN32OLE.ole_reference_count(aWIN32OLE) --> number
2777 * Returns reference counter of Dispatch interface of WIN32OLE object.
2778 * You should not use this method because this method
2779 * exists only for debugging WIN32OLE.
2782 fole_s_reference_count(VALUE self
, VALUE obj
)
2784 struct oledata
* pole
;
2785 OLEData_Get_Struct(obj
, pole
);
2786 return INT2NUM(reference_count(pole
));
2791 * WIN32OLE.ole_free(aWIN32OLE) --> number
2793 * Invokes Release method of Dispatch interface of WIN32OLE object.
2794 * You should not use this method because this method
2795 * exists only for debugging WIN32OLE.
2796 * The return value is reference counter of OLE object.
2799 fole_s_free(VALUE self
, VALUE obj
)
2802 struct oledata
* pole
;
2803 OLEData_Get_Struct(obj
, pole
);
2804 if(pole
->pDispatch
) {
2805 if (reference_count(pole
) > 0) {
2806 n
= OLE_RELEASE(pole
->pDispatch
);
2813 ole_show_help(VALUE helpfile
, VALUE helpcontext
)
2815 FNHTMLHELP
*pfnHtmlHelp
;
2819 ghhctrl
= LoadLibrary("HHCTRL.OCX");
2822 pfnHtmlHelp
= (FNHTMLHELP
*)GetProcAddress(ghhctrl
, "HtmlHelpA");
2825 hwnd
= pfnHtmlHelp(GetDesktopWindow(), StringValuePtr(helpfile
),
2826 0x0f, NUM2INT(helpcontext
));
2828 hwnd
= pfnHtmlHelp(GetDesktopWindow(), StringValuePtr(helpfile
),
2829 0, NUM2INT(helpcontext
));
2835 * WIN32OLE.ole_show_help(obj [,helpcontext])
2837 * Displays helpfile. The 1st argument specifies WIN32OLE_TYPE
2838 * object or WIN32OLE_METHOD object or helpfile.
2840 * excel = WIN32OLE.new('Excel.Application')
2841 * typeobj = excel.ole_type
2842 * WIN32OLE.ole_show_help(typeobj)
2845 fole_s_show_help(int argc
, VALUE
*argv
, VALUE self
)
2852 rb_scan_args(argc
, argv
, "11", &target
, &helpcontext
);
2853 if (rb_obj_is_kind_of(target
, cWIN32OLE_TYPE
) ||
2854 rb_obj_is_kind_of(target
, cWIN32OLE_METHOD
)) {
2855 helpfile
= rb_funcall(target
, rb_intern("helpfile"), 0);
2856 if(strlen(StringValuePtr(helpfile
)) == 0) {
2857 name
= rb_ivar_get(target
, rb_intern("name"));
2858 rb_raise(rb_eRuntimeError
, "no helpfile of `%s'",
2859 StringValuePtr(name
));
2861 helpcontext
= rb_funcall(target
, rb_intern("helpcontext"), 0);
2865 if (TYPE(helpfile
) != T_STRING
) {
2866 rb_raise(rb_eTypeError
, "1st parameter must be (String|WIN32OLE_TYPE|WIN32OLE_METHOD)");
2868 hwnd
= ole_show_help(helpfile
, helpcontext
);
2870 rb_raise(rb_eRuntimeError
, "failed to open help file `%s'",
2871 StringValuePtr(helpfile
));
2880 * Returns current codepage.
2881 * WIN32OLE.codepage # => WIN32OLE::CP_ACP
2884 fole_s_get_code_page(VALUE self
)
2886 return INT2FIX(cWIN32OLE_cp
);
2889 static BOOL CALLBACK
2890 installed_code_page_proc(LPTSTR str
) {
2891 if (strtoul(str
, NULL
, 10) == g_cp_to_check
) {
2892 g_cp_installed
= TRUE
;
2899 code_page_installed(UINT cp
)
2901 g_cp_installed
= FALSE
;
2903 EnumSystemCodePages(installed_code_page_proc
, CP_INSTALLED
);
2904 return g_cp_installed
;
2909 * WIN32OLE.codepage = CP
2911 * Sets current codepage.
2912 * WIN32OLE.codepage = WIN32OLE::CP_UTF8
2913 * WIN32OLE.codepage = 20932
2916 fole_s_set_code_page(VALUE self
, VALUE vcp
)
2918 UINT cp
= FIX2INT(vcp
);
2920 if (code_page_installed(cp
)) {
2934 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.");
2938 cWIN32OLE_enc
= ole_cp2encoding(cWIN32OLE_cp
);
2940 * Should this method return old codepage?
2947 * WIN32OLE.locale -> locale id.
2949 * Returns current locale id (lcid). The default locale is
2950 * LOCALE_SYSTEM_DEFAULT.
2952 * lcid = WIN32OLE.locale
2955 fole_s_get_locale(VALUE self
)
2957 return INT2FIX(cWIN32OLE_lcid
);
2961 CALLBACK
installed_lcid_proc(LPTSTR str
)
2963 if (strcmp(str
, g_lcid_to_check
) == 0) {
2964 g_lcid_installed
= TRUE
;
2971 lcid_installed(LCID lcid
)
2973 g_lcid_installed
= FALSE
;
2974 snprintf(g_lcid_to_check
, sizeof(g_lcid_to_check
), "%08lx", lcid
);
2975 EnumSystemLocales(installed_lcid_proc
, LCID_INSTALLED
);
2976 return g_lcid_installed
;
2981 * WIN32OLE.locale = lcid
2983 * Sets current locale id (lcid).
2985 * WIN32OLE.locale = 1033 # set locale English(U.S)
2986 * obj = WIN32OLE_VARIANT.new("$100,000", WIN32OLE::VARIANT::VT_CY)
2990 fole_s_set_locale(VALUE self
, VALUE vlcid
)
2992 LCID lcid
= FIX2INT(vlcid
);
2993 if (lcid_installed(lcid
)) {
2994 cWIN32OLE_lcid
= lcid
;
2997 case LOCALE_SYSTEM_DEFAULT
:
2998 case LOCALE_USER_DEFAULT
:
2999 cWIN32OLE_lcid
= lcid
;
3002 rb_raise(eWIN32OLERuntimeError
, "not installed locale: %u", (unsigned int)lcid
);
3010 * WIN32OLE.create_guid
3013 * WIN32OLE.create_guid # => {1CB530F1-F6B1-404D-BCE6-1959BF91F4A8}
3016 fole_s_create_guid(VALUE self
)
3022 hr
= CoCreateGuid(&guid
);
3024 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to create GUID");
3026 len
= StringFromGUID2(&guid
, bstr
, sizeof(bstr
)/sizeof(OLECHAR
));
3028 rb_raise(rb_eRuntimeError
, "failed to create GUID(buffer over)");
3030 return ole_wc2vstr(bstr
, FALSE
);
3034 * Document-class: WIN32OLE
3036 * <code>WIN32OLE</code> objects represent OLE Automation object in Ruby.
3038 * By using WIN32OLE, you can access OLE server like VBScript.
3040 * Here is sample script.
3042 * require 'win32ole'
3044 * excel = WIN32OLE.new('Excel.Application')
3045 * excel.visible = true
3046 * workbook = excel.Workbooks.Add();
3047 * worksheet = workbook.Worksheets(1);
3048 * worksheet.Range("A1:D1").value = ["North","South","East","West"];
3049 * worksheet.Range("A2:B2").value = [5.2, 10];
3050 * worksheet.Range("C2").value = 8;
3051 * worksheet.Range("D2").value = 20;
3053 * range = worksheet.Range("A1:D2");
3055 * chart = workbook.Charts.Add;
3057 * workbook.saved = true;
3059 * excel.ActiveWorkbook.Close(0);
3062 * Unfortunately, Win32OLE doesn't support the argument passed by
3063 * reference directly.
3064 * Instead, Win32OLE provides WIN32OLE::ARGV.
3065 * If you want to get the result value of argument passed by reference,
3066 * you can use WIN32OLE::ARGV.
3068 * oleobj.method(arg1, arg2, refargv3)
3069 * puts WIN32OLE::ARGV[2] # the value of refargv3 after called oleobj.method
3075 * WIN32OLE.new(server, [host]) -> WIN32OLE object
3077 * Returns a new WIN32OLE object(OLE Automation object).
3078 * The first argument server specifies OLE Automation server.
3079 * The first argument should be CLSID or PROGID.
3080 * If second argument host specified, then returns OLE Automation
3083 * WIN32OLE.new('Excel.Application') # => Excel OLE Automation WIN32OLE object.
3084 * WIN32OLE.new('{00024500-0000-0000-C000-000000000046}') # => Excel OLE Automation WIN32OLE object.
3087 fole_initialize(int argc
, VALUE
*argv
, VALUE self
)
3095 IDispatch
*pDispatch
;
3099 rb_call_super(0, 0);
3100 rb_scan_args(argc
, argv
, "11*", &svr_name
, &host
, &others
);
3102 if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name
)) {
3103 rb_raise(rb_eSecurityError
, "Insecure Object Creation - %s",
3104 StringValuePtr(svr_name
));
3107 if (rb_safe_level() > 0 && OBJ_TAINTED(host
)) {
3108 rb_raise(rb_eSecurityError
, "Insecure Object Creation - %s",
3109 StringValuePtr(svr_name
));
3111 return ole_create_dcom(argc
, argv
, self
);
3114 /* get CLSID from OLE server name */
3115 pBuf
= ole_vstr2wc(svr_name
);
3116 hr
= CLSIDFromProgID(pBuf
, &clsid
);
3118 hr
= CLSIDFromString(pBuf
, &clsid
);
3120 SysFreeString(pBuf
);
3122 ole_raise(hr
, eWIN32OLERuntimeError
,
3123 "unknown OLE server: `%s'",
3124 StringValuePtr(svr_name
));
3127 /* get IDispatch interface */
3128 hr
= CoCreateInstance(&clsid
, NULL
, CLSCTX_INPROC_SERVER
| CLSCTX_LOCAL_SERVER
,
3129 &IID_IDispatch
, &p
);
3132 ole_raise(hr
, eWIN32OLERuntimeError
,
3133 "failed to create WIN32OLE object from `%s'",
3134 StringValuePtr(svr_name
));
3137 ole_set_member(self
, pDispatch
);
3142 hash2named_arg(VALUE pair
, struct oleparam
* pOp
)
3144 unsigned int index
, i
;
3146 index
= pOp
->dp
.cNamedArgs
;
3148 /*---------------------------------------------
3149 the data-type of key must be String or Symbol
3150 -----------------------------------------------*/
3151 key
= rb_ary_entry(pair
, 0);
3152 if(TYPE(key
) != T_STRING
&& TYPE(key
) != T_SYMBOL
) {
3153 /* clear name of dispatch parameters */
3154 for(i
= 1; i
< index
+ 1; i
++) {
3155 SysFreeString(pOp
->pNamedArgs
[i
]);
3157 /* clear dispatch parameters */
3158 for(i
= 0; i
< index
; i
++ ) {
3159 VariantClear(&(pOp
->dp
.rgvarg
[i
]));
3161 /* raise an exception */
3162 rb_raise(rb_eTypeError
, "wrong argument type (expected String or Symbol)");
3164 if (TYPE(key
) == T_SYMBOL
) {
3165 key
= rb_sym_to_s(key
);
3168 /* pNamedArgs[0] is <method name>, so "index + 1" */
3169 pOp
->pNamedArgs
[index
+ 1] = ole_vstr2wc(key
);
3171 value
= rb_ary_entry(pair
, 1);
3172 VariantInit(&(pOp
->dp
.rgvarg
[index
]));
3173 ole_val2variant(value
, &(pOp
->dp
.rgvarg
[index
]));
3175 pOp
->dp
.cNamedArgs
+= 1;
3180 set_argv(VARIANTARG
* realargs
, unsigned int beg
, unsigned int end
)
3182 VALUE argv
= rb_const_get(cWIN32OLE
, rb_intern("ARGV"));
3184 Check_Type(argv
, T_ARRAY
);
3186 while (end
-- > beg
) {
3187 rb_ary_push(argv
, ole_variant2val(&realargs
[end
]));
3188 VariantClear(&realargs
[end
]);
3194 ole_invoke(int argc
, VALUE
*argv
, VALUE self
, USHORT wFlags
, BOOL is_bracket
)
3196 LCID lcid
= cWIN32OLE_lcid
;
3197 struct oledata
*pole
;
3209 EXCEPINFO excepinfo
;
3211 VARIANTARG
* realargs
= NULL
;
3212 unsigned int argErr
= 0;
3214 unsigned int cNamedArgs
;
3217 struct olevariantdata
*pvar
;
3218 memset(&excepinfo
, 0, sizeof(EXCEPINFO
));
3220 VariantInit(&result
);
3222 op
.dp
.rgvarg
= NULL
;
3223 op
.dp
.rgdispidNamedArgs
= NULL
;
3224 op
.dp
.cNamedArgs
= 0;
3227 rb_scan_args(argc
, argv
, "1*", &cmd
, ¶mS
);
3228 if(TYPE(cmd
) != T_STRING
&& TYPE(cmd
) != T_SYMBOL
) {
3229 rb_raise(rb_eTypeError
, "method is wrong type (expected String or Symbol)");
3231 if (TYPE(cmd
) == T_SYMBOL
) {
3232 cmd
= rb_sym_to_s(cmd
);
3234 OLEData_Get_Struct(self
, pole
);
3235 if(!pole
->pDispatch
) {
3236 rb_raise(rb_eRuntimeError
, "failed to get dispatch interface");
3239 DispID
= DISPID_VALUE
;
3241 rb_ary_unshift(paramS
, cmd
);
3243 wcmdname
= ole_vstr2wc(cmd
);
3244 hr
= pole
->pDispatch
->lpVtbl
->GetIDsOfNames( pole
->pDispatch
, &IID_NULL
,
3245 &wcmdname
, 1, lcid
, &DispID
);
3246 SysFreeString(wcmdname
);
3248 ole_raise(hr
, eWIN32OLERuntimeError
,
3249 "unknown property or method: `%s'",
3250 StringValuePtr(cmd
));
3254 /* pick up last argument of method */
3255 param
= rb_ary_entry(paramS
, argc
-2);
3257 op
.dp
.cNamedArgs
= 0;
3259 /* if last arg is hash object */
3260 if(TYPE(param
) == T_HASH
) {
3261 /*------------------------------------------
3262 hash object ==> named dispatch parameters
3263 --------------------------------------------*/
3264 cNamedArgs
= NUM2INT(rb_funcall(param
, rb_intern("length"), 0));
3265 op
.dp
.cArgs
= cNamedArgs
+ argc
- 2;
3266 op
.pNamedArgs
= ALLOCA_N(OLECHAR
*, cNamedArgs
+ 1);
3267 op
.dp
.rgvarg
= ALLOCA_N(VARIANTARG
, op
.dp
.cArgs
);
3268 rb_block_call(param
, rb_intern("each"), 0, 0, hash2named_arg
, (VALUE
)&op
);
3270 pDispID
= ALLOCA_N(DISPID
, cNamedArgs
+ 1);
3271 op
.pNamedArgs
[0] = ole_vstr2wc(cmd
);
3272 hr
= pole
->pDispatch
->lpVtbl
->GetIDsOfNames(pole
->pDispatch
,
3275 op
.dp
.cNamedArgs
+ 1,
3277 for(i
= 0; i
< op
.dp
.cNamedArgs
+ 1; i
++) {
3278 SysFreeString(op
.pNamedArgs
[i
]);
3279 op
.pNamedArgs
[i
] = NULL
;
3282 /* clear dispatch parameters */
3283 for(i
= 0; i
< op
.dp
.cArgs
; i
++ ) {
3284 VariantClear(&op
.dp
.rgvarg
[i
]);
3286 ole_raise(hr
, eWIN32OLERuntimeError
,
3287 "failed to get named argument info: `%s'",
3288 StringValuePtr(cmd
));
3290 op
.dp
.rgdispidNamedArgs
= &(pDispID
[1]);
3294 op
.dp
.cArgs
= argc
- 1;
3295 op
.pNamedArgs
= ALLOCA_N(OLECHAR
*, cNamedArgs
+ 1);
3296 if (op
.dp
.cArgs
> 0) {
3297 op
.dp
.rgvarg
= ALLOCA_N(VARIANTARG
, op
.dp
.cArgs
);
3300 /*--------------------------------------
3301 non hash args ==> dispatch parameters
3302 ----------------------------------------*/
3303 if(op
.dp
.cArgs
> cNamedArgs
) {
3304 realargs
= ALLOCA_N(VARIANTARG
, op
.dp
.cArgs
-cNamedArgs
+1);
3305 for(i
= cNamedArgs
; i
< op
.dp
.cArgs
; i
++) {
3306 n
= op
.dp
.cArgs
- i
+ cNamedArgs
- 1;
3307 VariantInit(&realargs
[n
]);
3308 VariantInit(&op
.dp
.rgvarg
[n
]);
3309 param
= rb_ary_entry(paramS
, i
-cNamedArgs
);
3310 if (rb_obj_is_kind_of(param
, cWIN32OLE_VARIANT
)) {
3311 Data_Get_Struct(param
, struct olevariantdata
, pvar
);
3312 VariantCopy(&op
.dp
.rgvarg
[n
], &(pvar
->var
));
3314 ole_val2variant(param
, &realargs
[n
]);
3315 V_VT(&op
.dp
.rgvarg
[n
]) = VT_VARIANT
| VT_BYREF
;
3316 V_VARIANTREF(&op
.dp
.rgvarg
[n
]) = &realargs
[n
];
3320 /* apparent you need to call propput, you need this */
3321 if (wFlags
& DISPATCH_PROPERTYPUT
) {
3322 if (op
.dp
.cArgs
== 0)
3323 ole_raise(ResultFromScode(E_INVALIDARG
), eWIN32OLERuntimeError
, "argument error");
3325 op
.dp
.cNamedArgs
= 1;
3326 op
.dp
.rgdispidNamedArgs
= ALLOCA_N( DISPID
, 1 );
3327 op
.dp
.rgdispidNamedArgs
[0] = DISPID_PROPERTYPUT
;
3330 hr
= pole
->pDispatch
->lpVtbl
->Invoke(pole
->pDispatch
, DispID
,
3331 &IID_NULL
, lcid
, wFlags
, &op
.dp
,
3332 &result
, &excepinfo
, &argErr
);
3335 /* retry to call args by value */
3336 if(op
.dp
.cArgs
>= cNamedArgs
) {
3337 for(i
= cNamedArgs
; i
< op
.dp
.cArgs
; i
++) {
3338 n
= op
.dp
.cArgs
- i
+ cNamedArgs
- 1;
3339 param
= rb_ary_entry(paramS
, i
-cNamedArgs
);
3340 ole_val2variant(param
, &op
.dp
.rgvarg
[n
]);
3342 if (hr
== DISP_E_EXCEPTION
) {
3343 ole_freeexceptinfo(&excepinfo
);
3345 memset(&excepinfo
, 0, sizeof(EXCEPINFO
));
3346 VariantInit(&result
);
3347 hr
= pole
->pDispatch
->lpVtbl
->Invoke(pole
->pDispatch
, DispID
,
3348 &IID_NULL
, lcid
, wFlags
,
3350 &excepinfo
, &argErr
);
3352 /* mega kludge. if a method in WORD is called and we ask
3353 * for a result when one is not returned then
3354 * hResult == DISP_E_EXCEPTION. this only happens on
3355 * functions whose DISPID > 0x8000 */
3356 if ((hr
== DISP_E_EXCEPTION
|| hr
== DISP_E_MEMBERNOTFOUND
) && DispID
> 0x8000) {
3357 if (hr
== DISP_E_EXCEPTION
) {
3358 ole_freeexceptinfo(&excepinfo
);
3360 memset(&excepinfo
, 0, sizeof(EXCEPINFO
));
3361 hr
= pole
->pDispatch
->lpVtbl
->Invoke(pole
->pDispatch
, DispID
,
3362 &IID_NULL
, lcid
, wFlags
,
3364 &excepinfo
, &argErr
);
3367 for(i
= cNamedArgs
; i
< op
.dp
.cArgs
; i
++) {
3368 n
= op
.dp
.cArgs
- i
+ cNamedArgs
- 1;
3369 VariantClear(&op
.dp
.rgvarg
[n
]);
3374 /* retry after converting nil to VT_EMPTY */
3375 if (op
.dp
.cArgs
> cNamedArgs
) {
3376 for(i
= cNamedArgs
; i
< op
.dp
.cArgs
; i
++) {
3377 n
= op
.dp
.cArgs
- i
+ cNamedArgs
- 1;
3378 param
= rb_ary_entry(paramS
, i
-cNamedArgs
);
3379 ole_val2variant2(param
, &op
.dp
.rgvarg
[n
]);
3381 if (hr
== DISP_E_EXCEPTION
) {
3382 ole_freeexceptinfo(&excepinfo
);
3384 memset(&excepinfo
, 0, sizeof(EXCEPINFO
));
3385 VariantInit(&result
);
3386 hr
= pole
->pDispatch
->lpVtbl
->Invoke(pole
->pDispatch
, DispID
,
3387 &IID_NULL
, lcid
, wFlags
,
3389 &excepinfo
, &argErr
);
3390 for(i
= cNamedArgs
; i
< op
.dp
.cArgs
; i
++) {
3391 n
= op
.dp
.cArgs
- i
+ cNamedArgs
- 1;
3392 VariantClear(&op
.dp
.rgvarg
[n
]);
3398 /* clear dispatch parameter */
3399 if(op
.dp
.cArgs
> cNamedArgs
) {
3400 for(i
= cNamedArgs
; i
< op
.dp
.cArgs
; i
++) {
3401 n
= op
.dp
.cArgs
- i
+ cNamedArgs
- 1;
3402 param
= rb_ary_entry(paramS
, i
-cNamedArgs
);
3403 if (rb_obj_is_kind_of(param
, cWIN32OLE_VARIANT
)) {
3404 ole_val2variant(param
, &realargs
[n
]);
3407 set_argv(realargs
, cNamedArgs
, op
.dp
.cArgs
);
3410 for(i
= 0; i
< op
.dp
.cArgs
; i
++) {
3411 VariantClear(&op
.dp
.rgvarg
[i
]);
3416 v
= ole_excepinfo2msg(&excepinfo
);
3417 ole_raise(hr
, eWIN32OLERuntimeError
, "(in OLE method `%s': )%s",
3418 StringValuePtr(cmd
),
3421 obj
= ole_variant2val(&result
);
3422 VariantClear(&result
);
3428 * WIN32OLE#invoke(method, [arg1,...]) => return value of method.
3431 * The first argument specifies the method name of OLE Automation object.
3432 * The others specify argument of the <i>method</i>.
3433 * If you can not execute <i>method</i> directly, then use this method instead.
3435 * excel = WIN32OLE.new('Excel.Application')
3436 * excel.invoke('Quit') # => same as excel.Quit
3440 fole_invoke(int argc
, VALUE
*argv
, VALUE self
)
3442 return ole_invoke(argc
, argv
, self
, DISPATCH_METHOD
|DISPATCH_PROPERTYGET
, FALSE
);
3446 ole_invoke2(VALUE self
, VALUE dispid
, VALUE args
, VALUE types
, USHORT dispkind
)
3449 struct oledata
*pole
;
3450 unsigned int argErr
= 0;
3451 EXCEPINFO excepinfo
;
3453 DISPPARAMS dispParams
;
3454 VARIANTARG
* realargs
= NULL
;
3461 Check_Type(args
, T_ARRAY
);
3462 Check_Type(types
, T_ARRAY
);
3464 memset(&excepinfo
, 0, sizeof(EXCEPINFO
));
3465 memset(&dispParams
, 0, sizeof(DISPPARAMS
));
3466 VariantInit(&result
);
3467 OLEData_Get_Struct(self
, pole
);
3469 dispParams
.cArgs
= RARRAY_LEN(args
);
3470 dispParams
.rgvarg
= ALLOCA_N(VARIANTARG
, dispParams
.cArgs
);
3471 realargs
= ALLOCA_N(VARIANTARG
, dispParams
.cArgs
);
3472 for (i
= 0, j
= dispParams
.cArgs
- 1; i
< (int)dispParams
.cArgs
; i
++, j
--)
3474 VariantInit(&realargs
[i
]);
3475 VariantInit(&dispParams
.rgvarg
[i
]);
3476 tp
= rb_ary_entry(types
, j
);
3477 vt
= (VARTYPE
)FIX2INT(tp
);
3478 V_VT(&dispParams
.rgvarg
[i
]) = vt
;
3479 param
= rb_ary_entry(args
, j
);
3483 V_VT(&dispParams
.rgvarg
[i
]) = V_VT(&realargs
[i
]) = VT_ERROR
;
3484 V_ERROR(&dispParams
.rgvarg
[i
]) = V_ERROR(&realargs
[i
]) = DISP_E_PARAMNOTFOUND
;
3497 SAFEARRAYBOUND rgsabound
[1];
3498 Check_Type(param
, T_ARRAY
);
3499 rgsabound
[0].lLbound
= 0;
3500 rgsabound
[0].cElements
= RARRAY_LEN(param
);
3501 v
= vt
& ~(VT_ARRAY
| VT_BYREF
);
3502 V_ARRAY(&realargs
[i
]) = SafeArrayCreate(v
, 1, rgsabound
);
3503 V_VT(&realargs
[i
]) = VT_ARRAY
| v
;
3504 SafeArrayLock(V_ARRAY(&realargs
[i
]));
3505 pb
= V_ARRAY(&realargs
[i
])->pvData
;
3506 ps
= V_ARRAY(&realargs
[i
])->pvData
;
3507 pl
= V_ARRAY(&realargs
[i
])->pvData
;
3508 py
= V_ARRAY(&realargs
[i
])->pvData
;
3509 pv
= V_ARRAY(&realargs
[i
])->pvData
;
3510 for (ent
= 0; ent
< (int)rgsabound
[0].cElements
; ent
++)
3513 VALUE elem
= rb_ary_entry(param
, ent
);
3514 ole_val2variant(elem
, &velem
);
3515 if (v
!= VT_VARIANT
)
3517 VariantChangeTypeEx(&velem
, &velem
,
3518 cWIN32OLE_lcid
, 0, v
);
3530 *py
++ = V_CY(&velem
);
3536 *ps
++ = V_I2(&velem
);
3541 *pb
++ = V_UI1(&velem
);
3545 *pl
++ = V_I4(&velem
);
3549 SafeArrayUnlock(V_ARRAY(&realargs
[i
]));
3553 ole_val2variant(param
, &realargs
[i
]);
3554 if ((vt
& (~VT_BYREF
)) != VT_VARIANT
)
3556 hr
= VariantChangeTypeEx(&realargs
[i
], &realargs
[i
],
3558 (VARTYPE
)(vt
& (~VT_BYREF
)));
3561 rb_raise(rb_eTypeError
, "not valid value");
3565 if ((vt
& VT_BYREF
) || vt
== VT_VARIANT
)
3567 if (vt
== VT_VARIANT
)
3568 V_VT(&dispParams
.rgvarg
[i
]) = VT_VARIANT
| VT_BYREF
;
3569 switch (vt
& (~VT_BYREF
))
3573 V_VARIANTREF(&dispParams
.rgvarg
[i
]) = &realargs
[i
];
3579 V_CYREF(&dispParams
.rgvarg
[i
]) = &V_CY(&realargs
[i
]);
3585 V_I2REF(&dispParams
.rgvarg
[i
]) = &V_I2(&realargs
[i
]);
3590 V_UI1REF(&dispParams
.rgvarg
[i
]) = &V_UI1(&realargs
[i
]);
3594 V_I4REF(&dispParams
.rgvarg
[i
]) = &V_I4(&realargs
[i
]);
3600 /* copy 64 bits of data */
3601 V_CY(&dispParams
.rgvarg
[i
]) = V_CY(&realargs
[i
]);
3606 if (dispkind
& DISPATCH_PROPERTYPUT
) {
3607 dispParams
.cNamedArgs
= 1;
3608 dispParams
.rgdispidNamedArgs
= ALLOCA_N( DISPID
, 1 );
3609 dispParams
.rgdispidNamedArgs
[0] = DISPID_PROPERTYPUT
;
3612 hr
= pole
->pDispatch
->lpVtbl
->Invoke(pole
->pDispatch
, NUM2INT(dispid
),
3613 &IID_NULL
, cWIN32OLE_lcid
,
3615 &dispParams
, &result
,
3616 &excepinfo
, &argErr
);
3619 v
= ole_excepinfo2msg(&excepinfo
);
3620 ole_raise(hr
, eWIN32OLERuntimeError
, "(in OLE method `<dispatch id:%d>': )%s",
3625 /* clear dispatch parameter */
3626 if(dispParams
.cArgs
> 0) {
3627 set_argv(realargs
, 0, dispParams
.cArgs
);
3630 obj
= ole_variant2val(&result
);
3631 VariantClear(&result
);
3637 * WIN32OLE#_invoke(dispid, args, types)
3639 * Runs the early binding method.
3640 * The 1st argument specifies dispatch ID,
3641 * the 2nd argument specifies the array of arguments,
3642 * the 3rd argument specifies the array of the type of arguments.
3644 * excel = WIN32OLE.new('Excel.Application')
3645 * excel._invoke(302, [], []) # same effect as excel.Quit
3648 fole_invoke2(VALUE self
, VALUE dispid
, VALUE args
, VALUE types
)
3650 return ole_invoke2(self
, dispid
, args
, types
, DISPATCH_METHOD
);
3655 * WIN32OLE#_getproperty(dispid, args, types)
3657 * Runs the early binding method to get property.
3658 * The 1st argument specifies dispatch ID,
3659 * the 2nd argument specifies the array of arguments,
3660 * the 3rd argument specifies the array of the type of arguments.
3662 * excel = WIN32OLE.new('Excel.Application')
3663 * puts excel._getproperty(558, [], []) # same effect as puts excel.visible
3666 fole_getproperty2(VALUE self
, VALUE dispid
, VALUE args
, VALUE types
)
3668 return ole_invoke2(self
, dispid
, args
, types
, DISPATCH_PROPERTYGET
);
3673 * WIN32OLE#_setproperty(dispid, args, types)
3675 * Runs the early binding method to set property.
3676 * The 1st argument specifies dispatch ID,
3677 * the 2nd argument specifies the array of arguments,
3678 * the 3rd argument specifies the array of the type of arguments.
3680 * excel = WIN32OLE.new('Excel.Application')
3681 * excel._setproperty(558, [true], [WIN32OLE::VARIANT::VT_BOOL]) # same effect as excel.visible = true
3684 fole_setproperty2(VALUE self
, VALUE dispid
, VALUE args
, VALUE types
)
3686 return ole_invoke2(self
, dispid
, args
, types
, DISPATCH_PROPERTYPUT
);
3691 * WIN32OLE[a1, a2, ...]=val
3693 * Sets the value to WIN32OLE object specified by a1, a2, ...
3695 * dict = WIN32OLE.new('Scripting.Dictionary')
3696 * dict.add('ruby', 'RUBY')
3697 * dict['ruby'] = 'Ruby'
3698 * puts dict['ruby'] # => 'Ruby'
3700 * Remark: You can not use this method to set the property value.
3702 * excel = WIN32OLE.new('Excel.Application')
3703 * # excel['Visible'] = true # This is error !!!
3704 * excel.Visible = true # You should to use this style to set the property.
3708 fole_setproperty_with_bracket(int argc
, VALUE
*argv
, VALUE self
)
3710 return ole_invoke(argc
, argv
, self
, DISPATCH_PROPERTYPUT
, TRUE
);
3715 * WIN32OLE.setproperty('property', [arg1, arg2,...] val)
3717 * Sets property of OLE object.
3718 * When you want to set property with argument, you can use this method.
3720 * excel = WIN32OLE.new('Excel.Application')
3721 * excel.Visible = true
3722 * book = excel.workbooks.add
3723 * sheet = book.worksheets(1)
3724 * sheet.setproperty('Cells', 1, 2, 10) # => The B1 cell value is 10.
3727 fole_setproperty(int argc
, VALUE
*argv
, VALUE self
)
3729 return ole_invoke(argc
, argv
, self
, DISPATCH_PROPERTYPUT
, FALSE
);
3734 * WIN32OLE[a1,a2,...]
3736 * Returns the value of Collection specified by a1, a2,....
3738 * dict = WIN32OLE.new('Scripting.Dictionary')
3739 * dict.add('ruby', 'Ruby')
3740 * puts dict['ruby'] # => 'Ruby' (same as `puts dict.item('ruby')')
3742 * Remark: You can not use this method to get the property.
3743 * excel = WIN32OLE.new('Excel.Application')
3744 * # puts excel['Visible'] This is error !!!
3745 * puts excel.Visible # You should to use this style to get the property.
3749 fole_getproperty_with_bracket(int argc
, VALUE
*argv
, VALUE self
)
3751 return ole_invoke(argc
, argv
, self
, DISPATCH_PROPERTYGET
, TRUE
);
3755 ole_propertyput(VALUE self
, VALUE property
, VALUE value
)
3757 struct oledata
*pole
;
3761 EXCEPINFO excepinfo
;
3762 DISPID dispID
= DISPID_VALUE
;
3763 DISPID dispIDParam
= DISPID_PROPERTYPUT
;
3764 USHORT wFlags
= DISPATCH_PROPERTYPUT
|DISPATCH_PROPERTYPUTREF
;
3765 DISPPARAMS dispParams
;
3766 VARIANTARG propertyValue
[2];
3769 LCID lcid
= cWIN32OLE_lcid
;
3770 dispParams
.rgdispidNamedArgs
= &dispIDParam
;
3771 dispParams
.rgvarg
= propertyValue
;
3772 dispParams
.cNamedArgs
= 1;
3773 dispParams
.cArgs
= 1;
3775 VariantInit(&propertyValue
[0]);
3776 VariantInit(&propertyValue
[1]);
3777 memset(&excepinfo
, 0, sizeof(excepinfo
));
3779 OLEData_Get_Struct(self
, pole
);
3781 /* get ID from property name */
3782 pBuf
[0] = ole_vstr2wc(property
);
3783 hr
= pole
->pDispatch
->lpVtbl
->GetIDsOfNames(pole
->pDispatch
, &IID_NULL
,
3784 pBuf
, 1, lcid
, &dispID
);
3785 SysFreeString(pBuf
[0]);
3789 ole_raise(hr
, eWIN32OLERuntimeError
,
3790 "unknown property or method: `%s'",
3791 StringValuePtr(property
));
3793 /* set property value */
3794 ole_val2variant(value
, &propertyValue
[0]);
3795 hr
= pole
->pDispatch
->lpVtbl
->Invoke(pole
->pDispatch
, dispID
, &IID_NULL
,
3796 lcid
, wFlags
, &dispParams
,
3797 NULL
, &excepinfo
, &argErr
);
3799 for(index
= 0; index
< dispParams
.cArgs
; ++index
) {
3800 VariantClear(&propertyValue
[index
]);
3803 v
= ole_excepinfo2msg(&excepinfo
);
3804 ole_raise(hr
, eWIN32OLERuntimeError
, "(in setting property `%s': )%s",
3805 StringValuePtr(property
),
3815 * invokes Release method of Dispatch interface of WIN32OLE object.
3816 * Usually, you do not need to call this method because Release method
3817 * called automatically when WIN32OLE object garbaged.
3821 fole_free(VALUE self
)
3823 struct oledata
*pole
;
3825 OLEData_Get_Struct(self
, pole
);
3826 OLE_FREE(pole
->pDispatch
);
3827 pole
->pDispatch
= NULL
;
3832 ole_each_sub(VALUE pEnumV
)
3836 IEnumVARIANT
*pEnum
= (IEnumVARIANT
*)pEnumV
;
3837 VariantInit(&variant
);
3838 while(pEnum
->lpVtbl
->Next(pEnum
, 1, &variant
, NULL
) == S_OK
) {
3839 obj
= ole_variant2val(&variant
);
3840 VariantClear(&variant
);
3841 VariantInit(&variant
);
3848 ole_ienum_free(VALUE pEnumV
)
3850 IEnumVARIANT
*pEnum
= (IEnumVARIANT
*)pEnumV
;
3857 * WIN32OLE#each {|i|...}
3859 * Iterates over each item of OLE collection which has IEnumVARIANT interface.
3861 * excel = WIN32OLE.new('Excel.Application')
3862 * book = excel.workbooks.add
3863 * sheets = book.worksheets(1)
3864 * cells = sheets.cells("A1:A5")
3865 * cells.each do |cell|
3870 fole_each(VALUE self
)
3872 LCID lcid
= cWIN32OLE_lcid
;
3874 struct oledata
*pole
;
3876 unsigned int argErr
;
3877 EXCEPINFO excepinfo
;
3878 DISPPARAMS dispParams
;
3881 IEnumVARIANT
*pEnum
= NULL
;
3884 RETURN_ENUMERATOR(self
, 0, 0);
3886 VariantInit(&result
);
3887 dispParams
.rgvarg
= NULL
;
3888 dispParams
.rgdispidNamedArgs
= NULL
;
3889 dispParams
.cNamedArgs
= 0;
3890 dispParams
.cArgs
= 0;
3891 memset(&excepinfo
, 0, sizeof(excepinfo
));
3893 OLEData_Get_Struct(self
, pole
);
3894 hr
= pole
->pDispatch
->lpVtbl
->Invoke(pole
->pDispatch
, DISPID_NEWENUM
,
3896 DISPATCH_METHOD
| DISPATCH_PROPERTYGET
,
3897 &dispParams
, &result
,
3898 &excepinfo
, &argErr
);
3901 VariantClear(&result
);
3902 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to get IEnum Interface");
3905 if (V_VT(&result
) == VT_UNKNOWN
) {
3906 hr
= V_UNKNOWN(&result
)->lpVtbl
->QueryInterface(V_UNKNOWN(&result
),
3910 } else if (V_VT(&result
) == VT_DISPATCH
) {
3911 hr
= V_DISPATCH(&result
)->lpVtbl
->QueryInterface(V_DISPATCH(&result
),
3916 if (FAILED(hr
) || !pEnum
) {
3917 VariantClear(&result
);
3918 ole_raise(hr
, rb_eRuntimeError
, "failed to get IEnum Interface");
3921 VariantClear(&result
);
3922 rb_ensure(ole_each_sub
, (VALUE
)pEnum
, ole_ienum_free
, (VALUE
)pEnum
);
3928 * WIN32OLE#method_missing(id [,arg1, arg2, ...])
3930 * Calls WIN32OLE#invoke method.
3933 fole_missing(int argc
, VALUE
*argv
, VALUE self
)
3938 id
= rb_to_id(argv
[0]);
3939 mname
= rb_id2name(id
);
3941 rb_raise(rb_eRuntimeError
, "fail: unknown method or property");
3944 if(mname
[n
-1] == '=') {
3945 argv
[0] = rb_enc_str_new(mname
, n
-1, cWIN32OLE_enc
);
3947 return ole_propertyput(self
, argv
[0], argv
[1]);
3950 argv
[0] = rb_enc_str_new(mname
, n
, cWIN32OLE_enc
);
3951 return ole_invoke(argc
, argv
, self
, DISPATCH_METHOD
|DISPATCH_PROPERTYGET
, FALSE
);
3956 ole_method_sub(VALUE self
, ITypeInfo
*pOwnerTypeInfo
, ITypeInfo
*pTypeInfo
, VALUE name
)
3959 TYPEATTR
*pTypeAttr
;
3961 FUNCDESC
*pFuncDesc
;
3964 VALUE method
= Qnil
;
3965 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
3967 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to GetTypeAttr");
3969 for(i
= 0; i
< pTypeAttr
->cFuncs
&& method
== Qnil
; i
++) {
3970 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, i
, &pFuncDesc
);
3974 hr
= pTypeInfo
->lpVtbl
->GetDocumentation(pTypeInfo
, pFuncDesc
->memid
,
3975 &bstr
, NULL
, NULL
, NULL
);
3977 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
3980 fname
= WC2VSTR(bstr
);
3981 if (strcasecmp(StringValuePtr(name
), StringValuePtr(fname
)) == 0) {
3982 olemethod_set_member(self
, pTypeInfo
, pOwnerTypeInfo
, i
, fname
);
3985 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
3988 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
3993 olemethod_from_typeinfo(VALUE self
, ITypeInfo
*pTypeInfo
, VALUE name
)
3996 TYPEATTR
*pTypeAttr
;
3999 ITypeInfo
*pRefTypeInfo
;
4000 VALUE method
= Qnil
;
4001 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
4003 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to GetTypeAttr");
4005 method
= ole_method_sub(self
, 0, pTypeInfo
, name
);
4006 if (method
!= Qnil
) {
4009 for(i
=0; i
< pTypeAttr
->cImplTypes
&& method
== Qnil
; i
++){
4010 hr
= pTypeInfo
->lpVtbl
->GetRefTypeOfImplType(pTypeInfo
, i
, &href
);
4013 hr
= pTypeInfo
->lpVtbl
->GetRefTypeInfo(pTypeInfo
, href
, &pRefTypeInfo
);
4016 method
= ole_method_sub(self
, pTypeInfo
, pRefTypeInfo
, name
);
4017 OLE_RELEASE(pRefTypeInfo
);
4019 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
4024 ole_methods_sub(ITypeInfo
*pOwnerTypeInfo
, ITypeInfo
*pTypeInfo
, VALUE methods
, int mask
)
4027 TYPEATTR
*pTypeAttr
;
4030 FUNCDESC
*pFuncDesc
;
4033 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
4035 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to GetTypeAttr");
4037 for(i
= 0; i
< pTypeAttr
->cFuncs
; i
++) {
4039 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, i
, &pFuncDesc
);
4043 hr
= pTypeInfo
->lpVtbl
->GetDocumentation(pTypeInfo
, pFuncDesc
->memid
,
4044 &bstr
, NULL
, NULL
, NULL
);
4046 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
4049 if(pFuncDesc
->invkind
& mask
) {
4050 method
= folemethod_s_allocate(cWIN32OLE_METHOD
);
4051 olemethod_set_member(method
, pTypeInfo
, pOwnerTypeInfo
,
4053 rb_ary_push(methods
, method
);
4055 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
4058 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
4064 ole_methods_from_typeinfo(ITypeInfo
*pTypeInfo
, int mask
)
4067 TYPEATTR
*pTypeAttr
;
4070 ITypeInfo
*pRefTypeInfo
;
4071 VALUE methods
= rb_ary_new();
4072 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
4074 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to GetTypeAttr");
4077 ole_methods_sub(0, pTypeInfo
, methods
, mask
);
4078 for(i
=0; i
< pTypeAttr
->cImplTypes
; i
++){
4079 hr
= pTypeInfo
->lpVtbl
->GetRefTypeOfImplType(pTypeInfo
, i
, &href
);
4082 hr
= pTypeInfo
->lpVtbl
->GetRefTypeInfo(pTypeInfo
, href
, &pRefTypeInfo
);
4085 ole_methods_sub(pTypeInfo
, pRefTypeInfo
, methods
, mask
);
4086 OLE_RELEASE(pRefTypeInfo
);
4088 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
4093 typeinfo_from_ole(struct oledata
*pole
, ITypeInfo
**ppti
)
4095 ITypeInfo
*pTypeInfo
;
4101 LCID lcid
= cWIN32OLE_lcid
;
4102 HRESULT hr
= pole
->pDispatch
->lpVtbl
->GetTypeInfo(pole
->pDispatch
,
4103 0, lcid
, &pTypeInfo
);
4105 ole_raise(hr
, rb_eRuntimeError
, "failed to GetTypeInfo");
4107 hr
= pTypeInfo
->lpVtbl
->GetDocumentation(pTypeInfo
,
4111 type
= WC2VSTR(bstr
);
4112 hr
= pTypeInfo
->lpVtbl
->GetContainingTypeLib(pTypeInfo
, &pTypeLib
, &i
);
4113 OLE_RELEASE(pTypeInfo
);
4115 ole_raise(hr
, rb_eRuntimeError
, "failed to GetContainingTypeLib");
4117 count
= pTypeLib
->lpVtbl
->GetTypeInfoCount(pTypeLib
);
4118 for (i
= 0; i
< count
; i
++) {
4119 hr
= pTypeLib
->lpVtbl
->GetDocumentation(pTypeLib
, i
,
4120 &bstr
, NULL
, NULL
, NULL
);
4121 if (SUCCEEDED(hr
) && rb_str_cmp(WC2VSTR(bstr
), type
) == 0) {
4122 hr
= pTypeLib
->lpVtbl
->GetTypeInfo(pTypeLib
, i
, &pTypeInfo
);
4123 if (SUCCEEDED(hr
)) {
4129 OLE_RELEASE(pTypeLib
);
4134 ole_methods(VALUE self
, int mask
)
4136 ITypeInfo
*pTypeInfo
;
4139 struct oledata
*pole
;
4141 OLEData_Get_Struct(self
, pole
);
4142 methods
= rb_ary_new();
4144 hr
= typeinfo_from_ole(pole
, &pTypeInfo
);
4147 rb_ary_concat(methods
, ole_methods_from_typeinfo(pTypeInfo
, mask
));
4148 OLE_RELEASE(pTypeInfo
);
4154 * WIN32OLE#ole_methods
4156 * Returns the array of WIN32OLE_METHOD object.
4157 * The element is OLE method of WIN32OLE object.
4159 * excel = WIN32OLE.new('Excel.Application')
4160 * methods = excel.ole_methods
4164 fole_methods(VALUE self
)
4166 return ole_methods( self
, INVOKE_FUNC
| INVOKE_PROPERTYGET
| INVOKE_PROPERTYPUT
| INVOKE_PROPERTYPUTREF
);
4171 * WIN32OLE#ole_get_methods
4173 * Returns the array of WIN32OLE_METHOD object .
4174 * The element of the array is property (gettable) of WIN32OLE object.
4176 * excel = WIN32OLE.new('Excel.Application')
4177 * properties = excel.ole_get_methods
4180 fole_get_methods(VALUE self
)
4182 return ole_methods( self
, INVOKE_PROPERTYGET
);
4187 * WIN32OLE#ole_put_methods
4189 * Returns the array of WIN32OLE_METHOD object .
4190 * The element of the array is property (settable) of WIN32OLE object.
4192 * excel = WIN32OLE.new('Excel.Application')
4193 * properties = excel.ole_put_methods
4196 fole_put_methods(VALUE self
)
4198 return ole_methods( self
, INVOKE_PROPERTYPUT
|INVOKE_PROPERTYPUTREF
);
4203 * WIN32OLE#ole_func_methods
4205 * Returns the array of WIN32OLE_METHOD object .
4206 * The element of the array is property (settable) of WIN32OLE object.
4208 * excel = WIN32OLE.new('Excel.Application')
4209 * properties = excel.ole_func_methods
4213 fole_func_methods(VALUE self
)
4215 return ole_methods( self
, INVOKE_FUNC
);
4219 ole_type_from_itypeinfo(ITypeInfo
*pTypeInfo
)
4227 hr
= pTypeInfo
->lpVtbl
->GetContainingTypeLib( pTypeInfo
, &pTypeLib
, &index
);
4231 hr
= pTypeLib
->lpVtbl
->GetDocumentation( pTypeLib
, index
,
4232 &bstr
, NULL
, NULL
, NULL
);
4233 OLE_RELEASE(pTypeLib
);
4237 type
= foletype_s_allocate(cWIN32OLE_TYPE
);
4238 oletype_set_member(type
, pTypeInfo
, WC2VSTR(bstr
));
4246 * Returns WIN32OLE_TYPE object.
4248 * excel = WIN32OLE.new('Excel.Application')
4249 * tobj = excel.ole_type
4252 fole_type(VALUE self
)
4254 ITypeInfo
*pTypeInfo
;
4256 struct oledata
*pole
;
4257 LCID lcid
= cWIN32OLE_lcid
;
4260 OLEData_Get_Struct(self
, pole
);
4262 hr
= pole
->pDispatch
->lpVtbl
->GetTypeInfo( pole
->pDispatch
, 0, lcid
, &pTypeInfo
);
4264 ole_raise(hr
, rb_eRuntimeError
, "failed to GetTypeInfo");
4266 type
= ole_type_from_itypeinfo(pTypeInfo
);
4267 OLE_RELEASE(pTypeInfo
);
4269 rb_raise(rb_eRuntimeError
, "failed to create WIN32OLE_TYPE obj from ITypeInfo");
4275 make_oletypelib_obj(VALUE guid
, VALUE major_version
, VALUE minor_version
)
4277 VALUE args
= rb_ary_new();
4278 rb_ary_push(args
, guid
);
4279 rb_ary_push(args
, major_version
);
4280 rb_ary_push(args
, minor_version
);
4281 return rb_apply(cWIN32OLE_TYPELIB
, rb_intern("new"), args
);
4285 ole_typelib_from_itypelib(ITypeLib
*pTypeLib
)
4287 TLIBATTR
*pTLibAttr
;
4294 hr
= pTypeLib
->lpVtbl
->GetLibAttr(pTypeLib
, &pTLibAttr
);
4298 len
= StringFromGUID2(&pTLibAttr
->guid
, bstr
, sizeof(bstr
)/sizeof(OLECHAR
));
4300 guid
= ole_wc2vstr(bstr
, FALSE
);
4302 major
= INT2NUM(pTLibAttr
->wMajorVerNum
);
4303 minor
= INT2NUM(pTLibAttr
->wMinorVerNum
);
4304 pTypeLib
->lpVtbl
->ReleaseTLibAttr(pTypeLib
, pTLibAttr
);
4308 return make_oletypelib_obj(guid
, major
, minor
);
4313 ole_typelib_from_itypeinfo(ITypeInfo
*pTypeInfo
)
4318 VALUE retval
= Qnil
;
4320 hr
= pTypeInfo
->lpVtbl
->GetContainingTypeLib(pTypeInfo
, &pTypeLib
, &index
);
4324 retval
= ole_typelib_from_itypelib(pTypeLib
);
4325 OLE_RELEASE(pTypeLib
);
4331 * WIN32OLE#ole_typelib -> The WIN32OLE_TYPELIB object
4333 * Returns the WIN32OLE_TYPELIB object. The object represents the
4334 * type library which contains the WIN32OLE object.
4336 * excel = WIN32OLE.new('Excel.Application')
4337 * tlib = excel.ole_typelib
4338 * puts tlib.name # -> 'Microsoft Excel 9.0 Object Library'
4341 fole_typelib(VALUE self
)
4343 struct oledata
*pole
;
4345 ITypeInfo
*pTypeInfo
;
4346 LCID lcid
= cWIN32OLE_lcid
;
4349 OLEData_Get_Struct(self
, pole
);
4350 hr
= pole
->pDispatch
->lpVtbl
->GetTypeInfo(pole
->pDispatch
,
4351 0, lcid
, &pTypeInfo
);
4353 ole_raise(hr
, rb_eRuntimeError
, "failed to GetTypeInfo");
4355 vtlib
= ole_typelib_from_itypeinfo(pTypeInfo
);
4356 OLE_RELEASE(pTypeInfo
);
4357 if (vtlib
== Qnil
) {
4358 rb_raise(rb_eRuntimeError
, "failed to get type library info.");
4365 * WIN32OLE#ole_query_interface(iid) -> WIN32OLE object
4367 * Returns WIN32OLE object for a specific dispatch or dual
4368 * interface specified by iid.
4370 * ie = WIN32OLE.new('InternetExplorer.Application')
4371 * ie_web_app = ie.ole_query_interface('{0002DF05-0000-0000-C000-000000000046}') # => WIN32OLE object for dispinterface IWebBrowserApp
4374 fole_query_interface(VALUE self
, VALUE str_iid
)
4379 struct oledata
*pole
;
4380 IDispatch
*pDispatch
;
4383 pBuf
= ole_vstr2wc(str_iid
);
4384 hr
= CLSIDFromString(pBuf
, &iid
);
4385 SysFreeString(pBuf
);
4387 ole_raise(hr
, eWIN32OLERuntimeError
,
4388 "invalid iid: `%s'",
4389 StringValuePtr(str_iid
));
4392 OLEData_Get_Struct(self
, pole
);
4393 if(!pole
->pDispatch
) {
4394 rb_raise(rb_eRuntimeError
, "failed to get dispatch interface");
4397 hr
= pole
->pDispatch
->lpVtbl
->QueryInterface(pole
->pDispatch
, &iid
,
4400 ole_raise(hr
, eWIN32OLERuntimeError
,
4401 "failed to get interface `%s'",
4402 StringValuePtr(str_iid
));
4406 return create_win32ole_object(cWIN32OLE
, pDispatch
, 0, 0);
4411 * WIN32OLE#ole_respond_to?(method) -> true or false
4413 * Returns true when OLE object has OLE method, otherwise returns false.
4415 * ie = WIN32OLE.new('InternetExplorer.Application')
4416 * ie.ole_respond_to?("gohome") => true
4419 fole_respond_to(VALUE self
, VALUE method
)
4421 struct oledata
*pole
;
4426 if(TYPE(method
) != T_STRING
&& TYPE(method
) != T_SYMBOL
) {
4427 rb_raise(rb_eTypeError
, "wrong argument type (expected String or Symbol)");
4429 if (TYPE(method
) == T_SYMBOL
) {
4430 method
= rb_sym_to_s(method
);
4432 OLEData_Get_Struct(self
, pole
);
4433 wcmdname
= ole_vstr2wc(method
);
4434 hr
= pole
->pDispatch
->lpVtbl
->GetIDsOfNames( pole
->pDispatch
, &IID_NULL
,
4435 &wcmdname
, 1, cWIN32OLE_lcid
, &DispID
);
4436 SysFreeString(wcmdname
);
4437 return SUCCEEDED(hr
) ? Qtrue
: Qfalse
;
4441 ole_docinfo_from_type(ITypeInfo
*pTypeInfo
, BSTR
*name
, BSTR
*helpstr
, DWORD
*helpcontext
, BSTR
*helpfile
)
4447 hr
= pTypeInfo
->lpVtbl
->GetContainingTypeLib(pTypeInfo
, &pTypeLib
, &i
);
4452 hr
= pTypeLib
->lpVtbl
->GetDocumentation(pTypeLib
, i
,
4454 helpcontext
, helpfile
);
4456 OLE_RELEASE(pTypeLib
);
4459 OLE_RELEASE(pTypeLib
);
4464 ole_usertype2val(ITypeInfo
*pTypeInfo
, TYPEDESC
*pTypeDesc
, VALUE typedetails
)
4468 ITypeInfo
*pRefTypeInfo
;
4471 hr
= pTypeInfo
->lpVtbl
->GetRefTypeInfo(pTypeInfo
,
4472 V_UNION1(pTypeDesc
, hreftype
),
4476 hr
= ole_docinfo_from_type(pRefTypeInfo
, &bstr
, NULL
, NULL
, NULL
);
4478 OLE_RELEASE(pRefTypeInfo
);
4481 OLE_RELEASE(pRefTypeInfo
);
4482 type
= WC2VSTR(bstr
);
4483 if(typedetails
!= Qnil
)
4484 rb_ary_push(typedetails
, type
);
4489 ole_ptrtype2val(ITypeInfo
*pTypeInfo
, TYPEDESC
*pTypeDesc
, VALUE typedetails
)
4491 TYPEDESC
*p
= pTypeDesc
;
4492 VALUE type
= rb_str_new2("");
4494 if (p
->vt
== VT_PTR
|| p
->vt
== VT_SAFEARRAY
) {
4495 p
= V_UNION1(p
, lptdesc
);
4496 type
= ole_typedesc2val(pTypeInfo
, p
, typedetails
);
4502 ole_typedesc2val(ITypeInfo
*pTypeInfo
, TYPEDESC
*pTypeDesc
, VALUE typedetails
)
4505 VALUE typestr
= Qnil
;
4506 switch(pTypeDesc
->vt
) {
4508 typestr
= rb_str_new2("I2");
4511 typestr
= rb_str_new2("I4");
4514 typestr
= rb_str_new2("R4");
4517 typestr
= rb_str_new2("R8");
4520 typestr
= rb_str_new2("CY");
4523 typestr
= rb_str_new2("DATE");
4526 typestr
= rb_str_new2("BSTR");
4529 typestr
= rb_str_new2("BOOL");
4532 typestr
= rb_str_new2("VARIANT");
4535 typestr
= rb_str_new2("DECIMAL");
4538 typestr
= rb_str_new2("I1");
4541 typestr
= rb_str_new2("UI1");
4544 typestr
= rb_str_new2("UI2");
4547 typestr
= rb_str_new2("UI4");
4549 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
4551 typestr
= rb_str_new2("I8");
4554 typestr
= rb_str_new2("UI8");
4558 typestr
= rb_str_new2("INT");
4561 typestr
= rb_str_new2("UINT");
4564 typestr
= rb_str_new2("VOID");
4567 typestr
= rb_str_new2("HRESULT");
4570 typestr
= rb_str_new2("PTR");
4571 if(typedetails
!= Qnil
)
4572 rb_ary_push(typedetails
, typestr
);
4573 return ole_ptrtype2val(pTypeInfo
, pTypeDesc
, typedetails
);
4575 typestr
= rb_str_new2("SAFEARRAY");
4576 if(typedetails
!= Qnil
)
4577 rb_ary_push(typedetails
, typestr
);
4578 return ole_ptrtype2val(pTypeInfo
, pTypeDesc
, typedetails
);
4580 typestr
= rb_str_new2("CARRAY");
4582 case VT_USERDEFINED
:
4583 typestr
= rb_str_new2("USERDEFINED");
4584 if (typedetails
!= Qnil
)
4585 rb_ary_push(typedetails
, typestr
);
4586 str
= ole_usertype2val(pTypeInfo
, pTypeDesc
, typedetails
);
4592 typestr
= rb_str_new2("UNKNOWN");
4595 typestr
= rb_str_new2("DISPATCH");
4598 typestr
= rb_str_new2("ERROR");
4601 typestr
= rb_str_new2("LPWSTR");
4604 typestr
= rb_str_new2("LPSTR");
4607 typestr
= rb_str_new2("Unknown Type ");
4608 rb_str_concat(typestr
, rb_fix2str(INT2FIX(pTypeDesc
->vt
), 10));
4611 if (typedetails
!= Qnil
)
4612 rb_ary_push(typedetails
, typestr
);
4618 * WIN32OLE#ole_method_help(method)
4620 * Returns WIN32OLE_METHOD object corresponding with method
4621 * specified by 1st argument.
4623 * excel = WIN32OLE.new('Excel.Application')
4624 * method = excel.ole_method_help('Quit')
4628 fole_method_help(VALUE self
, VALUE cmdname
)
4630 ITypeInfo
*pTypeInfo
;
4632 struct oledata
*pole
;
4635 Check_SafeStr(cmdname
);
4636 OLEData_Get_Struct(self
, pole
);
4637 hr
= typeinfo_from_ole(pole
, &pTypeInfo
);
4639 ole_raise(hr
, rb_eRuntimeError
, "failed to get ITypeInfo");
4640 method
= folemethod_s_allocate(cWIN32OLE_METHOD
);
4641 obj
= olemethod_from_typeinfo(method
, pTypeInfo
, cmdname
);
4642 OLE_RELEASE(pTypeInfo
);
4644 rb_raise(eWIN32OLERuntimeError
, "not found %s",
4645 StringValuePtr(cmdname
));
4651 * WIN32OLE#ole_activex_initialize() -> Qnil
4653 * Initialize WIN32OLE object(ActiveX Control) by calling
4654 * IPersistMemory::InitNew.
4656 * Before calling OLE method, some kind of the ActiveX controls
4657 * created with MFC should be initialized by calling
4658 * IPersistXXX::InitNew.
4660 * If and only if you received the exception "HRESULT error code:
4661 * 0x8000ffff catastrophic failure", try this method before
4662 * invoking any ole_method.
4664 * obj = WIN32OLE.new("ProgID_or_GUID_of_ActiveX_Control")
4665 * obj.ole_activex_initialize
4670 fole_activex_initialize(VALUE self
)
4672 struct oledata
*pole
;
4673 IPersistMemory
*pPersistMemory
;
4678 OLEData_Get_Struct(self
, pole
);
4680 hr
= pole
->pDispatch
->lpVtbl
->QueryInterface(pole
->pDispatch
, &IID_IPersistMemory
, &p
);
4682 if (SUCCEEDED(hr
)) {
4683 hr
= pPersistMemory
->lpVtbl
->InitNew(pPersistMemory
);
4684 OLE_RELEASE(pPersistMemory
);
4685 if (SUCCEEDED(hr
)) {
4691 ole_raise(hr
, eWIN32OLERuntimeError
, "fail to initialize ActiveX control");
4699 * WIN32OLE_TYPE.ole_classes(typelib)
4701 * Returns array of WIN32OLE_TYPE objects defined by the <i>typelib</i> type library.
4702 * This method will be OBSOLETE. Use WIN32OLE_TYPELIB.new(typelib).ole_classes instead.
4705 foletype_s_ole_classes(VALUE self
, VALUE typelib
)
4710 rb_warn("%s is obsolete; use %s instead.",
4711 "WIN32OLE_TYPE.ole_classes",
4712 "WIN32OLE_TYPELIB.new(typelib).ole_types");
4714 obj
= rb_funcall(cWIN32OLE_TYPELIB
, rb_intern("new"), 1, typelib
);
4715 return rb_funcall(obj
, rb_intern("ole_types"), 0);
4720 * WIN32OLE_TYPE.typelibs
4722 * Returns array of type libraries.
4723 * This method will be OBSOLETE. Use WIN32OLE_TYPELIB.typelibs.collect{|t| t.name} instead.
4727 foletype_s_typelibs(VALUE self
)
4730 rb_warn("%s is obsolete. use %s instead.",
4731 "WIN32OLE_TYPE.typelibs",
4732 "WIN32OLE_TYPELIB.typelibs.collect{t|t.name}");
4734 return rb_eval_string("WIN32OLE_TYPELIB.typelibs.collect{|t|t.name}");
4739 * WIN32OLE_TYPE.progids
4741 * Returns array of ProgID.
4744 foletype_s_progids(VALUE self
)
4746 HKEY hclsids
, hclsid
;
4750 VALUE v
= rb_str_new2("");
4751 VALUE progids
= rb_ary_new();
4753 err
= reg_open_key(HKEY_CLASSES_ROOT
, "CLSID", &hclsids
);
4754 if(err
!= ERROR_SUCCESS
) {
4758 clsid
= reg_enum_key(hclsids
, i
);
4761 err
= reg_open_vkey(hclsids
, clsid
, &hclsid
);
4762 if (err
!= ERROR_SUCCESS
)
4764 if ((v
= reg_get_val2(hclsid
, "ProgID")) != Qnil
)
4765 rb_ary_push(progids
, v
);
4766 if ((v
= reg_get_val2(hclsid
, "VersionIndependentProgID")) != Qnil
)
4767 rb_ary_push(progids
, v
);
4768 RegCloseKey(hclsid
);
4770 RegCloseKey(hclsids
);
4775 foletype_s_allocate(VALUE klass
)
4777 struct oletypedata
*poletype
;
4780 obj
= Data_Make_Struct(klass
,struct oletypedata
,0,oletype_free
,poletype
);
4781 poletype
->pTypeInfo
= NULL
;
4786 oletype_set_member(VALUE self
, ITypeInfo
*pTypeInfo
, VALUE name
)
4788 struct oletypedata
*ptype
;
4789 Data_Get_Struct(self
, struct oletypedata
, ptype
);
4790 rb_ivar_set(self
, rb_intern("name"), name
);
4791 ptype
->pTypeInfo
= pTypeInfo
;
4792 if(pTypeInfo
) OLE_ADDREF(pTypeInfo
);
4797 oleclass_from_typelib(VALUE self
, ITypeLib
*pTypeLib
, VALUE oleclass
)
4805 ITypeInfo
*pTypeInfo
;
4807 VALUE found
= Qfalse
;
4809 count
= pTypeLib
->lpVtbl
->GetTypeInfoCount(pTypeLib
);
4810 for (i
= 0; i
< count
&& found
== Qfalse
; i
++) {
4811 hr
= pTypeLib
->lpVtbl
->GetTypeInfo(pTypeLib
, i
, &pTypeInfo
);
4814 hr
= pTypeLib
->lpVtbl
->GetDocumentation(pTypeLib
, i
,
4815 &bstr
, NULL
, NULL
, NULL
);
4818 typelib
= WC2VSTR(bstr
);
4819 if (rb_str_cmp(oleclass
, typelib
) == 0) {
4820 oletype_set_member(self
, pTypeInfo
, typelib
);
4823 OLE_RELEASE(pTypeInfo
);
4829 * Document-class: WIN32OLE_TYPELIB
4831 * <code>WIN32OLE_TYPELIB</code> objects represent OLE tyblib information.
4836 oletypelib_set_member(VALUE self
, VALUE typelib
, VALUE guid
, VALUE version
)
4838 rb_ivar_set(self
, rb_intern("name"), typelib
);
4839 rb_ivar_set(self
, rb_intern("guid"), guid
);
4840 rb_ivar_set(self
, rb_intern("version"), version
);
4847 * WIN32OLE_TYPELIB.typelibs
4849 * Returns the array of WIN32OLE_TYPELIB object.
4851 * tlibs = WIN32OLE_TYPELIB.typelibs
4855 foletypelib_s_typelibs(VALUE self
)
4857 HKEY htypelib
, hguid
;
4863 VALUE typelibs
= rb_ary_new();
4864 VALUE typelib
= Qnil
;
4866 err
= reg_open_key(HKEY_CLASSES_ROOT
, "TypeLib", &htypelib
);
4867 if(err
!= ERROR_SUCCESS
) {
4871 guid
= reg_enum_key(htypelib
, i
);
4874 err
= reg_open_vkey(htypelib
, guid
, &hguid
);
4875 if (err
!= ERROR_SUCCESS
)
4878 version
= reg_enum_key(hguid
, j
);
4879 if (version
== Qnil
)
4881 if ( (name
= reg_get_val2(hguid
, StringValuePtr(version
))) != Qnil
) {
4882 typelib
= rb_funcall(cWIN32OLE_TYPELIB
, rb_intern("allocate"), 0);
4883 oletypelib_set_member(typelib
, name
, guid
, version
);
4884 rb_ary_push(typelibs
, typelib
);
4889 RegCloseKey(htypelib
);
4894 make_version_str(VALUE major
, VALUE minor
)
4896 VALUE version_str
= Qnil
;
4897 VALUE minor_str
= Qnil
;
4898 if (major
== Qnil
) {
4901 version_str
= rb_String(major
);
4902 if (minor
!= Qnil
) {
4903 minor_str
= rb_String(minor
);
4904 rb_str_cat2(version_str
, ".");
4905 rb_str_append(version_str
, minor_str
);
4911 oletypelib_search_registry2(VALUE self
, VALUE args
)
4913 HKEY htypelib
, hguid
, hversion
;
4917 VALUE found
= Qfalse
;
4921 VALUE version
= Qnil
;
4922 VALUE typelib
= Qnil
;
4924 VALUE guid
= rb_ary_entry(args
, 0);
4925 version_str
= make_version_str(rb_ary_entry(args
, 1), rb_ary_entry(args
, 2));
4927 err
= reg_open_key(HKEY_CLASSES_ROOT
, "TypeLib", &htypelib
);
4928 if(err
!= ERROR_SUCCESS
) {
4931 err
= reg_open_vkey(htypelib
, guid
, &hguid
);
4932 if (err
!= ERROR_SUCCESS
) {
4933 RegCloseKey(htypelib
);
4936 if (version_str
!= Qnil
) {
4937 err
= reg_open_vkey(hguid
, version_str
, &hversion
);
4938 if (err
== ERROR_SUCCESS
) {
4939 tlib
= reg_get_val(hversion
, NULL
);
4942 version
= version_str
;
4945 RegCloseKey(hversion
);
4949 ver
= reg_enum_key(hguid
, j
);
4952 err
= reg_open_vkey(hguid
, ver
, &hversion
);
4953 if (err
!= ERROR_SUCCESS
)
4955 tlib
= reg_get_val(hversion
, NULL
);
4957 RegCloseKey(hversion
);
4960 if (fver
< atof(StringValuePtr(ver
))) {
4961 fver
= atof(StringValuePtr(ver
));
4965 RegCloseKey(hversion
);
4969 RegCloseKey(htypelib
);
4970 if (typelib
!= Qnil
) {
4972 oletypelib_set_member(self
, typelib
, guid
, version
);
4978 oletypelib_search_registry(VALUE self
, VALUE typelib
)
4980 HKEY htypelib
, hguid
, hversion
;
4983 VALUE found
= Qfalse
;
4988 err
= reg_open_key(HKEY_CLASSES_ROOT
, "TypeLib", &htypelib
);
4989 if(err
!= ERROR_SUCCESS
) {
4992 for(i
= 0; !found
; i
++) {
4993 guid
= reg_enum_key(htypelib
, i
);
4996 err
= reg_open_vkey(htypelib
, guid
, &hguid
);
4997 if (err
!= ERROR_SUCCESS
)
4999 for(j
= 0; found
== Qfalse
; j
++) {
5000 ver
= reg_enum_key(hguid
, j
);
5003 err
= reg_open_vkey(hguid
, ver
, &hversion
);
5004 if (err
!= ERROR_SUCCESS
)
5006 tlib
= reg_get_val(hversion
, NULL
);
5008 RegCloseKey(hversion
);
5011 if (rb_str_cmp(typelib
, tlib
) == 0) {
5012 oletypelib_set_member(self
, typelib
, guid
, ver
);
5015 RegCloseKey(hversion
);
5019 RegCloseKey(htypelib
);
5025 * WIN32OLE_TYPELIB.new(typelib [, version1, version2]) -> WIN32OLE_TYPELIB object
5027 * Returns a new WIN32OLE_TYPELIB object.
5029 * The first argument <i>typelib</i> specifies OLE type library name or GUID or
5031 * The second argument is major version or version of the type library.
5032 * The third argument is minor version.
5033 * The second argument and third argument are optional.
5034 * If the first argument is type library name, then the second and third argument
5037 * tlib1 = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5038 * tlib2 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}')
5039 * tlib3 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}', 1.3)
5040 * tlib4 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}', 1, 3)
5041 * tlib5 = WIN32OLE_TYPELIB.new("C:\\WINNT\\SYSTEM32\\SHELL32.DLL")
5042 * puts tlib1.name # -> 'Microsoft Excel 9.0 Object Library'
5043 * puts tlib2.name # -> 'Microsoft Excel 9.0 Object Library'
5044 * puts tlib3.name # -> 'Microsoft Excel 9.0 Object Library'
5045 * puts tlib4.name # -> 'Microsoft Excel 9.0 Object Library'
5046 * puts tlib5.name # -> 'Microsoft Shell Controls And Automation'
5050 foletypelib_initialize(VALUE self
, VALUE args
)
5052 VALUE found
= Qfalse
;
5053 VALUE typelib
= Qnil
;
5060 len
= RARRAY_LEN(args
);
5061 if (len
< 1 || len
> 3) {
5062 rb_raise(rb_eArgError
, "wrong number of arguments (%d for 1..3)", len
);
5065 typelib
= rb_ary_entry(args
, 0);
5067 Check_SafeStr(typelib
);
5069 found
= oletypelib_search_registry(self
, typelib
);
5070 if (found
== Qfalse
) {
5071 found
= oletypelib_search_registry2(self
, args
);
5073 if (found
== Qfalse
) {
5074 pbuf
= ole_vstr2wc(typelib
);
5075 hr
= LoadTypeLibEx(pbuf
, REGKIND_NONE
, &pTypeLib
);
5076 SysFreeString(pbuf
);
5077 if (SUCCEEDED(hr
)) {
5078 retval
= ole_typelib_from_itypelib(pTypeLib
);
5079 OLE_RELEASE(pTypeLib
);
5080 if (retval
!= Qnil
) {
5082 oletypelib_set_member(self
,
5083 rb_ivar_get(retval
, rb_intern("name")),
5084 rb_ivar_get(retval
, rb_intern("guid")),
5085 rb_ivar_get(retval
, rb_intern("version")));
5090 if (found
== Qfalse
) {
5091 rb_raise(eWIN32OLERuntimeError
, "not found type library `%s`",
5092 StringValuePtr(typelib
));
5099 * WIN32OLE_TYPELIB#guid -> The guid string.
5101 * Returns guid string which specifies type library.
5103 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5104 * guid = tlib.guid # -> '{00020813-0000-0000-C000-000000000046}'
5107 foletypelib_guid(VALUE self
)
5109 return rb_ivar_get(self
, rb_intern("guid"));
5114 * WIN32OLE_TYPELIB#name -> The type library name
5116 * Returns the type library name.
5118 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5119 * name = tlib.name # -> 'Microsoft Excel 9.0 Object Library'
5122 foletypelib_name(VALUE self
)
5124 return rb_ivar_get(self
, rb_intern("name"));
5129 * WIN32OLE_TYPELIB#version -> The type library version.
5131 * Returns the type library version.
5133 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5134 * puts tlib.version #-> 1.3
5137 foletypelib_version(VALUE self
)
5139 VALUE ver
= rb_ivar_get(self
, rb_intern("version"));
5140 return rb_Float(ver
);
5145 * WIN32OLE_TYPELIB#major_version -> The type library major version.
5147 * Returns the type library major version.
5149 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5150 * puts tlib.major_version # -> 1
5153 foletypelib_major_version(VALUE self
)
5155 VALUE ver
= rb_ivar_get(self
, rb_intern("version"));
5156 VALUE ary
= rb_str_split(ver
, ".");
5157 return rb_Integer(rb_ary_entry(ary
, 0));
5162 * WIN32OLE_TYPELIB#minor_version -> The type library minor version.
5164 * Returns the type library minor version.
5166 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5167 * puts tlib.minor_version # -> 3
5170 foletypelib_minor_version(VALUE self
)
5172 VALUE ver
= rb_ivar_get(self
, rb_intern("version"));
5173 VALUE ary
= rb_str_split(ver
, ".");
5174 return rb_Integer(rb_ary_entry(ary
, 1));
5178 oletypelib_path(VALUE guid
, VALUE version
)
5187 VALUE key
= rb_str_new2("TypeLib\\");
5188 rb_str_concat(key
, guid
);
5189 rb_str_cat2(key
, "\\");
5190 rb_str_concat(key
, version
);
5192 err
= reg_open_vkey(HKEY_CLASSES_ROOT
, key
, &hkey
);
5193 if (err
!= ERROR_SUCCESS
) {
5196 for(k
= 0; path
== Qnil
; k
++) {
5197 lang
= reg_enum_key(hkey
, k
);
5200 err
= reg_open_vkey(hkey
, lang
, &hlang
);
5201 if (err
== ERROR_SUCCESS
) {
5202 path
= reg_get_typelib_file_path(hlang
);
5212 * WIN32OLE_TYPELIB#path -> The type library file path.
5214 * Returns the type library file path.
5216 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5217 * puts tlib.path #-> 'C:\...\EXCEL9.OLB'
5220 foletypelib_path(VALUE self
)
5222 VALUE guid
= rb_ivar_get(self
, rb_intern("guid"));
5223 VALUE version
= rb_ivar_get(self
, rb_intern("version"));
5224 return oletypelib_path(guid
, version
);
5228 oletypelib2itypelib(VALUE self
, ITypeLib
**ppTypeLib
)
5233 path
= rb_funcall(self
, rb_intern("path"), 0);
5235 pbuf
= ole_vstr2wc(path
);
5236 hr
= LoadTypeLibEx(pbuf
, REGKIND_NONE
, ppTypeLib
);
5237 SysFreeString(pbuf
);
5239 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to LoadTypeLibEx from `%s'",
5240 StringValuePtr(path
));
5242 rb_raise(eWIN32OLERuntimeError
, "failed to get type library path");
5248 * WIN32OLE_TYPELIB#visible?
5250 * Returns true if the type library information is not hidden.
5251 * If wLibFlags of TLIBATTR is 0 or LIBFLAG_FRESTRICTED or LIBFLAG_FHIDDEN,
5252 * the method returns false, otherwise, returns true.
5253 * If the method fails to access the TLIBATTR information, then
5254 * WIN32OLERuntimeError is raised.
5256 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5257 * tlib.visible? # => true
5260 foletypelib_visible(VALUE self
)
5263 ITypeLib
*pTypeLib
= NULL
;
5264 VALUE visible
= Qtrue
;
5265 TLIBATTR
*pTLibAttr
;
5267 oletypelib2itypelib(self
, &pTypeLib
);
5269 hr
= pTypeLib
->lpVtbl
->GetLibAttr(pTypeLib
, &pTLibAttr
);
5271 OLE_RELEASE(pTypeLib
);
5272 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to get TLIBATTR information");
5274 if ((pTLibAttr
->wLibFlags
== 0) ||
5275 (pTLibAttr
->wLibFlags
& LIBFLAG_FRESTRICTED
) ||
5276 (pTLibAttr
->wLibFlags
& LIBFLAG_FHIDDEN
)) {
5279 pTypeLib
->lpVtbl
->ReleaseTLibAttr(pTypeLib
, pTLibAttr
);
5280 OLE_RELEASE(pTypeLib
);
5286 * WIN32OLE_TYPELIB#library_name
5288 * Returns library name.
5289 * If the method fails to access library name, WIN32OLERuntimeError is raised.
5291 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5292 * tlib.library_name # => Excel
5295 foletypelib_library_name(VALUE self
)
5298 ITypeLib
*pTypeLib
= NULL
;
5299 VALUE libname
= Qnil
;
5302 oletypelib2itypelib(self
, &pTypeLib
);
5303 hr
= pTypeLib
->lpVtbl
->GetDocumentation(pTypeLib
, -1,
5304 &bstr
, NULL
, NULL
, NULL
);
5306 OLE_RELEASE(pTypeLib
);
5307 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to get library name");
5309 OLE_RELEASE(pTypeLib
);
5310 libname
= WC2VSTR(bstr
);
5317 * WIN32OLE_TYPELIB#ole_types -> The array of WIN32OLE_TYPE object included the type library.
5319 * Returns the type library file path.
5321 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5322 * classes = tlib.ole_types.collect{|k| k.name} # -> ['AddIn', 'AddIns' ...]
5325 foletypelib_ole_types(VALUE self
)
5327 ITypeLib
*pTypeLib
= NULL
;
5328 VALUE classes
= rb_ary_new();
5329 oletypelib2itypelib(self
, &pTypeLib
);
5330 ole_types_from_typelib(pTypeLib
, classes
);
5331 OLE_RELEASE(pTypeLib
);
5337 * WIN32OLE_TYPELIB#inspect -> String
5339 * Returns the type library name with class name.
5341 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5342 * tlib.inspect # => "<#WIN32OLE_TYPELIB:Microsoft Excel 9.0 Object Library>"
5345 foletypelib_inspect(VALUE self
)
5347 return default_inspect(self
, "WIN32OLE_TYPELIB");
5351 * Document-class: WIN32OLE_TYPE
5353 * <code>WIN32OLE_TYPE</code> objects represent OLE type libarary information.
5358 * WIN32OLE_TYPE.new(typelib, ole_class) -> WIN32OLE_TYPE object
5360 * Returns a new WIN32OLE_TYPE object.
5361 * The first argument <i>typelib</i> specifies OLE type library name.
5362 * The second argument specifies OLE class name.
5364 * WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
5365 * # => WIN32OLE_TYPE object of Application class of Excel.
5368 foletype_initialize(VALUE self
, VALUE typelib
, VALUE oleclass
)
5375 Check_SafeStr(oleclass
);
5376 Check_SafeStr(typelib
);
5377 file
= typelib_file(typelib
);
5381 pbuf
= ole_vstr2wc(file
);
5382 hr
= LoadTypeLibEx(pbuf
, REGKIND_NONE
, &pTypeLib
);
5384 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to LoadTypeLibEx");
5385 SysFreeString(pbuf
);
5386 if (oleclass_from_typelib(self
, pTypeLib
, oleclass
) == Qfalse
) {
5387 OLE_RELEASE(pTypeLib
);
5388 rb_raise(eWIN32OLERuntimeError
, "not found `%s` in `%s`",
5389 StringValuePtr(oleclass
), StringValuePtr(typelib
));
5391 OLE_RELEASE(pTypeLib
);
5397 * WIN32OLE_TYPE#name #=> OLE type name
5399 * Returns OLE type name.
5400 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
5401 * puts tobj.name # => Application
5404 foletype_name(VALUE self
)
5406 return rb_ivar_get(self
, rb_intern("name"));
5410 ole_ole_type(ITypeInfo
*pTypeInfo
)
5413 TYPEATTR
*pTypeAttr
;
5415 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
5419 switch(pTypeAttr
->typekind
) {
5421 type
= rb_str_new2("Enum");
5424 type
= rb_str_new2("Record");
5427 type
= rb_str_new2("Module");
5429 case TKIND_INTERFACE
:
5430 type
= rb_str_new2("Interface");
5432 case TKIND_DISPATCH
:
5433 type
= rb_str_new2("Dispatch");
5436 type
= rb_str_new2("Class");
5439 type
= rb_str_new2("Alias");
5442 type
= rb_str_new2("Union");
5445 type
= rb_str_new2("Max");
5451 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
5457 * WIN32OLE_TYPE#ole_type #=> OLE type string.
5459 * returns type of OLE class.
5460 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
5461 * puts tobj.ole_type # => Class
5464 foletype_ole_type(VALUE self
)
5466 struct oletypedata
*ptype
;
5467 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5468 return ole_ole_type(ptype
->pTypeInfo
);
5472 ole_type_guid(ITypeInfo
*pTypeInfo
)
5475 TYPEATTR
*pTypeAttr
;
5479 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
5482 len
= StringFromGUID2(&pTypeAttr
->guid
, bstr
, sizeof(bstr
)/sizeof(OLECHAR
));
5484 guid
= ole_wc2vstr(bstr
, FALSE
);
5486 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
5492 * WIN32OLE_TYPE#guid #=> GUID
5495 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
5496 * puts tobj.guid # => {00024500-0000-0000-C000-000000000046}
5499 foletype_guid(VALUE self
)
5501 struct oletypedata
*ptype
;
5502 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5503 return ole_type_guid(ptype
->pTypeInfo
);
5507 ole_type_progid(ITypeInfo
*pTypeInfo
)
5510 TYPEATTR
*pTypeAttr
;
5512 VALUE progid
= Qnil
;
5513 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
5516 hr
= ProgIDFromCLSID(&pTypeAttr
->guid
, &pbuf
);
5517 if (SUCCEEDED(hr
)) {
5518 progid
= ole_wc2vstr(pbuf
, FALSE
);
5519 CoTaskMemFree(pbuf
);
5521 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
5527 * WIN32OLE_TYPE#progid #=> ProgID
5529 * Returns ProgID if it exists. If not found, then returns nil.
5530 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
5531 * puts tobj.progid # => Excel.Application.9
5534 foletype_progid(VALUE self
)
5536 struct oletypedata
*ptype
;
5537 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5538 return ole_type_progid(ptype
->pTypeInfo
);
5543 ole_type_visible(ITypeInfo
*pTypeInfo
)
5546 TYPEATTR
*pTypeAttr
;
5548 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
5551 if (pTypeAttr
->wTypeFlags
& (TYPEFLAG_FHIDDEN
| TYPEFLAG_FRESTRICTED
)) {
5556 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
5562 * WIN32OLE_TYPE#visible #=> true or false
5564 * Returns true if the OLE class is public.
5565 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
5566 * puts tobj.visible # => true
5569 foletype_visible(VALUE self
)
5571 struct oletypedata
*ptype
;
5572 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5573 return ole_type_visible(ptype
->pTypeInfo
);
5577 ole_type_major_version(ITypeInfo
*pTypeInfo
)
5580 TYPEATTR
*pTypeAttr
;
5582 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
5584 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to GetTypeAttr");
5585 ver
= INT2FIX(pTypeAttr
->wMajorVerNum
);
5586 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
5592 * WIN32OLE_TYPE#major_version
5594 * Returns major version.
5595 * tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents')
5596 * puts tobj.major_version # => 8
5599 foletype_major_version(VALUE self
)
5601 struct oletypedata
*ptype
;
5602 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5603 return ole_type_major_version(ptype
->pTypeInfo
);
5607 ole_type_minor_version(ITypeInfo
*pTypeInfo
)
5610 TYPEATTR
*pTypeAttr
;
5612 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
5614 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to GetTypeAttr");
5615 ver
= INT2FIX(pTypeAttr
->wMinorVerNum
);
5616 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
5622 * WIN32OLE_TYPE#minor_version #=> OLE minor version
5624 * Returns minor version.
5625 * tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents')
5626 * puts tobj.minor_version # => 2
5629 foletype_minor_version(VALUE self
)
5631 struct oletypedata
*ptype
;
5632 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5633 return ole_type_minor_version(ptype
->pTypeInfo
);
5637 ole_type_typekind(ITypeInfo
*pTypeInfo
)
5640 TYPEATTR
*pTypeAttr
;
5642 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
5644 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to GetTypeAttr");
5645 typekind
= INT2FIX(pTypeAttr
->typekind
);
5646 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
5652 * WIN32OLE_TYPE#typekind #=> number of type.
5654 * Returns number which represents type.
5655 * tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents')
5656 * puts tobj.typekind # => 4
5660 foletype_typekind(VALUE self
)
5662 struct oletypedata
*ptype
;
5663 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5664 return ole_type_typekind(ptype
->pTypeInfo
);
5668 ole_type_helpstring(ITypeInfo
*pTypeInfo
)
5672 hr
= ole_docinfo_from_type(pTypeInfo
, NULL
, &bhelpstr
, NULL
, NULL
);
5676 return WC2VSTR(bhelpstr
);
5681 * WIN32OLE_TYPE#helpstring #=> help string.
5683 * Returns help string.
5684 * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'IWebBrowser')
5685 * puts tobj.helpstring # => Web Browser interface
5688 foletype_helpstring(VALUE self
)
5690 struct oletypedata
*ptype
;
5691 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5692 return ole_type_helpstring(ptype
->pTypeInfo
);
5696 ole_type_src_type(ITypeInfo
*pTypeInfo
)
5699 TYPEATTR
*pTypeAttr
;
5701 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
5704 if(pTypeAttr
->typekind
!= TKIND_ALIAS
) {
5705 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
5708 alias
= ole_typedesc2val(pTypeInfo
, &(pTypeAttr
->tdescAlias
), Qnil
);
5709 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
5715 * WIN32OLE_TYPE#src_type #=> OLE source class
5717 * Returns source class when the OLE class is 'Alias'.
5718 * tobj = WIN32OLE_TYPE.new('Microsoft Office 9.0 Object Library', 'MsoRGBType')
5719 * puts tobj.src_type # => I4
5723 foletype_src_type(VALUE self
)
5725 struct oletypedata
*ptype
;
5726 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5727 return ole_type_src_type(ptype
->pTypeInfo
);
5731 ole_type_helpfile(ITypeInfo
*pTypeInfo
)
5735 hr
= ole_docinfo_from_type(pTypeInfo
, NULL
, NULL
, NULL
, &bhelpfile
);
5739 return WC2VSTR(bhelpfile
);
5744 * WIN32OLE_TYPE#helpfile
5746 * Returns helpfile path. If helpfile is not found, then returns nil.
5747 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
5748 * puts tobj.helpfile # => C:\...\VBAXL9.CHM
5752 foletype_helpfile(VALUE self
)
5754 struct oletypedata
*ptype
;
5755 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5756 return ole_type_helpfile(ptype
->pTypeInfo
);
5760 ole_type_helpcontext(ITypeInfo
*pTypeInfo
)
5764 hr
= ole_docinfo_from_type(pTypeInfo
, NULL
, NULL
,
5765 &helpcontext
, NULL
);
5768 return INT2FIX(helpcontext
);
5773 * WIN32OLE_TYPE#helpcontext
5775 * Returns helpcontext. If helpcontext is not found, then returns nil.
5776 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
5777 * puts tobj.helpfile # => 131185
5780 foletype_helpcontext(VALUE self
)
5782 struct oletypedata
*ptype
;
5783 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5784 return ole_type_helpcontext(ptype
->pTypeInfo
);
5789 * WIN32OLE_TYPE#ole_typelib
5791 * Returns the WIN32OLE_TYPELIB object which is including the WIN32OLE_TYPE
5792 * object. If it is not found, then returns nil.
5793 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
5794 * puts tobj.ole_typelib # => 'Microsoft Excel 9.0 Object Library'
5797 foletype_ole_typelib(VALUE self
)
5799 struct oletypedata
*ptype
;
5800 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5801 return ole_typelib_from_itypeinfo(ptype
->pTypeInfo
);
5805 ole_type_impl_ole_types(ITypeInfo
*pTypeInfo
, int implflags
)
5808 ITypeInfo
*pRefTypeInfo
;
5812 TYPEATTR
*pTypeAttr
;
5815 VALUE types
= rb_ary_new();
5816 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
5820 for (i
= 0; i
< pTypeAttr
->cImplTypes
; i
++) {
5821 hr
= pTypeInfo
->lpVtbl
->GetImplTypeFlags(pTypeInfo
, i
, &flags
);
5825 hr
= pTypeInfo
->lpVtbl
->GetRefTypeOfImplType(pTypeInfo
, i
, &href
);
5828 hr
= pTypeInfo
->lpVtbl
->GetRefTypeInfo(pTypeInfo
, href
, &pRefTypeInfo
);
5832 if ((flags
& implflags
) == implflags
) {
5833 type
= ole_type_from_itypeinfo(pRefTypeInfo
);
5835 rb_ary_push(types
, type
);
5839 OLE_RELEASE(pRefTypeInfo
);
5841 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
5847 * WIN32OLE_TYPE#implemented_ole_types
5849 * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE
5851 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
5852 * p tobj.implemented_ole_types # => [_Worksheet, DocEvents]
5855 foletype_impl_ole_types(VALUE self
)
5857 struct oletypedata
*ptype
;
5858 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5859 return ole_type_impl_ole_types(ptype
->pTypeInfo
, 0);
5864 * WIN32OLE_TYPE#source_ole_types
5866 * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE
5867 * object and having IMPLTYPEFLAG_FSOURCE.
5868 * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer")
5869 * p tobj.source_ole_types
5870 * # => [#<WIN32OLE_TYPE:DWebBrowserEvents2>, #<WIN32OLE_TYPE:DWebBrowserEvents>]
5873 foletype_source_ole_types(VALUE self
)
5875 struct oletypedata
*ptype
;
5876 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5877 return ole_type_impl_ole_types(ptype
->pTypeInfo
, IMPLTYPEFLAG_FSOURCE
);
5882 * WIN32OLE_TYPE#default_event_sources
5884 * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE
5885 * object and having IMPLTYPEFLAG_FSOURCE and IMPLTYPEFLAG_FDEFAULT.
5886 * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer")
5887 * p tobj.default_event_sources # => [#<WIN32OLE_TYPE:DWebBrowserEvents2>]
5890 foletype_default_event_sources(VALUE self
)
5892 struct oletypedata
*ptype
;
5893 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5894 return ole_type_impl_ole_types(ptype
->pTypeInfo
, IMPLTYPEFLAG_FSOURCE
|IMPLTYPEFLAG_FDEFAULT
);
5899 * WIN32OLE_TYPE#default_ole_types
5901 * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE
5902 * object and having IMPLTYPEFLAG_FDEFAULT.
5903 * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer")
5904 * p tobj.default_ole_types
5905 * # => [#<WIN32OLE_TYPE:IWebBrowser2>, #<WIN32OLE_TYPE:DWebBrowserEvents2>]
5908 foletype_default_ole_types(VALUE self
)
5910 struct oletypedata
*ptype
;
5911 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5912 return ole_type_impl_ole_types(ptype
->pTypeInfo
, IMPLTYPEFLAG_FDEFAULT
);
5917 * WIN32OLE_TYPE#inspect -> String
5919 * Returns the type name with class name.
5921 * ie = WIN32OLE.new('InternetExplorer.Application')
5922 * ie.ole_type.inspect => #<WIN32OLE_TYPE:IWebBrowser2>
5925 foletype_inspect(VALUE self
)
5927 return default_inspect(self
, "WIN32OLE_TYPE");
5931 ole_variables(ITypeInfo
*pTypeInfo
)
5934 TYPEATTR
*pTypeAttr
;
5940 struct olevariabledata
*pvar
;
5942 VALUE variables
= rb_ary_new();
5943 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
5945 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to GetTypeAttr");
5948 for(i
= 0; i
< pTypeAttr
->cVars
; i
++) {
5949 hr
= pTypeInfo
->lpVtbl
->GetVarDesc(pTypeInfo
, i
, &pVarDesc
);
5954 hr
= pTypeInfo
->lpVtbl
->GetNames(pTypeInfo
, pVarDesc
->memid
, &bstr
,
5956 if(FAILED(hr
) || len
== 0 || !bstr
)
5959 var
= Data_Make_Struct(cWIN32OLE_VARIABLE
, struct olevariabledata
,
5960 0,olevariable_free
,pvar
);
5961 pvar
->pTypeInfo
= pTypeInfo
;
5962 OLE_ADDREF(pTypeInfo
);
5964 rb_ivar_set(var
, rb_intern("name"), WC2VSTR(bstr
));
5965 rb_ary_push(variables
, var
);
5967 pTypeInfo
->lpVtbl
->ReleaseVarDesc(pTypeInfo
, pVarDesc
);
5970 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
5976 * WIN32OLE_TYPE#variables
5978 * Returns array of WIN32OLE_VARIABLE objects which represent variables
5979 * defined in OLE class.
5980 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
5981 * vars = tobj.variables
5983 * puts "#{v.name} = #{v.value}"
5986 * The result of above sample script is follows:
5988 * xlDialogSheet = -4116
5989 * xlExcel4IntlMacroSheet = 4
5990 * xlExcel4MacroSheet = 3
5991 * xlWorksheet = -4167
5995 foletype_variables(VALUE self
)
5997 struct oletypedata
*ptype
;
5998 Data_Get_Struct(self
, struct oletypedata
, ptype
);
5999 return ole_variables(ptype
->pTypeInfo
);
6004 * WIN32OLE_TYPE#ole_methods # the array of WIN32OLE_METHOD objects.
6006 * Returns array of WIN32OLE_METHOD objects which represent OLE method defined in
6008 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
6009 * methods = tobj.ole_methods.collect{|m|
6012 * # => ['Activate', 'Copy', 'Delete',....]
6015 foletype_methods(VALUE self
)
6017 struct oletypedata
*ptype
;
6018 Data_Get_Struct(self
, struct oletypedata
, ptype
);
6019 return ole_methods_from_typeinfo(ptype
->pTypeInfo
, INVOKE_FUNC
| INVOKE_PROPERTYGET
| INVOKE_PROPERTYPUT
| INVOKE_PROPERTYPUTREF
);
6023 * Document-class: WIN32OLE_VARIABLE
6025 * <code>WIN32OLE_VARIABLE</code> objects represent OLE variable information.
6030 * WIN32OLE_VARIABLE#name
6032 * Returns the name of variable.
6034 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
6035 * variables = tobj.variables
6036 * variables.each do |variable|
6037 * puts "#{variable.name}"
6040 * The result of above script is following:
6043 * xlExcel4IntlMacroSheet
6044 * xlExcel4MacroSheet
6049 folevariable_name(VALUE self
)
6051 return rb_ivar_get(self
, rb_intern("name"));
6055 ole_variable_ole_type(ITypeInfo
*pTypeInfo
, UINT var_index
)
6060 hr
= pTypeInfo
->lpVtbl
->GetVarDesc(pTypeInfo
, var_index
, &pVarDesc
);
6062 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to GetVarDesc");
6063 type
= ole_typedesc2val(pTypeInfo
, &(pVarDesc
->elemdescVar
.tdesc
), Qnil
);
6064 pTypeInfo
->lpVtbl
->ReleaseVarDesc(pTypeInfo
, pVarDesc
);
6070 * WIN32OLE_VARIABLE#ole_type
6072 * Returns OLE type string.
6074 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
6075 * variables = tobj.variables
6076 * variables.each do |variable|
6077 * puts "#{variable.ole_type} #{variable.name}"
6080 * The result of above script is following:
6083 * INT xlExcel4IntlMacroSheet
6084 * INT xlExcel4MacroSheet
6089 folevariable_ole_type(VALUE self
)
6091 struct olevariabledata
*pvar
;
6092 Data_Get_Struct(self
, struct olevariabledata
, pvar
);
6093 return ole_variable_ole_type(pvar
->pTypeInfo
, pvar
->index
);
6097 ole_variable_ole_type_detail(ITypeInfo
*pTypeInfo
, UINT var_index
)
6101 VALUE type
= rb_ary_new();
6102 hr
= pTypeInfo
->lpVtbl
->GetVarDesc(pTypeInfo
, var_index
, &pVarDesc
);
6104 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to GetVarDesc");
6105 ole_typedesc2val(pTypeInfo
, &(pVarDesc
->elemdescVar
.tdesc
), type
);
6106 pTypeInfo
->lpVtbl
->ReleaseVarDesc(pTypeInfo
, pVarDesc
);
6112 * WIN32OLE_VARIABLE#ole_type_detail
6114 * Returns detail information of type. The information is array of type.
6116 * tobj = WIN32OLE_TYPE.new('DirectX 7 for Visual Basic Type Library', 'D3DCLIPSTATUS')
6117 * variable = tobj.variables.find {|variable| variable.name == 'lFlags'}
6118 * tdetail = variable.ole_type_detail
6119 * p tdetail # => ["USERDEFINED", "CONST_D3DCLIPSTATUSFLAGS"]
6123 folevariable_ole_type_detail(VALUE self
)
6125 struct olevariabledata
*pvar
;
6126 Data_Get_Struct(self
, struct olevariabledata
, pvar
);
6127 return ole_variable_ole_type_detail(pvar
->pTypeInfo
, pvar
->index
);
6131 ole_variable_value(ITypeInfo
*pTypeInfo
, UINT var_index
)
6136 hr
= pTypeInfo
->lpVtbl
->GetVarDesc(pTypeInfo
, var_index
, &pVarDesc
);
6139 if(pVarDesc
->varkind
== VAR_CONST
)
6140 val
= ole_variant2val(V_UNION1(pVarDesc
, lpvarValue
));
6141 pTypeInfo
->lpVtbl
->ReleaseVarDesc(pTypeInfo
, pVarDesc
);
6147 * WIN32OLE_VARIABLE#value
6149 * Returns value if value is exists. If the value does not exist,
6150 * this method returns nil.
6152 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
6153 * variables = tobj.variables
6154 * variables.each do |variable|
6155 * puts "#{variable.name} #{variable.value}"
6158 * The result of above script is following:
6160 * xlDialogSheet = -4116
6161 * xlExcel4IntlMacroSheet = 4
6162 * xlExcel4MacroSheet = 3
6163 * xlWorksheet = -4167
6167 folevariable_value(VALUE self
)
6169 struct olevariabledata
*pvar
;
6170 Data_Get_Struct(self
, struct olevariabledata
, pvar
);
6171 return ole_variable_value(pvar
->pTypeInfo
, pvar
->index
);
6175 ole_variable_visible(ITypeInfo
*pTypeInfo
, UINT var_index
)
6179 VALUE visible
= Qfalse
;
6180 hr
= pTypeInfo
->lpVtbl
->GetVarDesc(pTypeInfo
, var_index
, &pVarDesc
);
6183 if (!(pVarDesc
->wVarFlags
& (VARFLAG_FHIDDEN
|
6184 VARFLAG_FRESTRICTED
|
6185 VARFLAG_FNONBROWSABLE
))) {
6188 pTypeInfo
->lpVtbl
->ReleaseVarDesc(pTypeInfo
, pVarDesc
);
6194 * WIN32OLE_VARIABLE#visible?
6196 * Returns true if the variable is public.
6198 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
6199 * variables = tobj.variables
6200 * variables.each do |variable|
6201 * puts "#{variable.name} #{variable.visible?}"
6204 * The result of above script is following:
6206 * xlDialogSheet true
6207 * xlExcel4IntlMacroSheet true
6208 * xlExcel4MacroSheet true
6213 folevariable_visible(VALUE self
)
6215 struct olevariabledata
*pvar
;
6216 Data_Get_Struct(self
, struct olevariabledata
, pvar
);
6217 return ole_variable_visible(pvar
->pTypeInfo
, pvar
->index
);
6221 ole_variable_kind(ITypeInfo
*pTypeInfo
, UINT var_index
)
6225 VALUE kind
= rb_str_new2("UNKNOWN");
6226 hr
= pTypeInfo
->lpVtbl
->GetVarDesc(pTypeInfo
, var_index
, &pVarDesc
);
6229 switch(pVarDesc
->varkind
) {
6230 case VAR_PERINSTANCE
:
6231 kind
= rb_str_new2("PERINSTANCE");
6234 kind
= rb_str_new2("STATIC");
6237 kind
= rb_str_new2("CONSTANT");
6240 kind
= rb_str_new2("DISPATCH");
6245 pTypeInfo
->lpVtbl
->ReleaseVarDesc(pTypeInfo
, pVarDesc
);
6251 * WIN32OLE_VARIABLE#variable_kind
6253 * Returns variable kind string.
6255 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
6256 * variables = tobj.variables
6257 * variables.each do |variable|
6258 * puts "#{variable.name} #{variable.variable_kind}"
6261 * The result of above script is following:
6263 * xlDialogSheet CONSTANT
6264 * xlExcel4IntlMacroSheet CONSTANT
6265 * xlExcel4MacroSheet CONSTANT
6266 * xlWorksheet CONSTANT
6269 folevariable_variable_kind(VALUE self
)
6271 struct olevariabledata
*pvar
;
6272 Data_Get_Struct(self
, struct olevariabledata
, pvar
);
6273 return ole_variable_kind(pvar
->pTypeInfo
, pvar
->index
);
6277 ole_variable_varkind(ITypeInfo
*pTypeInfo
, UINT var_index
)
6282 hr
= pTypeInfo
->lpVtbl
->GetVarDesc(pTypeInfo
, var_index
, &pVarDesc
);
6285 pTypeInfo
->lpVtbl
->ReleaseVarDesc(pTypeInfo
, pVarDesc
);
6286 kind
= INT2FIX(pVarDesc
->varkind
);
6292 * WIN32OLE_VARIABLE#varkind
6294 * Returns the number which represents variable kind.
6295 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
6296 * variables = tobj.variables
6297 * variables.each do |variable|
6298 * puts "#{variable.name} #{variable.varkind}"
6301 * The result of above script is following:
6304 * xlExcel4IntlMacroSheet 2
6305 * xlExcel4MacroSheet 2
6309 folevariable_varkind(VALUE self
)
6311 struct olevariabledata
*pvar
;
6312 Data_Get_Struct(self
, struct olevariabledata
, pvar
);
6313 return ole_variable_varkind(pvar
->pTypeInfo
, pvar
->index
);
6318 * WIN32OLE_VARIABLE#inspect -> String
6320 * Returns the OLE variable name and the value with class name.
6324 folevariable_inspect(VALUE self
)
6326 VALUE detail
= rb_funcall(self
, rb_intern("to_s"), 0);
6327 rb_str_cat2(detail
, "=");
6328 rb_str_concat(detail
, rb_funcall(rb_funcall(self
, rb_intern("value"), 0), rb_intern("inspect"), 0));
6329 return make_inspect("WIN32OLE_VARIABLE", detail
);
6333 * Document-class: WIN32OLE_METHOD
6335 * <code>WIN32OLE_METHOD</code> objects represent OLE method information.
6339 olemethod_set_member(VALUE self
, ITypeInfo
*pTypeInfo
, ITypeInfo
*pOwnerTypeInfo
, int index
, VALUE name
)
6341 struct olemethoddata
*pmethod
;
6342 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
6343 pmethod
->pTypeInfo
= pTypeInfo
;
6344 OLE_ADDREF(pTypeInfo
);
6345 pmethod
->pOwnerTypeInfo
= pOwnerTypeInfo
;
6346 if(pOwnerTypeInfo
) OLE_ADDREF(pOwnerTypeInfo
);
6347 pmethod
->index
= index
;
6348 rb_ivar_set(self
, rb_intern("name"), name
);
6353 folemethod_s_allocate(VALUE klass
)
6355 struct olemethoddata
*pmethod
;
6357 obj
= Data_Make_Struct(klass
,
6358 struct olemethoddata
,
6359 0, olemethod_free
, pmethod
);
6360 pmethod
->pTypeInfo
= NULL
;
6361 pmethod
->pOwnerTypeInfo
= NULL
;
6368 * WIN32OLE_METHOD.new(ole_type, method) -> WIN32OLE_METHOD object
6370 * Returns a new WIN32OLE_METHOD object which represents the information
6372 * The first argument <i>ole_type</i> specifies WIN32OLE_TYPE object.
6373 * The second argument <i>method</i> specifies OLE method name defined OLE class
6374 * which represents WIN32OLE_TYPE object.
6376 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
6377 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
6380 folemethod_initialize(VALUE self
, VALUE oletype
, VALUE method
)
6382 struct oletypedata
*ptype
;
6384 if (rb_obj_is_kind_of(oletype
, cWIN32OLE_TYPE
)) {
6385 Check_SafeStr(method
);
6386 Data_Get_Struct(oletype
, struct oletypedata
, ptype
);
6387 obj
= olemethod_from_typeinfo(self
, ptype
->pTypeInfo
, method
);
6389 rb_raise(eWIN32OLERuntimeError
, "not found %s",
6390 StringValuePtr(method
));
6394 rb_raise(rb_eTypeError
, "1st argument should be WIN32OLE_TYPE object");
6401 * WIN32OLE_METHOD#name
6403 * Returns the name of the method.
6405 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
6406 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
6407 * puts method.name # => SaveAs
6411 folemethod_name(VALUE self
)
6413 return rb_ivar_get(self
, rb_intern("name"));
6417 ole_method_return_type(ITypeInfo
*pTypeInfo
, UINT method_index
)
6419 FUNCDESC
*pFuncDesc
;
6423 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, method_index
, &pFuncDesc
);
6425 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to GetFuncDesc");
6427 type
= ole_typedesc2val(pTypeInfo
, &(pFuncDesc
->elemdescFunc
.tdesc
), Qnil
);
6428 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
6434 * WIN32OLE_METHOD#return_type
6436 * Returns string of return value type of method.
6437 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6438 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6439 * puts method.return_type # => Workbook
6443 folemethod_return_type(VALUE self
)
6445 struct olemethoddata
*pmethod
;
6446 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
6447 return ole_method_return_type(pmethod
->pTypeInfo
, pmethod
->index
);
6451 ole_method_return_vtype(ITypeInfo
*pTypeInfo
, UINT method_index
)
6453 FUNCDESC
*pFuncDesc
;
6457 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, method_index
, &pFuncDesc
);
6459 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to GetFuncDesc");
6461 vvt
= INT2FIX(pFuncDesc
->elemdescFunc
.tdesc
.vt
);
6462 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
6468 * WIN32OLE_METHOD#return_vtype
6470 * Returns number of return value type of method.
6471 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6472 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6473 * puts method.return_vtype # => 26
6477 folemethod_return_vtype(VALUE self
)
6479 struct olemethoddata
*pmethod
;
6480 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
6481 return ole_method_return_vtype(pmethod
->pTypeInfo
, pmethod
->index
);
6485 ole_method_return_type_detail(ITypeInfo
*pTypeInfo
, UINT method_index
)
6487 FUNCDESC
*pFuncDesc
;
6489 VALUE type
= rb_ary_new();
6491 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, method_index
, &pFuncDesc
);
6495 ole_typedesc2val(pTypeInfo
, &(pFuncDesc
->elemdescFunc
.tdesc
), type
);
6496 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
6502 * WIN32OLE_METHOD#return_type_detail
6504 * Returns detail information of return value type of method.
6505 * The information is array.
6506 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6507 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6508 * p method.return_type_detail # => ["PTR", "USERDEFINED", "Workbook"]
6511 folemethod_return_type_detail(VALUE self
)
6513 struct olemethoddata
*pmethod
;
6514 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
6515 return ole_method_return_type_detail(pmethod
->pTypeInfo
, pmethod
->index
);
6519 ole_method_invkind(ITypeInfo
*pTypeInfo
, UINT method_index
)
6521 FUNCDESC
*pFuncDesc
;
6524 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, method_index
, &pFuncDesc
);
6526 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to GetFuncDesc");
6527 invkind
= INT2FIX(pFuncDesc
->invkind
);
6528 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
6533 ole_method_invoke_kind(ITypeInfo
*pTypeInfo
, UINT method_index
)
6535 VALUE type
= rb_str_new2("UNKNOWN");
6536 VALUE invkind
= ole_method_invkind(pTypeInfo
, method_index
);
6537 if((FIX2INT(invkind
) & INVOKE_PROPERTYGET
) &&
6538 (FIX2INT(invkind
) & INVOKE_PROPERTYPUT
) ) {
6539 type
= rb_str_new2("PROPERTY");
6540 } else if(FIX2INT(invkind
) & INVOKE_PROPERTYGET
) {
6541 type
= rb_str_new2("PROPERTYGET");
6542 } else if(FIX2INT(invkind
) & INVOKE_PROPERTYPUT
) {
6543 type
= rb_str_new2("PROPERTYPUT");
6544 } else if(FIX2INT(invkind
) & INVOKE_PROPERTYPUTREF
) {
6545 type
= rb_str_new2("PROPERTYPUTREF");
6546 } else if(FIX2INT(invkind
) & INVOKE_FUNC
) {
6547 type
= rb_str_new2("FUNC");
6554 * WIN32OLE_MTHOD#invkind
6556 * Returns the method invoke kind.
6557 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6558 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6559 * puts method.invkind # => 1
6563 folemethod_invkind(VALUE self
)
6565 struct olemethoddata
*pmethod
;
6566 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
6567 return ole_method_invkind(pmethod
->pTypeInfo
, pmethod
->index
);
6572 * WIN32OLE_METHOD#invoke_kind
6574 * Returns the method kind string. The string is "UNKNOWN" or "PROPERTY"
6575 * or "PROPERTY" or "PROPERTYGET" or "PROPERTYPUT" or "PROPERTYPPUTREF"
6577 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6578 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6579 * puts method.invoke_kind # => "FUNC"
6582 folemethod_invoke_kind(VALUE self
)
6584 struct olemethoddata
*pmethod
;
6585 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
6586 return ole_method_invoke_kind(pmethod
->pTypeInfo
, pmethod
->index
);
6590 ole_method_visible(ITypeInfo
*pTypeInfo
, UINT method_index
)
6592 FUNCDESC
*pFuncDesc
;
6595 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, method_index
, &pFuncDesc
);
6598 if (pFuncDesc
->wFuncFlags
& (FUNCFLAG_FRESTRICTED
|
6600 FUNCFLAG_FNONBROWSABLE
)) {
6605 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
6611 * WIN32OLE_METHOD#visible?
6613 * Returns true if the method is public.
6614 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6615 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6616 * puts method.visible? # => true
6619 folemethod_visible(VALUE self
)
6621 struct olemethoddata
*pmethod
;
6622 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
6623 return ole_method_visible(pmethod
->pTypeInfo
, pmethod
->index
);
6627 ole_method_event(ITypeInfo
*pTypeInfo
, UINT method_index
, VALUE method_name
)
6629 TYPEATTR
*pTypeAttr
;
6634 ITypeInfo
*pRefTypeInfo
;
6635 FUNCDESC
*pFuncDesc
;
6638 VALUE event
= Qfalse
;
6640 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
6643 if(pTypeAttr
->typekind
!= TKIND_COCLASS
) {
6644 pTypeInfo
->lpVtbl
->ReleaseTypeAttr(pTypeInfo
, pTypeAttr
);
6647 for (i
= 0; i
< pTypeAttr
->cImplTypes
; i
++) {
6648 hr
= pTypeInfo
->lpVtbl
->GetImplTypeFlags(pTypeInfo
, i
, &flags
);
6652 if (flags
& IMPLTYPEFLAG_FSOURCE
) {
6653 hr
= pTypeInfo
->lpVtbl
->GetRefTypeOfImplType(pTypeInfo
,
6657 hr
= pTypeInfo
->lpVtbl
->GetRefTypeInfo(pTypeInfo
,
6658 href
, &pRefTypeInfo
);
6661 hr
= pRefTypeInfo
->lpVtbl
->GetFuncDesc(pRefTypeInfo
, method_index
,
6664 OLE_RELEASE(pRefTypeInfo
);
6668 hr
= pRefTypeInfo
->lpVtbl
->GetDocumentation(pRefTypeInfo
,
6670 &bstr
, NULL
, NULL
, NULL
);
6672 pRefTypeInfo
->lpVtbl
->ReleaseFuncDesc(pRefTypeInfo
, pFuncDesc
);
6673 OLE_RELEASE(pRefTypeInfo
);
6677 name
= WC2VSTR(bstr
);
6678 pRefTypeInfo
->lpVtbl
->ReleaseFuncDesc(pRefTypeInfo
, pFuncDesc
);
6679 OLE_RELEASE(pRefTypeInfo
);
6680 if (rb_str_cmp(method_name
, name
) == 0) {
6686 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
6692 * WIN32OLE_METHOD#event?
6694 * Returns true if the method is event.
6695 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
6696 * method = WIN32OLE_METHOD.new(tobj, 'SheetActivate')
6697 * puts method.event? # => true
6701 folemethod_event(VALUE self
)
6703 struct olemethoddata
*pmethod
;
6704 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
6705 if (!pmethod
->pOwnerTypeInfo
)
6707 return ole_method_event(pmethod
->pOwnerTypeInfo
,
6709 rb_ivar_get(self
, rb_intern("name")));
6714 * WIN32OLE_METHOD#event_interface
6716 * Returns event interface name if the method is event.
6717 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
6718 * method = WIN32OLE_METHOD.new(tobj, 'SheetActivate')
6719 * puts method.event_interface # => WorkbookEvents
6722 folemethod_event_interface(VALUE self
)
6725 struct olemethoddata
*pmethod
;
6727 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
6728 if(folemethod_event(self
) == Qtrue
) {
6729 hr
= ole_docinfo_from_type(pmethod
->pTypeInfo
, &name
, NULL
, NULL
, NULL
);
6731 return WC2VSTR(name
);
6737 ole_method_docinfo_from_type(
6738 ITypeInfo
*pTypeInfo
,
6746 FUNCDESC
*pFuncDesc
;
6748 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, method_index
, &pFuncDesc
);
6751 hr
= pTypeInfo
->lpVtbl
->GetDocumentation(pTypeInfo
, pFuncDesc
->memid
,
6753 helpcontext
, helpfile
);
6754 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
6759 ole_method_helpstring(ITypeInfo
*pTypeInfo
, UINT method_index
)
6763 hr
= ole_method_docinfo_from_type(pTypeInfo
, method_index
, NULL
, &bhelpstring
,
6767 return WC2VSTR(bhelpstring
);
6772 * WIN32OLE_METHOD#helpstring
6774 * Returns help string of OLE method. If the help string is not found,
6775 * then the method returns nil.
6776 * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'IWebBrowser')
6777 * method = WIN32OLE_METHOD.new(tobj, 'Navigate')
6778 * puts method.helpstring # => Navigates to a URL or file.
6782 folemethod_helpstring(VALUE self
)
6784 struct olemethoddata
*pmethod
;
6785 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
6786 return ole_method_helpstring(pmethod
->pTypeInfo
, pmethod
->index
);
6790 ole_method_helpfile(ITypeInfo
*pTypeInfo
, UINT method_index
)
6794 hr
= ole_method_docinfo_from_type(pTypeInfo
, method_index
, NULL
, NULL
,
6798 return WC2VSTR(bhelpfile
);
6803 * WIN32OLE_METHOD#helpfile
6805 * Returns help file. If help file is not found, then
6806 * the method returns nil.
6807 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6808 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6809 * puts method.helpfile # => C:\...\VBAXL9.CHM
6812 folemethod_helpfile(VALUE self
)
6814 struct olemethoddata
*pmethod
;
6815 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
6817 return ole_method_helpfile(pmethod
->pTypeInfo
, pmethod
->index
);
6821 ole_method_helpcontext(ITypeInfo
*pTypeInfo
, UINT method_index
)
6824 DWORD helpcontext
= 0;
6825 hr
= ole_method_docinfo_from_type(pTypeInfo
, method_index
, NULL
, NULL
,
6826 &helpcontext
, NULL
);
6829 return INT2FIX(helpcontext
);
6834 * WIN32OLE_METHOD#helpcontext
6836 * Returns help context.
6837 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6838 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6839 * puts method.helpcontext # => 65717
6842 folemethod_helpcontext(VALUE self
)
6844 struct olemethoddata
*pmethod
;
6845 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
6846 return ole_method_helpcontext(pmethod
->pTypeInfo
, pmethod
->index
);
6850 ole_method_dispid(ITypeInfo
*pTypeInfo
, UINT method_index
)
6852 FUNCDESC
*pFuncDesc
;
6854 VALUE dispid
= Qnil
;
6855 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, method_index
, &pFuncDesc
);
6858 dispid
= INT2NUM(pFuncDesc
->memid
);
6859 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
6865 * WIN32OLE_METHOD#dispid
6867 * Returns dispatch ID.
6868 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6869 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6870 * puts method.dispid # => 181
6873 folemethod_dispid(VALUE self
)
6875 struct olemethoddata
*pmethod
;
6876 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
6877 return ole_method_dispid(pmethod
->pTypeInfo
, pmethod
->index
);
6881 ole_method_offset_vtbl(ITypeInfo
*pTypeInfo
, UINT method_index
)
6883 FUNCDESC
*pFuncDesc
;
6885 VALUE offset_vtbl
= Qnil
;
6886 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, method_index
, &pFuncDesc
);
6889 offset_vtbl
= INT2FIX(pFuncDesc
->oVft
);
6890 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
6896 * WIN32OLE_METHOD#offset_vtbl
6898 * Returns the offset ov VTBL.
6899 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6900 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6901 * puts method.offset_vtbl # => 40
6904 folemethod_offset_vtbl(VALUE self
)
6906 struct olemethoddata
*pmethod
;
6907 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
6908 return ole_method_offset_vtbl(pmethod
->pTypeInfo
, pmethod
->index
);
6912 ole_method_size_params(ITypeInfo
*pTypeInfo
, UINT method_index
)
6914 FUNCDESC
*pFuncDesc
;
6916 VALUE size_params
= Qnil
;
6917 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, method_index
, &pFuncDesc
);
6920 size_params
= INT2FIX(pFuncDesc
->cParams
);
6921 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
6927 * WIN32OLE_METHOD#size_params
6929 * Returns the size of arguments of the method.
6930 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
6931 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
6932 * puts method.size_params # => 11
6936 folemethod_size_params(VALUE self
)
6938 struct olemethoddata
*pmethod
;
6939 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
6940 return ole_method_size_params(pmethod
->pTypeInfo
, pmethod
->index
);
6944 ole_method_size_opt_params(ITypeInfo
*pTypeInfo
, UINT method_index
)
6946 FUNCDESC
*pFuncDesc
;
6948 VALUE size_opt_params
= Qnil
;
6949 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, method_index
, &pFuncDesc
);
6951 return size_opt_params
;
6952 size_opt_params
= INT2FIX(pFuncDesc
->cParamsOpt
);
6953 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
6954 return size_opt_params
;
6959 * WIN32OLE_METHOD#size_opt_params
6961 * Returns the size of optional parameters.
6962 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
6963 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
6964 * puts method.size_opt_params # => 4
6967 folemethod_size_opt_params(VALUE self
)
6969 struct olemethoddata
*pmethod
;
6970 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
6971 return ole_method_size_opt_params(pmethod
->pTypeInfo
, pmethod
->index
);
6975 ole_method_params(ITypeInfo
*pTypeInfo
, UINT method_index
)
6977 FUNCDESC
*pFuncDesc
;
6981 struct oleparamdata
*pparam
;
6983 VALUE params
= rb_ary_new();
6984 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, method_index
, &pFuncDesc
);
6989 bstrs
= ALLOCA_N(BSTR
, pFuncDesc
->cParams
+ 1);
6990 hr
= pTypeInfo
->lpVtbl
->GetNames(pTypeInfo
, pFuncDesc
->memid
,
6991 bstrs
, pFuncDesc
->cParams
+ 1,
6994 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
6997 SysFreeString(bstrs
[0]);
6998 if (pFuncDesc
->cParams
> 0) {
6999 for(i
= 1; i
< len
; i
++) {
7000 param
= Data_Make_Struct(cWIN32OLE_PARAM
, struct oleparamdata
, 0,
7001 oleparam_free
, pparam
);
7002 pparam
->pTypeInfo
= pTypeInfo
;
7003 OLE_ADDREF(pTypeInfo
);
7004 pparam
->method_index
= method_index
;
7005 pparam
->index
= i
- 1;
7006 rb_ivar_set(param
, rb_intern("name"), WC2VSTR(bstrs
[i
]));
7007 rb_ary_push(params
, param
);
7010 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
7017 * WIN32OLE_METHOD#params
7019 * returns array of WIN32OLE_PARAM object corresponding with method parameters.
7020 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
7021 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
7022 * p method.params # => [Filename, FileFormat, Password, WriteResPassword,
7023 * ReadOnlyRecommended, CreateBackup, AccessMode,
7024 * ConflictResolution, AddToMru, TextCodepage,
7028 folemethod_params(VALUE self
)
7030 struct olemethoddata
*pmethod
;
7031 Data_Get_Struct(self
, struct olemethoddata
, pmethod
);
7032 return ole_method_params(pmethod
->pTypeInfo
, pmethod
->index
);
7037 * WIN32OLE_METHOD#inspect -> String
7039 * Returns the method name with class name.
7043 folemethod_inspect(VALUE self
)
7045 return default_inspect(self
, "WIN32OLE_METHOD");
7049 * Document-class: WIN32OLE_PARAM
7051 * <code>WIN32OLE_PARAM</code> objects represent param information of
7057 * WIN32OLE_PARAM#name
7060 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
7061 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
7062 * param1 = method.params[0]
7063 * puts param1.name # => Filename
7066 foleparam_name(VALUE self
)
7068 return rb_ivar_get(self
, rb_intern("name"));
7072 ole_param_ole_type(ITypeInfo
*pTypeInfo
, UINT method_index
, UINT index
)
7074 FUNCDESC
*pFuncDesc
;
7076 VALUE type
= rb_str_new2("unknown type");
7077 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, method_index
, &pFuncDesc
);
7080 type
= ole_typedesc2val(pTypeInfo
,
7081 &(pFuncDesc
->lprgelemdescParam
[index
].tdesc
), Qnil
);
7082 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
7088 * WIN32OLE_PARAM#ole_type
7090 * Returns OLE type of WIN32OLE_PARAM object(parameter of OLE method).
7091 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
7092 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
7093 * param1 = method.params[0]
7094 * puts param1.ole_type # => VARIANT
7097 foleparam_ole_type(VALUE self
)
7099 struct oleparamdata
*pparam
;
7100 Data_Get_Struct(self
, struct oleparamdata
, pparam
);
7101 return ole_param_ole_type(pparam
->pTypeInfo
, pparam
->method_index
,
7106 ole_param_ole_type_detail(ITypeInfo
*pTypeInfo
, UINT method_index
, UINT index
)
7108 FUNCDESC
*pFuncDesc
;
7110 VALUE typedetail
= rb_ary_new();
7111 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, method_index
, &pFuncDesc
);
7114 ole_typedesc2val(pTypeInfo
,
7115 &(pFuncDesc
->lprgelemdescParam
[index
].tdesc
), typedetail
);
7116 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
7122 * WIN32OLE_PARAM#ole_type_detail
7124 * Returns detail information of type of argument.
7125 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'IWorksheetFunction')
7126 * method = WIN32OLE_METHOD.new(tobj, 'SumIf')
7127 * param1 = method.params[0]
7128 * p param1.ole_type_detail # => ["PTR", "USERDEFINED", "Range"]
7131 foleparam_ole_type_detail(VALUE self
)
7133 struct oleparamdata
*pparam
;
7134 Data_Get_Struct(self
, struct oleparamdata
, pparam
);
7135 return ole_param_ole_type_detail(pparam
->pTypeInfo
, pparam
->method_index
,
7140 ole_param_flag_mask(ITypeInfo
*pTypeInfo
, UINT method_index
, UINT index
, USHORT mask
)
7142 FUNCDESC
*pFuncDesc
;
7145 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, method_index
, &pFuncDesc
);
7148 if (V_UNION1((&(pFuncDesc
->lprgelemdescParam
[index
])), paramdesc
).wParamFlags
&mask
)
7150 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
7156 * WIN32OLE_PARAM#input?
7158 * Returns true if the parameter is input.
7159 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
7160 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
7161 * param1 = method.params[0]
7162 * puts param1.input? # => true
7164 static VALUE
foleparam_input(VALUE self
)
7166 struct oleparamdata
*pparam
;
7167 Data_Get_Struct(self
, struct oleparamdata
, pparam
);
7168 return ole_param_flag_mask(pparam
->pTypeInfo
, pparam
->method_index
,
7169 pparam
->index
, PARAMFLAG_FIN
);
7176 * Returns true if argument is output.
7177 * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'DWebBrowserEvents')
7178 * method = WIN32OLE_METHOD.new(tobj, 'NewWindow')
7179 * method.params.each do |param|
7180 * puts "#{param.name} #{param.output?}"
7183 * The result of above script is following:
7186 * TargetFrameName false
7191 static VALUE
foleparam_output(VALUE self
)
7193 struct oleparamdata
*pparam
;
7194 Data_Get_Struct(self
, struct oleparamdata
, pparam
);
7195 return ole_param_flag_mask(pparam
->pTypeInfo
, pparam
->method_index
,
7196 pparam
->index
, PARAMFLAG_FOUT
);
7201 * WIN32OLE_PARAM#optional?
7203 * Returns true if argument is optional.
7204 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
7205 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
7206 * param1 = method.params[0]
7207 * puts "#{param1.name} #{param1.optional?}" # => Filename true
7209 static VALUE
foleparam_optional(VALUE self
)
7211 struct oleparamdata
*pparam
;
7212 Data_Get_Struct(self
, struct oleparamdata
, pparam
);
7213 return ole_param_flag_mask(pparam
->pTypeInfo
, pparam
->method_index
,
7214 pparam
->index
, PARAMFLAG_FOPT
);
7219 * WIN32OLE_PARAM#retval?
7221 * Returns true if argument is return value.
7222 * tobj = WIN32OLE_TYPE.new('DirectX 7 for Visual Basic Type Library',
7223 * 'DirectPlayLobbyConnection')
7224 * method = WIN32OLE_METHOD.new(tobj, 'GetPlayerShortName')
7225 * param = method.params[0]
7226 * puts "#{param.name} #{param.retval?}" # => name true
7228 static VALUE
foleparam_retval(VALUE self
)
7230 struct oleparamdata
*pparam
;
7231 Data_Get_Struct(self
, struct oleparamdata
, pparam
);
7232 return ole_param_flag_mask(pparam
->pTypeInfo
, pparam
->method_index
,
7233 pparam
->index
, PARAMFLAG_FRETVAL
);
7237 ole_param_default(ITypeInfo
*pTypeInfo
, UINT method_index
, UINT index
)
7239 FUNCDESC
*pFuncDesc
;
7240 ELEMDESC
*pElemDesc
;
7241 PARAMDESCEX
* pParamDescEx
;
7244 USHORT mask
= PARAMFLAG_FOPT
|PARAMFLAG_FHASDEFAULT
;
7245 VALUE defval
= Qnil
;
7246 hr
= pTypeInfo
->lpVtbl
->GetFuncDesc(pTypeInfo
, method_index
, &pFuncDesc
);
7249 pElemDesc
= &pFuncDesc
->lprgelemdescParam
[index
];
7250 wParamFlags
= V_UNION1(pElemDesc
, paramdesc
).wParamFlags
;
7251 if ((wParamFlags
& mask
) == mask
) {
7252 pParamDescEx
= V_UNION1(pElemDesc
, paramdesc
).pparamdescex
;
7253 defval
= ole_variant2val(&pParamDescEx
->varDefaultValue
);
7255 pTypeInfo
->lpVtbl
->ReleaseFuncDesc(pTypeInfo
, pFuncDesc
);
7261 * WIN32OLE_PARAM#default
7263 * Returns default value. If the default value does not exist,
7264 * this method returns nil.
7265 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
7266 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
7267 * method.params.each do |param|
7269 * puts "#{param.name} (= #{param.default})"
7275 * The above script result is following:
7280 * ReadOnlyRecommended
7283 * ConflictResolution
7288 static VALUE
foleparam_default(VALUE self
)
7290 struct oleparamdata
*pparam
;
7291 Data_Get_Struct(self
, struct oleparamdata
, pparam
);
7292 return ole_param_default(pparam
->pTypeInfo
, pparam
->method_index
,
7298 * WIN32OLE_PARAM#inspect -> String
7300 * Returns the parameter name with class name. If the parameter has default value,
7301 * then returns name=value string with class name.
7305 foleparam_inspect(VALUE self
)
7307 VALUE detail
= foleparam_name(self
);
7308 VALUE defval
= foleparam_default(self
);
7309 if (defval
!= Qnil
) {
7310 rb_str_cat2(detail
, "=");
7311 rb_str_concat(detail
, rb_funcall(defval
, rb_intern("inspect"), 0));
7313 return make_inspect("WIN32OLE_PARAM", detail
);
7317 * Document-class: WIN32OLE_EVENT
7319 * <code>WIN32OLE_EVENT</code> objects controls OLE event.
7322 static IEventSinkVtbl vtEventSink
;
7323 static BOOL g_IsEventSinkVtblInitialized
= FALSE
;
7325 void EVENTSINK_Destructor(PIEVENTSINKOBJ
);
7328 EVENTSINK_QueryInterface(
7333 if (IsEqualIID(iid
, &IID_IUnknown
) ||
7334 IsEqualIID(iid
, &IID_IDispatch
) ||
7335 IsEqualIID(iid
, &((PIEVENTSINKOBJ
)pEV
)->m_iid
)) {
7340 return E_NOINTERFACE
;
7342 ((LPUNKNOWN
)*ppv
)->lpVtbl
->AddRef((LPUNKNOWN
)*ppv
);
7346 STDMETHODIMP_(ULONG
)
7350 PIEVENTSINKOBJ pEVObj
= (PIEVENTSINKOBJ
)pEV
;
7351 return ++pEVObj
->m_cRef
;
7354 STDMETHODIMP_(ULONG
) EVENTSINK_Release(
7357 PIEVENTSINKOBJ pEVObj
= (PIEVENTSINKOBJ
)pEV
;
7359 if(pEVObj
->m_cRef
!= 0)
7360 return pEVObj
->m_cRef
;
7361 EVENTSINK_Destructor(pEVObj
);
7365 STDMETHODIMP
EVENTSINK_GetTypeInfoCount(
7373 STDMETHODIMP
EVENTSINK_GetTypeInfo(
7380 return DISP_E_BADINDEX
;
7383 STDMETHODIMP
EVENTSINK_GetIDsOfNames(
7384 PEVENTSINK pEventSink
,
7391 ITypeInfo
*pTypeInfo
;
7392 PIEVENTSINKOBJ pEV
= (PIEVENTSINKOBJ
)pEventSink
;
7393 pTypeInfo
= pEV
->pTypeInfo
;
7395 return pTypeInfo
->lpVtbl
->GetIDsOfNames(pTypeInfo
, szNames
, cNames
, pDispID
);
7397 return DISP_E_UNKNOWNNAME
;
7401 ole_search_event_at(VALUE ary
, VALUE ev
)
7409 len
= RARRAY_LEN(ary
);
7410 for(i
= 0; i
< len
; i
++) {
7411 event
= rb_ary_entry(ary
, i
);
7412 event_name
= rb_ary_entry(event
, 1);
7413 if(NIL_P(event_name
) && NIL_P(ev
)) {
7417 else if (TYPE(ev
) == T_STRING
&&
7418 TYPE(event_name
) == T_STRING
&&
7419 rb_str_cmp(ev
, event_name
) == 0) {
7428 ole_search_event(VALUE ary
, VALUE ev
, BOOL
*is_default
)
7434 *is_default
= FALSE
;
7436 len
= RARRAY_LEN(ary
);
7437 for(i
= 0; i
< len
; i
++) {
7438 event
= rb_ary_entry(ary
, i
);
7439 event_name
= rb_ary_entry(event
, 1);
7440 if(NIL_P(event_name
)) {
7444 else if (rb_str_cmp(ev
, event_name
) == 0) {
7445 *is_default
= FALSE
;
7452 ole_search_handler_method(VALUE handler
, VALUE ev
, BOOL
*is_default_handler
)
7456 *is_default_handler
= FALSE
;
7457 mid
= rb_to_id(rb_sprintf("on%s", StringValuePtr(ev
)));
7458 if (rb_respond_to(handler
, mid
)) {
7461 mid
= rb_intern("method_missing");
7462 if (rb_respond_to(handler
, mid
)) {
7463 *is_default_handler
= TRUE
;
7470 ole_delete_event(VALUE ary
, VALUE ev
)
7473 at
= ole_search_event_at(ary
, ev
);
7475 rb_ary_delete_at(ary
, at
);
7480 hash2ptr_dispparams(VALUE hash
, ITypeInfo
*pTypeInfo
, DISPID dispid
, DISPPARAMS
*pdispparams
)
7489 bstrs
= ALLOCA_N(BSTR
, pdispparams
->cArgs
+ 1);
7490 hr
= pTypeInfo
->lpVtbl
->GetNames(pTypeInfo
, dispid
,
7491 bstrs
, pdispparams
->cArgs
+ 1,
7496 for (i
= 0; i
< len
- 1; i
++) {
7497 key
= WC2VSTR(bstrs
[i
+ 1]);
7498 val
= rb_hash_aref(hash
, INT2FIX(i
));
7500 val
= rb_hash_aref(hash
, key
);
7502 val
= rb_hash_aref(hash
, rb_str_intern(key
));
7503 pvar
= &pdispparams
->rgvarg
[pdispparams
->cArgs
-i
-1];
7504 ole_val2ptr_variant(val
, pvar
);
7509 hash2result(VALUE hash
)
7512 ret
= rb_hash_aref(hash
, rb_str_new2("return"));
7514 ret
= rb_hash_aref(hash
, rb_str_intern(rb_str_new2("return")));
7519 ary2ptr_dispparams(VALUE ary
, DISPPARAMS
*pdispparams
)
7524 for(i
= 0; i
< RARRAY_LEN(ary
) && (unsigned int) i
< pdispparams
->cArgs
; i
++) {
7525 v
= rb_ary_entry(ary
, i
);
7526 pvar
= &pdispparams
->rgvarg
[pdispparams
->cArgs
-i
-1];
7527 ole_val2ptr_variant(v
, pvar
);
7532 exec_callback(VALUE arg
)
7534 VALUE
*parg
= (VALUE
*)arg
;
7535 VALUE handler
= parg
[0];
7536 VALUE mid
= parg
[1];
7537 VALUE args
= parg
[2];
7538 return rb_apply(handler
, mid
, args
);
7542 rescue_callback(VALUE arg
)
7545 VALUE e
= rb_errinfo();
7546 VALUE bt
= rb_funcall(e
, rb_intern("backtrace"), 0);
7547 VALUE msg
= rb_funcall(e
, rb_intern("message"), 0);
7548 bt
= rb_ary_entry(bt
, 0);
7549 fprintf(stdout
, "%s: %s (%s)\n", StringValuePtr(bt
), StringValuePtr(msg
), rb_obj_classname(e
));
7557 STDMETHODIMP
EVENTSINK_Invoke(
7558 PEVENTSINK pEventSink
,
7563 DISPPARAMS
*pdispparams
,
7564 VARIANT
*pvarResult
,
7565 EXCEPINFO
*pexcepinfo
,
7573 ITypeInfo
*pTypeInfo
;
7575 VALUE ary
, obj
, event
, args
, outargv
, ev
, result
;
7576 VALUE handler
= Qnil
;
7579 VALUE is_outarg
= Qfalse
;
7580 BOOL is_default_handler
= FALSE
;
7583 PIEVENTSINKOBJ pEV
= (PIEVENTSINKOBJ
)pEventSink
;
7584 pTypeInfo
= pEV
->pTypeInfo
;
7585 obj
= evs_entry(pEV
->m_event_id
);
7586 if (!rb_obj_is_kind_of(obj
, cWIN32OLE_EVENT
)) {
7590 ary
= rb_ivar_get(obj
, id_events
);
7591 if (NIL_P(ary
) || TYPE(ary
) != T_ARRAY
) {
7594 hr
= pTypeInfo
->lpVtbl
->GetNames(pTypeInfo
, dispid
,
7600 event
= ole_search_event(ary
, ev
, &is_default_handler
);
7601 if (TYPE(event
) == T_ARRAY
) {
7602 handler
= rb_ary_entry(event
, 0);
7603 mid
= rb_intern("call");
7604 is_outarg
= rb_ary_entry(event
, 3);
7606 handler
= rb_ivar_get(obj
, rb_intern("handler"));
7607 if (handler
== Qnil
) {
7610 mid
= ole_search_handler_method(handler
, ev
, &is_default_handler
);
7612 if (handler
== Qnil
|| mid
== Qnil
) {
7616 args
= rb_ary_new();
7617 if (is_default_handler
) {
7618 rb_ary_push(args
, ev
);
7621 /* make argument of event handler */
7622 for (i
= 0; i
< pdispparams
->cArgs
; ++i
) {
7623 pvar
= &pdispparams
->rgvarg
[pdispparams
->cArgs
-i
-1];
7624 rb_ary_push(args
, ole_variant2val(pvar
));
7627 if (is_outarg
== Qtrue
) {
7628 outargv
= rb_ary_new();
7629 rb_ary_push(args
, outargv
);
7633 * if exception raised in event callback,
7634 * then you receive cfp consistency error.
7635 * to avoid this error we use begin rescue end.
7636 * and the exception raised then error message print
7637 * and exit ruby process by Win32OLE itself.
7642 result
= rb_protect(exec_callback
, (VALUE
)arg
, &state
);
7644 rescue_callback(Qnil
);
7646 if(TYPE(result
) == T_HASH
) {
7647 hash2ptr_dispparams(result
, pTypeInfo
, dispid
, pdispparams
);
7648 result
= hash2result(result
);
7649 }else if (is_outarg
== Qtrue
&& TYPE(outargv
) == T_ARRAY
) {
7650 ary2ptr_dispparams(outargv
, pdispparams
);
7654 ole_val2variant(result
, pvarResult
);
7661 EVENTSINK_Constructor() {
7663 if (!g_IsEventSinkVtblInitialized
) {
7664 vtEventSink
.QueryInterface
=EVENTSINK_QueryInterface
;
7665 vtEventSink
.AddRef
= EVENTSINK_AddRef
;
7666 vtEventSink
.Release
= EVENTSINK_Release
;
7667 vtEventSink
.Invoke
= EVENTSINK_Invoke
;
7668 vtEventSink
.GetIDsOfNames
= EVENTSINK_GetIDsOfNames
;
7669 vtEventSink
.GetTypeInfoCount
= EVENTSINK_GetTypeInfoCount
;
7670 vtEventSink
.GetTypeInfo
= EVENTSINK_GetTypeInfo
;
7672 g_IsEventSinkVtblInitialized
= TRUE
;
7674 pEv
= ALLOC_N(IEVENTSINKOBJ
, 1);
7675 if(pEv
== NULL
) return NULL
;
7676 pEv
->lpVtbl
= &vtEventSink
;
7678 pEv
->m_event_id
= 0;
7679 pEv
->pTypeInfo
= NULL
;
7683 void EVENTSINK_Destructor(
7684 PIEVENTSINKOBJ pEVObj
7686 if(pEVObj
!= NULL
) {
7687 OLE_RELEASE(pEVObj
->pTypeInfo
);
7694 find_iid(VALUE ole
, char *pitf
, IID
*piid
, ITypeInfo
**ppTypeInfo
)
7697 IDispatch
*pDispatch
;
7698 ITypeInfo
*pTypeInfo
;
7700 TYPEATTR
*pTypeAttr
;
7702 ITypeInfo
*pImplTypeInfo
;
7703 TYPEATTR
*pImplTypeAttr
;
7705 struct oledata
*pole
;
7712 BOOL is_found
= FALSE
;
7713 LCID lcid
= cWIN32OLE_lcid
;
7715 OLEData_Get_Struct(ole
, pole
);
7717 pDispatch
= pole
->pDispatch
;
7719 hr
= pDispatch
->lpVtbl
->GetTypeInfo(pDispatch
, 0, lcid
, &pTypeInfo
);
7723 hr
= pTypeInfo
->lpVtbl
->GetContainingTypeLib(pTypeInfo
,
7726 OLE_RELEASE(pTypeInfo
);
7731 hr
= pTypeLib
->lpVtbl
->GetTypeInfoOfGuid(pTypeLib
,
7734 OLE_RELEASE(pTypeLib
);
7737 count
= pTypeLib
->lpVtbl
->GetTypeInfoCount(pTypeLib
);
7738 for (index
= 0; index
< count
; index
++) {
7739 hr
= pTypeLib
->lpVtbl
->GetTypeInfo(pTypeLib
,
7744 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
7747 OLE_RELEASE(pTypeInfo
);
7750 if(pTypeAttr
->typekind
== TKIND_COCLASS
) {
7751 for (type
= 0; type
< pTypeAttr
->cImplTypes
; type
++) {
7752 hr
= pTypeInfo
->lpVtbl
->GetRefTypeOfImplType(pTypeInfo
,
7757 hr
= pTypeInfo
->lpVtbl
->GetRefTypeInfo(pTypeInfo
,
7763 hr
= pImplTypeInfo
->lpVtbl
->GetDocumentation(pImplTypeInfo
,
7768 OLE_RELEASE(pImplTypeInfo
);
7771 pstr
= ole_wc2mb(bstr
);
7772 if (strcmp(pitf
, pstr
) == 0) {
7773 hr
= pImplTypeInfo
->lpVtbl
->GetTypeAttr(pImplTypeInfo
,
7775 if (SUCCEEDED(hr
)) {
7777 *piid
= pImplTypeAttr
->guid
;
7779 *ppTypeInfo
= pImplTypeInfo
;
7780 (*ppTypeInfo
)->lpVtbl
->AddRef((*ppTypeInfo
));
7782 pImplTypeInfo
->lpVtbl
->ReleaseTypeAttr(pImplTypeInfo
,
7787 OLE_RELEASE(pImplTypeInfo
);
7788 if (is_found
|| FAILED(hr
))
7793 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
7794 OLE_RELEASE(pTypeInfo
);
7795 if (is_found
|| FAILED(hr
))
7798 OLE_RELEASE(pTypeLib
);
7800 return E_NOINTERFACE
;
7806 ITypeInfo
*pTypeInfo
,
7807 TYPEATTR
*pTypeAttr
,
7808 ITypeInfo
**pCOTypeInfo
,
7809 TYPEATTR
**pCOTypeAttr
)
7811 HRESULT hr
= E_NOINTERFACE
;
7815 ITypeInfo
*pTypeInfo2
;
7816 TYPEATTR
*pTypeAttr2
;
7820 ITypeInfo
*pRefTypeInfo
;
7821 TYPEATTR
*pRefTypeAttr
;
7823 hr
= pTypeInfo
->lpVtbl
->GetContainingTypeLib(pTypeInfo
, &pTypeLib
, NULL
);
7827 count
= pTypeLib
->lpVtbl
->GetTypeInfoCount(pTypeLib
);
7828 for (i
= 0; i
< count
&& !found
; i
++) {
7829 hr
= pTypeLib
->lpVtbl
->GetTypeInfo(pTypeLib
, i
, &pTypeInfo2
);
7832 hr
= OLE_GET_TYPEATTR(pTypeInfo2
, &pTypeAttr2
);
7834 OLE_RELEASE(pTypeInfo2
);
7837 if (pTypeAttr2
->typekind
!= TKIND_COCLASS
) {
7838 OLE_RELEASE_TYPEATTR(pTypeInfo2
, pTypeAttr2
);
7839 OLE_RELEASE(pTypeInfo2
);
7842 for (j
= 0; j
< pTypeAttr2
->cImplTypes
&& !found
; j
++) {
7843 hr
= pTypeInfo2
->lpVtbl
->GetImplTypeFlags(pTypeInfo2
, j
, &flags
);
7846 if (!(flags
& IMPLTYPEFLAG_FDEFAULT
))
7848 hr
= pTypeInfo2
->lpVtbl
->GetRefTypeOfImplType(pTypeInfo2
, j
, &href
);
7851 hr
= pTypeInfo2
->lpVtbl
->GetRefTypeInfo(pTypeInfo2
, href
, &pRefTypeInfo
);
7854 hr
= OLE_GET_TYPEATTR(pRefTypeInfo
, &pRefTypeAttr
);
7856 OLE_RELEASE(pRefTypeInfo
);
7859 if (IsEqualGUID(&(pTypeAttr
->guid
), &(pRefTypeAttr
->guid
))) {
7864 OLE_RELEASE_TYPEATTR(pTypeInfo2
, pTypeAttr2
);
7865 OLE_RELEASE(pTypeInfo2
);
7868 OLE_RELEASE(pTypeLib
);
7870 *pCOTypeInfo
= pTypeInfo2
;
7871 *pCOTypeAttr
= pTypeAttr2
;
7880 find_default_source_from_typeinfo(
7881 ITypeInfo
*pTypeInfo
,
7882 TYPEATTR
*pTypeAttr
,
7883 ITypeInfo
**ppTypeInfo
)
7886 HRESULT hr
= E_NOINTERFACE
;
7889 /* Enumerate all implemented types of the COCLASS */
7890 for (i
= 0; i
< pTypeAttr
->cImplTypes
; i
++) {
7891 hr
= pTypeInfo
->lpVtbl
->GetImplTypeFlags(pTypeInfo
, i
, &flags
);
7896 looking for the [default] [source]
7897 we just hope that it is a dispinterface :-)
7899 if ((flags
& IMPLTYPEFLAG_FDEFAULT
) &&
7900 (flags
& IMPLTYPEFLAG_FSOURCE
)) {
7902 hr
= pTypeInfo
->lpVtbl
->GetRefTypeOfImplType(pTypeInfo
,
7906 hr
= pTypeInfo
->lpVtbl
->GetRefTypeInfo(pTypeInfo
,
7907 hRefType
, ppTypeInfo
);
7916 find_default_source(VALUE ole
, IID
*piid
, ITypeInfo
**ppTypeInfo
)
7919 IProvideClassInfo2
*pProvideClassInfo2
;
7920 IProvideClassInfo
*pProvideClassInfo
;
7923 IDispatch
*pDispatch
;
7924 ITypeInfo
*pTypeInfo
;
7925 ITypeInfo
*pTypeInfo2
= NULL
;
7926 TYPEATTR
*pTypeAttr
;
7927 TYPEATTR
*pTypeAttr2
= NULL
;
7929 struct oledata
*pole
;
7931 OLEData_Get_Struct(ole
, pole
);
7932 pDispatch
= pole
->pDispatch
;
7933 hr
= pDispatch
->lpVtbl
->QueryInterface(pDispatch
,
7934 &IID_IProvideClassInfo2
,
7936 if (SUCCEEDED(hr
)) {
7937 pProvideClassInfo2
= p
;
7938 hr
= pProvideClassInfo2
->lpVtbl
->GetGUID(pProvideClassInfo2
,
7939 GUIDKIND_DEFAULT_SOURCE_DISP_IID
,
7941 OLE_RELEASE(pProvideClassInfo2
);
7942 if (SUCCEEDED(hr
)) {
7943 hr
= find_iid(ole
, NULL
, piid
, ppTypeInfo
);
7946 if (SUCCEEDED(hr
)) {
7949 hr
= pDispatch
->lpVtbl
->QueryInterface(pDispatch
,
7950 &IID_IProvideClassInfo
,
7952 if (SUCCEEDED(hr
)) {
7953 pProvideClassInfo
= p
;
7954 hr
= pProvideClassInfo
->lpVtbl
->GetClassInfo(pProvideClassInfo
,
7956 OLE_RELEASE(pProvideClassInfo
);
7959 hr
= pDispatch
->lpVtbl
->GetTypeInfo(pDispatch
, 0, cWIN32OLE_lcid
, &pTypeInfo
);
7963 hr
= OLE_GET_TYPEATTR(pTypeInfo
, &pTypeAttr
);
7965 OLE_RELEASE(pTypeInfo
);
7970 hr
= find_default_source_from_typeinfo(pTypeInfo
, pTypeAttr
, ppTypeInfo
);
7972 hr
= find_coclass(pTypeInfo
, pTypeAttr
, &pTypeInfo2
, &pTypeAttr2
);
7973 if (SUCCEEDED(hr
)) {
7974 hr
= find_default_source_from_typeinfo(pTypeInfo2
, pTypeAttr2
, ppTypeInfo
);
7975 OLE_RELEASE_TYPEATTR(pTypeInfo2
, pTypeAttr2
);
7976 OLE_RELEASE(pTypeInfo2
);
7979 OLE_RELEASE_TYPEATTR(pTypeInfo
, pTypeAttr
);
7980 OLE_RELEASE(pTypeInfo
);
7981 /* Now that would be a bad surprise, if we didn't find it, wouldn't it? */
7988 /* Determine IID of default source interface */
7989 hr
= (*ppTypeInfo
)->lpVtbl
->GetTypeAttr(*ppTypeInfo
, &pTypeAttr
);
7990 if (SUCCEEDED(hr
)) {
7991 *piid
= pTypeAttr
->guid
;
7992 (*ppTypeInfo
)->lpVtbl
->ReleaseTypeAttr(*ppTypeInfo
, pTypeAttr
);
7995 OLE_RELEASE(*ppTypeInfo
);
8002 ole_event_free(struct oleeventdata
*poleev
)
8004 OLE_FREE(poleev
->pConnectionPoint
);
8009 fev_s_allocate(VALUE klass
)
8012 struct oleeventdata
*poleev
;
8013 obj
= Data_Make_Struct(klass
,struct oleeventdata
,0,ole_event_free
,poleev
);
8014 poleev
->dwCookie
= 0;
8015 poleev
->pConnectionPoint
= NULL
;
8016 poleev
->event_id
= 0;
8021 ev_advise(int argc
, VALUE
*argv
, VALUE self
)
8025 struct oledata
*pole
;
8029 ITypeInfo
*pTypeInfo
= 0;
8030 IDispatch
*pDispatch
;
8031 IConnectionPointContainer
*pContainer
;
8032 IConnectionPoint
*pConnectionPoint
;
8033 IEVENTSINKOBJ
*pIEV
;
8035 struct oleeventdata
*poleev
;
8039 rb_scan_args(argc
, argv
, "11", &ole
, &itf
);
8041 if (!rb_obj_is_kind_of(ole
, cWIN32OLE
)) {
8042 rb_raise(rb_eTypeError
, "1st parameter must be WIN32OLE object");
8045 if(TYPE(itf
) != T_NIL
) {
8046 if (rb_safe_level() > 0 && OBJ_TAINTED(itf
)) {
8047 rb_raise(rb_eSecurityError
, "Insecure Event Creation - %s",
8048 StringValuePtr(itf
));
8051 pitf
= StringValuePtr(itf
);
8052 hr
= find_iid(ole
, pitf
, &iid
, &pTypeInfo
);
8055 hr
= find_default_source(ole
, &iid
, &pTypeInfo
);
8058 ole_raise(hr
, rb_eRuntimeError
, "interface not found");
8061 OLEData_Get_Struct(ole
, pole
);
8062 pDispatch
= pole
->pDispatch
;
8063 hr
= pDispatch
->lpVtbl
->QueryInterface(pDispatch
,
8064 &IID_IConnectionPointContainer
,
8067 OLE_RELEASE(pTypeInfo
);
8068 ole_raise(hr
, rb_eRuntimeError
,
8069 "failed to query IConnectionPointContainer");
8073 hr
= pContainer
->lpVtbl
->FindConnectionPoint(pContainer
,
8076 OLE_RELEASE(pContainer
);
8078 OLE_RELEASE(pTypeInfo
);
8079 ole_raise(hr
, rb_eRuntimeError
, "failed to query IConnectionPoint");
8081 pIEV
= EVENTSINK_Constructor();
8083 hr
= pConnectionPoint
->lpVtbl
->Advise(pConnectionPoint
,
8087 ole_raise(hr
, rb_eRuntimeError
, "Advise Error");
8090 Data_Get_Struct(self
, struct oleeventdata
, poleev
);
8092 = NUM2INT(evs_length());
8093 pIEV
->pTypeInfo
= pTypeInfo
;
8094 poleev
->dwCookie
= dwCookie
;
8095 poleev
->pConnectionPoint
= pConnectionPoint
;
8096 poleev
->event_id
= pIEV
->m_event_id
;
8103 * WIN32OLE_EVENT.new(ole, event) #=> WIN32OLE_EVENT object.
8105 * Returns OLE event object.
8106 * The first argument specifies WIN32OLE object.
8107 * The second argument specifies OLE event name.
8108 * ie = WIN32OLE.new('InternetExplorer.Application')
8109 * ev = WIN32OLE_EVENT.new(ie, 'DWebBrowserEvents')
8112 fev_initialize(int argc
, VALUE
*argv
, VALUE self
)
8114 ev_advise(argc
, argv
, self
);
8116 rb_ivar_set(self
, id_events
, rb_ary_new());
8122 * WIN32OLE_EVENT.message_loop
8124 * Translates and dispatches Windows message.
8127 fev_s_msg_loop(VALUE klass
)
8135 add_event_call_back(VALUE obj
, VALUE event
, VALUE data
)
8137 VALUE events
= rb_ivar_get(obj
, id_events
);
8138 if (NIL_P(events
) || TYPE(events
) != T_ARRAY
) {
8139 events
= rb_ary_new();
8140 rb_ivar_set(obj
, id_events
, events
);
8142 ole_delete_event(events
, event
);
8143 rb_ary_push(events
, data
);
8147 ev_on_event(int argc
, VALUE
*argv
, VALUE self
, VALUE is_ary_arg
)
8149 struct oleeventdata
*poleev
;
8150 VALUE event
, args
, data
;
8151 Data_Get_Struct(self
, struct oleeventdata
, poleev
);
8152 if (poleev
->pConnectionPoint
== NULL
) {
8153 rb_raise(eWIN32OLERuntimeError
, "IConnectionPoint not found. You must call advise at first.");
8155 rb_scan_args(argc
, argv
, "01*", &event
, &args
);
8157 if(TYPE(event
) != T_STRING
&& TYPE(event
) != T_SYMBOL
) {
8158 rb_raise(rb_eTypeError
, "wrong argument type (expected String or Symbol)");
8160 if (TYPE(event
) == T_SYMBOL
) {
8161 event
= rb_sym_to_s(event
);
8164 data
= rb_ary_new3(4, rb_block_proc(), event
, args
, is_ary_arg
);
8165 add_event_call_back(self
, event
, data
);
8171 * WIN32OLE_EVENT#on_event([event]){...}
8173 * Defines the callback event.
8174 * If argument is omitted, this method defines the callback of all events.
8175 * If you want to modify reference argument in callback, return hash in
8176 * callback. If you want to return value to OLE server as result of callback
8177 * use `return' or :return.
8179 * ie = WIN32OLE.new('InternetExplorer.Application')
8180 * ev = WIN32OLE_EVENT.new(ie)
8181 * ev.on_event("NavigateComplete") {|url| puts url}
8182 * ev.on_event() {|ev, *args| puts "#{ev} fired"}
8184 * ev.on_event("BeforeNavigate2") {|*args|
8186 * # set true to BeforeNavigate reference argument `Cancel'.
8187 * # Cancel is 7-th argument of BeforeNavigate,
8188 * # so you can use 6 as key of hash instead of 'Cancel'.
8189 * # The argument is counted from 0.
8190 * # The hash key of 0 means first argument.)
8191 * {:Cancel => true} # or {'Cancel' => true} or {6 => true}
8194 * ev.on_event(...) {|*args|
8195 * {:return => 1, :xxx => yyy}
8199 fev_on_event(int argc
, VALUE
*argv
, VALUE self
)
8201 return ev_on_event(argc
, argv
, self
, Qfalse
);
8206 * WIN32OLE_EVENT#on_event_with_outargs([event]){...}
8208 * Defines the callback of event.
8209 * If you want modify argument in callback,
8210 * you could use this method instead of WIN32OLE_EVENT#on_event.
8212 * ie = WIN32OLE.new('InternetExplorer.Application')
8213 * ev = WIN32OLE_EVENT.new(ie)
8214 * ev.on_event_with_outargs('BeforeNavigate2') {|*args|
8215 * args.last[6] = true
8219 fev_on_event_with_outargs(int argc
, VALUE
*argv
, VALUE self
)
8221 return ev_on_event(argc
, argv
, self
, Qtrue
);
8226 * WIN32OLE_EVENT#off_event([event])
8228 * removes the callback of event.
8230 * ie = WIN32OLE.new('InternetExplorer.Application')
8231 * ev = WIN32OLE_EVENT.new(ie)
8232 * ev.on_event('BeforeNavigate2') {|*args|
8233 * args.last[6] = true
8236 * ev.off_event('BeforeNavigate2')
8240 fev_off_event(int argc
, VALUE
*argv
, VALUE self
)
8246 rb_scan_args(argc
, argv
, "01", &event
);
8248 if(TYPE(event
) != T_STRING
&& TYPE(event
) != T_SYMBOL
) {
8249 rb_raise(rb_eTypeError
, "wrong argument type (expected String or Symbol)");
8251 if (TYPE(event
) == T_SYMBOL
) {
8252 event
= rb_sym_to_s(event
);
8255 events
= rb_ivar_get(self
, id_events
);
8256 if (NIL_P(events
)) {
8259 ole_delete_event(events
, event
);
8265 * WIN32OLE_EVENT#unadvise -> nil
8267 * disconnects OLE server. If this method called, then the WIN32OLE_EVENT object
8268 * does not receive the OLE server event any more.
8269 * This method is trial implementation.
8271 * ie = WIN32OLE.new('InternetExplorer.Application')
8272 * ev = WIN32OLE_EVENT.new(ie)
8273 * ev.on_event() {...}
8279 fev_unadvise(VALUE self
)
8281 struct oleeventdata
*poleev
;
8282 Data_Get_Struct(self
, struct oleeventdata
, poleev
);
8283 if (poleev
->pConnectionPoint
) {
8285 evs_delete(poleev
->event_id
);
8286 poleev
->pConnectionPoint
->lpVtbl
->Unadvise(poleev
->pConnectionPoint
, poleev
->dwCookie
);
8287 OLE_RELEASE(poleev
->pConnectionPoint
);
8288 poleev
->pConnectionPoint
= NULL
;
8296 return rb_ary_push(ary_ole_event
, ev
);
8302 rb_ary_store(ary_ole_event
, i
, Qnil
);
8309 return rb_ary_entry(ary_ole_event
, i
);
8315 return rb_funcall(ary_ole_event
, rb_intern("length"), 0);
8320 * WIN32OLE_EVENT#handler=
8322 * sets event handler object. If handler object has onXXX
8323 * method according to XXX event, then onXXX method is called
8324 * when XXX event occurs.
8326 * If handler object has method_missing and there is no
8327 * method according to the event, then method_missing
8328 * called and 1-st argument is event name.
8330 * If handler object has onXXX method and there is block
8331 * defined by WIN32OLE_EVENT#on_event('XXX'){},
8332 * then block is executed but handler object method is not called
8333 * when XXX event occurs.
8336 * def onStatusTextChange(text)
8337 * puts "StatusTextChanged"
8339 * def onPropertyChange(prop)
8340 * puts "PropertyChanged"
8342 * def method_missing(ev, *arg)
8343 * puts "other event #{ev}"
8347 * handler = Handler.new
8348 * ie = WIN32OLE.new('InternetExplorer.Application')
8349 * ev = WIN32OLE_EVENT.new(ie)
8350 * ev.on_event("StatusTextChange") {|*args|
8351 * puts "this block executed."
8352 * puts "handler.onStatusTextChange method is not called."
8354 * ev.handler = handler
8358 fev_set_handler(VALUE self
, VALUE val
)
8360 return rb_ivar_set(self
, rb_intern("handler"), val
);
8365 * WIN32OLE_EVENT#handler
8367 * returns handler object.
8371 fev_get_handler(VALUE self
)
8373 return rb_ivar_get(self
, rb_intern("handler"));
8377 olevariant_free(struct olevariantdata
*pvar
)
8379 VariantClear(&(pvar
->realvar
));
8380 VariantClear(&(pvar
->var
));
8385 folevariant_s_allocate(VALUE klass
)
8387 struct olevariantdata
*pvar
;
8390 obj
= Data_Make_Struct(klass
,struct olevariantdata
,0,olevariant_free
,pvar
);
8391 VariantInit(&(pvar
->var
));
8392 VariantInit(&(pvar
->realvar
));
8398 * WIN32OLE_VARIANT.array(ary, vt)
8400 * Returns Ruby object wrapping OLE variant whose variant type is VT_ARRAY.
8401 * The first argument should be Array object which specifies dimensions
8402 * and each size of dimensions of OLE array.
8403 * The second argument specifies variant type of the element of OLE array.
8405 * The following create 2 dimensions OLE array. The first dimensions size
8406 * is 3, and the second is 4.
8408 * ole_ary = WIN32OLE_VARIANT.array([3,4], VT_I4)
8409 * ruby_ary = ole_ary.value # => [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
8413 folevariant_s_array(VALUE klass
, VALUE elems
, VALUE vvt
)
8417 struct olevariantdata
*pvar
;
8418 SAFEARRAYBOUND
*psab
= NULL
;
8419 SAFEARRAY
*psa
= NULL
;
8426 vt
= (vt
| VT_ARRAY
);
8427 Check_Type(elems
, T_ARRAY
);
8428 obj
= folevariant_s_allocate(klass
);
8430 Data_Get_Struct(obj
, struct olevariantdata
, pvar
);
8431 dim
= RARRAY_LEN(elems
);
8433 psab
= ALLOC_N(SAFEARRAYBOUND
, dim
);
8436 rb_raise(rb_eRuntimeError
, "memory allocation error");
8439 for (i
= 0; i
< dim
; i
++) {
8440 psab
[i
].cElements
= FIX2INT(rb_ary_entry(elems
, i
));
8441 psab
[i
].lLbound
= 0;
8444 psa
= SafeArrayCreate((VARTYPE
)(vt
& VT_TYPEMASK
), dim
, psab
);
8446 if (psab
) free(psab
);
8447 rb_raise(rb_eRuntimeError
, "memory allocation error(SafeArrayCreate)");
8450 V_VT(&(pvar
->var
)) = vt
;
8451 if (vt
& VT_BYREF
) {
8452 V_VT(&(pvar
->realvar
)) = (vt
& ~VT_BYREF
);
8453 V_ARRAY(&(pvar
->realvar
)) = psa
;
8454 V_ARRAYREF(&(pvar
->var
)) = &(V_ARRAY(&(pvar
->realvar
)));
8456 V_ARRAY(&(pvar
->var
)) = psa
;
8458 if (psab
) free(psab
);
8464 * WIN32OLE_VARIANT.new(val, vartype) #=> WIN32OLE_VARIANT object.
8466 * Returns Ruby object wrapping OLE variant.
8467 * The first argument specifies Ruby object to convert OLE variant variable.
8468 * The second argument specifies VARIANT type.
8469 * In some situation, you need the WIN32OLE_VARIANT object to pass OLE method
8471 * shell = WIN32OLE.new("Shell.Application")
8472 * folder = shell.NameSpace("C:\\Windows")
8473 * item = folder.ParseName("tmp.txt")
8474 * # You can't use Ruby String object to call FolderItem.InvokeVerb.
8475 * # Instead, you have to use WIN32OLE_VARIANT object to call the method.
8476 * shortcut = WIN32OLE_VARIANT.new("Create Shortcut(\&S)")
8477 * item.invokeVerb(shortcut)
8481 folevariant_initialize(VALUE self
, VALUE args
)
8488 struct olevariantdata
*pvar
;
8490 len
= RARRAY_LEN(args
);
8491 if (len
< 1 || len
> 3) {
8492 rb_raise(rb_eArgError
, "wrong number of arguments (%d for 1..3)", len
);
8495 val
= rb_ary_entry(args
, 0);
8496 Data_Get_Struct(self
, struct olevariantdata
, pvar
);
8498 ole_val2variant(val
, &(pvar
->var
));
8500 vvt
= rb_ary_entry(args
, 1);
8502 ole_val2olevariantdata(val
, vt
, pvar
);
8504 vt
= V_VT(&pvar
->var
);
8509 get_locked_safe_array(VALUE val
)
8511 struct olevariantdata
*pvar
;
8512 SAFEARRAY
*psa
= NULL
;
8514 Data_Get_Struct(val
, struct olevariantdata
, pvar
);
8515 if (!(V_VT(&(pvar
->var
)) & VT_ARRAY
)) {
8516 rb_raise(rb_eTypeError
, "variant type is not VT_ARRAY.");
8518 psa
= V_ISBYREF(&(pvar
->var
)) ? *V_ARRAYREF(&(pvar
->var
)) : V_ARRAY(&(pvar
->var
));
8522 hr
= SafeArrayLock(psa
);
8524 ole_raise(hr
, rb_eRuntimeError
, "failed to SafeArrayLock");
8530 ary2safe_array_index(int ary_size
, VALUE
*ary
, SAFEARRAY
*psa
)
8535 dim
= SafeArrayGetDim(psa
);
8536 if (dim
!= ary_size
) {
8537 rb_raise(rb_eArgError
, "unmatch number of indices");
8539 pid
= ALLOC_N(long, dim
);
8541 rb_raise(rb_eRuntimeError
, "failed to allocate memory for indices");
8543 for (i
= 0; i
< dim
; i
++) {
8544 pid
[i
] = NUM2INT(ary
[i
]);
8550 unlock_safe_array(SAFEARRAY
*psa
)
8553 hr
= SafeArrayUnlock(psa
);
8555 ole_raise(hr
, rb_eRuntimeError
, "failed to SafeArrayUnlock");
8561 * WIN32OLE_VARIANT[i,j,...] #=> element of OLE array.
8563 * Returns the element of WIN32OLE_VARIANT object(OLE array).
8564 * This method is available only when the variant type of
8565 * WIN32OLE_VARIANT object is VT_ARRAY.
8568 * The all indicies should be 0 or natural number and
8569 * lower than or equal to max indicies.
8570 * (This point is different with Ruby Array indicies.)
8572 * obj = WIN32OLE_VARIANT.new([[1,2,3],[4,5,6]])
8575 * p obj[2,0] # => WIN32OLERuntimeError
8576 * p obj[0, -1] # => WIN32OLERuntimeError
8580 folevariant_ary_aref(int argc
, VALUE
*argv
, VALUE self
)
8582 struct olevariantdata
*pvar
;
8589 Data_Get_Struct(self
, struct olevariantdata
, pvar
);
8590 if (!V_ISARRAY(&(pvar
->var
))) {
8591 rb_raise(eWIN32OLERuntimeError
,
8592 "`[]' is not available for this variant type object");
8594 psa
= get_locked_safe_array(self
);
8599 pid
= ary2safe_array_index(argc
, argv
, psa
);
8601 VariantInit(&variant
);
8602 V_VT(&variant
) = (V_VT(&(pvar
->var
)) & ~VT_ARRAY
) | VT_BYREF
;
8603 hr
= SafeArrayPtrOfIndex(psa
, pid
, &V_BYREF(&variant
));
8605 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to SafeArrayPtrOfIndex");
8607 val
= ole_variant2val(&variant
);
8609 unlock_safe_array(psa
);
8615 val2variant_ptr(VALUE val
, VARIANT
*var
, VARTYPE vt
)
8619 ole_val2variant_ex(val
, var
, vt
);
8620 if ((vt
& ~VT_BYREF
) == VT_VARIANT
) {
8623 if ( (vt
& ~VT_BYREF
) != V_VT(var
)) {
8624 hr
= VariantChangeTypeEx(var
, var
,
8625 cWIN32OLE_lcid
, 0, (VARTYPE
)(vt
& ~VT_BYREF
));
8627 ole_raise(hr
, rb_eRuntimeError
, "failed to change type");
8630 p
= get_ptr_of_variant(var
);
8633 rb_raise(rb_eRuntimeError
, "failed to get pointer of variant");
8640 * WIN32OLE_VARIANT[i,j,...] = val #=> set the element of OLE array
8642 * Set the element of WIN32OLE_VARIANT object(OLE array) to val.
8643 * This method is available only when the variant type of
8644 * WIN32OLE_VARIANT object is VT_ARRAY.
8647 * The all indicies should be 0 or natural number and
8648 * lower than or equal to max indicies.
8649 * (This point is different with Ruby Array indicies.)
8651 * obj = WIN32OLE_VARIANT.new([[1,2,3],[4,5,6]])
8654 * p obj.value # => [[7,2,3], [8,5,6]]
8655 * obj[2,0] = 9 # => WIN32OLERuntimeError
8656 * obj[0, -1] = 9 # => WIN32OLERuntimeError
8660 folevariant_ary_aset(int argc
, VALUE
*argv
, VALUE self
)
8662 struct olevariantdata
*pvar
;
8670 Data_Get_Struct(self
, struct olevariantdata
, pvar
);
8671 if (!V_ISARRAY(&(pvar
->var
))) {
8672 rb_raise(eWIN32OLERuntimeError
,
8673 "`[]' is not available for this variant type object");
8675 psa
= get_locked_safe_array(self
);
8677 rb_raise(rb_eRuntimeError
, "failed to get SafeArray pointer");
8680 pid
= ary2safe_array_index(argc
-1, argv
, psa
);
8683 vt
= (V_VT(&(pvar
->var
)) & ~VT_ARRAY
);
8684 p
= val2variant_ptr(argv
[argc
-1], &var
, vt
);
8685 if ((V_VT(&var
) == VT_DISPATCH
&& V_DISPATCH(&var
) == NULL
) ||
8686 (V_VT(&var
) == VT_UNKNOWN
&& V_UNKNOWN(&var
) == NULL
)) {
8687 rb_raise(eWIN32OLERuntimeError
, "argument does not have IDispatch or IUnknown Interface");
8689 hr
= SafeArrayPutElement(psa
, pid
, p
);
8691 ole_raise(hr
, eWIN32OLERuntimeError
, "failed to SafeArrayPutElement");
8694 unlock_safe_array(psa
);
8696 return argv
[argc
-1];
8701 * WIN32OLE_VARIANT.value #=> Ruby object.
8703 * Returns Ruby object value from OLE variant.
8704 * obj = WIN32OLE_VARIANT.new(1, WIN32OLE::VARIANT::VT_BSTR)
8705 * obj.value # => "1" (not Fixnum object, but String object "1")
8709 folevariant_value(VALUE self
)
8711 struct olevariantdata
*pvar
;
8716 Data_Get_Struct(self
, struct olevariantdata
, pvar
);
8718 val
= ole_variant2val(&(pvar
->var
));
8719 vt
= V_VT(&(pvar
->var
));
8721 if ((vt
& ~VT_BYREF
) == (VT_UI1
|VT_ARRAY
)) {
8722 if (vt
& VT_BYREF
) {
8723 psa
= *V_ARRAYREF(&(pvar
->var
));
8725 psa
= V_ARRAY(&(pvar
->var
));
8730 dim
= SafeArrayGetDim(psa
);
8732 val
= rb_funcall(val
, rb_intern("pack"), 1, rb_str_new2("C*"));
8740 * WIN32OLE_VARIANT.vartype #=> OLE variant type.
8742 * Returns OLE variant type.
8743 * obj = WIN32OLE_VARIANT.new("string")
8744 * obj.vartype # => WIN32OLE::VARIANT::VT_BSTR
8748 folevariant_vartype(VALUE self
)
8750 struct olevariantdata
*pvar
;
8751 Data_Get_Struct(self
, struct olevariantdata
, pvar
);
8752 return INT2FIX(V_VT(&pvar
->var
));
8757 * WIN32OLE_VARIANT.value = val #=> set WIN32OLE_VARIANT value to val.
8759 * Sets variant value to val. If the val type does not match variant value
8760 * type(vartype), then val is changed to match variant value type(vartype)
8761 * before setting val.
8762 * Thie method is not available when vartype is VT_ARRAY(except VT_UI1|VT_ARRAY).
8763 * If the vartype is VT_UI1|VT_ARRAY, the val should be String object.
8765 * obj = WIN32OLE_VARIANT.new(1) # obj.vartype is WIN32OLE::VARIANT::VT_I4
8766 * obj.value = 3.2 # 3.2 is changed to 3 when setting value.
8767 * p obj.value # => 3
8770 folevariant_set_value(VALUE self
, VALUE val
)
8772 struct olevariantdata
*pvar
;
8774 Data_Get_Struct(self
, struct olevariantdata
, pvar
);
8775 vt
= V_VT(&(pvar
->var
));
8776 if (V_ISARRAY(&(pvar
->var
)) && ((vt
& ~VT_BYREF
) != (VT_UI1
|VT_ARRAY
) || TYPE(val
) != T_STRING
)) {
8777 rb_raise(eWIN32OLERuntimeError
,
8778 "`value=' is not available for this variant type object");
8780 ole_val2olevariantdata(val
, vt
, pvar
);
8787 enc2cp_table
= st_init_numtable();
8793 st_free_table(enc2cp_table
);
8799 ary_ole_event
= rb_ary_new();
8800 rb_register_mark_object(ary_ole_event
);
8801 id_events
= rb_intern("events");
8803 com_vtbl
.QueryInterface
= QueryInterface
;
8804 com_vtbl
.AddRef
= AddRef
;
8805 com_vtbl
.Release
= Release
;
8806 com_vtbl
.GetTypeInfoCount
= GetTypeInfoCount
;
8807 com_vtbl
.GetTypeInfo
= GetTypeInfo
;
8808 com_vtbl
.GetIDsOfNames
= GetIDsOfNames
;
8809 com_vtbl
.Invoke
= Invoke
;
8811 message_filter
.QueryInterface
= mf_QueryInterface
;
8812 message_filter
.AddRef
= mf_AddRef
;
8813 message_filter
.Release
= mf_Release
;
8814 message_filter
.HandleInComingCall
= mf_HandleInComingCall
;
8815 message_filter
.RetryRejectedCall
= mf_RetryRejectedCall
;
8816 message_filter
.MessagePending
= mf_MessagePending
;
8818 com_hash
= Data_Wrap_Struct(rb_cData
, rb_mark_hash
, st_free_table
, st_init_numtable());
8819 rb_register_mark_object(com_hash
);
8821 cWIN32OLE
= rb_define_class("WIN32OLE", rb_cObject
);
8823 rb_define_alloc_func(cWIN32OLE
, fole_s_allocate
);
8825 rb_define_method(cWIN32OLE
, "initialize", fole_initialize
, -1);
8827 rb_define_singleton_method(cWIN32OLE
, "connect", fole_s_connect
, -1);
8828 rb_define_singleton_method(cWIN32OLE
, "const_load", fole_s_const_load
, -1);
8830 rb_define_singleton_method(cWIN32OLE
, "ole_free", fole_s_free
, 1);
8831 rb_define_singleton_method(cWIN32OLE
, "ole_reference_count", fole_s_reference_count
, 1);
8832 rb_define_singleton_method(cWIN32OLE
, "ole_show_help", fole_s_show_help
, -1);
8833 rb_define_singleton_method(cWIN32OLE
, "codepage", fole_s_get_code_page
, 0);
8834 rb_define_singleton_method(cWIN32OLE
, "codepage=", fole_s_set_code_page
, 1);
8835 rb_define_singleton_method(cWIN32OLE
, "locale", fole_s_get_locale
, 0);
8836 rb_define_singleton_method(cWIN32OLE
, "locale=", fole_s_set_locale
, 1);
8837 rb_define_singleton_method(cWIN32OLE
, "create_guid", fole_s_create_guid
, 0);
8839 rb_define_method(cWIN32OLE
, "invoke", fole_invoke
, -1);
8840 rb_define_method(cWIN32OLE
, "[]", fole_getproperty_with_bracket
, -1);
8841 rb_define_method(cWIN32OLE
, "_invoke", fole_invoke2
, 3);
8842 rb_define_method(cWIN32OLE
, "_getproperty", fole_getproperty2
, 3);
8843 rb_define_method(cWIN32OLE
, "_setproperty", fole_setproperty2
, 3);
8845 /* support propput method that takes an argument */
8846 rb_define_method(cWIN32OLE
, "[]=", fole_setproperty_with_bracket
, -1);
8848 rb_define_method(cWIN32OLE
, "ole_free", fole_free
, 0);
8850 rb_define_method(cWIN32OLE
, "each", fole_each
, 0);
8851 rb_define_method(cWIN32OLE
, "method_missing", fole_missing
, -1);
8853 /* support setproperty method much like Perl ;-) */
8854 rb_define_method(cWIN32OLE
, "setproperty", fole_setproperty
, -1);
8856 rb_define_method(cWIN32OLE
, "ole_methods", fole_methods
, 0);
8857 rb_define_method(cWIN32OLE
, "ole_get_methods", fole_get_methods
, 0);
8858 rb_define_method(cWIN32OLE
, "ole_put_methods", fole_put_methods
, 0);
8859 rb_define_method(cWIN32OLE
, "ole_func_methods", fole_func_methods
, 0);
8861 rb_define_method(cWIN32OLE
, "ole_method", fole_method_help
, 1);
8862 rb_define_alias(cWIN32OLE
, "ole_method_help", "ole_method");
8863 rb_define_method(cWIN32OLE
, "ole_activex_initialize", fole_activex_initialize
, 0);
8864 rb_define_method(cWIN32OLE
, "ole_type", fole_type
, 0);
8865 rb_define_alias(cWIN32OLE
, "ole_obj_help", "ole_type");
8866 rb_define_method(cWIN32OLE
, "ole_typelib", fole_typelib
, 0);
8867 rb_define_method(cWIN32OLE
, "ole_query_interface", fole_query_interface
, 1);
8868 rb_define_method(cWIN32OLE
, "ole_respond_to?", fole_respond_to
, 1);
8870 rb_define_const(cWIN32OLE
, "VERSION", rb_str_new2(WIN32OLE_VERSION
));
8871 rb_define_const(cWIN32OLE
, "ARGV", rb_ary_new());
8873 rb_define_const(cWIN32OLE
, "CP_ACP", INT2FIX(CP_ACP
));
8874 rb_define_const(cWIN32OLE
, "CP_OEMCP", INT2FIX(CP_OEMCP
));
8875 rb_define_const(cWIN32OLE
, "CP_MACCP", INT2FIX(CP_MACCP
));
8876 rb_define_const(cWIN32OLE
, "CP_THREAD_ACP", INT2FIX(CP_THREAD_ACP
));
8877 rb_define_const(cWIN32OLE
, "CP_SYMBOL", INT2FIX(CP_SYMBOL
));
8878 rb_define_const(cWIN32OLE
, "CP_UTF7", INT2FIX(CP_UTF7
));
8879 rb_define_const(cWIN32OLE
, "CP_UTF8", INT2FIX(CP_UTF8
));
8881 rb_define_const(cWIN32OLE
, "LOCALE_SYSTEM_DEFAULT", INT2FIX(LOCALE_SYSTEM_DEFAULT
));
8882 rb_define_const(cWIN32OLE
, "LOCALE_USER_DEFAULT", INT2FIX(LOCALE_USER_DEFAULT
));
8884 mWIN32OLE_VARIANT
= rb_define_module_under(cWIN32OLE
, "VARIANT");
8885 rb_define_const(mWIN32OLE_VARIANT
, "VT_EMPTY", INT2FIX(VT_EMPTY
));
8886 rb_define_const(mWIN32OLE_VARIANT
, "VT_NULL", INT2FIX(VT_NULL
));
8887 rb_define_const(mWIN32OLE_VARIANT
, "VT_I2", INT2FIX(VT_I2
));
8888 rb_define_const(mWIN32OLE_VARIANT
, "VT_I4", INT2FIX(VT_I4
));
8889 rb_define_const(mWIN32OLE_VARIANT
, "VT_R4", INT2FIX(VT_R4
));
8890 rb_define_const(mWIN32OLE_VARIANT
, "VT_R8", INT2FIX(VT_R8
));
8891 rb_define_const(mWIN32OLE_VARIANT
, "VT_CY", INT2FIX(VT_CY
));
8892 rb_define_const(mWIN32OLE_VARIANT
, "VT_DATE", INT2FIX(VT_DATE
));
8893 rb_define_const(mWIN32OLE_VARIANT
, "VT_BSTR", INT2FIX(VT_BSTR
));
8894 rb_define_const(mWIN32OLE_VARIANT
, "VT_USERDEFINED", INT2FIX(VT_USERDEFINED
));
8895 rb_define_const(mWIN32OLE_VARIANT
, "VT_PTR", INT2FIX(VT_PTR
));
8896 rb_define_const(mWIN32OLE_VARIANT
, "VT_DISPATCH", INT2FIX(VT_DISPATCH
));
8897 rb_define_const(mWIN32OLE_VARIANT
, "VT_ERROR", INT2FIX(VT_ERROR
));
8898 rb_define_const(mWIN32OLE_VARIANT
, "VT_BOOL", INT2FIX(VT_BOOL
));
8899 rb_define_const(mWIN32OLE_VARIANT
, "VT_VARIANT", INT2FIX(VT_VARIANT
));
8900 rb_define_const(mWIN32OLE_VARIANT
, "VT_UNKNOWN", INT2FIX(VT_UNKNOWN
));
8901 rb_define_const(mWIN32OLE_VARIANT
, "VT_I1", INT2FIX(VT_I1
));
8902 rb_define_const(mWIN32OLE_VARIANT
, "VT_UI1", INT2FIX(VT_UI1
));
8903 rb_define_const(mWIN32OLE_VARIANT
, "VT_UI2", INT2FIX(VT_UI2
));
8904 rb_define_const(mWIN32OLE_VARIANT
, "VT_UI4", INT2FIX(VT_UI4
));
8905 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
8906 rb_define_const(mWIN32OLE_VARIANT
, "VT_I8", INT2FIX(VT_I8
));
8907 rb_define_const(mWIN32OLE_VARIANT
, "VT_UI8", INT2FIX(VT_UI8
));
8909 rb_define_const(mWIN32OLE_VARIANT
, "VT_INT", INT2FIX(VT_INT
));
8910 rb_define_const(mWIN32OLE_VARIANT
, "VT_UINT", INT2FIX(VT_UINT
));
8911 rb_define_const(mWIN32OLE_VARIANT
, "VT_ARRAY", INT2FIX(VT_ARRAY
));
8912 rb_define_const(mWIN32OLE_VARIANT
, "VT_BYREF", INT2FIX(VT_BYREF
));
8914 cWIN32OLE_TYPELIB
= rb_define_class("WIN32OLE_TYPELIB", rb_cObject
);
8915 rb_define_singleton_method(cWIN32OLE_TYPELIB
, "typelibs", foletypelib_s_typelibs
, 0);
8916 rb_define_method(cWIN32OLE_TYPELIB
, "initialize", foletypelib_initialize
, -2);
8917 rb_define_method(cWIN32OLE_TYPELIB
, "guid", foletypelib_guid
, 0);
8918 rb_define_method(cWIN32OLE_TYPELIB
, "name", foletypelib_name
, 0);
8919 rb_define_method(cWIN32OLE_TYPELIB
, "version", foletypelib_version
, 0);
8920 rb_define_method(cWIN32OLE_TYPELIB
, "major_version", foletypelib_major_version
, 0);
8921 rb_define_method(cWIN32OLE_TYPELIB
, "minor_version", foletypelib_minor_version
, 0);
8922 rb_define_method(cWIN32OLE_TYPELIB
, "path", foletypelib_path
, 0);
8923 rb_define_method(cWIN32OLE_TYPELIB
, "ole_types", foletypelib_ole_types
, 0);
8924 rb_define_alias(cWIN32OLE_TYPELIB
, "ole_classes", "ole_types");
8925 rb_define_method(cWIN32OLE_TYPELIB
, "visible?", foletypelib_visible
, 0);
8926 rb_define_method(cWIN32OLE_TYPELIB
, "library_name", foletypelib_library_name
, 0);
8927 rb_define_alias(cWIN32OLE_TYPELIB
, "to_s", "name");
8928 rb_define_method(cWIN32OLE_TYPELIB
, "inspect", foletypelib_inspect
, 0);
8930 cWIN32OLE_TYPE
= rb_define_class("WIN32OLE_TYPE", rb_cObject
);
8931 rb_define_singleton_method(cWIN32OLE_TYPE
, "ole_classes", foletype_s_ole_classes
, 1);
8932 rb_define_singleton_method(cWIN32OLE_TYPE
, "typelibs", foletype_s_typelibs
, 0);
8933 rb_define_singleton_method(cWIN32OLE_TYPE
, "progids", foletype_s_progids
, 0);
8934 rb_define_alloc_func(cWIN32OLE_TYPE
, foletype_s_allocate
);
8935 rb_define_method(cWIN32OLE_TYPE
, "initialize", foletype_initialize
, 2);
8936 rb_define_method(cWIN32OLE_TYPE
, "name", foletype_name
, 0);
8937 rb_define_method(cWIN32OLE_TYPE
, "ole_type", foletype_ole_type
, 0);
8938 rb_define_method(cWIN32OLE_TYPE
, "guid", foletype_guid
, 0);
8939 rb_define_method(cWIN32OLE_TYPE
, "progid", foletype_progid
, 0);
8940 rb_define_method(cWIN32OLE_TYPE
, "visible?", foletype_visible
, 0);
8941 rb_define_alias(cWIN32OLE_TYPE
, "to_s", "name");
8942 rb_define_method(cWIN32OLE_TYPE
, "major_version", foletype_major_version
, 0);
8943 rb_define_method(cWIN32OLE_TYPE
, "minor_version", foletype_minor_version
, 0);
8944 rb_define_method(cWIN32OLE_TYPE
, "typekind", foletype_typekind
, 0);
8945 rb_define_method(cWIN32OLE_TYPE
, "helpstring", foletype_helpstring
, 0);
8946 rb_define_method(cWIN32OLE_TYPE
, "src_type", foletype_src_type
, 0);
8947 rb_define_method(cWIN32OLE_TYPE
, "helpfile", foletype_helpfile
, 0);
8948 rb_define_method(cWIN32OLE_TYPE
, "helpcontext", foletype_helpcontext
, 0);
8949 rb_define_method(cWIN32OLE_TYPE
, "variables", foletype_variables
, 0);
8950 rb_define_method(cWIN32OLE_TYPE
, "ole_methods", foletype_methods
, 0);
8951 rb_define_method(cWIN32OLE_TYPE
, "ole_typelib", foletype_ole_typelib
, 0);
8952 rb_define_method(cWIN32OLE_TYPE
, "implemented_ole_types", foletype_impl_ole_types
, 0);
8953 rb_define_method(cWIN32OLE_TYPE
, "source_ole_types", foletype_source_ole_types
, 0);
8954 rb_define_method(cWIN32OLE_TYPE
, "default_event_sources", foletype_default_event_sources
, 0);
8955 rb_define_method(cWIN32OLE_TYPE
, "default_ole_types", foletype_default_ole_types
, 0);
8956 rb_define_method(cWIN32OLE_TYPE
, "inspect", foletype_inspect
, 0);
8958 cWIN32OLE_VARIABLE
= rb_define_class("WIN32OLE_VARIABLE", rb_cObject
);
8959 rb_define_method(cWIN32OLE_VARIABLE
, "name", folevariable_name
, 0);
8960 rb_define_method(cWIN32OLE_VARIABLE
, "ole_type", folevariable_ole_type
, 0);
8961 rb_define_method(cWIN32OLE_VARIABLE
, "ole_type_detail", folevariable_ole_type_detail
, 0);
8962 rb_define_method(cWIN32OLE_VARIABLE
, "value", folevariable_value
, 0);
8963 rb_define_method(cWIN32OLE_VARIABLE
, "visible?", folevariable_visible
, 0);
8964 rb_define_method(cWIN32OLE_VARIABLE
, "variable_kind", folevariable_variable_kind
, 0);
8965 rb_define_method(cWIN32OLE_VARIABLE
, "varkind", folevariable_varkind
, 0);
8966 rb_define_method(cWIN32OLE_VARIABLE
, "inspect", folevariable_inspect
, 0);
8967 rb_define_alias(cWIN32OLE_VARIABLE
, "to_s", "name");
8969 cWIN32OLE_METHOD
= rb_define_class("WIN32OLE_METHOD", rb_cObject
);
8970 rb_define_alloc_func(cWIN32OLE_METHOD
, folemethod_s_allocate
);
8971 rb_define_method(cWIN32OLE_METHOD
, "initialize", folemethod_initialize
, 2);
8972 rb_define_method(cWIN32OLE_METHOD
, "name", folemethod_name
, 0);
8973 rb_define_method(cWIN32OLE_METHOD
, "return_type", folemethod_return_type
, 0);
8974 rb_define_method(cWIN32OLE_METHOD
, "return_vtype", folemethod_return_vtype
, 0);
8975 rb_define_method(cWIN32OLE_METHOD
, "return_type_detail", folemethod_return_type_detail
, 0);
8976 rb_define_method(cWIN32OLE_METHOD
, "invoke_kind", folemethod_invoke_kind
, 0);
8977 rb_define_method(cWIN32OLE_METHOD
, "invkind", folemethod_invkind
, 0);
8978 rb_define_method(cWIN32OLE_METHOD
, "visible?", folemethod_visible
, 0);
8979 rb_define_method(cWIN32OLE_METHOD
, "event?", folemethod_event
, 0);
8980 rb_define_method(cWIN32OLE_METHOD
, "event_interface", folemethod_event_interface
, 0);
8981 rb_define_method(cWIN32OLE_METHOD
, "helpstring", folemethod_helpstring
, 0);
8982 rb_define_method(cWIN32OLE_METHOD
, "helpfile", folemethod_helpfile
, 0);
8983 rb_define_method(cWIN32OLE_METHOD
, "helpcontext", folemethod_helpcontext
, 0);
8984 rb_define_method(cWIN32OLE_METHOD
, "dispid", folemethod_dispid
, 0);
8985 rb_define_method(cWIN32OLE_METHOD
, "offset_vtbl", folemethod_offset_vtbl
, 0);
8986 rb_define_method(cWIN32OLE_METHOD
, "size_params", folemethod_size_params
, 0);
8987 rb_define_method(cWIN32OLE_METHOD
, "size_opt_params", folemethod_size_opt_params
, 0);
8988 rb_define_method(cWIN32OLE_METHOD
, "params", folemethod_params
, 0);
8989 rb_define_alias(cWIN32OLE_METHOD
, "to_s", "name");
8990 rb_define_method(cWIN32OLE_METHOD
, "inspect", folemethod_inspect
, 0);
8992 cWIN32OLE_PARAM
= rb_define_class("WIN32OLE_PARAM", rb_cObject
);
8993 rb_define_method(cWIN32OLE_PARAM
, "name", foleparam_name
, 0);
8994 rb_define_method(cWIN32OLE_PARAM
, "ole_type", foleparam_ole_type
, 0);
8995 rb_define_method(cWIN32OLE_PARAM
, "ole_type_detail", foleparam_ole_type_detail
, 0);
8996 rb_define_method(cWIN32OLE_PARAM
, "input?", foleparam_input
, 0);
8997 rb_define_method(cWIN32OLE_PARAM
, "output?", foleparam_output
, 0);
8998 rb_define_method(cWIN32OLE_PARAM
, "optional?", foleparam_optional
, 0);
8999 rb_define_method(cWIN32OLE_PARAM
, "retval?", foleparam_retval
, 0);
9000 rb_define_method(cWIN32OLE_PARAM
, "default", foleparam_default
, 0);
9001 rb_define_alias(cWIN32OLE_PARAM
, "to_s", "name");
9002 rb_define_method(cWIN32OLE_PARAM
, "inspect", foleparam_inspect
, 0);
9004 cWIN32OLE_EVENT
= rb_define_class("WIN32OLE_EVENT", rb_cObject
);
9005 rb_define_singleton_method(cWIN32OLE_EVENT
, "message_loop", fev_s_msg_loop
, 0);
9006 rb_define_alloc_func(cWIN32OLE_EVENT
, fev_s_allocate
);
9007 rb_define_method(cWIN32OLE_EVENT
, "initialize", fev_initialize
, -1);
9008 rb_define_method(cWIN32OLE_EVENT
, "on_event", fev_on_event
, -1);
9009 rb_define_method(cWIN32OLE_EVENT
, "on_event_with_outargs", fev_on_event_with_outargs
, -1);
9010 rb_define_method(cWIN32OLE_EVENT
, "off_event", fev_off_event
, -1);
9011 rb_define_method(cWIN32OLE_EVENT
, "unadvise", fev_unadvise
, 0);
9012 rb_define_method(cWIN32OLE_EVENT
, "handler=", fev_set_handler
, 1);
9013 rb_define_method(cWIN32OLE_EVENT
, "handler", fev_get_handler
, 0);
9015 cWIN32OLE_VARIANT
= rb_define_class("WIN32OLE_VARIANT", rb_cObject
);
9016 rb_define_alloc_func(cWIN32OLE_VARIANT
, folevariant_s_allocate
);
9017 rb_define_singleton_method(cWIN32OLE_VARIANT
, "array", folevariant_s_array
, 2);
9018 rb_define_method(cWIN32OLE_VARIANT
, "initialize", folevariant_initialize
, -2);
9019 rb_define_method(cWIN32OLE_VARIANT
, "value", folevariant_value
, 0);
9020 rb_define_method(cWIN32OLE_VARIANT
, "value=", folevariant_set_value
, 1);
9021 rb_define_method(cWIN32OLE_VARIANT
, "vartype", folevariant_vartype
, 0);
9022 rb_define_method(cWIN32OLE_VARIANT
, "[]", folevariant_ary_aref
, -1);
9023 rb_define_method(cWIN32OLE_VARIANT
, "[]=", folevariant_ary_aset
, -1);
9024 rb_define_const(cWIN32OLE_VARIANT
, "Empty", rb_funcall(cWIN32OLE_VARIANT
, rb_intern("new"), 2, Qnil
, INT2FIX(VT_EMPTY
)));
9025 rb_define_const(cWIN32OLE_VARIANT
, "Null", rb_funcall(cWIN32OLE_VARIANT
, rb_intern("new"), 2, Qnil
, INT2FIX(VT_NULL
)));
9026 rb_define_const(cWIN32OLE_VARIANT
, "Nothing", rb_funcall(cWIN32OLE_VARIANT
, rb_intern("new"), 2, Qnil
, INT2FIX(VT_DISPATCH
)));
9028 eWIN32OLERuntimeError
= rb_define_class("WIN32OLERuntimeError", rb_eRuntimeError
);
9031 atexit((void (*)(void))free_enc2cp
);
9033 cWIN32OLE_enc
= ole_cp2encoding(cWIN32OLE_cp
);