Introduction

This sample demonstrates how to create a simple Windows Runtime component in C++ using the WRL Library. It also demonstrates how to build methods that return vector or map collections from STL vector and map container.

Building the Sample

The sample is made with Visual C++ 2013

Description

To provide a method that return a vector collection or a map collection, you have to implement IVector, IIterable and IIterator and IMap, IKeyValuePair interfaces.

C++
Edit|Remove
        STDMETHODIMP Root::GetVector(Windows::Foundation::Collections::IVector<HSTRING>** value) 
        { 
            ComPtr<Vector<HSTRING>> v = Make<Vector<HSTRING>>(); 
            HString str; 
            str.Set(L"Edith"); 
            v->Append(str.Get()); 
            str.Set(L"Lisa"); 
            v->Append(str.Get()); 
            str.Set(L"Audrey"); 
            v->Append(str.Get()); 
            *value = v.Detach(); 
            return S_OK; 
        } 
 
        STDMETHODIMP Root::GetVectorData(Windows::Foundation::Collections::IVector<IMyData *>** value) 
        { 
            ComPtr<Vector<IMyData *>> v = Make<Vector<IMyData *>>(); 
 
            HString str1; 
            str1.Set(L"Lisa"); 
            ComPtr<MyData> data1 = Make<MyData>(); 
            data1->put_Name(str1.Detach()); 
            v->Append(data1.Detach()); 
 
            HString str2; 
            str2.Set(L"Audrey"); 
            ComPtr<MyData> data2 = Make<MyData>(); 
            data2->put_Name(str2.Detach()); 
            v->Append(data2.Detach()); 
 
            *value = v.Detach(); 
            return S_OK; 
        } 
 
        STDMETHODIMP Root::GetVectorView(Windows::Foundation::Collections::IVectorView<HSTRING>** value) 
        { 
            ComPtr<Vector<HSTRING>> v = Make<Vector<HSTRING>>(); 
            HString str; 
            str.Set(L"Edith"); 
            v->Append(str.Get()); 
            str.Set(L"Lisa"); 
            v->Append(str.Get()); 
            str.Set(L"Audrey"); 
            v->Append(str.Get()); 
 
            v->GetView(value); 
            return S_OK; 
        } 
 
        STDMETHODIMP Root::GetVectorInt(Windows::Foundation::Collections::IVector<int>** value) 
        { 
            ComPtr<Vector<int>> v = Make<Vector<int>>(); 
            v->Append(11); 
            v->Append(8); 
            v->Append(3); 
            *value = v.Detach(); 
            return S_OK; 
        } 
 
        STDMETHODIMP Root::GetMap(Windows::Foundation::Collections::IMap<HSTRING, HSTRING>** value) 
        { 
            ComPtr<Map<HSTRING, HSTRING>> m = Make<Map<HSTRING, HSTRING>>(); 
 
            HString key1; key1.Set(L"Lisa"); 
            HString val1; val1.Set(L"Mini-mini"); 
            HString key2; key2.Set(L"Audrey"); 
            HString val2; val2.Set(L"Maggy"); 
            boolean replaced = FALSE; 
 
            m->Insert(key1.Get(), val1.Get(), &replaced); 
            m->Insert(key2.Get(), val2.Get(), &replaced); 
            *value = m.Detach(); 
            return S_OK; 
        } 
 
        STDMETHODIMP Root::GetMapView(Windows::Foundation::Collections::IMapView<HSTRING, HSTRING>** value) 
        { 
            ComPtr<Map<HSTRING, HSTRING>> m = Make<Map<HSTRING, HSTRING>>(); 
 
            HString key1; key1.Set(L"Lisa"); 
            HString val1; val1.Set(L"Mini-mini"); 
            HString key2; key2.Set(L"Audrey"); 
            HString val2; val2.Set(L"Maggy"); 
            boolean replaced = FALSE; 
 
            m->Insert(key1.Get(), val1.Get(), &replaced); 
            m->Insert(key2.Get(), val2.Get(), &replaced); 
 
            m->GetView(value); 
            return S_OK; 
        } 
 
        STDMETHODIMP Root::GetUnorderedMap(Windows::Foundation::Collections::IMap<HSTRING, HSTRING>** value) 
        { 
            ComPtr<UnorderedMap<HSTRING, HSTRING>> m = Make<UnorderedMap<HSTRING, HSTRING>>(); 
 
            HString key1; key1.Set(L"Lisa"); 
            HString val1; val1.Set(L"Mini-mini"); 
            HString key2; key2.Set(L"Audrey"); 
            HString val2; val2.Set(L"Maggy"); 
            boolean replaced = FALSE; 
 
            m->Insert(key1.Get(), val1.Get(), &replaced); 
            m->Insert(key2.Get(), val2.Get(), &replaced); 
            *value = m.Detach(); 
            return S_OK; 
        } 
 
        STDMETHODIMP Root::GetUnorderedMapView(Windows::Foundation::Collections::IMapView<HSTRING, HSTRING>** value) 
        { 
            ComPtr<UnorderedMap<HSTRING, HSTRING>> m = Make<UnorderedMap<HSTRING, HSTRING>>(); 
 
            HString key1; key1.Set(L"Lisa"); 
            HString val1; val1.Set(L"Mini-mini"); 
            HString key2; key2.Set(L"Audrey"); 
            HString val2; val2.Set(L"Maggy"); 
            boolean replaced = FALSE; 
 
            m->Insert(key1.Get(), val1.Get(), &replaced); 
            m->Insert(key2.Get(), val2.Get(), &replaced); 
 
            m->GetView(value); 
            return S_OK; 
        } 
 
        STDMETHODIMP Root::GetMapStringMyData(Windows::Foundation::Collections::IMap<HSTRING, IMyData *>** value) 
        { 
            ComPtr<Map<HSTRING, IMyData *>> m = Make<Map<HSTRING, IMyData *>>(); 
 
            HString key1; key1.Set(L"Lisa"); 
            HString key2; key2.Set(L"Audrey"); 
            boolean replaced = FALSE; 
 
            HString str1; 
            str1.Set(L"Lisa"); 
            ComPtr<MyData> data1 = Make<MyData>(); 
            data1->put_Name(str1.Detach()); 
 
            HString str2; 
            str2.Set(L"Audrey"); 
            ComPtr<MyData> data2 = Make<MyData>(); 
            data2->put_Name(str2.Detach()); 
 
            m->Insert(key1.Get(), data1.Detach(), &replaced); 
            m->Insert(key2.Get(), data2.Detach(), &replaced); 
            *value = m.Detach(); 
            return S_OK; 
        } 

Source Code Files

More Information

For more information on this sample, you can contact me or email me at christophepichaud@hotmail.com.

WRL is a C++ template library shipped with the Windows SDK 8 and 8.1. It allows to build WinRT components.

WinRT components are used in Windows Store Apps. Microsoft provides a new C++ set of compiler extensions for building WinRT components but this is not the standard ISO C++ and has some changes with operator ^ and ref keywords. Thoses extensions are aligned with the Managed C++ syntax but it generates native code.

But a lot of developers want to develop using the real and standard ISO C++ so this article is dedicated only with standard ISO C++. It is possible to write WinRT components using the WRL library and consume them into JS, C# or C++ XAML apps.

This sample is the port of collection.h header file from C++/CX to Standard ISO C++.

Compiler Error C2338 Information

If you just take the headers files and use them in your own library, you could encountered a compiler error like "error C2338: This interface instance has not been specialized by MIDL. This may be caused by forgetting a '*' pointer on an interface type, by omitting a necessary 'declare' clause in your idl file, by forgetting to include one of the necessary MIDL generated headers." This error occurs because the base class that implements IVector<T> also implements IObservableVector and you have to declare something in your IDL file.

In the WinRT component provided with this sample, I use Vector<int>, Vector<HSTRING>, Vector<IMyData *> and Map<HSTRING, IMyData *> so my IDL file contains some needed declarations at the end of the file:

    declare
    {
        interface Windows.Foundation.Collections.IObservableVector<HSTRING>;
        interface Windows.Foundation.Collections.IObservableVector<int>;
        interface Windows.Foundation.Collections.IObservableVector<IMyData *>;
        interface Windows.Foundation.Collections.IMap<HSTRING, IMyData *>;
        interface Windows.Foundation.Collections.IObservableMap<HSTRING, IMyData *>;
    }

Without these declarations, it won't compile. Windows provides a lot of declarations in Windows.Foundation.idl file. If you include a declaration that already exists, you will also encountered an error.

VectorChanged and MapChanged events

Some containers handle changes via triggered events.

Example of events implemented : add_VectorChanged, remove_VectorChanged.

Example of events implemented : add_MapChanged, remove_MapChanged.