1 / 42

Tips and tricks for developing Metro style apps using C++

TOOL-845T. Tips and tricks for developing Metro style apps using C++. Tarek Madkour Principal Lead Program Manager Microsoft Corporation. Agenda. Very Brief Recap Windows Runtime C++ for Windows Runtime Common Patterns WinRT Types (esp. String and Exceptions)

issac
Download Presentation

Tips and tricks for developing Metro style apps using C++

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. TOOL-845T Tips and tricks for developing Metro style apps using C++ Tarek Madkour Principal Lead Program Manager Microsoft Corporation

  2. Agenda • Very Brief Recap • Windows Runtime • C++ for Windows Runtime • Common Patterns • WinRT Types (esp. String and Exceptions) • Collections and Iteration • Asynchronous Calls • Calling Win32

  3. Why you should care • Get the experience from our own app-building efforts: • Basic fundamentals always come into play • Many learnings from common gotchas • Getting you ready beyond the primer

  4. Quick Recap • WinRT • Visual C++ Component Extensions

  5. Windows 8 APIs Metro style app WinRT Win32 (Desktop Subset) Win32 (Metro style Subset) Windows Core OS Services

  6. Microsoft Confidential C++ for Windows Runtime Set of language extensions and libraries to allow direct consumption and authoring of Windows Runtime types. • delegate void CarouselInitDoneHandler(IUIAnimationVariable^ rotation); • voidCarouselAnimation::Initialize(double angle, CarouselInitDoneHandler^ callback) { • // Create Animation Manager • usingnamespace Engine::Graphics; • UIAnimationManageranimationManager(); • // Create rotation animation variable • IUIAnimationVariable^ rotation = animationManager.CreateAnimationVariable(angle); • // Set the event handler for the story board • rotation->GetCurrentStoryBoard() • ->SetStoryBoardEventHandler( • ref newCarouselStoryBoardHandler(this, &CarouselAnimation::StoryBoard) • ); • // Invoke the callback when done • callback(rotation); • }

  7. String^

  8. String^ • Platform::String^ as a boundary type • Immutable, can have embedded nulls • Copies are not expensive (ref counts) • Inherently more parallel • Can easily interop with std::wstring and wchar_t* • To “modify” the string • Create a new immutable string • Use std::wstring as a string builder

  9. String^ 1. usingnamespace Platform; 2. #include<string> 3. // initializing a String^ 4. String^ str1 = "Test"; // no need for L 5. String^ str2("Test"); 6. String^ str3 = L"Test"; 7. String^ str4(L"Test"); 8. String^ str5 = refnewString(L"Test"); 9. String^ str6(str1); 10. String^ str7 = str2; 11. wchar_tmsg[] = L"Test"; 12. String^ str8 = refnewString(msg); 13. std::wstring wstr1(L"Test"); 14. String^ str9 = refnewString(wstr1.c_str()); 15. String^ str10 = refnewString(wstr1.c_str(), wstr1.length());

  10. String^ 1. // initializing a std::wstring from String^ 2. std::wstring wstr2(str1->Data()); 3. std::wstring wstr3(str1->Data(), str1->Length()); 4. // comparisons 5. if(str1 == str2) { /* ... */ } 6. if(str1 != str2) { /* ... */} 7. if(str1 < str2) { /* ... */} 8. if(str1 < "test") { /* ... */ }

  11. String^ usage considerations • No need for L”” anymore • Compile-time convenience for String^ only • String^ parameter optimizations (Fast Pass) • String parameters on the stack; don’t destroy source string during call • How do you get a mutable string? • Use std::wstring for that • When to use String^ vs. std::wstring? • Judgment: proximity to boundary, how often to you intend to modify the string • Only trust the profiler • String^ works with STL algorithms (e.g. regex)

  12. Exception^

  13. Exception^ • WinRT APIs throw exceptions deriving from Platform::Exception • … really, it’s HRESULTs under the cover

  14. Exception^ 1. usingnamespace Platform; 2. 3. try 4. { 5. if (filename == "") { throwrefnewInvalidArgumentException(); } 6. autopics = Windows::Storage::KnownFolders::PicturesLibrary; 7. auto res = pics->GetFilesAsync(); 8. } 9. catch (InvalidArgumentException^ e) { /* same as E_INVALIDARG */ } 10. catch (NullReferenceException^ e) { /* same as E_POINTER */ } 11. catch(AccessDeniedException^ e) { /* same as E_ACCESSDENIED */ } 12. catch(FailureException^ e) { /* same as E_FAIL */ }

  15. Exception^ • At the WinRT boundary, every exception will be translated into an HRESULT module_b.dll module_a.exe voidApple() { throwrefnew Platform::FailureException(); } void Orange() { try { ModuleA::Pear(); } catch (Platform::OutOfBoundsException^) { } } void main() { try { ModuleB::Apple(); } catch (Platform::FailureException^) { ModuleB::Orange(); } } void Pear() { // perform out-of-bounds operation } E_FAIL E_BOUNDS

  16. Exception^ usage considerations • You can create “custom” exceptions; but it is not recommended • Use ComException; do not inherit from Platform::Exception • Exception strings are almost the same but not quite • ToString() for debugging; Message for logging • ComException(E_FAIL) and FailureException are not identical • Do not throw ComException(hr) blindly; throw most-derived exception • __cli_WinRTThrowError(hr) has the big switch statement • C++ exceptions turn into a FailureException • Travel as E_FAIL across the boundary

  17. Collections

  18. WinRT collections family Vector Map VectorView MapView IVector IMap IVectorView IMapView IIterable IObservableVector IObservableMap IIterator • STL containers are the backing store see <collection.h>

  19. Windows::Foundation::Collections 1. #include<vector> 2. #include<algorithm> 3. #include<utility> • 4. #include<collection.h> 5. namespace WFC = Windows::Foundation::Collections; 6. 7. WFC::IVectorView<int>^ Producer(){ 8. std::vector<int> v; 9. v.push_back(1); 10. v.push_back(2); 11. 12. returnrefnew Platform::VectorView<int>(std::move(v)); 13. } 14. 15.intsum = 0; 16. WFC::IVectorView<int>^ v = Producer(); 17. std::for_each(begin(v), end(v), [&sum](int i) { sum += i; });

  20. Collections usage considerations • Mix STL containers with WinRT collections • STL containers are faster but don’t have observable behavior • Use STL containers internally; use WinRT collections at the boundary • Fire up a profiler where it matters! • Use STL algorithms on WinRT collections • No need to copy the WinRT collection into an STL container • You can have STL containers of ^ types • Use Vector not IVector most of the time • Only use IVector the public API surface

  21. Collections usage considerations (cont.) • VectorView, MapView and Iterator get invalidated • Copy if you plan to change the underlying Vector or Map • Each iteration over collections is a virtual call • Use bulk iteration (GetMany) when it makes sense • Implementing IVector is tricky • Use an underlying Vector

  22. Async pattern

  23. Why Async? • Important for creating smooth experiences • Very common pattern among key WinRT APIs • Favors non-blocking scenarios • Provides you the control over when to block if needed

  24. Basic WinRT Pattern 1. voidmain() 2. { 3. // create the async operation, but don’t start it 4. SomeOperation^ someOp = Operation(); 5. 6. // define what happens when the operation completes 7. someOp->Completed = refnewAsyncOperationCompletedHandler<SomeType^> 8. ([](IAsyncOperation<SomeType^>^ asyncOp) { 9. // do whatever you want with the result after the operation has completed 10. auto result = asyncOp->GetResults(); 11. } 12. 13. // invoke the async operation 14.someOp->Start(); 15. }

  25. Async Example 1. using namespace Windows::Storage; • 2. using namespace Windows::Foundation; • 3. • 4. void main () { • 5. autoop = KnownFolders::PicturesLibrary->GetItemsAsync(); • 6. 7. op->Completed = refnewAsyncOperationCompletedHandler<IVectorView<IStorageItem^>^>( 8. [](IAsyncOperation<IVectorView<IStorageItem^>^>^ op) 9. { 10. autoitems = op->GetResults(); 11. }); 12. 13. op->Start(); 14. }

  26. Async Example (cont.) voidmain() { StorageFolder^ item = Windows::Storage::KnownFolders::PicturesLibrary; CreateStorageFileOperation^ createStorageFileOp = item->CreateFileAsync("bar.txt"); createStorageFileOp->Completed = ref newAsyncOperationCompletedHandler<StorageFile^>( [](IAsyncOperation<StorageFile^>^ asyncOp) { StreamRetrievalOperation^ streamRetrievalOp = asyncOp->GetResults()->OpenAsync(FileAccessMode::ReadWrite); streamRetrievalOp->Completed = ref newAsyncOperationCompletedHandler<IRandomAccessStream^>( [](IAsyncOperation<IRandomAccessStream^>^ asyncOp2) { IOutputStream^ stream = asyncOp2->GetResults()->GetOutputStreamAt(0); BasicBinaryReaderWriter^ bbrw = ref newBasicBinaryReaderWriter(); WriteBinaryStringOperation^ writeBinaryStringOp = bbrw->WriteBinaryStringAsync(stream, "this string gets written into the file"); writeBinaryStringOp->Completed = ref newAsyncOperationCompletedHandler<unsignedint>( [=](IAsyncOperation<unsignedint>^ asyncOp3) { int bytes = asyncOp3->GetResults(); IStreamFlushOperation^ streamFlushOp = stream->FlushAsync(); streamFlushOp->Completed = refnewStreamFlushCompletedEventHandler( [](IStreamFlushOperation^ asyncOp4) { bool result = asyncOp4->GetResults(); }); streamFlushOp->Start(); }); writeBinaryStringOp->Start(); }); streamRetrievalOp->Start(); }); createStorageFileOp->Start(); }

  27. Async simplified • Build on Parallel Patterns Library (PPL) tasks to implement async pattern • Sample available here: http://go.microsoft.com/fwlink/?LinkId=228286 • Using this technique, async code is cleaner and more maintainable

  28. Async Using PPL Sample • 1. voidSomeClass::InvokeOperation() • 2. { • 3. // create the async operation, but don’t start it • 4. autosomeOp= OperationAsync(); • 5.task<SomeType^> t(someOp); • 6. • 6. // define what happens when the operation completes • 7. t.then ([](SomeType^ opResult) { • 9. // do whatever you want with the result after the operation has completed • 10. }); • 11. • 12. // no need to manually “start” the async operation • 13. }

  29. Async Using PPL Sample (cont.) • 1. voidSomeClass::InvokeOperation() • 2. { • 3. StorageFolder^ item = Windows::Storage::KnownFolders::PicturesLibrary; • 4. task<StorageFile^> t(item->CreateFileAsync("bar.txt")); • 5. shared_ptr<IOutputStream^> ostream = make_shared<IOutputStream^>(nullptr); • 6.// use a shared pointer to ensure the stream is valid after function exits • 7. t.then([](StorageFile^ storageFile) { • 8. returnstorageFile->OpenAsync(FileAccessMode::ReadWrite); • 9. }).then([=](IRandomAccessStream^ rastream) -> StringBinaryAsyncOperation { • 10. *ostream= rastream->GetOutputStreamAt(0); • 11. BasicBinaryReaderWriter^ bbrw = refnewBasicBinaryReaderWriter(); • 12. returnbbrw->WriteBinaryStringAsync(ostream, "this string gets written into the file"); • 13. }).then([=](unsignedintbytesWritten) { • 14. return(*ostream)->FlushAsync(); • 15. }).then([](boolflushed) { • 16. // all done! • 17. }); • 18. }

  30. Win32

  31. Windows SDK for Metro style apps • Windows 8 introduces the concept of “app container” sandbox • Access to a number of resources (files, devices, etc.) is controlled by the sandbox • A large number for Win32 APIs are replaced by the WinRT library • A good number of Win32 will not be available to Metro style apps • Some Win32 APIs are still available directly to Metro style apps • COM Core • Kernel • Accessibility • Audio • Direct2D • Direct3D • DirectComposition • DirectManipulation • DirectWrite • File Systems • Globalization • Media Foundation • Windows and Messages

  32. Win32 • 1. voidLoadFromImageFile (String^ wFileName) { • 2. HRESULT hr = S_OK; • 3. ComPtr decoder, bitmapSource, wicBitmap, wicFactory, scaler, FlipRotator; • 4. • 5. hr= CoCreateInstance (CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, • 6. IID_IWICImagingFactory, &wicFactory); • 7. if(SUCCEEDED(hr)) • 8. hr= wicFactory->CreateDecoderFromFilename • 9. (wFileName->Data(),nullptr,GENERIC_READ,WICDecodeMetadataCacheOnLoad,&decoder); • 10. if(SUCCEEDED(hr)) • 11. hr= decoder->GetFrame (0, &bitmapSource); • 12. if(SUCCEEDED(hr)) • 13. hr= bitmapSource.As (&wicBitmap); • 14. if(SUCCEEDED(hr)) • 15. GetImageSize(); • 16. __cli_WinRTThrowError(hr); // if fail, throw the most specific Exception^ type • 17. }

  33. Win32 usage considerations • DirectX is one of the primary reasons to drop to Win32 • Use Win32 APIs when there is no WinRT equivalent • Use C++ runtime APIs in platform-agnostic code

  34. Summary • You have access to the Windows 8 Metro style API surface area • All WinRT APIs • The Metro style subset of Win32 and COM • Use WinRT types when calling or exposing WinRT APIs • Use standard C++ types freely within your Metro style app; mix with WinRT types as well • Use async APIs to create responsive Metro style apps

  35. Related sessions [TOOL-479T] A lap around Visual Studio 11 Express for Metro style apps using C++ [TOOL-532T] Using the Windows Runtime from C++ [TOOL-690C] Under the covers with C++ for Metro style apps [TOOL-789C] Bringing existing C++ code into Metro style apps [TOOL-802T] Taming GPU compute with C++ AMP [TOOL-835T] Writing modern C++ code: how C++ has evolved over the years

  36. Further reading and documentation • MSDN Documentation: Building your first Windows Metro style app with C++, C#, or Visual Basic http://go.microsoft.com/fwlink/?LinkID=227459 • Async Sample using the Parallel Patterns Library (PPL) http://go.microsoft.com/fwlink/?LinkId=228286 • Contact tarekm@microsoft.com

  37. Questions?

  38. thank you Feedback and questions http://forums.dev.windows.com Session feedbackhttp://bldw.in/SessionFeedback

  39. © 2011 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries. The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

  40. Useful Resources

  41. Windows 8 Metro style Apps Desktop Apps HTML JavaScript HTML / CSS XAML View JavaScript (Chakra) C C++ C# VB Model Controller C C++ C# VB WinRT APIs Devices & Printing Communication & Data Graphics & Media System Services .NET / SL Internet Explorer Win32 Application Model Windows Core OS Services Core

More Related