OleObjectData *dataPtr = NULL;
IConnectionPointContainer *containerPtr = NULL;
IConnectionPoint *connectionPtr = NULL;
- IUnknown *sinkPtr = NULL;
- DWORD cookie = 0;
int r = TCL_OK;
if (objc != 4) {
hr = containerPtr->lpVtbl->FindConnectionPoint(containerPtr,
&iid, &connectionPtr);
if (SUCCEEDED(hr)) {
- hr = connectionPtr->lpVtbl->Advise(connectionPtr,
- sinkPtr, &cookie);
+ IUnknown *sinkPtr = NULL;
+
+ /* create a Tcl sink instance */
+ hr = Ole_CreateComInstance(interp, objv[2],
+ &IID_IUnknown, sinkPtr);
if (SUCCEEDED(hr)) {
- /*
- * add the sink cookie into a list of sinks
- * so we can unadvise at some point
- */
+ DWORD cookie = 0;
+
+ hr = connectionPtr->lpVtbl->Advise(connectionPtr,
+ sinkPtr, &cookie);
+ if (SUCCEEDED(hr)) {
+ /*
+ * add the sink cookie into a list of sinks
+ * so we can unadvise at some point
+ */
+ }
+
+ sinkPtr->lpVtbl->Release(sinkPtr);
}
}
dataPtr->typeinfoPtr->lpVtbl->ReleaseTypeAttr(dataPtr->typeinfoPtr,
ISupportErrorInfoVtbl *lpVtbl2;
long refcount;
Tcl_Interp *interp;
+ Tcl_Obj *cmdObj;
} OleInterpCom;
static void OleInterpComDestroy(OleInterpCom *this);
static void
OleInterpComDestroy(OleInterpCom *this)
{
+ Tcl_DecrRefCount(this->cmdObj);
+ Tcl_Release(this->interp);
CoTaskMemFree(this);
}
HRESULT
-Ole_CreateComInstance(Tcl_Interp *interp, REFIID riid, void **unkPtrPtr)
+Ole_CreateComInstance(Tcl_Interp *interp, Tcl_Obj *cmdObj,
+ REFIID riid, void **unkPtrPtr)
{
static IDispatchVtbl vtbl = {
OleInterpCom_QueryInterface,
comPtr->lpVtbl2 = &vtbl2;
comPtr->refcount = 0;
comPtr->interp = interp;
+ comPtr->cmdObj = Tcl_DuplicateObj(cmdObj);
+ Tcl_IncrRefCount(comPtr->cmdObj);
+ Tcl_Preserve(comPtr->interp);
hr = comPtr->lpVtbl->QueryInterface((IDispatch *)comPtr,
riid, unkPtrPtr);
if (FAILED(hr)) {
- CoTaskMemFree(comPtr);
+ OleInterpComDestroy(comPtr);
comPtr = NULL;
}
}
*resultPtrPtr = Ole_NewOleObj(interp, V_DISPATCH(vPtr));
break;
case VT_DISPATCH | VT_BYREF:
- if (V_DISPATCHREF(vPtr) != NULL)
+ if (V_DISPATCHREF(vPtr)) {
*resultPtrPtr = Ole_NewOleObj(interp, *V_DISPATCHREF(vPtr));
+ } else {
+ *resultPtrPtr = Tcl_NewStringObj(NULL, 0);
+ }
break;
case VT_CY: case VT_DECIMAL: case VT_DATE:
case VT_VARIANT:
int isnew = 0;
char name[4 + TCL_INTEGER_SPACE];
+ if (dispPtr == NULL) {
+ return Tcl_NewStringObj(NULL, 0);
+ }
+
pkgPtr = Tcl_GetAssocData(interp, "ole::package", NULL);
entryPtr = Tcl_CreateHashEntry(&pkgPtr->table,
(const char *)dispPtr, &isnew);
return TCL_OK;
}
\f
+/*
+ * RefSelfCmd --
+ * Return an COM object that has its IDispatch interface
+ * implemented by the given Tcl procedure.
+ */
+static int
+RefSelfCmd(ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[])
+{
+ HRESULT hr = S_OK;
+ IDispatch *dispPtr = NULL;
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "command");
+ return TCL_ERROR;
+ }
+
+ hr = Ole_CreateComInstance(interp, objv[2],
+ &IID_IDispatch, (void **)&dispPtr);
+ if (SUCCEEDED(hr)) {
+ Tcl_SetObjResult(interp, Ole_NewOleObj(interp, dispPtr));
+ dispPtr->lpVtbl->Release(dispPtr);
+ } else {
+ Tcl_SetObjResult(interp,
+ Ole_Win32ErrorObj(interp, Tcl_GetString(objv[1]), hr));
+ return TCL_ERROR;
+ }
+ return TCL_OK;
+}
+\f
/*
* RefCmd --
* ref command ensemble
{ "getactiveobject", RefGetActiveObjectCmd, NULL },
{ "getobject", RefGetObjectCmd, NULL },
{ "equal", RefEqualCmd, NULL },
+ { "self", RefSelfCmd, NULL },
/* undocumented */
/*{ "count", RefCountCmd, NULL },*/
/*{ "querydispatch", RefQueryDispatch, NULL },*/
OlePackageData *pkgPtr = clientData;
Tcl_DeleteHashTable(&pkgPtr->table);
if (pkgPtr->selfPtr) {
- /* RevokeActiveObject(pkgPtr->activeid, NULL);*/
pkgPtr->selfPtr->lpVtbl->Release(pkgPtr->selfPtr);
pkgPtr->selfPtr = NULL;
}
tclTypes[tclCmdNameIndex] = Tcl_GetObjType("cmdName");
OleObjInit(interp);
- Ole_CreateComInstance(interp, &IID_IDispatch, &pkgPtr->selfPtr);
- /* RegisterActiveObject((IUnknown *)pkgPtr->selfPtr, &clsid,
- ACTIVEOBJECT_WEAK, &pkgPtr->activeid); */
/* create commands */
Tcl_CreateObjCommand(interp, "ole::ref", RefCmd, NULL, NULL);
Tcl_Obj *const *objv, int flags);
int OleForeachCmd(ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);
-HRESULT Ole_CreateComInstance(Tcl_Interp *interp,
+HRESULT Ole_CreateComInstance(Tcl_Interp *interp, Tcl_Obj *cmdObj,
REFIID riid, void **unkPtrPtr);
int OleBindCmd(ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);