Tips for building a windows store app using xaml and c the hilo project
Download
1 / 44

Tips for building a Windows Store app using XAML and C++: The Hilo project - PowerPoint PPT Presentation


  • 154 Views
  • Uploaded on

Tips for building a Windows Store app using XAML and C++: The Hilo project. Scott Densmore – Development Lead 3-001. Agenda. Hilo C++ Background Tips for building C++ Windows Store apps. The Hilo Project.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' Tips for building a Windows Store app using XAML and C++: The Hilo project' - yosefu


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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Tips for building a windows store app using xaml and c the hilo project

Tips for building a Windows Store app using XAML and C++: The Hilo project

Scott Densmore – Development Lead

3-001


Agenda
Agenda

  • Hilo C++ Background

  • Tips for building C++ Windows Store apps


The hilo project
The Hilo Project

  • End-to-end photo sample that provides guidance to C++ developers on how to use modern C++, asynchronous programming, XAML, and the Windows Runtime to build a world-ready app for the global market.



Demo

  • Walkthrough


1 use smart pointers stack semantics and raii pattern
1. Use smart pointers, stack semantics and RAII pattern

  • // old way

  • void func() {

  • widget* p = new widget();

  • p->draw();

  • delete p;

  • }


Smart pointers
Smart Pointers

  • void func() {

  • auto p = make_shared<widget>(); // no leak, and exception safe

  • p->draw();

  • }

  • // no delete required, out-of-scope triggers smart pointer destructor


Stack semantics and the raii pattern
Stack semantics and the RAII pattern

  • void f() {

  • unique_ptr<widget> p( new widget(…) );

  • my_classx( new widget() ); …

  • }

  • // automatic destruction and deallocation for both widget objects

  • // automatic exception safety


2 use public ref classes only for interop
2. Use public ref classes only for interop

  • public ref class Photo sealed : public IResizable, public IPhoto, public Windows::UI::Xaml::Data::INotifyPropertyChanged

  • {

  • internal:

  • Photo(Windows::Storage::BulkAccess::FileInformation^ file, IPhotoGroup^ photoGroup, std::shared_ptr<ExceptionPolicy> exceptionPolicy);

  • public:

  • virtual ~Photo();

  • virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;

  • ...

  • internal:

  • concurrency::task<void> QueryPhotoImageAsync();

  • ...

  • private:

  • Windows::Storage::BulkAccess::FileInformation^ m_fileInfo;

  • ...

  • };



3 don t create circular references between ref classes and lambda expressions
3. Don't create circular references between ref classes and lambda expressions.

  • {

  • auto wr = Platform::WeakReference(this);

  • function<void()> callback = [wr] {

  • auto vm = wr.Resolve<HubPhotoGroup>();

  • if (nullptr != vm)

  • {

  • vm->OnDataChanged();

  • }

  • };

  • m_repository->AddObserver(callback, PageType::Hub);

  • }


4 use explicit capture for lambda expressions
4. Use explicit capture for lambda expressions

  • intmain()

  • {

  • using namespace std;

  • inti = 3;

  • int j = 5;

  • ... // more variables

  • // bad – specifies that the body of the lambda expression accesses all captured variables by reference unless you explicitly specify otherwise

  • function<int(void)> f = [&] { return i + j; };

  • // bad – that the body of the lambda expression accesses all captured variables by value

  • function<int (void)> f = [=] { return i + j; };

  • // The following lambda expression captures i by value and j by reference.

  • function<int (void)> f = [i, &j] { return i + j; };

  • }


5 use task cancellation consistently
5. Use task cancellation consistently.

  • void CartoonizeImageViewModel::CartoonizeImage(Object^ parameter) {

  • m_cts = cancellation_token_source();

  • auto token = m_cts.get_token();

  • m_initializationTask = m_initializationTask.then([this, token]() -> task<void>

  • {

  • if (m_useHardwareAcceleration){

  • return CartoonizeImageAmpAsync(token);

  • }

  • ...

  • }

  • void CartoonizeImageViewModel::CancelCartoonize(Object^ parameter)

  • {

  • m_cts.cancel();

  • ViewModelBase::GoBack();

  • }


6 be aware of context rules for continuations of tasks
6. Be aware of context rules for continuations of tasks

  • task<void> ImageViewModel::QueryPhotosAsync() {

  • assert(IsMainThread());

  • ...

  • auto t = m_repository->GetPhotosForDateRangeQueryAsync(m_query);

  • return t.then([this](IVectorView<IPhoto^>^ photos) {

  • assert(IsBackgroundThread());

  • auto temp = ref new Vector<IPhoto^>();

  • ...

  • }, task_continuation_context::use_arbitrary()).then([this](Vector<IPhoto^>^ temp) {

  • assert(IsMainThread());

  • auto size = temp->Size;

  • ...

  • }).then([this](task<void> priorTask) {

  • assert(IsMainThread());

  • try {

  • priorTask.get();

  • ...

  • });



7 use the layoutawarepage class to provide navigation state management and view management
7. Use the LayoutAwarePage class to provide navigation, state management, and view management

  • Navigation support

  • virtual void GoHome(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);

  • virtual void GoBack(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);

  • virtual void GoForward(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);

  • Visual state switching

  • void StartLayoutUpdates(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);

  • void StopLayoutUpdates(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);

  • Process lifetime management

  • virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;

  • virtual void OnNavigatedFrom(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;

  • virtual void LoadState(Platform::Object^ navigationParameter,

  • Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ pageState);

  • virtual void SaveState(Windows::Foundation::Collections::IMap<Platform::String^,

  • Platform::Object^>^ pageState);


Navigating with xaml
Navigating with XAML

  • <local:HiloPage … />

  • <Button x:Name="FilmStripBackButton" AutomationProperties.AutomationId="FilmStripBackButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Margin="26,53,36,36" Style="{StaticResourceBackButtonStyle}“VerticalAlignment="Top"/>


Navigating with code
Navigating with Code

  • void RotateImageViewModel::Initialize(String^ photoPath) { assert(IsMainThread()); m_photo= nullptr; m_photoPath= photoPath; GetImagePhotoAsync().then([this](IPhoto^ photo) { assert(IsMainThread()); // Return to the hub page if the photo is no longer present if (photo == nullptr) { GoHome(); } });

  • }


8 support visual state for landscape portrait fill and snap
8. Support visual state for landscape, portrait, fill, and snap

  • <VisualStateManager.VisualStateGroups>

  • <VisualStateGroup x:Name="ApplicationViewStates">

  • <VisualState x:Name="FullScreenLandscape"/>

  • <VisualState x:Name="Filled"/>

  • <VisualState x:Name="FullScreenPortrait">

  • <Storyboard> ... </Storyboard>

  • </VisualState>

  • <VisualState x:Name="Snapped">

  • <Storyboard> ... </Storyboard>

  • </VisualState>

  • </VisualStateGroup>

  • </VisualStateManager.VisualStateGroups>


9 use asynchronous programming techniques to keep the ui responsive
9. Use asynchronous programming techniques to keep the UI responsive.

  • task<void> ImageViewModel::QueryPhotosAsync() {

  • assert(IsMainThread());

  • ...

  • auto t = m_repository->GetPhotosForDateRangeQueryAsync(m_query);

  • return t.then([this](IVectorView<IPhoto^>^ photos) {

  • assert(IsBackgroundThread());

  • auto temp = ref new Vector<IPhoto^>();

  • ...

  • }, task_continuation_context::use_arbitrary()).then([this](Vector<IPhoto^>^ temp) {

  • assert(IsMainThread());

  • auto size = temp->Size;

  • ...

  • }).then([this](task<void> priorTask) {

  • assert(IsMainThread());

  • try {

  • priorTask.get();

  • ...

  • });



10 use bindablebase class to provide support for mvvm
10. Use BindableBase class to provide support for MVVM

  • public ref class BindableBase : Windows::UI::Xaml::DependencyObject,

  • Windows::UI::Xaml::Data::INotifyPropertyChanged,

  • Windows::UI::Xaml::Data::ICustomPropertyProvider

  • {

  • public:

  • virtual event Windows::UI::Xaml::Data::PropertyChangedEventHandler^ PropertyChanged;

  • ...

  • protected:

  • virtual void OnPropertyChanged(Platform::String^ propertyName);

  • ...

  • }


11 use mvvm to build an interop layer between xaml and your models
11. Use MVVM to build an interop layer between XAML and your models



12 separate resources for each locale
12. Separate resources for each locale


13 use the calendar class to support world calendars
13. Use the Calendar class to support world calendars

  • Calendar^ CalendarExtensions::GetCalendar() {

  • return ref new Calendar();

  • }

  • intCalendarExtensions::GetNumberOfMonthsInYear(DateTimeyearDate)

  • {

  • auto cal = GetCalendar();

  • cal->SetDateTime(yearDate);

  • return cal->NumberOfMonthsInThisYear;

  • }



14 save application data when the app is being suspended
14. Save application data when the app is being suspended.


15 when the app resumes after termination use the saved app data to restore the app state
15. When the app resumes after termination, use the saved app data to restore the app state.


16 release exclusive resources when the app is being suspended
16. Release exclusive resources when the app is being suspended.



17 ensure your controls for tap and hold appears above the touch point
17. Ensure your controls for tap and hold appears above the touch point

  • void Hilo::ImageView::OnImagePointerPressed(Object^ sender, PointerRoutedEventArgs^ e)

  • {

  • m_pointerPressed = true;

  • PointerPoint^ point = e->GetCurrentPoint(PhotoGrid);

  • m_pointer = point->Position;

  • if (point->Properties->IsLeftButtonPressed)

  • {

  • ImageViewFileInformationPopup->HorizontalOffset = point->Position.X - 200;

  • ImageViewFileInformationPopup->VerticalOffset = point->Position.Y - 200;

  • ImageViewFileInformationPopup->IsOpen = true;

  • }

  • }


18 use the standard touch gestures and controls that windows 8 provides
18. Use the standard touch gestures and controls that Windows 8 provides.



19 use windows runtime to create image thumbnail for tiles
19. Use Windows Runtime to create image thumbnail for tiles

  • auto createThumbnail = create_task(sourceFile->GetThumbnailAsync(ThumbnailMode::PicturesView, ThumbnailSize));

  • return createThumbnail.then([](StorageItemThumbnail^ thumbnail) {

  • IRandomAccessStream^ imageFileStream = static_cast<IRandomAccessStream^>(thumbnail);

  • return BitmapDecoder::CreateAsync(imageFileStream);

  • }).then([decoder](BitmapDecoder^ createdDecoder) {

  • (*decoder) = createdDecoder;

  • return createdDecoder->GetPixelDataAsync(BitmapPixelFormat::Rgba8, ...);

  • }).then([pixelProvider, resizedImageStream](PixelDataProvider^ provider) {

  • (*pixelProvider) = provider;

  • return BitmapEncoder::CreateAsync(BitmapEncoder::JpegEncoderId, resizedImageStream);

  • }).then([pixelProvider, decoder](BitmapEncoder^ createdEncoder) {

  • createdEncoder->SetPixelData(BitmapPixelFormat::Rgba8, ...);

  • return createdEncoder->FlushAsync();

  • }).then([resizedImageStream] {

  • resizedImageStream->Seek(0);

  • return resizedImageStream;

  • });



20 ensure queries prefetch properties to improve performance
20. Ensure queries prefetchproperties to improve performance

  • auto queryOptions = ref new QueryOptions(CommonFileQuery::OrderByDate, fileTypeFilter);

  • queryOptions->IndexerOption = IndexerOption::UseIndexerWhenAvailable;

  • queryOptions->SetPropertyPrefetch(PropertyPrefetchOptions::ImageProperties, dateTakenProperties);

  • queryOptions->Language = CalendarExtensions::ResolvedLanguage();

  • auto fileQuery = folderQuery->CreateFileQueryWithOptions(queryOptions);



21 keep the launch times of your app fast
21. Keep the launch times of your app fast

  • ...

  • m_tileUpdateScheduler= std::make_shared<TileUpdateScheduler>();

  • m_tileUpdateScheduler->ScheduleUpdateAsync(m_repository, m_exceptionPolicy);

  • ...



Related sessions

Related Sessions

  • 11/2/2012 12:45- B33 McKinley- The Future of C++


Links thank you
Links & thank you

  • Code  http://aka.ms/Hilocpp-code

  • Documentation  http://aka.ms/hilocpp-doc

  • Codeplex  http://hilo.codeplex.com

  • Thank you


ad