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. |