×
Namespaces

Variants
Actions
(Difference between revisions)

C++ support from Windows Phone 8

From Nokia Developer Wiki
Jump to: navigation, search
yan_ (Talk | contribs)
(Yan - - Windows Phone Tuntime (C#, VB & C++/CX))
rudyhuyn (Talk | contribs)
(Rudyhuyn -)
Line 1: Line 1:
 
[[Category:Windows Phone 8]][[Category:Windows Phone]][[Category:C++/CX]][[Category:DirectX]]
 
[[Category:Windows Phone 8]][[Category:Windows Phone]][[Category:C++/CX]][[Category:DirectX]]
{{Abstract|Windows Phone 8 SDK adds two new sets of APIs to develop applications using native code. This article will explain how to use C++ under Windows Phone and some general directions that any C++ developer should know when targeting the platform.}}
+
''Delete instructional text in italic''
  
{{Note|This is a community entry in the [[Windows Phone 8 Wiki Competition 2012Q4]]}}
+
{{Abstract|This article explains how to ... }} ''Replace the abstract text with a short paragraph (or sentence) describing what the topic covers.''
  
 +
''Enter article metadata as described below. Note that this template can be placed anywhere in the article. Do not remove parameters that you do not use''
 
{{ArticleMetaData <!-- v1.2 -->
 
{{ArticleMetaData <!-- v1.2 -->
 
|sourcecode= <!-- Link to example source code e.g. [[Media:The Code Example ZIP.zip]] -->
 
|sourcecode= <!-- Link to example source code e.g. [[Media:The Code Example ZIP.zip]] -->
 
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) -->
 
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) -->
 
|devices= <!-- Devices tested against - e.g. ''devices=Nokia 6131 NFC, Nokia C7-00'') -->
 
|devices= <!-- Devices tested against - e.g. ''devices=Nokia 6131 NFC, Nokia C7-00'') -->
|sdk= [http://www.microsoft.com/en-us/download/details.aspx?id=35471 Windows Phone 8.0]
+
|sdk= <!-- SDK(s) built and tested against (e.g. [http://linktosdkdownload/ Qt SDK 1.1.4]) -->
|platform= Windows Phone 8.0
+
|platform= <!-- Compatible platforms - e.g. Symbian^1 and later, Qt 4.6 and later -->
 
|devicecompatability= <!-- Compatible devices e.g.: All* (must have internal GPS) -->
 
|devicecompatability= <!-- Compatible devices e.g.: All* (must have internal GPS) -->
|dependencies= <!-- Any other/external dependencies e.g.: Google Maps Api v1.0 -->
+
|dependencies= <!-- Any other/external dependencies e.g.: Google Maps Api v1.0 -->  
|signing= <!-- Signing requirements - empty or one of: Self-Signed, DevCert, Manufacturer -->
+
|signing=<!-- Signing requirements - empty or one of: Self-Signed, DevCert, Manufacturer -->
 
|capabilities= <!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
 
|capabilities= <!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
|keywords= windows phone, c++, managed, direct 3D, natif
+
|keywords= <!-- APIs, classes and methods (e.g. QSystemScreenSaver, QList, CBase -->
 
|language= <!-- Language category code for non-English topics - e.g. Lang-Chinese -->
 
|language= <!-- Language category code for non-English topics - e.g. Lang-Chinese -->
 
|translated-by= <!-- [[User:XXXX]] -->
 
|translated-by= <!-- [[User:XXXX]] -->
|translated-from-title= <!-- Title only -->
+
|translated-from-title= <!-- Title only -->  
 
|translated-from-id= <!-- Id of translated revision -->
 
|translated-from-id= <!-- Id of translated revision -->
|review-by= <!-- After re-review: [[User:username]] -->
+
|review-by=<!-- After re-review: [[User:username]] -->
 
|review-timestamp= <!-- After re-review: YYYYMMDD -->
 
|review-timestamp= <!-- After re-review: YYYYMMDD -->
 
|update-by= <!-- After significant update: [[User:username]]-->
 
|update-by= <!-- After significant update: [[User:username]]-->
 
|update-timestamp= <!-- After significant update: YYYYMMDD -->
 
|update-timestamp= <!-- After significant update: YYYYMMDD -->
|creationdate= 20121107
+
|creationdate= <!-- Format YYYYMMDD -->
|author= [[User:Yan]]
+
|author= <!-- Display as link [[User:username]] -->
}}
+
{{SeeAlso|
+
*[http://channel9.msdn.com/Shows/Inside+Windows+Phone/Inside-Windows-Phone-42--Sam-George-on-Native-C-Game-Development-in-Windows-Phone-8 Inside Windows Phone 42 - Sam George on Native C++ Game Development in Windows Phone 8]
+
*[http://channel9.msdn.com/Events/Build/2012/3-046 Windows Phone 8: Native C/C++ Game Development]
+
 
}}
 
}}
  
 
== Introduction ==
 
== Introduction ==
Windows Phone 8 SDK adds two new sets of APIs to develop applications using native code. This article will explain how to use C++ under Windows Phone and some general directions that any C++ developer should know when targeting the platform.
+
It's sometimes useful to launch a messagebox asynchronously.
  
Windows Phone 8 SDK API is divided in three complementary parts:
+
By default, all silverlight messagebox are synchronous but... there is a solution.
  
[[File:WP api.png]]
+
== Solution ==
  
* '''.NET''' gives access to Windows Phone functionality like Live Tiles, send SMS...
+
One might consider reimplementing the messagebox, it is a possibility, but we will see today that it is possible to access advanced features of MessageBox through one back door, thanks to our friend XNA!
* '''Windows Phone Runtime''' is an intermediate API which gives access to low level functionality like Voice Commands, VoIP...
+
* '''Native code''' gives access to low level APIs like Socket, DirectX...
+
  
For more information read :[http://msdn.microsoft.com/library/windowsphone/develop/ff626516(v=vs.105).aspx Windows Phone API reference]
+
If you look at the Microsoft.Xna.Framework.GameServices assembly, you will notice that the Guide object has methods quite interesting:
  
=== .NET (C# & VB) ===
 
.NET API is the original Windows Phone framework. It lets you to develop GUI with XAML technologies, access principal functionality (live tiles, tasks, send Mail, sms, ...) and XNA. It's actually the most important framework to develop Windows Phone application. To develop with this framework you can use C# or VB.
 
You can find .NET reference documentation here :
 
* [http://msdn.microsoft.com/library/windowsphone/develop/jj207211(v=vs.105).aspx .NET API for Windows Phone]
 
  
'''Note''' : [http://msdn.microsoft.com/library/bb200104.aspx XNA] is always supported, but only to develop Windows Phone 7  application. It's replaced by Direct3D with Windows Phone 8 .
 
  
===  Windows Phone Tuntime (C#, VB & C++/CX) ===
+
BeginShowMessageBox !
This API have two functionalities :
+
* share API with windows 8. [http://msdn.microsoft.com/library/windowsphone/develop/ff626516(v=vs.105).aspx A subset of this api is shared with windows 8].
+
* '''mixes managed and native code'''.  Managed and Native code are incompatible by nature but this API can be consumed by both.
+
This API is based on an evolution of COM technology.  To use it with C++ and write easily a WinPRT component, Microsoft have created the [http://msdn.microsoft.com/library/windows/apps/hh699871.aspx Visual C++ Language Reference (C++/CX)]. This extension adds to C++  managed equivalent like  properties, delegate, event.... To be consumed by manged code, class developed with C++/Cx generate metadata. In fact, toolchain translate this class to a complex  C++ code with WinPRT annotations :
+
{| class="wikitable"
+
|-
+
! with C++/CX  !! whitout C++/CX
+
|-
+
|
+
<code cpp>public ref class Number sealed
+
{
+
public:
+
  
Number() : _value(0) { }
+
This method displays a native and asynchronously messagebox with  parameters:
 +
*title: Title of the message box
 +
*text: text to be displayed in the message box
 +
*buttons: Legends associated with the buttons on the message box. The maximum number of buttons is two.
 +
*focusButton: 0-based index that defines the button highlighted.
 +
*icon: Type icon in the message box.
 +
*callback: method to call when the asynchronous operation is complete.
 +
*STATE: The unique user-created that identifies this request.
  
int GetValue()          { return _value;  }
+
Title and text match mutually the parameters "caption" and "messageboxtext" of Silverlight.
void SetValue(int value) { _value = value; }
+
  
private:
+
One difference here: the text can not exceed 256 characters, otherwise an exception is thrown.
  
int _value;
+
Buttons is here much more advanced than our Silverlight MessageBox, we can specify the button text, for example, we can modify the "ok" and "cancel" text like that :
};
+
</code>
+
| |
+
<code cpp >[exclusiveto(Number)]
+
[uuid(5b197688-2f57-4d01-92cd-a888f10dcd90)]
+
[version(1.0)]
+
interface INumber : IInspectable
+
{
+
HRESULT GetValue([out, retval] INT32* value);
+
HRESULT SetValue([in] INT32 value);
+
}
+
  
[activatable(1.0), version(1.0)]
 
runtimeclass Number
 
{
 
[default] interface INumber;
 
}
 
  
class Number : public RuntimeClass<INumber>
 
{
 
InspectableClass(RuntimeClass_WRLNumberComponent_Number, BaseTrust)
 
  
public:
 
  
Number() : _value(0) { }
+
<code csharp>
 
+
Microsoft.Xna.Framework.GamerServices.Guide.BeginShowMessageBox(
virtual HRESULT STDMETHODCALLTYPE GetValue(INT32* value) override
+
"Quizz",
{
+
"What is your favorite Windows Phone?",
*value = _value;
+
new string[] { "Nokia Lumia 820", "Nokia Lumia 920" },
return S_OK;
+
0,
}
+
Microsoft.Xna.Framework.GamerServices.MessageBoxIcon.Alert,
 
+
null,
virtual HRESULT STDMETHODCALLTYPE SetValue(INT32 value) override
+
null);
{
+
_value = value;
+
return S_OK;
+
}
+
 
+
private:
+
 
+
INT32 _value;
+
};
+
 
</code>
 
</code>
|}
 
  
To develop in C++ you will always use this extension somewhere because it's your C++ code which is consumed by managed API and not the other way round. For example "you can't use a C++ object directly in your C# app. you need to first write a Windows Runtime Component.
+
This offers us a lot of new possibilities!
  
===  Native (C++) ===
+
But be careful to localize your buttons!
Visual studio 2012 have a really good support of C++ language and its recent normalization. For windows phone, these links are good entries to find supported  features :
+
* [http://msdn.microsoft.com/library/dtefa218.aspx C/C++ Languages]
+
* [http://msdn.microsoft.com/library/cscc687y.aspx Standard C++ Library Reference]
+
* [http://msdn.microsoft.com/library/3bstk3k5.aspx C++ Language Reference]
+
  
C++11 adds a lot of really good concepts and features. Too learn more and  update your abilities, you should read this link : [http://msdn.microsoft.com/library/hh279654.aspx Modern C++].
+
How to make synchronous messagebox again?
  
Native API is developed in C++ and divided into libraries :
+
Able to have a dialog asynchronous's pretty cool, but in most cases, we expect it to be synchronous. To do this simply to retrieve the result of the asynchronous call and wait for its execution.
* [http://msdn.microsoft.com/library/windowsphone/develop/jj662956(v=vs.105).aspx Win 32 & COM] api : subset of Win32 API. This library gives acces to function to manipulate files, raw sockets and COM object.
+
* [http://msdn.microsoft.com/library/windowsphone/develop/jj207010(v=vs.105).aspx Direct3D 11]: 3D rendering.
+
* [http://msdn.microsoft.com/library/windowsphone/develop/jj681688(v=vs.105).aspx Microsoft Media Foundation APIs ] : Microsoft framework for audio/video capture and rendering. [http://msdn.microsoft.com/library/windowsphone/develop/jj207074(v=vs.105).aspx Windows Phone implement a subset of Windows 8 version].
+
* [http://msdn.microsoft.com/library/hh438466.aspx Windows Runtime C++ Template Library] : helper to consume and create COM or Windows Runtime component in C++. It's replace old ATL API. With Windows Phone, this library is generally use only to consume COM and WinPRT components.
+
* [http://msdn.microsoft.com/library/dd492418.aspx Parallel Patterns Library] : high level multithread library with concurency algorithm and task concept.
+
  
In few cases, you can use directly COM Object :
 
* advanced access to [http://msdn.microsoft.com/library/windowsphone/develop/jj571202(v=vs.105).aspx camera]
 
* advanced access to  [http://msdn.microsoft.com/library/windowsphone/develop/jj715884(v=vs.105).aspx audio].
 
 
== Native application ==
 
 
To launch an application, Windows phone need an "entry point" it may consume. To perform it, your "entry point" will be developed with C++/CX and C++ main function is replaced by a C++/CX version :
 
 
<code csharp>
 
<code csharp>
[Platform::MTAThread]
+
IAsyncResult result = Microsoft.Xna.Framework.GamerServices.Guide.BeginShowMessageBox(
int main(Platform::Array<Platform::String^>^)
+
  "Quizz",
{
+
  "What is your favorite Windows Phone?",
auto factory= ref new myFactory();
+
  new string[] { "Nokia Lumia 820", "Nokia Lumia 920" },
CoreApplication::Run(direct3DApplicationSource);
+
  0,
return 0;
+
  Microsoft.Xna.Framework.GamerServices.MessageBoxIcon.None,
}
+
  null,
</code>
+
  null);
* [http://msdn.microsoft.com/library/windows/apps/hh710417.aspx Platform::MTAThread] : metadata about application multi-thread apartment.
+
* '''myFactory''': implement [http://msdn.microsoft.com/library/windowsphone/develop/windows.applicationmodel.core.iframeworkviewsource.aspx IFrameworkViewSource]. This class is a factory use to instantiate a [http://msdn.microsoft.com/library/windowsphone/develop/windows.applicationmodel.core.iframeworkview.aspx Iframeworkview].
+
<code csharp>
+
ref class myFactory sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
+
{
+
public:
+
    virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView()
+
    {
+
        return ref new myView();
+
    };
+
};
+
</code>
+
* [http://msdn.microsoft.com/library/windowsphone/develop/hh700469.aspx CoreApplication::Run] : C++/CX function which acquire an [http://msdn.microsoft.com/library/windowsphone/develop/windows.applicationmodel.core.iframeworkview.aspx Iframeworkview] from an [http://msdn.microsoft.com/library/windowsphone/develop/windows.applicationmodel.core.iframeworkviewsource.aspx IFrameworkViewSource] factory.
+
  
IFrameworkView is the display provider use to make Direct3D rendering. Interface function are :
+
result.AsyncWaitHandle.WaitOne();
* Initialize : initialization  function. take a[http://msdn.microsoft.com/library/windowsphone/develop/windows.applicationmodel.core.coreapplicationview.aspx CoreApplicationView] in parameters. You can use [http://msdn.microsoft.com/library/windowsphone/develop/windows.applicationmodel.core.coreapplicationview.activated.aspx CoreApplicationView Activated  event] to be notified when application is activated and use this function to register your IFrameworkView with [http://msdn.microsoft.com/library/windowsphone/develop/windows.applicationmodel.core.coreapplication.aspx CoreApplication events] to handle application state changes.
+
<code csharp>
+
void myView::Initialize(CoreApplicationView^ applicationView)
+
{
+
applicationView->Activated +=
+
ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &myView::OnActivated);
+
 
+
        //handle suspending and resuming application states.
+
CoreApplication::Suspending +=
+
ref new EventHandler<SuspendingEventArgs^>(this, &myView::OnSuspending);
+
 
+
CoreApplication::Resuming +=
+
ref new EventHandler<Platform::Object^>(this, &myView::OnResuming);
+
}
+
 
</code>
 
</code>
* Load : load and activate external resources. This function is called before Run().
 
  
* SetWindow : sets the current [http://msdn.microsoft.com/library/windowsphone/develop/windows.ui.core.corewindow.aspx CoreWindow]. Use it to handle application display event like close, visibility change, mono-touch event, ...
+
and here we have a native, synchronous and customizable message box !
<code csharp>
+
void myView::SetWindow(CoreWindow^ window)
+
{
+
window->VisibilityChanged +=
+
ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &myView::OnVisibilityChanged);
+
  
window->Closed +=  
+
== Test result of the dialog ==
ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &myView::OnWindowClosed);
+
  
window->PointerPressed +=
+
If you want to test the result of your dialog box (which button was clicked), simply call the method EndShowMessageBox :
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &myView::OnPointerPressed);
+
  
window->PointerMoved +=
 
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &myView::OnPointerMoved);
 
 
window->PointerReleased +=
 
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &myView::OnPointerReleased);
 
}
 
</code>
 
* Uninitialize : uninitializes ressources.
 
* Run : start your view. Your must implement an application event-loop here.
 
 
<code csharp>
 
<code csharp>
void myView::Run()
+
int? choice = Microsoft.Xna.Framework.GamerServices.Guide.EndShowMessageBox(result);
{
+
if(choice.HasValue)
        //reference time.
+
{
BasicTimer^ timer = ref new BasicTimer();
+
if(choice.Value==0)
 
+
{
while (!m_windowClosed)//while application is not closed
+
//user clicks the first button
{
+
}
if (m_windowVisible)// application is visible, update Direct3D rendering
+
}
{
+
timer->Update();
+
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);//process current system events
+
m_renderer->Update(timer->Total, timer->Delta); //update your render from time reference.
+
m_renderer->Render();// Direct3D rendering
+
m_renderer->Present(); // This call is synchronized to the display frame rate.
+
}
+
else // application is not visible
+
{
+
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending); ;//process current system events and wait new events.
+
}
+
}
+
}
+
 
</code>
 
</code>
  
Native application have three importants points:
+
== Summary ==
* you can only use Direct3D for display data. Native API doesn't have API to build GUI.
+
* you must execute system events.
+
* You don't have access to .Net functionality. You can't use live tiles, send a SMS, ...
+
  
Without .Net functionality, native applications are not so cool and you are limited to Direct3D develop ... But remember, you can develop WinPRT components with  C++/CX. So it's possible to encapsulate your c++ Code with C++/CX and consume it with managed code
+
*Add reference Microsoft.Xna.Framework.GameServices
 +
*Write the following code:
  
  
Other wiki resources about Direct3D development:
 
* [[DirectX Developers - DirectX in Windows Phone]]
 
* [[Windows Phone Native C++ and DirectX - First Direct3D App, setting up Touch and Sensors]]
 
 
== Mixed application ==
 
You can develop mixed application where your managed code consume Windows Phone Runtime components. To develop with C++ Code, you must create a Windows Phone Runtime Component which interface C++ part with a public  sealed C++/CX class . It's important to read[http://msdn.microsoft.com/library/windows/apps/xaml/br212455.aspx C++ extension documentation] to understand its specificities :
 
*a C++/CX class/struct is declared with  '''ref''' keyword
 
 
<code csharp>
 
<code csharp>
ref class myclass
+
IAsyncResult result = Microsoft.Xna.Framework.GamerServices.Guide.BeginShowMessageBox(
{
+
  "Quizz",
    //...
+
  "What is your favorite Windows Phone?",
};
+
  new string[] { "Nokia Lumia 820", "Nokia Lumia 920" },
</code>
+
  0,
* Allocation is performed by [http://msdn.microsoft.com/library/windows/apps/xaml/hh699870.aspx '''ref new'''].  
+
  Microsoft.Xna.Framework.GamerServices.MessageBoxIcon.None,
* C++/CX struct can be use like a POD.
+
  null,
*Class instance is handled by  '''^ type''' ( is known as a "hat"). This type is a smart pointer with a counting reference like std::shared_ptr.
+
  null);
<code csharp>
+
myclass ^ myClass = ref new myclass ();
+
</code>
+
* [http://msdn.microsoft.com/library/windows/apps/xaml/hh699879.aspx Platform::String Class] replace std::wstring. C++/CX String are Unicode.
+
* [http://msdn.microsoft.com/library/windows/apps/xaml/hh700103.aspx C++/CX collections] are compliant with STL.
+
* [http://msdn.microsoft.com/library/windows/apps/xaml/hh700121.aspx Fundamental types] are similar.
+
* A [http://msdn.microsoft.com/library/windows/apps/xaml/hh755807.aspx property] is similar to getter/setter in C++.
+
* A [http://msdn.microsoft.com/library/windows/apps/xaml/hh755798.aspx delegate] is a function object. It can encapsulate n C++/CX or managed code.
+
* An [http://msdn.microsoft.com/library/windows/apps/xaml/hh755799.aspx event]  is a delegate collection which perform all delegate when event is raised.
+
* '''sealed''' keyword : a sealed class or a sealed function can't be overridden.
+
  
To be consumed by managed code, C++/CX code generate a set of metadata. This generation depend on [http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh969551.aspx access modifier] :
+
result.AsyncWaitHandle.WaitOne();
{| class="wikitable"
+
|-
+
! Modifier !!Meaning !! Emitted to metadata?
+
|-
+
|private || The default accessibility. Same meaning as in standard C++.|| No
+
|-
+
|protected || Same meaning as in standard C++, both within the app or component and in metadata. || Yes
+
|-
+
|public ||Same meaning as in standard C++.||Yes
+
|-
+
|public protected –or- protected public || Protected accessibility in metadata, public within the app or component. || Yes
+
|-
+
|protected private or private protected || Not visible in metadata; protected accessibility within the app or component. || No
+
|-
+
|internal or private public||The member is public within the app or component, but is not visible in metadata.|| No
+
|}
+
 
+
Metadata are generated only for specific C++/CX objects. A C++/CX class can declare  C++ object only if the  member/function have a private or internal access. Your public Class/Struct must be sealed because Managed code can't override it.
+
<code csharp>
+
//C++/CX class declaration which can be consumed by managed code
+
public ref class MyClass sealed
+
{
+
private : //  C++ object can be used
+
    std::string aString:
+
    std::vector<uint32_t> aFunction();
+
  
public : //object and function are accessible by managed coe. if a c++ object is used, error is generated.
+
int? choice = Microsoft.Xna.Framework.GamerServices.Guide.EndShowMessageBox(result);
    property Platform::String ^ anotherString;
+
if(choice.HasValue)
    Windows::Foundation::Collections::IVector<uint32> ^anotherFunction();
+
{
//...
+
if(choice.Value==0)
};
+
{
 +
//User clicks on the first button
 +
}
 +
}
 
</code>
 
</code>
  
Public access is very strict, and only specific C++/CX objects can be used  :
+
== How to remove the messagebox sound? ==
* function,
+
* [http://msdn.microsoft.com/library/windows/apps/xaml/hh755807.aspx property],
+
* [http://msdn.microsoft.com/library/windows/apps/xaml/hh755798.aspx delegate],
+
* [http://msdn.microsoft.com/library/windows/apps/xaml/hh755799.aspx event],
+
These Objects must be defined with these types :
+
* [http://msdn.microsoft.com/library/windows/apps/xaml/hh700121.aspx Fundamental],
+
* [http://msdn.microsoft.com/library/windowsphone/develop/jj207212(v=vs.105).aspx Windows Phone Runtime API objects ],
+
* [http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh832106.aspx C++/CX namespace reference] with restriction. When class is not compatible, it generally implement an Interface declared in  [http://msdn.microsoft.com/library/windowsphone/develop/jj207212(v=vs.105).aspx Windows Phone Runtime API],
+
* Your public sealed class/struct.
+
  
Once your components is referenced by your managed application, you can consume it like other Managed object. It's so possible to bind public properties with XAML and connect to public events.
 
 
You can find interesting explanation here :
 
* [http://msdn.microsoft.com/library/windows/apps/hh441569.aspx Creating Windows Runtime Components in C++]
 
* [http://blogs.msdn.com/b/vcblog/archive/2012/08/29/cxxcxpart00anintroduction.aspx C++/CX Part 0 of n:  An Introduction]
 
* [http://blogs.msdn.com/b/vcblog/archive/2012/09/05/cxxcxpart01asimpleclass.aspx C++/CX Part 1 of n:  A Simple Class]
 
* [http://blogs.msdn.com/b/vcblog/archive/2012/09/17/cxxcxpart02typesthatwearhats.aspx C++/CX Part 2 of n:  Types That Wear Hats]
 
* [http://blogs.msdn.com/b/vcblog/archive/2012/10/05/cxxcxpart03underconstruction.aspx C++/CX Part 3 of n:  Under Construction]
 
* [http://blogs.msdn.com/b/vcblog/archive/2012/10/19/cxxcxpart04staticmemberfunctions.aspx C++/CX Part 4 of n:  Static Member Functions]
 
 
   
 
   
'''Warning''' :  Windows phone implement a subset of the [http://msdn.microsoft.com/en-us/library/windows/apps/hh832106.aspx Windows 8 C++/CX namespace]. Few object are not accessible.
+
To remove the beep or the vibration, just change the icon... Ok I know this is not great logic, but that's how. In fact it should be understood that XNA is a common platform between Windows, Xbox and Windows Phone. In the windows world, we are used to display icons 'warning', 'alert', etc. .. left of the dialog box, which is not super top for a mobile display or width of the screen is already binding. The distinction between a normal dialog and a dialog box warning / alert, is therefore the sound / vibration. To remove the sound, we just have to set the type to None.
=== Collections===
+
Windows Phone Runtime API doesn't implement collections class. To transfer collection between managed and native code, a set of [http://msdn.microsoft.com/en-us/library/windowsphone/develop/windows.foundation.collections.aspx#interfaces collections Interface] are defined. These interface have Equivalent in managed. For example  IVector besome an IList in C#.
+
 
+
[http://msdn.microsoft.com/en-US/library/windows/apps/hh700103.aspx C++/CX collections] use C++ parts and can't be consumed directly by managed Code. Like these classes implement a Windows Phone Runtime interface, you can cast these to be consumed through the interface
+
 
<code csharp>
 
<code csharp>
Windows::Foundation::Collections::IVector<int>^ Class1::GetInts()
+
Microsoft.Xna.Framework.GamerServices.Guide.BeginShowMessageBox(
{
+
  "Quizz",
  auto vec = ref new Platform::Collections::Vector<int>();
+
  "What is your favorite Windows Phone?",
    ...
+
  new string[] { "Nokia Lumia 820", "Nokia Lumia 920" },
    return  vec;// implicit  cast to Windows Phone Runtime interface. Managed code can consume collection returned.
+
  0,
}
+
  Microsoft.Xna.Framework.GamerServices.MessageBoxIcon.None,
 +
  null,
 +
  null);
 
</code>
 
</code>
 
 
'''Remarque''' : STL collection can be converted to its C++/CX equivalent. When you convert a temporary collection, You can use  std::move to avoid unnecessary internal copy
 
<code csharp>
 
Windows::Foundation::Collections::IVector<int>^ Class1::GetInts()
 
{
 
    st::vector<int> vec;
 
    for(int i = 0; i < 10; i++)
 
    {
 
        vec.push_back(i);
 
    }   
 
    // Implicit conversion to IVector
 
    return ref new  Platform::Collections::Vector<int>(std::move(vec));
 
}
 
</code>
 
 
=== Debugger ===
 
You can't debug managed code and native code in same times. To selected which debugger you want use :
 
# open project properties
 
# open debug tab and select debugger mode
 
[[File:Debugger_selection.png]]
 
 
=== Direct 3D  ===
 
Managed code can't access directly to Direct 3D. You must develop a WinPRT component which consume Direct3D with C++ code. Direct3D rendering can be display by two XAML controls:
 
* [http://msdn.microsoft.com/library/windowsphone/develop/system.windows.controls.drawingsurface(v=vs.105).aspx DrawingSurface]. Direct3D will be rendering on DrawingSurface region. This element is used like other UI control and you can perform transformation, animation,... 
 
* [http://msdn.microsoft.com/library/windowsphone/develop/system.windows.controls.drawingsurfacebackgroundgrid(v=vs.105).aspx DrawingSurfaceBackgroundGrid]:Direct3D is rendering on all your application background. This layout must be the root UI  control in XAML. You can add UI control like a [http://msdn.microsoft.com/library/windowsphone/develop/system.windows.controls.grid(v=vs.105).aspx Grid].
 
More informations can be found in [[Windows Phone Direct3D XAML Application Introduction]]  article.
 
 
Unfortunately, integration with XAML is more complicated. You need a layer of Interopility to acces to Direct3D device ( look  Direct3DContentProvider.h class in VS project) ... SDk give two project template :
 
* [http://msdn.microsoft.com/library/windowsphone/develop/jj207012(v=vs.105).aspx Visual C# => WIndows Phone XAML and Direct 3D] : this project use  DrawingSurface to render Direct3D
 
* [http://msdn.microsoft.com/library/windowsphone/develop/jj714079(v=vs.105).aspx  Visual C++ => WIndows Phone Direct 3D with XAML] : this project use DrawingSurfaceBackgroundGrid to render Direct3D.
 
 
These projects share important  code :
 
* Direct3DContentProvider.h : COM class coded with  wrl library and implement the  layer of Interopility  between a IDrawingSurfaceContentProvider and IDrawingSurfaceContentProviderNative COM interface.
 
* Direct3DBase.h : Helper class that initializes DirectX APIs for 3D rendering. Your can use it for your Direct3D class.
 
*  XXX::CreateContentProvider() : add a layer of Interopility and return IDrawingSurfaceBackgroundContentProvider or IDrawingSurfaceContentProvider.
 
 
Your class must implement functions which are called by Direct3DContentProvider :
 
<code cpp >
 
// IDrawingSurfaceContentProviderNative
 
HRESULT STDMETHODCALLTYPE Connect(_In_ IDrawingSurfaceRuntimeHostNative* host);
 
void STDMETHODCALLTYPE Disconnect();
 
 
HRESULT STDMETHODCALLTYPE PrepareResources(_In_ const LARGE_INTEGER* presentTargetTime, _Out_ BOOL* contentDirty);
 
HRESULT STDMETHODCALLTYPE GetTexture(_In_ const DrawingSurfaceSizeF* size, _Out_ IDrawingSurfaceSynchronizedTextureNative** synchronizedTexture, _Out_ DrawingSurfaceRectF* textureSubRectangle);
 
</code>
 
 
this method are called by Direct3DContentProvider to give Direct3D context for rendering.
 
 
IDrawingSurfaceBackgroundContentProvider  and  IDrawingSurfaceContentProvider are empty interface. They are only use to associate your class with target UI Controler. But XXX::CreateContentProvider() is mportant :
 
<code cpp>
 
IDrawingSurfaceContentProvider^ Direct3DInterop::CreateContentProvider()
 
{
 
ComPtr<Direct3DContentProvider> provider = Make<Direct3DContentProvider>(this);
 
return reinterpret_cast<IDrawingSurfaceContentProvider^>(provider.Detach());
 
}
 
</code>
 
* Make<Direct3DContentProvider>(this); : encapsulate your class instance to  a Direct3DContentProvider COM object.
 
* Cast COM Obect to IDrawingSurfaceContentProvider interface. '''You must use this returned  instance to associate your rendering with UI Controler.'''
 
 
==Reference links ==
 
Ressources about C++ Direct3D developpement on Windon sPhone  :
 
*[http://channel9.msdn.com/Shows/Inside+Windows+Phone/Inside-Windows-Phone-42--Sam-George-on-Native-C-Game-Development-in-Windows-Phone-8 Inside Windows Phone 42 - Sam George on Native C++ Game Development in Windows Phone 8]
 
 
<mediaplayer>http://media.ch9.ms/ch9/c9cc/b29ceafd-ecc3-4980-b4a8-8b7f678bc9cc/iwp42sgc_high.mp4</mediaplayer>
 
*[http://channel9.msdn.com/Events/Build/2012/3-046 Windows Phone 8: Native C/C++ Game Development]
 
<mediaplayer>http://video.ch9.ms/sessions/build/2012/3-046.mp4</mediaplayer>
 
* [http://msdn.microsoft.com/library/windowsphone/develop/jj207052(v=vs.105).aspx Direct3D app development for Windows Phone 8]
 

Revision as of 21:56, 3 December 2012

Delete instructional text in italic

This article explains how to ... Replace the abstract text with a short paragraph (or sentence) describing what the topic covers.

Enter article metadata as described below. Note that this template can be placed anywhere in the article. Do not remove parameters that you do not use

WP Metro Icon DirectX.png
WP Metro Icon WP8.png
Article Metadata
Compatibility
Platform(s):
Windows Phone 8
Article
Created: (16 Nov 2012)
Last edited: rudyhuyn (03 Dec 2012)

Contents

Introduction

It's sometimes useful to launch a messagebox asynchronously.

By default, all silverlight messagebox are synchronous but... there is a solution.

Solution

One might consider reimplementing the messagebox, it is a possibility, but we will see today that it is possible to access advanced features of MessageBox through one back door, thanks to our friend XNA!

If you look at the Microsoft.Xna.Framework.GameServices assembly, you will notice that the Guide object has methods quite interesting:


BeginShowMessageBox !

This method displays a native and asynchronously messagebox with parameters:

  • title: Title of the message box
  • text: text to be displayed in the message box
  • buttons: Legends associated with the buttons on the message box. The maximum number of buttons is two.
  • focusButton: 0-based index that defines the button highlighted.
  • icon: Type icon in the message box.
  • callback: method to call when the asynchronous operation is complete.
  • STATE: The unique user-created that identifies this request.

Title and text match mutually the parameters "caption" and "messageboxtext" of Silverlight.

One difference here: the text can not exceed 256 characters, otherwise an exception is thrown.

Buttons is here much more advanced than our Silverlight MessageBox, we can specify the button text, for example, we can modify the "ok" and "cancel" text like that :



 Microsoft.Xna.Framework.GamerServices.Guide.BeginShowMessageBox(
"Quizz",
"What is your favorite Windows Phone?",
new string[] { "Nokia Lumia 820", "Nokia Lumia 920" },
0,
Microsoft.Xna.Framework.GamerServices.MessageBoxIcon.Alert,
null,
null);

This offers us a lot of new possibilities!

But be careful to localize your buttons!

How to make synchronous messagebox again?

Able to have a dialog asynchronous's pretty cool, but in most cases, we expect it to be synchronous. To do this simply to retrieve the result of the asynchronous call and wait for its execution.

 IAsyncResult result = Microsoft.Xna.Framework.GamerServices.Guide.BeginShowMessageBox(
"Quizz",
"What is your favorite Windows Phone?",
new string[] { "Nokia Lumia 820", "Nokia Lumia 920" },
0,
Microsoft.Xna.Framework.GamerServices.MessageBoxIcon.None,
null,
null);
 
result.AsyncWaitHandle.WaitOne();

and here we have a native, synchronous and customizable message box !

Test result of the dialog

If you want to test the result of your dialog box (which button was clicked), simply call the method EndShowMessageBox :

 int? choice = Microsoft.Xna.Framework.GamerServices.Guide.EndShowMessageBox(result);
if(choice.HasValue)
{
if(choice.Value==0)
{
//user clicks the first button
}
}

Summary

  • Add reference Microsoft.Xna.Framework.GameServices
  • Write the following code:


 IAsyncResult result = Microsoft.Xna.Framework.GamerServices.Guide.BeginShowMessageBox(
"Quizz",
"What is your favorite Windows Phone?",
new string[] { "Nokia Lumia 820", "Nokia Lumia 920" },
0,
Microsoft.Xna.Framework.GamerServices.MessageBoxIcon.None,
null,
null);
 
result.AsyncWaitHandle.WaitOne();
 
int? choice = Microsoft.Xna.Framework.GamerServices.Guide.EndShowMessageBox(result);
if(choice.HasValue)
{
if(choice.Value==0)
{
//User clicks on the first button
}
}

How to remove the messagebox sound?

To remove the beep or the vibration, just change the icon... Ok I know this is not great logic, but that's how. In fact it should be understood that XNA is a common platform between Windows, Xbox and Windows Phone. In the windows world, we are used to display icons 'warning', 'alert', etc. .. left of the dialog box, which is not super top for a mobile display or width of the screen is already binding. The distinction between a normal dialog and a dialog box warning / alert, is therefore the sound / vibration. To remove the sound, we just have to set the type to None.

 Microsoft.Xna.Framework.GamerServices.Guide.BeginShowMessageBox(
"Quizz",
"What is your favorite Windows Phone?",
new string[] { "Nokia Lumia 820", "Nokia Lumia 920" },
0,
Microsoft.Xna.Framework.GamerServices.MessageBoxIcon.None,
null,
null);
1606 page views in the last 30 days.
×