Figure 3   Type Library Excerpt

 [<attributes>]
library
    {
    importlib("datapath.tlb")      //TLB for datapath types

    [<attributes>]
    interface IMyControlProperties
        {
.
.
.
        [id(19), bindable, requestedit, propget] OLE_DATAPATH_MPG MoviePath(void);

        [id(19), bindable, requestedit, propput] void MoviePath([in] OLE_DATAPATH_MPG pathMPG);
                               .
.
.
        }
                               .
.
.
    }

Figure 5   Readiness States

State

Value

Description

Uninitialized

No value

By definition an unintialized object can'tprovide any properties, so there's no way you'd ever be able to obtain a value for it. You simply have to assume that it's not initialized. The control is waiting to be initialized through IPersist*::Load.

Loading

READYSTATE_LOADING = 0

The control is initializing itself through IPersistMoniker::Load and retrieving its non-BLOB properties asynchronously.

Loaded/Can Render

READYSTATE_LOADED = 2

The control has returned from IPersist*::Load such that all properties are available and it has started asynchronous data transfers of BLOB properties.

Interactive

READYSTATE_INTERACTIVE = 3

The control is capable of interacting with the user in at least some limited sense and can supply its type information. Full interaction may not be available until all asynchronous data arrives.

Complete

READYSTATE_COMPLETED = 4

The control is completely ready for all requests.

Figure 6   OnReadyStateChange Event Handler

 Const READYSTATE_LOADING       = 0
Const READYSTATE_LOADED        = 2
Const READYSTATE_INTERACTIVE   = 3
Const READYSTATE_COMPLETE      = 4

Sub Playback1_OnReadyStateChange ( currentReadyState )

   Select Case currentReadyState

      Case READYSTATE_LOADED
         ' Ready for async download.Disableallbuttonsuntilwe areinteractive.
         Playback1.StopButton.Enabled = FALSE
         Playback1.StartButton.Enabled = FALSE
         Playback1.PauseButton.Enabled = FALSE
         Playback1.RewindButton.Enabled = FALSE
         Playback1.FForwardButton.Enabled = FALSE

      Case READYSTATE_INTERACTIVE
         ' Enable all buttons that are appropriate at this point since 
         ' enough data is available to start the playback.
         Playback1.StopButton.Enabled = TRUE
         Playback1.StartButton.Enabled = TRUE
         Playback1.PauseButton.Enabled = TRUE
         Playback1.RewindButton.Enabled = TRUE

      Case READYSTATE_COMPLETE
         ' Now that the download is complete, enable the Fast Forward 
         ' button to allow the user to move forward in the movie
         Playback1.FForwardButton.Enabled = TRUE

   End Select

End Sub 

Figure A   IPersistMoniker & IBindStatusCallback

 interface IPersistMoniker : public IPersist
{
    HRESULT IsDirty(void);
    HRESULT InitNew([in] IMoniker* pmkStore, [in] DWORD grfMode, 
                    [in] IBindCtx* pbindctx);
    HRESULT Load([in] IMoniker *pmkStore, [in] DWORD grfMode, 
                 [in] IBindCtx *pBindCtx);
    HRESULT Save([in] IMoniker *pmkStore, [in] BOOL fRemember, 
                 [in] IBindCtx *pBindCtx);
    HRESULT SaveCompleted([in] IMoniker *pmkStore);
    HRESULT GetCurMoniker([out] IMoniker **ppmkStore);
}

interface IBindStatusCallback : IUnknown
{
    HRESULT GetBindInfo([out] DWORD* pgrfBINDF, 
                        [in, out] BINDINFO* pbindinfo);
    HRESULT OnStartBinding([in] IBinding* pbinding);
    HRESULT GetPriority([out] LONG* pnPriority);
    HRESULT OnProgress([in] ULONG ulProgress, [in] ULONG ulProgressMax, 
                       [in] ULONG ulStatusCode, [in] LPCWSTR szStatusText);
    HRESULT OnDataAvailable([in] DWORD grfBSC, [in] DWORD dwSize, 
                            [in] IUnknown* punkStorage, 
                            [in] FORMATETC* pformatetc, 
                            [in] STGMEDIUM* pstgmed);
    HRESULT OnLowResource([in] DWORD dwReserved);
    HRESULT OnStopBinding([in] HRESULT hrStatus);
};

Figure B   IProvideClassINfo3 ARRAYIDs

ARRAYID_Interfaces_Incoming

On return, pcaUUID contains the interface identifiers of all the object's possible "incoming" interfaces that a client might access through QueryInterface. pcadw in this case must be empty (that is, pcadw->cElems is zero). These IIDs are only suggestions of what the object supports and in no way guarantee support at run time. A client must always request an interface through QueryInterface(riid) and must be able to handle the E_NOINTERFACE failure code even if riid was specified in this array.

ARRAYID_Interfaces_Outgoing

On return, pcaUUID contains the interface identifiers of all the object's "outgoing" interfaces, that is, those that would be marked as [source] in an object's type library. pcadw in this case must be empty (that is, pcadw.cElems is zero). These IIDs are only suggestions of what the object supports and in no way guarantee support at run time. A client must always connect to an outgoing interface through IConnectionPointContainer::FindConnectionPoint(riid), and must handle the possible failure of this call even if the riid in question was specified in this array.

ARRAYID_Categories_Implemented

On return, pcaUUID contains the CATIDs of the object's supported categories. pcadw in this case must be empty (that is, pcadw.cElems is zero).

ARRAYID_Categories_Required

On return, pcaUUID contains the CATIDs of the object's required categories, that is, the necessary container-side support without which the object cannot operate. pcadw in this case must be empty (that is, pcadw.cElems is zero).

ARRAYID_PathProperties

On return, pcadw contains the dispIDs of the object's data path properties, and pcaUUID contains the GUIDs identifying the OLE_DATAPATH_<xx> type of the corresponding property in pcadw. The object must allocate and fill both arrays in this case, and both arrays must contain the same number of elements.

ARRAYID_Methods_Primary

On return, pcadw contains the dispIDs of the object's "primary" methods that best describe its user-level functionality-such methods would be displayed in the caller's user interface for providing features like event binding. In this case, pcaUUID->cElems must be zero.

ARRAYID_Methods_Secondary

On return, pcadw contains the dispIDs of the object's "secondary" methods, that is, the list of all object methods excluding those returned from ARRAYID_Methods_Primary. In this case, pcaUUID->cElems must be zero.