Figure 1   UnlockCookie


 // secondary object that releases lock at final release
 class UnlockCookie : public IUnknown {
     HANDLE m_hsem;
     UnlockCookie(HANDLE h) : m_hsem(h) {}
     ~UnlockCookie() {  
     // release lock back to OS at final release
         ReleaseSemaphore(m_hsem, 1, 0); 
     }
 // heap-based IUnknown implementation deleted
 };
 // primary object that holds lock until released
 class SharedObject : public ISharedObject2 {
     HANDLE m_hsem; // init'ed in constructor
     STDMETHODIMP LockExclusive(IUnknown **ppUnkLock) {
     // acquire lock from OS
         WaitForSingleObject(m_hsem, INFINITE);
     // create and return an intermediate object that 
     // will unlock at its final release
         (*ppUnkLock = new UnlockCookie(m_hsem))->AddRef();
         return S_OK;
     }
     :     :     :
 };


Figure 2   OSI Reference Models

Layer COM Sockets Description
Application Your code
Presentation   NDR: Presents data in host's native format
Session   DCE: Manages state for an association
Transport UDP/TCP: Exposes multiple endpoints on host
Network IP: Exposes hosts across subnets
Data Link ENET: Exposes hosts within a single subnet
Physical COAX/UTP: Transmits bits


Figure 3   Displaying Jukebox Titles


 #include <jukebox.h>
 const UINT CF_JUKEBOX_TITLE_INFO =
     RegisterClipboardFormat( "JukeboxTitleInfo" );
 
 void DisplayItems(IJukeBox* pjb, ostream& os) {
     IDataObject* pdo = 0;
     for ( long i = 0;
           SUCCEEDED(pjb->GetDiskInfo(i, &pdo));
           i++ ) {
         FORMATETC fe = {CF_JUKEBOX_TITLE_INFO, 0,
                         DVASPECT_CONTENT, -1,
                         TYMED_HGLOBAL};
         STGMEDIUM stgm; ZeroMemory(&stgm, sizeof stgm);
         if (SUCCEEDED(pdo->GetData(&fe, &stgm))) {
             JUKEBOX_TITLE_INFO* pInfo =
                             GlobalLock(stgm.hGlobal);
             os << pInfo->Author << ": "
                << pInfo->Title  << endl;  
 
             GlobalUnlock(stgm.hGlobal);
             ReleaseStgMedium(&stgm);
         }
         pdo->Release();
     }
 }

Figure 4   IWorker Interface


 // We're not supporting late-binding clients
 // (which tend to require connection points)
 // so this doesn't need to be a dispinterface
 interface IWorkerEvents : IUnknown {
     HRESULT OnWorkCompleted([in] IWorker *pWorker);
     HRESULT OnWorkDelayed([in] IWorker *pWorker);
 }
 
 interface IWorker : IUnknown {
     enum WorkerAdviseFlags {
         WAF_COMPLETED = 0x1,
         WAF_DELAYED   = 0x2,
         WAF_ALL       = 0x3
     };
     HRESULT StartWork();
     HRESULT WorkerAdvise(
         [in]  IWorkerEvents* pEvents,
         [in]  enum WorkerAdviseFlags flags,
         [out] long * pnCookie);
     HRESULT WorkerUnadvise([in] long dwCookie);
 }

Figure 5   Implementing IworkerEvents


 ' Event interface implementation
 Implements IWorkerEvents
 
 Dim g_worker As IWorker
 Dim g_cookie As Long
 
 Private Sub Form_Load()
         Set g_worker = New Worker
         ' Set up communication for a subset of events
         g_cookie = g_worker.WorkerAdvise(Me, WE_COMPLETED)
 End Sub
 
 ' Handle the events we're interested in
 Private Sub IWorkerEvents_OnWorkCompleted(IWorker src)
         MsgBox "Work Completed"
         g_worker.WorkerUnadvise g_cookie
 End Sub
 Private Sub IWorkerEvents_OnWorkDelayed(IWorker src)
         ' this will never be called since WorkerAdvise
         ' was called with WE_COMPLETED only
 End Sub

Figure 6   IDL for Typeless Languages


 [object,dual,uuid(92284211-9221-2412-11d1-552124391232)]
 interface ICat : IDispatch {
     [id(1)] HRESULT Meow([in] long nVolume);
     [id(2),propget] HRESULT AsDog([out, retval] IDog **p);
 }
 [object,dual,uuid(92284212-9221-2412-11d1-552124391232)]
 interface IDog : IDispatch {
     [id(1)] HRESULT Bark([in] long nVolume);
     [id(2),propget] HRESULT AsCat([out, retval] ICat **p);
 }
 In the Ory, this allows the typeless client to write the following:
 Sub MeowAndBark( )
     Dim cat ' typeless language, so everything is variant
     Dim dog ' typeless language, so everything is variant
     Set dog = CreateObject("DogCat")
     Set cat = dog.AsCat ' pseudo QueryInterface
     dog.Bark 100
     cat.Meow 200
 End Sub

Figure 7   Automation-style Model


 [ uuid(E4244920-3DA0-11d1-A84F-0080C7667ABF) ]
 library AnimalLib {
     dispinterface _PetStore; dispinterface _Animal; 
     dispinterface _Dog;      dispinterface _Cat;
 
     // Top-level object
     [ uuid(E4244921-3DA0-11d1-A84F-0080C7667ABF) ]
     dispinterface _PetStore {
     properties:
         [id(1), readonly] _Animal Youngest;
         [id(2), readonly] _Animal Cutest;
     methods:
         [id(3)] _Animal GetAnimal([in] BSTR bstrName);
         [id(4)] void PutAnimal([in] _Animal a);
     }
 
     [ uuid(E4244922-3DA0-11d1-A84F-0080C7667ABF) ]
     dispinterface _Animal {
     properties:
         [id(1), readonly] _PetStore PetStore;
         [id(2), readonly] _Dog Dogness;
         [id(3), readonly] _Cat Catness;
     methods:
         [id(4)] void Eat();
     }
 
     [ uuid(E4244923-3DA0-11d1-A84F-0080C7667ABF) ]
     dispinterface _Dog {
     properties:
         [id(1), readonly] _Animal Animalness;
     methods:
         [id(2)] void Bark();
     }
     [ uuid(E4244924-3DA0-11d1-A84F-0080C7667ABF) ]
     dispinterface _Cat {
     properties:
         [id(1), readonly] _Animal Animalness;
     methods:
         [id(2)] void Meow();
     }
     [uuid(E4244925-3DA0-11d1-A84F-0080C7667ABF),appobject]
     coclass PetStore {
         [hidden, default] dispinterface _PetStore;
     }
     [uuid(E4244926-3DA0-11d1-A84F-0080C7667ABF)]
     coclass Animal {
         [hidden, default] dispinterface _Animal;
     }
     [uuid(E4244927-3DA0-11d1-A84F-0080C7667ABF),
         noncreatable]
     coclass Dog {
         [hidden, default] dispinterface _Dog;
     }
     [uuid(E4244927-3DA0-11d1-A84F-0080C7667ABF),
         noncreatable]
     coclass Cat {
         [hidden, default] dispinterface _Cat;
     }
 }