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>
|
||||
|
||||
* ruby.h, dir.c (rb_glob): add const.
|
||||
|
@ -78,7 +78,7 @@
|
||||
|
||||
#define WC2VSTR(x) ole_wc2vstr((x), TRUE)
|
||||
|
||||
#define WIN32OLE_VERSION "0.5.5"
|
||||
#define WIN32OLE_VERSION "0.5.6"
|
||||
|
||||
typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
|
||||
(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
|
||||
@ -151,6 +151,8 @@ static BOOL gOLEInitialized = Qfalse;
|
||||
static HINSTANCE ghhctrl = NULL;
|
||||
static HINSTANCE gole32 = NULL;
|
||||
static FNCOCREATEINSTANCEEX *gCoCreateInstanceEx = NULL;
|
||||
static VALUE com_hash;
|
||||
static IDispatchVtbl com_vtbl;
|
||||
|
||||
struct oledata {
|
||||
IDispatch *pDispatch;
|
||||
@ -192,6 +194,137 @@ static VALUE foletype_s_allocate _((VALUE));
|
||||
static VALUE oletype_set_member _((VALUE, ITypeInfo *, VALUE));
|
||||
static VALUE olemethod_from_typeinfo _((VALUE, ITypeInfo *, VALUE));
|
||||
static HRESULT ole_docinfo_from_type _((ITypeInfo *, BSTR *, BSTR *, DWORD *, BSTR *));
|
||||
static char *ole_wc2mb(LPWSTR);
|
||||
static VALUE ole_variant2val(VARIANT*);
|
||||
static void ole_val2variant(VALUE, VARIANT*);
|
||||
|
||||
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
|
||||
time2d(hh, mm, ss, pv)
|
||||
@ -698,7 +831,8 @@ ole_val2variant(val, var)
|
||||
V_ERROR(var) = DISP_E_PARAMNOTFOUND;
|
||||
break;
|
||||
default:
|
||||
rb_raise(rb_eTypeError, "not valid value");
|
||||
V_VT(var) = VT_DISPATCH;
|
||||
V_DISPATCH(var) = val2dispatch(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -5276,6 +5410,16 @@ Init_win32ole()
|
||||
rb_global_variable(&ary_ole_event);
|
||||
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);
|
||||
|
||||
rb_define_alloc_func(cWIN32OLE, fole_s_allocate);
|
||||
|
Loading…
x
Reference in New Issue
Block a user