Quote Originally Posted by wqweto View Post
Here is an implementation of PutObject (the opposite of the built-in GetObject) w/ no external typelibs.

thinBasic Code:
  1. Option Explicit
  2.  
  3. Private Declare Function CreateFileMoniker Lib "ole32" (ByVal lpszPathName As Long, pResult As IUnknown) As Long
  4. Private Declare Function GetRunningObjectTable Lib "ole32" (ByVal dwReserved As Long, pResult As IUnknown) As Long
  5. Private Declare Function DispCallFunc Lib "oleaut32" (ByVal pvInstance As Long, ByVal oVft As Long, ByVal lCc As Long, ByVal vtReturn As VbVarType, ByVal cActuals As Long, prgVt As Any, prgpVarg As Any, pvargResult As Variant) As Long
  6.  
  7. Private Sub Form_Load()
  8.     Dim lCookie     As Long
  9.     Dim oCol        As Collection
  10.     Dim lColCookie  As Long
  11.    
  12.     lCookie = PutObject(Me, "MyMoniker")
  13.     Debug.Print TypeName(GetObject("MyMoniker"))    '--- returns Form1
  14.     '--- warning: "MyMoniker" path is "stacked"
  15.     Set oCol = New Collection
  16.     lColCookie = PutObject(oCol, "MyMoniker")
  17.     Debug.Print TypeName(GetObject("MyMoniker"))    '--- still Form1
  18.     '--- "pops" Form1
  19.     RevokeObject lCookie
  20.     Debug.Print TypeName(GetObject("MyMoniker"))    '--- returns Collection now
  21.     RevokeObject lColCookie
  22. End Sub
  23.  
  24. Private Function PutObject(oObj As Object, sPathName As String) As Long
  25.     Const ROTFLAGS_REGISTRATIONKEEPSALIVE As Long = 1
  26.     Const IDX_REGISTER  As Long = 3
  27.     Dim pROT            As IUnknown
  28.     Dim pMoniker        As IUnknown
  29.    
  30.     Call GetRunningObjectTable(0, pROT)
  31.     Call CreateFileMoniker(StrPtr(sPathName), pMoniker)
  32.     DispCallByVtbl pROT, IDX_REGISTER, ROTFLAGS_REGISTRATIONKEEPSALIVE, ObjPtr(oObj), ObjPtr(pMoniker), VarPtr(PutObject)
  33. End Function
  34.  
  35. Private Sub RevokeObject(ByVal lCookie As Long)
  36.     Const IDX_REVOKE    As Long = 4
  37.     Dim pROT            As IUnknown
  38.    
  39.     Call GetRunningObjectTable(0, pROT)
  40.     DispCallByVtbl pROT, IDX_REVOKE, lCookie
  41. End Sub
  42.  
  43. Private Function DispCallByVtbl(pUnk As IUnknown, ByVal lIndex As Long, ParamArray A() As Variant) As Variant
  44.     Const CC_STDCALL    As Long = 4
  45.     Dim lIdx            As Long
  46.     Dim vParam()        As Variant
  47.     Dim vType(0 To 63)  As Integer
  48.     Dim vPtr(0 To 63)   As Long
  49.     Dim hResult         As Long
  50.    
  51.     vParam = A
  52.     For lIdx = 0 To UBound(vParam)
  53.         vType(lIdx) = VarType(vParam(lIdx))
  54.         vPtr(lIdx) = VarPtr(vParam(lIdx))
  55.     Next
  56.     hResult = DispCallFunc(ObjPtr(pUnk), lIndex * 4, CC_STDCALL, vbLong, lIdx, vType(0), vPtr(0), DispCallByVtbl)
  57.     If hResult < 0 Then
  58.         Err.Raise hResult
  59.     End If
  60. End Function
You get RevokeObject too to test ROT registration at will.

Also note that you would probably need to use "MyMoniker" & App.hInstance just to be safe with these moniker paths cross-process "interferences".

cheers,
</wqw>
Hi wqweto,

Nice code. Thanks.

I want to add a new file moniker name to an item already existing in the Running Object Table so I can then Use GetObject("NEW MONIKER PATHNAME")

It works only if PutObject is executed from within the Process where the object being registered resides\lives... It doesn't work and I get an NULL cookie if PutObject is ran from different Application\Process.

This is what I am doing from a different process.

Set Obj= GetObject ("Exising Moniker PathName")
PutObject Obj, "New Moniker PathName"
then
Set Obj= GetObject ("New Moniker PathName") <= error - not registered in ROT.

Is there a way of using PutObject from a different process ?

Regards.