2012-08-29 2 views
1

IRandomAccessStream을 피커가없는 파일로 가져와야합니다.Windows 저장 App의 파일에 IRandomAccessStream 가져 오기

그러나 IStorageFile 또는 IRandomAccessStreamReference가 붙어있어 그 중 하나에서 IRandomAccessStream을 가져 오는 방법을 찾을 수 없습니다.

저는 C++ (no/ZW)로 코드를 작성하지만이 경우 중요하지 않다고 생각합니다.

도와주세요, 모세

답변

1

나는 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; 
} 
관련 문제