introduction to writing metro style apps in native c ++
DESCRIPTION
Introduction to Writing Metro Style Apps in Native C ++. Marc Grégoire Software Architect [email protected] http://www.nuonsoft.com / http://www.nuonsoft.com/blog /. Agenda. Windows 8 Platform Windows Runtime ( WinRT ) C++ Extensions (C++/CX) Asynchronous programming model - PowerPoint PPT PresentationTRANSCRIPT
Introduction to Writing Metro Style Apps in Native C++
Marc GrégoireSoftware [email protected] http://www.nuonsoft.com/ http://www.nuonsoft.com/blog/ May 8th 2012
Agenda Windows 8 Platform Windows Runtime (WinRT) C++ Extensions (C++/CX) Asynchronous programming model Libraries (WinRT STL) XAML
Windows 8 Platform
Windows Core OS Services
JavaScript(Chakra)
C#VB
Metro style Apps
Communication & Data
Application Model
Devices & Printing
WinRT APIsGraphics &
Media
XAML HTML / CSS
HTMLJavaScrip
tC
C++C#VB
Desktop Apps
Win32
.NET / SL
Internet Explorer
CC++
Syst
em S
ervi
ces
Vie w
Mod
el
Cont
roll
erCo
re
CC++
XAML
Windows 8 Platform – Where can C++ be used?
Metro Hybrid Apps HTML5 + Javascript front-end C++ components
Metro XAML Apps UI using XAML C++ code behind
Metro high performance 2D/3D Apps C++ with DirectX rendering
Windows Runtime Set of language extensions and libraries
to allow direct consumption and authoring of WinRT types Strongly-typed system for Windows Runtime Automatically reference counted Exception-based Deep integration with STL Well defined binary contract across module
boundaries, ABI-safe
C++ Extensions (C++/CX)
C++ Extensions (C++/CX)Key Bindings Feature Summary1. Data Types ref class Reference type
value class Value typeinterface class Interfaceproperty Property with get/setevent “Delegate property” with add/remove/raisedelegate Type-safe function pointergeneric Type-safe generics
2. Allocation ref new Reference-counted allocation3. Pointer & Reference
^ Strong pointer (“hat” or “handle”)% Strong reference
C++ Extensions (C++/CX)
ModuleInternals
written in C++
WinRT External Surface
for WinRT callers/callees
C/C++ External Surface
for native callers/callees
Automatic Lifetime Management Handle (^ / Hat) is smart pointer to WinRT
objects Reference counted Allocated with ref new Example:
Person^ p;{ Person^ p2 = ref new Person(); // ref count = 1 p2->Name = "John"; // ref count = 1 p = p2; // ref count = 2} // ref count = 1p = nullptr; // ref count = 0 ~Person()
Automatic Lifetime Management On the stack, or as a member of another
WinRT type Example:
{ Person p; p.Name = "John"; /* ... */} // ~Person()
WinRT Class Use ref class to define new WinRT classes
(ABI-safe cross-language classes) Example:
public ref class Person{ public: Person(String^ name, String^ email); void Greet(Person^ other);
internal: ~Person(); void SetPassword(const std::wstring& passwd);};
Public/protected methods only WinRT parameters
Private/internal methods any C++ types as parameters
Usage:Person^ p = ref new Person("John");p->Greet(ref new Person("Jim"));
WinRT Interface Defining
public interface class IShape{ void Draw();};
Inheritingpublic interface class ISelectableShape : IShape{ void Select();};
Implementingref class Rectangle : ISelectableShape{ public: virtual void Draw(); virtual void Select();};
UsingIShape^ shape = ref new Rectangle();shape->Draw();
WinRT Property Defining
Trivial properties (with private backing store)public: property String^ Name;
User defined propertiespublic: property Person^ Sibling { Person^ get() { InitSiblings(); return _sibling; } void set(Person^ value) { _sibling = value; NotifySibling(); } }private: Person^ _sibling;
UsingPerson^ p = ref new Person("John");p->Sibling = ref new Person(p->Name);
WinRT Delegate Declaring
public delegate void PropertyChanged(String^ propName, String^ propValue);
Instantiating From lambda:
auto p = ref new PropertyChanged( [](String^ pn, String^ pv) { cout << pn << " = " << pv; });
From free-functionauto p = ref new PropertyChanged(UIPropertyChanged);
From class-memberauto p = ref new PropertyChanged(this, MainPage::OnPropertyChanged);
Invokingp("Visible", "f");
WinRT Event Defining
Trivial event (with private backing store)public: event PropertyChanged^ OnPropertyChanged;
User defined propertiespublic: event PropertyChanged^ OnNetworkChanged { EventRegistrationToken add(PropertyChanged^); void remove(EventRegistrationToken t); void raise(String^, String^);}
Using Subscribing
person->OnPropertyChanged += propertyChangedDelegate;auto token = person->OnPropertyChanged::add(propertyChangedDelegate);
Unsubscribingperson->OnPropertyChanged -= token;person->OnPropertyChanged::remove(token);
WinRT Exceptions Under the covers, WinRT uses COM, thus
HRESULTs WinRT wraps HRESULTs into exceptions Throwing exceptions
throw ref new InvalidArgumentException();throw ref new COMException(E_*);
Catching exceptionstry { … } catch (OutOfMemoryException^ ex) { … }
Access HRESULT value via ex->HResult
WinRT Exceptions Only a fixed set of exceptions available
Catch all WinRT exceptions:catch (Platform::Exception^) { }
You cannot derive your ownexceptions from Exception
HRESULT ExceptionE_OUTOFMEMORY OutOfMemoryExceptionE_INVALIDARG InvalidArgumentExceptio
nE_NOINTERFACE InvalidCastExceptionE_POINTER NullReferenceExceptionE_NOTIMPL NotImplementedExceptio
nE_ACCESSDENIED AccessDeniedExceptionE_FAIL FailureExceptionE_BOUNDS OutOfBoundsExceptionE_CHANGED_STATE ChangedStateExceptionREGDB_E_CLASSNOTREG
ClassNotRegisteredException
E_DISCONNECTED DisconnectedExceptionE_ABORT OperationCanceledExcep
tion
WinRT Generics Defining
generic<typename T, typename U> public interface class IPair {
property T First;property U Second;
};
Implementingref class PairStringUri: IPair<String^, Uri^> {public:
property String^ First;property Uri^ Second;
};
UsingIPair<String^, Uri^>^ uri = ref new PairStringUri();auto first = uri->First; // String^auto second = uri->Second; // Uri^
WinRT .winmd Metadata Files .winmd files
Contain the metadata representation of WinRT types To consume a winmd file:
Right click on project in Solution Explorer > References > Add New Reference… Or
#using <Company.Component.winmd> Make sure the winmd and implementation dll is packaged together
with your application To produce a .winmd file:
Start from the “C++ WinRT Component Dll” template Define public types (ref classes, interfaces, delegates, etc.)
WinRT Partial Runtime Classes Partial class definition
partial ref class MainPage: UserControl, IComponentConnector{public: void InitializeComponent(); void Connect() { btn1->Click += ref new EventHandler(this, &MainPage::Button_Click); }};
Class definitionref class MainPage{public: MainPage() { InitializeComponent(); } void Button_Click(Object^ sender, RoutedEventArgs^ e);};
Async
Async with PPL Tasks Windows 8 Metro only allows asynchronous operations
for anything that can take longer than a couple milliseconds.
For example: there are no synchronous file operations possible in Metro.
Advantage: keeps UI fast and fluid Disadvantage: programming can be more complex,
but new PPL tasks support helps alot here.
Async with PPL Tasks Example: create a file in the standard
“Pictures” folder, without PPL Tasks:StorageFolder^ folder = KnownFolders::PicturesLibrary;auto createStorageFileOp = folder->CreateFileAsync("myfile.txt");
createStorageFileOp->Completed =ref new AsyncOperationCompletedHandler<StorageFile^>([](IAsyncOperation<StorageFile^>^ asyncOp, AsyncStatus status) {StorageFile^ storageFile = asyncOp->GetResults();/* Do something with the file. */});
Async with PPL Tasks with PPL Tasks:
StorageFolder^ folder = KnownFolders::PicturesLibrary;create_task(folder->CreateFileAsync("myfile.txt")).then([](StorageFile^ storageFile) {
/* Do something with the file. */}
);
Libraries (WinRT STL)
Vector and ObservableVector Instantiating
using namespace Platform::Collections;Vector<String^>^ items = ref new Vector<String^>();
Adding elementsitems->Append("Hello");
Returning a read-only view of the vectorIVectorView<String^>^ view = items->GetView();
Getting notification for changesitems->VectorChanged += ref new VectorChangedEventHandler<String^> (this, &MyClass::VectorChanged);
Map and ObservableMap Defining
using namespace Platform::Collections;auto favorites = ref new Map<String^, Uri^>();
Adding elementsfavorites->Insert("MSDN", ref new Uri("http://msdn.com"));
Checking and removing elementsif (favorites->HasKey("MSDN")) favorites->Remove("MSDN");
Integration with STL Algorithms WinRT String has Begin()/End() member methods. For WinRT collections, collection.h defines begin() and
end() functions. Example:
IVector<int>^ v = GetItems();int sum = 0;std::for_each(begin(v), end(v), [&sum](int element) { sum += element; });
Integration with STL Containers Conversion is possible between STL containers and
WinRT containers String^ std::wstring (via wchar_t*) Vector std::vector
std::vector<int> v;v.push_back(10);auto items = ref new Vector<int>(v);
Vector std::vectorVector<int>^ items = ...;std::vector<int> v = to_vector(items);
XAML
Windows 8 Platform – Where can C++ be used?
Metro Hybrid Apps HTML5 + Javascript front-end C++ components
Metro XAML Apps UI using XAML C++ code behind
Metro high performance 2D/3D Apps C++ with DirectX rendering
Demo C++ and XAML
Resources “Using Windows Runtime With C++” – Herb
Sutter http://
channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-532T “Building Windows Metro style apps in
C++/XAML” – Vikas Bhatia, Joanna Mason http://
channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-479T
Questions
?I would like to thank Herb Sutter
from Microsoft for his permission to base this presentation on one that
he wrote for Build 2011.