2014-09-19 67 views
0

我是WinRT C++的新手。我試圖從C#傳遞一個StorageFile圖像並打開該文件並將其設置爲WinRT中BitmapImage中的源以提取圖像的高度和寬度。我正在使用下面的代碼。WinRT中的BitmapImage SetSourceAsync C++

auto openOperation = StorageImageFile->OpenAsync(FileAccessMode::Read); // from http://msdn.microsoft.com/en-us/library/windows/desktop/hh780393%28v=vs.85%29.aspx 
openOperation->Completed = ref new 
    AsyncOperationCompletedHandler<IRandomAccessStream^>(
    [=](IAsyncOperation<IRandomAccessStream^> ^operation, AsyncStatus status) 
{ 
    auto Imagestream = operation->GetResults(); 
    BitmapImage^ bmp = ref new BitmapImage(); 
    auto bmpOp = bmp->SetSourceAsync(Imagestream); 
    bmpOp->Completed = ref new 
     AsyncActionCompletedHandler (
     [=](IAsyncAction^ action, AsyncStatus status) 
    { 
     action->GetResults(); 
     UINT32 imageWidth = (UINT32)bmp->PixelWidth; 
     UINT32 imageHeight = (UINT32)bmp->PixelHeight; 
    }); 
}); 

此代碼似乎不起作用。在BitmapImage之後^ bmp = ref new BitmapImage();調試器停止說沒有找到源代碼。 你能幫我寫出正確的代碼嗎?

+0

我想你的意思是寫'openOperation-> Completed' **'+ =''**參考新...'和'bmpOp- >已完成'**'+ ='**'ref new ...' – 2014-09-19 15:28:11

回答

1

我想你的意思是寫openOperation->Completed+=ref new...bmpOp->Completed+=ref new...。我不是C++的專家,但從我所見 - 異步操作通常包含在create_task調用中。不太確定爲什麼 - 也許爲了避免訂閱未取消訂閱的活動?

,我認爲它應該大致是這樣的:

auto bmp = ref new BitmapImage(); 

create_task(storageImageFile->OpenAsync(FileAccessMode::Read)) // get the stream 
    .then([bmp](IRandomAccessStream^ ^stream) // continuation lambda 
{ 
    return create_task(bmp->SetSourceAsync(stream)); // needs to run on ASTA/Dispatcher thread 
}, task_continuation_context::use_current()) // run on ASTA/Dispatcher thread 
    .then([bmp]() // continuation lambda 
{ 
     UINT32 imageWidth = (UINT32)bmp->PixelWidth; // needs to run on ASTA/Dispatcher thread 
     UINT32 imageHeight = (UINT32)bmp->PixelHeight; // needs to run on ASTA/Dispatcher thread 

     // TODO: use imageWidth and imageHeight 
}, task_continuation_context::use_current()); // run on ASTA/Dispatcher thread 
+0

非常感謝。我對ppl任務和concunrrency任務瞭解甚少。只需要一點建議,我應該在異步函數返回IAsyncOperation時使用create_task(),並在異步函數返回IAsyncAction時使用task_continuation_context :: use_current()來捕獲返回值。是對的嗎? – croc 2014-09-22 10:11:12

+0

'create_task'在任務中包裝'IAsyncOperation',您可以繼續。 '.then(lambda,task_continuation_context :: use_current())'使得在觸摸UI對象時所需的UI線程上運行lambda。 – 2014-09-22 14:44:38