Aangepaste asynchrone resultaatobjecten
In dit onderwerp wordt beschreven hoe u de interface IMFAsyncResult implementeert.
Het is zeldzaam dat u een aangepaste implementatie van de IMFAsyncResult interface moet schrijven. In bijna alle gevallen is de standaard Media Foundation-implementatie voldoende. (Deze implementatie wordt geretourneerd door de functie MFCreateAsyncResult.) Als u echter wel een aangepaste implementatie schrijft, zijn er enkele problemen waarmee u rekening moet houden.
Ten eerste moet uw implementatie de MFASYNCRESULT structuur overnemen. De Media Foundation-werkwachtrijen gebruiken deze structuur intern om de bewerking te verzenden. Initialiseer alle structuurleden tot nul, met uitzondering van het pCallback- lid, dat een aanwijzer bevat naar de callback-interface van de beller.
Ten tweede moet uw object MFLockPlatform aanroepen in de constructor om het Media Foundation-platform te vergrendelen. Roep MFUnlockPlatform aan om het platform te ontgrendelen. Deze functies helpen voorkomen dat het platform wordt afgesloten voordat het object wordt vernietigd. Zie Werkwachtrijenvoor meer informatie.
De volgende code toont een basis implementatie van de IMFAsyncResult interface. Zoals weergegeven, biedt deze code geen extra functies buiten de standaard Media Foundation-implementatie.
///////////////////////////////////////////////////////////////////////////////
// CMyAsyncResult
//
// Custom implementation of IMFAsyncResult. All implementations of this
// interface must inherit the MFASYNCRESULT structure.
//
///////////////////////////////////////////////////////////////////////////////
class CMyAsyncResult : public MFASYNCRESULT
{
protected:
LONG m_cRef; // Reference count.
BOOL m_bLockPlatform; // Locked the Media Foundation platform?
IUnknown* m_pState; // Caller's state object.
IUnknown* m_pObject; // Optional object. See IMFAsyncResult::GetObject.
// Constructor.
CMyAsyncResult(IMFAsyncCallback *pCallback, IUnknown *pState, HRESULT *phr) :
m_cRef(1),
m_bLockPlatform(FALSE),
m_pObject(NULL),
m_pState(pState)
{
*phr = MFLockPlatform();
m_bLockPlatform = TRUE;
// Initialize the MFASYNCRESULT members.
ZeroMemory(&this->overlapped, sizeof(OVERLAPPED));
hrStatusResult = S_OK;
dwBytesTransferred = 0;
hEvent = NULL;
this->pCallback = pCallback;
if (pCallback)
{
this->pCallback->AddRef();
}
if (m_pState)
{
m_pState->AddRef();
}
}
virtual ~CMyAsyncResult()
{
SafeRelease(&pCallback);
SafeRelease(&m_pState);
SafeRelease(&m_pObject);
if (m_bLockPlatform)
{
MFUnlockPlatform();
}
}
public:
// Static method to create an instance of this object.
static HRESULT CreateInstance(
IMFAsyncCallback *pCallback, // Callback to invoke.
IUnknown *pState, // Optional state object.
CMyAsyncResult **ppResult // Receives a pointer to the object.
)
{
HRESULT hr = S_OK;
*ppResult = NULL;
CMyAsyncResult *pResult =
new (std::nothrow) CMyAsyncResult(pCallback, pState, &hr);
if (pResult == NULL)
{
return E_OUTOFMEMORY;
}
if (FAILED(hr))
{
delete pResult;
return hr;
}
// If the callback is NULL, create an event that will be signaled.
if (pCallback == NULL)
{
pResult->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (pResult->hEvent == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
if (SUCCEEDED(hr))
{
*ppResult = pResult; // Return the pointer to the caller.
}
else
{
pResult->Release();
}
return hr;
}
// SetObject: Sets the optional result object.
// (This method is not part of the interface.)
HRESULT SetObject(IUnknown *pObject)
{
SafeRelease(&m_pObject);
m_pObject = pObject;
if (pObject)
{
m_pObject->AddRef();
}
return S_OK;
}
// IUnknown methods.
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
static const QITAB qit[] =
{
QITABENT(CMyAsyncResult, IMFAsyncResult),
{ 0 }
};
return QISearch(this, qit, riid, ppv);
}
STDMETHODIMP_(ULONG) AddRef()
{
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) Release()
{
LONG cRef = InterlockedDecrement(&m_cRef);
if (cRef == 0)
{
delete this;
}
return cRef;
}
// IMFAsyncResult methods.
STDMETHODIMP GetState(IUnknown** ppunkState)
{
if (ppunkState == NULL)
{
return E_POINTER;
}
*ppunkState = m_pState;
if (m_pState)
{
(*ppunkState)->AddRef();
}
return S_OK;
}
STDMETHODIMP GetStatus( void)
{
return hrStatusResult;
}
STDMETHODIMP STDMETHODCALLTYPE SetStatus(HRESULT hrStatus)
{
hrStatusResult = hrStatus;
return S_OK;
}
STDMETHODIMP GetObject(IUnknown **ppObject)
{
if (ppObject == NULL)
{
return E_POINTER;
}
*ppObject = m_pObject;
if (m_pObject)
{
(*ppObject)->AddRef();
}
return S_OK;
}
IUnknown* STDMETHODCALLTYPE GetStateNoAddRef()
{
return m_pState; // Warning! Can be NULL.
}
};
Verwante onderwerpen