To contact the authors with suggestions or comments, use csells@sellsbrothers.com, tewald@obelisk-llc.com and dbox@develop.com.
Monikers, on the other hand, provide a general-purpose way for a client to separate itself from the object binding policy. These object binding polices can be composed and stored in strings. These strings contain a string description of the binding policy and policy parameters. By building a custom moniker that takes a string-ized interface reference as a parameter, a client can use the standard moniker-based binding algorithm and bind to a running object via an interface reference. The MeowMoniker is an implementation of a moniker that can compose display names out of interface pointers and bind to objects via its display names.
To create a MeowMoniker from an interface pointer, MeowMoniker.dll exposes the CreateMeowMoniker() function:
STDAPI CreateMeowMoniker( IUnknown* punk, // Pointer to the interface to be marshaled REFIID riid, // Reference to the identifier of the interface DWORD dwDestContext, // Destination context DWORD mshlflags, // Reason for marshaling IMoniker** ppmk); // Indirect pointer to the moniker e.g. IMoniker* pmk; hr = CreateMeowMoniker(punkObject, IID_IUnknown, MSHCTX_DIFFERENTMACHINE, MSHLFLAGS_NORMAL, &pmk);
To obtain the MeowMoniker's display name, use the GetDisplayName() member function of the IMoniker interface:
HRESULT GetDisplayName( IBindCtx *pbc, // Pointer to bind context to be used IMoniker *pmkToLeft, // Pointer to moniker to the left in the composite LPOLESTR *ppszDisplayName); //Indirect pointer to the display name e.g. IBindCtx* pbc; hr = CreateBindCtx(0, &pbc); wchar_t* pwszDisplayName; hr = pmk->GetDisplayName(pbc, 0, &pwszDisplayName);
To parse a display name composed by the MeowMoniker, OLE32.dll exposes the MkParseDisplayName() function:
WINOLEAPI MkParseDisplayName( LPBC pbc, // Pointer to the bind context object LPCOLESTR szUserName, // Pointer to display name ULONG FAR *pchEaten, // Pointer to the number of characters consumed LPMONIKER FAR *ppmk); // Indirect pointer to the moniker e.g. IBindCtx* pbc; hr = CreateBindCtx(0, &pbc); IMoniker* pmk; ULONG cchEaten; hr = MkParseDisplayName(pbc, pwszDisplayName, &cchEaten, &pmk);
To bind to a object, use the BindToObject() member function of the IMoniker interface:
HRESULT BindToObject( IBindCtx *pbc, // Pointer to bind context object to be used IMoniker *pmkToLeft,// Pointer to moniker that precedes this one in the composite REFIID riidResult, // IID of interface pointer requested void **ppvResult); // Indirect pointer to the specified interface on the object e.g. IUnknown* punk; hr = pmk->BindToObject(pbc, 0, IID_IUnknown, (void**)&punk);Note: The MeowMoniker does not current supportly composition or the IMoniker interface member function BindToStorage().
[ object, uuid(CB18CB8E-C7CC-11D0-9A44-00008600A105), dual, helpstring("DIFeline Interface"), pointer_default(unique) ] interface DIFeline : IDispatch { [id(1), helpstring("Returns the Meow Moniker name of an interface pointer")] HRESULT GetDisplayName([in] IDispatch* pdisp, [out, retval] BSTR* pbstrName); [id(2), helpstring("Returns an interface pointer given any moniker display name")] HRESULT ParseDisplayName([in] BSTR bstrName, [out, retval] IDispatch** ppdisp); };The following is an example Active Server Page that creates an object on the server, creates a display name using the object's interface pointer and uses the display name to create a client-side script. The client-side script uses its own instance of a feline object to parse the display name and bind to the object created on the server-side.
<HEAD> <TITLE>feline.asp</TITLE> </HEAD> <BODY> <object classid="clsid:CB18CB8F-C7CC-11D0-9A44-00008600A105" runat=server id=feline> </object> <object classid="clsid:7CF322E0-29A9-11D0-B367-0080C7BC7884" runat=server id=pt> </object> <object classid="clsid:CB18CB8F-C7CC-11D0-9A44-00008600A105" id=feline> </object> <script language=vbscript> dim pt set pt = feline.ParseDisplayName("<%= feline.GetDisplayName(pt) %>") pt.x = 100 pt.y = 200 document.write pt.x & ", " & pt.y </script> </BODY> </HTML>
STDMETHODIMP BindToObject( IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riidResult, void** ppvResult); STDMETHODIMP GetDisplayName( IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR* ppszDisplayName); STDMETHODIMP ParseDisplayName( IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);As a aid in parsing display names, the CComMoniker class provides the following helper function:
bool MatchesProgID( const wchar_t* pwszDisplayName, // Display name being parsed const wchar_t** ppwszDisplayParam); // Pointer to character past :This function checks the display name for a leading ProgID or VersionIndependentProgID followed by a colon and returns a pointer to the first character of the display name parameter(s), i.e. one character past the colon. The implementation of this function requires the derived class to implement the following member functions:
virtual const wchar_t* ProgID() =0; virtual const wchar_t* VersionIndependentProgID() =0; e.g. const wchar_t* ProgID() { return L"dm.meow.1"; } const wchar_t* VersionIndependentProgID() { return L"dm.meow"; }