ピッカーなしでIRandomAccessStreamをファイルに取得する必要があります。
しかし、私はIStorageFileまたはIRandomAccessStreamReferenceで立ち往生しており、これらのいずれかからIRandomAccessStreamを取得する方法を見つけることができません。
私はC++(/ ZWなし)でコードを書いていますが、この場合は重要ではないと思います。
助けてください、モシェ
ピッカーなしでIRandomAccessStreamをファイルに取得する必要があります。
しかし、私はIStorageFileまたはIRandomAccessStreamReferenceで立ち往生しており、これらのいずれかからIRandomAccessStreamを取得する方法を見つけることができません。
私はC++(/ ZWなし)でコードを書いていますが、この場合は重要ではないと思います。
助けてください、モシェ
StorageFile の OpenReadAsync を使用して、やりたいことができました。しかし、これには 2 つの非同期呼び出しが含まれ、面倒です。より短く、よりエレガントな方法があるのだろうか。以下の関連するサンプル コード:
IFACEMETHODIMP MyClass::BeginCreateObject(
//... rest of parameters
_In_ IMFAsyncCallback *pCallback,
_In_ IUnknown *punkState)
{
OutputDebugStringW(__FUNCTIONW__);
HRESULT hr;
HString hstrStorageFile;
hstrStorageFile.Set(RuntimeClass_Windows_Storage_StorageFile);
// Get the Activation Factory
ComPtr<IActivationFactory> pStorageFileActivationFactory;
hr = GetActivationFactory(hstrStorageFile.Get(), &pStorageFileActivationFactory);
if (FAILED(hr))
{
::Microsoft::WRL::Details::RaiseException(hr);
}
// QI for StorageFileStatics
ComPtr<IStorageFileStatics> pStorageFileStatics;
hr = pStorageFileActivationFactory.As(&pStorageFileStatics);
if (FAILED(hr))
{
::Microsoft::WRL::Details::RaiseException(hr);
}
HString hstrFileName;
hstrFileName.Set(L"My_Cool_Movie.ts");
// Call CreateFileAsync
__FIAsyncOperation_1_Windows__CStorage__CStorageFile * operation;
hr = pStorageFileStatics->GetFileFromPathAsync(hstrFileName.Get(),
&operation
);
if (FAILED(hr))
{
::Microsoft::WRL::Details::RaiseException(hr);
}
typedef IAsyncOperationCompletedHandler<StorageFile*> HandlerDoneType;
ComPtr<HandlerDoneType> handler(Callback<HandlerDoneType>(
this, &MyClass::FileOpenCompletionHandler));
hr = operation->put_Completed(handler.Get());
ComPtr<IMFAsyncResult> spResult;
//maybe I should pass some data in the first parameter?
hr = MFCreateAsyncResult(nullptr, pCallback, punkState, &_spOpenResult);
//the further processing will be done in the completion handler
return hr;
}
IFACEMETHODIMP MyClass::EndCreateObject(
_In_ IMFAsyncResult *pResult,
_Out_ MF_OBJECT_TYPE *pObjectType,
_Out_ IUnknown **ppObject)
{
OutputDebugStringW(__FUNCTIONW__);
if (pResult == nullptr || pObjectType == nullptr || ppObject == nullptr)
{
return E_INVALIDARG;
}
HRESULT hr = S_OK;
//get a random access stream
if(!_spFile)
{
return E_FAIL;
}
ComPtr<IRandomAccessStream> streamHandle;
hr = _spStream.As(&streamHandle);
if (FAILED(hr))
{
::Microsoft::WRL::Details::RaiseException(hr);
}
//Do what you need with IRandomAccessStream!
//...
return S_OK;
}
IFACEMETHODIMP MyClass::CancelObjectCreation(
_In_ IUnknown *pIUnknownCancelCookie)
{
return E_NOTIMPL;
}
HRESULT MyClass::FileOpenCompletionHandler( IAsyncOperation<StorageFile*>* async, AsyncStatus status)
{
//file is open, call the invoke to carry one
if (status == Completed) {
HRESULT hr = async->GetResults(_spFile.GetAddressOf());
if (_spFile) {
ComPtr<IRandomAccessStreamReference> streamReference;
hr = _spFile.As(&streamReference);
if (FAILED(hr))
{
::Microsoft::WRL::Details::RaiseException(hr);
}
__FIAsyncOperation_1_Windows__CStorage__CStreams__CIRandomAccessStreamWithContentType * operation;
hr = streamReference->OpenReadAsync(&operation);
if (FAILED(hr))
{
::Microsoft::WRL::Details::RaiseException(hr);
}
typedef IAsyncOperationCompletedHandler<IRandomAccessStreamWithContentType*> OpenReadAsyncHandlerDoneType;
ComPtr<OpenReadAsyncHandlerDoneType> handler(Callback<OpenReadAsyncHandlerDoneType>(
this, &MyClass::FileOpenReadCompletionHandler));
hr = operation->put_Completed(handler.Get());
}
return hr;
}
else {
OutputDebugStringW(L"Unexpected async status\n");
return E_FAIL;
}
return S_OK;
}
HRESULT MyClass::FileOpenReadCompletionHandler( IAsyncOperation<IRandomAccessStreamWithContentType*>* async, AsyncStatus status)
{
if (status == Completed) {
HRESULT hr = async->GetResults(_spStream.GetAddressOf());
if (_spStream) {
_spOpenResult->SetStatus(S_OK);
hr = MFInvokeCallback(_spOpenResult.Get());
_spOpenResult.ReleaseAndGetAddressOf();
}
return hr;
}
else {
OutputDebugStringW(L"Unexpected async status\n");
return E_FAIL;
}
return S_OK;
}