add IDispatch wrapper in val2variant
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5710 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
30fd29a174
commit
d780328362
@ -1,3 +1,8 @@
|
|||||||
|
Sun Feb 15 15:48:57 2004 Masaki Suketa <masaki.suketa@nifty.ne.jp>
|
||||||
|
|
||||||
|
* ext/win32ole/win32ole.c: add IDispatch wrapper in val2variant.
|
||||||
|
Thanks, arton.
|
||||||
|
|
||||||
Sun Feb 15 15:23:29 2004 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>
|
Sun Feb 15 15:23:29 2004 Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp>
|
||||||
|
|
||||||
* ruby.h, dir.c (rb_glob): add const.
|
* ruby.h, dir.c (rb_glob): add const.
|
||||||
|
@ -78,7 +78,7 @@
|
|||||||
|
|
||||||
#define WC2VSTR(x) ole_wc2vstr((x), TRUE)
|
#define WC2VSTR(x) ole_wc2vstr((x), TRUE)
|
||||||
|
|
||||||
#define WIN32OLE_VERSION "0.5.5"
|
#define WIN32OLE_VERSION "0.5.6"
|
||||||
|
|
||||||
typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
|
typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
|
||||||
(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
|
(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
|
||||||
@ -151,6 +151,8 @@ static BOOL gOLEInitialized = Qfalse;
|
|||||||
static HINSTANCE ghhctrl = NULL;
|
static HINSTANCE ghhctrl = NULL;
|
||||||
static HINSTANCE gole32 = NULL;
|
static HINSTANCE gole32 = NULL;
|
||||||
static FNCOCREATEINSTANCEEX *gCoCreateInstanceEx = NULL;
|
static FNCOCREATEINSTANCEEX *gCoCreateInstanceEx = NULL;
|
||||||
|
static VALUE com_hash;
|
||||||
|
static IDispatchVtbl com_vtbl;
|
||||||
|
|
||||||
struct oledata {
|
struct oledata {
|
||||||
IDispatch *pDispatch;
|
IDispatch *pDispatch;
|
||||||
@ -192,6 +194,137 @@ static VALUE foletype_s_allocate _((VALUE));
|
|||||||
static VALUE oletype_set_member _((VALUE, ITypeInfo *, VALUE));
|
static VALUE oletype_set_member _((VALUE, ITypeInfo *, VALUE));
|
||||||
static VALUE olemethod_from_typeinfo _((VALUE, ITypeInfo *, VALUE));
|
static VALUE olemethod_from_typeinfo _((VALUE, ITypeInfo *, VALUE));
|
||||||
static HRESULT ole_docinfo_from_type _((ITypeInfo *, BSTR *, BSTR *, DWORD *, BSTR *));
|
static HRESULT ole_docinfo_from_type _((ITypeInfo *, BSTR *, BSTR *, DWORD *, BSTR *));
|
||||||
|
static char *ole_wc2mb(LPWSTR);
|
||||||
|
static VALUE ole_variant2val(VARIANT*);
|
||||||
|
static void ole_val2variant(VALUE, VARIANT*);
|
||||||
|
|
||||||
|
typedef struct _Win32OLEIDispatch
|
||||||
|
{
|
||||||
|
IDispatch dispatch;
|
||||||
|
ULONG refcount;
|
||||||
|
VALUE obj;
|
||||||
|
} Win32OLEIDispatch;
|
||||||
|
|
||||||
|
static HRESULT ( STDMETHODCALLTYPE QueryInterface )(
|
||||||
|
IDispatch __RPC_FAR * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
|
||||||
|
{
|
||||||
|
if (MEMCMP(riid, &IID_IUnknown, GUID, 1) == 0
|
||||||
|
|| MEMCMP(riid, &IID_IDispatch, GUID, 1) == 0)
|
||||||
|
{
|
||||||
|
Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
|
||||||
|
p->refcount++;
|
||||||
|
*ppvObject = This;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG ( STDMETHODCALLTYPE AddRef )(
|
||||||
|
IDispatch __RPC_FAR * This)
|
||||||
|
{
|
||||||
|
Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
|
||||||
|
return ++(p->refcount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG ( STDMETHODCALLTYPE Release )(
|
||||||
|
IDispatch __RPC_FAR * This)
|
||||||
|
{
|
||||||
|
Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
|
||||||
|
ULONG u = --(p->refcount);
|
||||||
|
if (u == 0) {
|
||||||
|
st_data_t key = p->obj;
|
||||||
|
st_delete(DATA_PTR(com_hash), &key, 0);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT ( STDMETHODCALLTYPE GetTypeInfoCount )(
|
||||||
|
IDispatch __RPC_FAR * This,
|
||||||
|
/* [out] */ UINT __RPC_FAR *pctinfo)
|
||||||
|
{
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT ( STDMETHODCALLTYPE GetTypeInfo )(
|
||||||
|
IDispatch __RPC_FAR * This,
|
||||||
|
/* [in] */ UINT iTInfo,
|
||||||
|
/* [in] */ LCID lcid,
|
||||||
|
/* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo)
|
||||||
|
{
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static HRESULT ( STDMETHODCALLTYPE GetIDsOfNames )(
|
||||||
|
IDispatch __RPC_FAR * This,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
|
||||||
|
/* [in] */ UINT cNames,
|
||||||
|
/* [in] */ LCID lcid,
|
||||||
|
/* [size_is][out] */ DISPID __RPC_FAR *rgDispId)
|
||||||
|
{
|
||||||
|
Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
|
||||||
|
char* psz = ole_wc2mb(*rgszNames); // support only one method
|
||||||
|
*rgDispId = rb_intern(psz);
|
||||||
|
free(psz);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static /* [local] */ HRESULT ( STDMETHODCALLTYPE Invoke )(
|
||||||
|
IDispatch __RPC_FAR * This,
|
||||||
|
/* [in] */ DISPID dispIdMember,
|
||||||
|
/* [in] */ REFIID riid,
|
||||||
|
/* [in] */ LCID lcid,
|
||||||
|
/* [in] */ WORD wFlags,
|
||||||
|
/* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
|
||||||
|
/* [out] */ VARIANT __RPC_FAR *pVarResult,
|
||||||
|
/* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
|
||||||
|
/* [out] */ UINT __RPC_FAR *puArgErr)
|
||||||
|
{
|
||||||
|
VALUE v;
|
||||||
|
int i;
|
||||||
|
int args = pDispParams->cArgs;
|
||||||
|
Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
|
||||||
|
VALUE* parg = ALLOCA_N(VALUE, args);
|
||||||
|
for (i = 0; i < args; i++) {
|
||||||
|
*(parg + i) = ole_variant2val(&pDispParams->rgvarg[args - i - 1]);
|
||||||
|
}
|
||||||
|
if (dispIdMember == DISPID_VALUE) {
|
||||||
|
if (wFlags == DISPATCH_METHOD) {
|
||||||
|
dispIdMember = rb_intern("call");
|
||||||
|
} else if (wFlags & DISPATCH_PROPERTYGET) {
|
||||||
|
dispIdMember = rb_intern("value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v = rb_funcall2(p->obj, dispIdMember, args, parg);
|
||||||
|
ole_val2variant(v, pVarResult);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IDispatch*
|
||||||
|
val2dispatch(val)
|
||||||
|
VALUE val;
|
||||||
|
{
|
||||||
|
struct st_table *tbl = DATA_PTR(com_hash);
|
||||||
|
Win32OLEIDispatch* pdisp;
|
||||||
|
st_data_t data;
|
||||||
|
|
||||||
|
if (st_lookup(tbl, val, &data)) {
|
||||||
|
pdisp = (Win32OLEIDispatch *)(data & ~FIXNUM_FLAG);
|
||||||
|
pdisp->refcount++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pdisp = ALLOC(Win32OLEIDispatch);
|
||||||
|
pdisp->dispatch.lpVtbl = &com_vtbl;
|
||||||
|
pdisp->refcount = 1;
|
||||||
|
pdisp->obj = val;
|
||||||
|
st_insert(tbl, val, (VALUE)pdisp | FIXNUM_FLAG);
|
||||||
|
}
|
||||||
|
return &pdisp->dispatch;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
time2d(hh, mm, ss, pv)
|
time2d(hh, mm, ss, pv)
|
||||||
@ -698,7 +831,8 @@ ole_val2variant(val, var)
|
|||||||
V_ERROR(var) = DISP_E_PARAMNOTFOUND;
|
V_ERROR(var) = DISP_E_PARAMNOTFOUND;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
rb_raise(rb_eTypeError, "not valid value");
|
V_VT(var) = VT_DISPATCH;
|
||||||
|
V_DISPATCH(var) = val2dispatch(val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5276,6 +5410,16 @@ Init_win32ole()
|
|||||||
rb_global_variable(&ary_ole_event);
|
rb_global_variable(&ary_ole_event);
|
||||||
id_events = rb_intern("events");
|
id_events = rb_intern("events");
|
||||||
|
|
||||||
|
com_vtbl.QueryInterface = QueryInterface;
|
||||||
|
com_vtbl.AddRef = AddRef;
|
||||||
|
com_vtbl.Release = Release;
|
||||||
|
com_vtbl.GetTypeInfoCount = GetTypeInfoCount;
|
||||||
|
com_vtbl.GetTypeInfo = GetTypeInfo;
|
||||||
|
com_vtbl.GetIDsOfNames = GetIDsOfNames;
|
||||||
|
com_vtbl.Invoke = Invoke;
|
||||||
|
com_hash = Data_Wrap_Struct(rb_cData, rb_mark_hash, st_free_table, st_init_numtable());
|
||||||
|
rb_global_variable(&com_hash);
|
||||||
|
|
||||||
cWIN32OLE = rb_define_class("WIN32OLE", rb_cObject);
|
cWIN32OLE = rb_define_class("WIN32OLE", rb_cObject);
|
||||||
|
|
||||||
rb_define_alloc_func(cWIN32OLE, fole_s_allocate);
|
rb_define_alloc_func(cWIN32OLE, fole_s_allocate);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user