Tag Archives: vc++

Under the hood Part 4 : C++ WinRT Component DLL & C++ XAML application – WinRT, Windows 8, C++, Metro

Calling WinRT Component from C++

We have developed a C++ WinRT Component DLL & C#.NET application in the post here Under the hood Part 1 : C++ WinRT Component DLL & C#.NET Metro application

we have seen the compiler generated components for making the C# application access the C++ WinRT component here Under the hood Part 2 : C++ WinRT Component DLL & C#.NET Metro application

We have seen the packaging and installation process that happens in the background during building and deploying of the applications here Under the hood Part 3 : WinRT, Windows 8, C++, C#.NET, Metro, WinRT Component DLL

Going further, I created a C++ Metro application and accessed the C++ WinRT Component DLL from this application. The interesting part here is that C++ applications is XAML based. No more .RC and resource.h files in C++ (for metro). In the previous post, we created a WinRT C++ DLL that contains a class calculatorSample. Now let us create  a C++ application to consume the C++ WinRT DLL.

To get started with creating a C++ XAML application, go to Visual Studio 2011 –> Solution Explorer–> New Project –> Go to Installed Templates section –> Visual C++ –>Select Application and name it as CPPApplication1 as shown in the following fig 1.

image

Fig 1: Creating a C++ XAML application.

Right click on the project, click on Add References and the following dialog shown in figure 2 comes up.

image

Fig 2: Reference manager dialog to add references to another components.

Click on Solution section –> Projects and Select  CppWinRTComponentDLL –> click on Add button and click on Close as shown in figure 3.

image

Fig 3: Selecting WinRT CppWinRTComponentDLL.

The CppWinRTComponentDLL reference appears in the References section as shown in the following figure 4.

image

Fig 4: CppWinRTComponentDLL dll appears in the References section.

Goto MainPage.xaml.cpp and include the namespace for CppWinRTComponentDLL

Code Snippet
using namespace CppWinRTComponentDll;

 

Then create an object of calculatorSample on the heap using ref new. In this scenario, ref new  is like cocreateinstance of COM. It’s a smart allocator. we also use ref class to indicate the authoring of a Windows Runtime class . using ^ to represent a “refcounted” pointer in ZW fits quite well

The following code shows how to use the ref new expression to create a new reference-counted Windows Runtime object. Note that you use the ^ (“hat”) symbol instead of the pointer dereference operator (*) when declaring the variable, but that you use the familiar -> operator to access the objects instance members. Note also that you do not call delete explicitly on the object. The object will be destroyed deterministically when the last remaining copy of it goes out of scope. At the lowest level, the object is basically a COM object owned by a smart pointer.

Code Snippet
CalculatorSample^ calcobj = ref new  CalculatorSample();
txtAddResult->Text = calcobj->Add(10,20).ToString();

 

So from the C++ application, we are calling the C++ Windows Runtime Component DLL. This is all native code. C++ calling C++ and everything is ref counted.

Compiler options: /ZW enable WinRT language extensions /AI<dir> add to assembly search path <dir> is the folder where the compiler searches the winmd files /FU<file> forced using assembly/module force the inclusion of the specified winmd file /D "WINAPI_FAMILY=2" set this define to compile against the ModernSDK subset of Win32

Linker options: /APPCONTAINER[:NO] marks the executable as runnable in the appcontainer (only) /WINMD[:{NO|ONLY}] emits a winmd; if “ONLY” is specified, does not emit the executable, but just the winmd /WINMDFILE:filename name of the winmd file to emit /WINMDDELAYSIGN[:NO] /WINMDKEYCONTAINER:name /WINMDKEYFILE:filename used to sign the winmd file

However, in a Metro style app or Windows Runtime component, all the C++ code is native. The /ZW compiler option causes the Component Extensions to be compiled for Windows Runtime. The /cli compiler option causes them to be compiled for C++/CLI. Currently, C++/CLI is not supported for Metro style apps

Code snippet of the complete MainPage class.

Code Snippet
//
// MainPage.xaml.cpp
// Implementation of the MainPage.xaml class.
//

#include "pch.h"
#include "MainPage.xaml.h"

using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Data;
using namespace CPPApplication1;

using namespace CppWinRTComponentDll;

MainPage::MainPage()
{
    InitializeComponent();

      CalculatorSample^ calcobj = ref newCalculatorSample();
    txtAddResult->Text = calcobj->Add(10,20).ToString();

    int result;
    HRESULT hr = calcobj->__cli_Add(20,30,&result);
    txtAddResult->Text = result.ToString();
}

MainPage::~MainPage()
{
}

All Windows Runtime types derive from the universal base class Platform::Object. There is therefore an implicit conversion from any Windows Runtime object to Platform::Object.

Code snippet of the XAML page.

Code Snippet
<UserControl x:Class="CPPApplication1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008&quot;
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
    mc:Ignorable="d"
    d:DesignHeight="768" d:DesignWidth="1366">
    
    <Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
        <TextBox x:Name="txtAddResult" HorizontalAlignment="Left" Text="TextBox" VerticalAlignment="Top" Margin="343,90,0,0" Width="212"/>
        <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="Calling C++ component Add method from C++ XAML Application" VerticalAlignment="Top" Margin="81,90,0,0" Height="45" Width="258" FontSize="14" FontWeight="Bold"/>

    </Grid>
    
</UserControl>

 

Build the solution and deploy the application. The application output is as follows.image

Configuration settings:

Enable Windows Runtime Extensions enables the runtime extensions throughout the type system which includes the ability to do Boxing. I.e. Boxing to WinRT type system. Every fundamental types and WinRT types are derived from Platform.Object.image

heap-allocated objects with heap semantics:

Calculator^ calc = ref new Calculator(); // Calculator is a ref class from a custom WinRT component

txtResult->Text = calc->Add(10, 20).ToString();

The ^syntax will fire a destructor when the refcount on the object drops to 0, or if you explicitly call delete. (So if you handed the object out it’s not necessarily at the end of your scope)

heap-allocated objects with Stack semantics:

Calculator calc;

txtResult->Text = calc.Add(10, 20).ToString();

Both of those create heap-allocated objects behind the scenes, but the difference is whether you logically have heap semantics vs. stack semantics.

The stack syntax will fire a destructor when the object goes out of scope (or on an exception etc.). This is important when you e.g. handed of the object to another thread or async callback, so there may still be a refcount on it, but you need to get rid of it right away. (E.g. a file handle that needs to be closed otherwise the file is locked). The main advantage is exception-safe deterministic destruction.

PS: Because of the nature of refcounting, it’s a little bit less important with WinRT to have deterministic destruction than with e.g. the /clr and a garbage collected heap (where the point of destruction is virtually random). However, you will find that with async patterns it is common to get into a situation where you’re transfer the ownership of an object from one thread to another (e.g. via a lambda). There is then a race condition between the two threads for releasing the object. This is generally still ok, but if the object represents a file or other exclusive resource it might be critical to perform the destruction at a specific time, rather than relying on the timing between the two threads.

value classes & Ref classes

Int32 x(15); // Compiles and x is initialized and works as expected.

String str("test1"); // Doesn’t compile and compiler complains C3149: ‘Platform::String’ : cannot use this type here without a top-level ‘^’

Int32 is a value class, and String or the custom winRT component are all ref class. They are different.

Differences between C++/CLI and WinRT C++

In terms of the differences like flags are as follows.

Basic types:
/clr: From mscorlib.dll (System::* types)
/ZW: From vccorlib.dll (Platform::* types)

Lifetime management:
/clr: Garbage collected
/ZW: Refcounted

Cycles Broken:
/clr: By garbage collector
/ZW: Broken by user (weak references or explicit delete)

Code generation:
/clr: MSIL + native code. Can create a cross-platform binary if MSIL-only.
/ZW: Native code only. Binaries target a specific platform.

Object Creation:
/clr: gcnew
/ZW: ref new

interior_ptr:
/clr: Supported
/ZW: Not supported

pin_ptr:
/clr: Supported
/ZW: Not supported

V% (% when it refers to a byref (kind’a like an "interior_ref") ):
/clr: Supported
/ZW: Not supported

R% (% when it refers to an implicitly dereferenced ref type):
/clr: Supported
/ZW: Supported

Ref to ^:
/clr: R^%
/ZW: R^&

Boxing:
/clr: syntax V^
/ZW: IReference<V>^

Dereferenced box type:
/clr: V%
/ZW: const V

Generics:
/clr: Generics classes, interfaces & delegates allowed.
/ZW: Generic interfaces & delegates only.

Static constructors:
/clr: Supported
/ZW: Not supported

Address of member of ref class:
/clr: Returns an interior_ptr
/ZW: Returns a type*

friends:
/clr: Not supported
/ZW: Supported

C++ class embedded in ref class:
/clr: Not supported
/ZW: Supported

ref class embedded in C++ class:
/clr: Not supported
/ZW: Supported (R-on-stack)

^ embedded in C++ class:
/clr: Not supported (Needs GCHandle)
/ZW: Supported

^ embedded in value class with value class on native heap:
/clr: Not supported
/ZW: Supported (for String^)

Global ^:
/clr: Not supported
/ZW: Supported

Global R-on-stack:
/clr: Not supported
/ZW: Supported

Finalizer:
/clr: Supported
/ZW: Not supported

Destructor:
/ZW: Runs on IDisposable::Dispose (delete / stack unwind) only
/clr: Runs on IDisposable::Dispose (delete / stack unwind) -or- last release (never both)

T::typeid:
/clr: Supported
/ZW: Not supported

R-on-stack (ref class on stack) syntax is supported on C++/cli and C++/CX, but you’ll notice that unfortunately the /CX implementation in the developer preview release has a code generation bug that will make it impractical to test this right now. (R^ and R% should be fine though). The most important reason for R-on-stack is exception-safe destruction (Like ‘using’ gives you in C#) – other than that it is purely compiler syntactic sugar.

Download the source code here.

"If one advances confidently in the direction of his dreams, and endeavors to live the life which he has imagined, he will meet with success unexpected in common hours." — Henry David Thoreau

Advertisements

Design & Develop for the present and future – WinRT, .NET, C++, HTML5

A collection of useful information from the web.

With the new Windows 8, Metro , WinRT and other stuff coming out of Microsoft, the question is when should we care about Metro and WinRT from a development perspective? Here is the information from different sources like Gartner, Magenic, etc. that I found useful.

As per Research, Windows Phone will be No. 2 smartphone OS by 2015 according to Gartner, IDC.  The question to ask is how long it will take until Windows 8 is finally out and reached a critical mass. Coming to desktops, a lot of machines out there still run Windows XP. Windows 7 is way better and I guess the transition to Windows 8 will take even longer. Windows 8 will probably mainly pushed by non-PC multi-touch consumer devices in the near future. Win8 will probably RTM in time for hardware vendors to create, package, and deliver all sorts of machines for the 2012 holiday season. So probably somewhere between July and October 2012.

Understanding of some of the new common terms:

  • Windows 8 – the new operating system that runs in a “dual mode”: Desktop (Win32) and WinRT
  • Win32 – the OS API that supports today’s applications in Win8
  • WinRT – the new OS API that supports future applications
  • Metro – a user experience design language often used when building WinRT applications.
  • “WinRT apps” includes any/all apps written on the WinRT API.
  • “Metro apps” that are probably a WinRT app, that also follows the Metro user experience guidelines.

For consumer apps this means you might care about Win8 now, because you might want to make sure your cool app is in the Win8 online store for the 2012 launch. So you will start writing code using Windows 8 Runtime, Metro and bunch of other tools.

For business apps the timing is quite different. Corporations roll out a new OS much later than consumers get it through retailers. As an example, Windows 7 has now been out for about three years, but some corporations still use Windows XP!!! So for business apps, we can look at doing a reasonable amount of Win8 Metro development around 2014-2015.

Attached is the Technology Comparison Chart:image

* Note: combinations of factors not listed here may point to two or more UI technologies being needed.

  1. If touch is needed in the future, application can be designed to Metro style standards.
  2. Windows 8 phones are planned to be supported with Metro applications.
  3. HTML5/JS Metro applications could be selected if there is an internal skill set for that technology.
  4. WebForms are generally considered an older technology, in general use ASP MVC unless there is a compelling reason to use WebForms.
  5. For applications not in the app store, a deployment system will be needed.
  6. Mono may make app store approval more difficult.
  7. Windows Phone 7 leverages .NET skill sets.

Some of us will be lucky enough to work for "type A" companies that jump on new things as they come out, and we’ll get to build Metro apps starting in Q1- Q2 2012.

Most of us work for "type B" companies, and they’ll roll out a new OS after SP1 has been deployed by the "type A" companies – these are the companies that will deploy Win8 after has been out for 1-2 years.

Some unfortunate souls work for "type C" companies, and they’ll roll out Win8 when Win7 loses support (so around 2018?).  That’s a hard place to find yourself as a developer. Yet those companies do exist even today.

What does this all mean? It means that for a typical corporate or business developer, we have around 2-3 years from today before we’re building WinRT apps. The logical question to ask then (and you really should ask this question), is what do we do for the next 2-3 years? How do we build software between now and when we get to use Metro/WinRT? Obviously the concern is that if you build an app starting today, how do you protect that investment so you don’t have to completely rewrite the app in 3 years?

This flowchart by the Telerik guys sums it up pretty nicely.

image

Clearly any app that uses multiple windows or modal dialogs (or really any dialogs) will not migrate to Metro without some major rework. The one remaining concern is the new run/suspend/resume/terminate application model. Even Silverlight doesn’t use that model today – except on WP7. I think some thought needs to go into application design today to enable support for suspend in the future. I don’t have a great answer right at the moment, but I know that I’ll be thinking about it, because this is important to easing migrations in the future.

It is true that whatever XAML you use today won’t move to WinRT unchanged. Well, I can’t say that with certainty, but the reality is that WinRT exposes several powerful UI controls we don’t have today. And any Metro style app will need to use those WinRT controls to fit seamlessly into the Win8 world. For better compatibility with future versions of Windows, it seems sticking to the XAML path would be more beneficial. What does this mean for developers? Well, if you are on .NET today, you can simply start learning the new WinRT using the XAML/C#/VB route and start creating Metro apps. If you are a HTML/CSS/JS developer, ramp up on HTML5/CSS3 and the JavaScript extensions and frameworks available as well as the WinRT code. If you want to build an application that would run both on Windows 7 and Windows 8 you can create it with XAML and then for Windows 8 also provide a Metro XAML frontend. We will of course need to see how all of this comes together as we start getting more information out of Microsoft.

Conversion Strategies:

image

No existing technologies map directly to the WinRT platform. Figure 4 shows how existing technologies map to the Windows 8 development platform. As you can see, all existing technologies map directly to the Windows 8 desktop environment. This is illustrated by the green lines, indicating that these applications are expected to work in Windows 8 with no effort.

The yellow line for Silverlight indicates that many Silverlight applications can be migrated to WinRT with reasonable effort. We will discuss this in more detail later in the paper.

The red line for WPF indicates that migration to WinRT is possible, but will require more substantial effort.

The red dashed line for HTML indicates that development skills will transfer, and a limited amount of existing HTML, CSS, and code assets may apply to WinRT application development.

Applications written using existing technologies will require effort to migrate to WinRT. For applications written with technologies other than Silverlight and WPF, the term “rewrite” is probably more accurate than “migrate”.

In summary, Windows 8, WinRT, and Metro are a big deal. But not in the way most people seem to think. The .NET/C#/CLR/BCL story is evolutionary and just isn’t that big a deal. It is the user experience and application lifecycle story that will require the most thought and effort as we build software over the next several years. These are good challenges, and I very much look forward to building .NET applications that deeply integrate with Windows 8. People will ultimately be building business applications on WinRT. Those apps may or may not be strictly “Metro”, but by running on WinRT they’ll gain the benefits of the new runtime API, services, and application model.

Under the hood Part 3 : Internals of how the application is installed and run – WinRT, Windows 8, C++, C#.NET, Metro

Under the hood Part 3 : WinRT, Windows 8, C++, C#.NET, Metro, WinRT Component DLL

We have developed a C++ WinRT Component DLL & C#.NET application in the post here Under the hood Part 1 : C++ WinRT Component DLL & C#.NET Metro application

we have seen the compiler generated components for making the C# application access the C++ WinRT component here Under the hood Part 2 : C++ WinRT Component DLL & C#.NET Metro application

See the post on First Look at What’s New in Windows 8 here.

Going further, I created a C++ Metro application and accessed the C++ WinRT Component DLL from this application. The interesting part here is that C++ applications is XAML based. No more .RC and resource.h files in C++ (for metro). We will explore the C++ application in another post. In this post, let us walk through the packaging and installation process that happens in the background during building and deploying of the applications.

Basically, there are two registrations for our application.

  1. Extension registration
  2. Class registration.

The figure 1 (from Build con) shows the relation between the two.

image

Fig : Slide related to Extension Catalog and Class Catalog shown @ Build con.

Go to  Visual Studio 2011 –> Solution Explorer –> CSharpApplication project, here you can find a file named Package.appxmanifest as shown in figure 1 . This file has most of the information needed to deploy the application. This is the information that windows uses to identify the application. Package Name is the name used in most of the identification process.

image

Fig 1: Package.appxmanifest file in Visual Studio 2011 Solution Explorer.

Code snippet of Package.appxmanifest file.

Code Snippet
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
  <Identity Name="CSharpApplicationCallingCPPComponent" Publisher="CN=Kishore" Version="1.0.0.0" />
  <Properties>
    <DisplayName>CSharpApplication</DisplayName>
    <PublisherDisplayName>Kishore</PublisherDisplayName>
    <Logo>Images\StoreLogo.png</Logo>
    <Description>CSharpApplication</Description>
  </Properties>
  <Prerequisites>
    <OSMinVersion>6.2</OSMinVersion>
    <OSMaxVersionTested>6.2</OSMaxVersionTested>
  </Prerequisites>
  <Resources>
    <Resource Language="en-us" />
  </Resources>
  <Applications>
    <Application Id="App" Executable="csharpapplication.exe" EntryPoint="CSharpApplication.App">
      <VisualElements DisplayName="CSharpApplication" Logo="Images\Logo.png" SmallLogo="Images\SmallLogo.png" Description="CSharpApplication" ForegroundText="light" BackgroundColor="#222222" InitialRotationPreference="portrait">
        <SplashScreen Image="Images\SplashScreen.png" />
      </VisualElements>
    </Application>
  </Applications>
  <Capabilities>
    <Capability Name="internetClient" />
  </Capabilities>
</Package>

 

The applications implement contract like search contract, share, play queue contract. Those contract registrations are the extensions registration for the operating system.  Tile that you see in the Windows start page is just another contract activation. I,e windows.launch contract. So if you go to HKEY_CURRENT_USER\Software\Classes\Extensions\ContractId\Windows.Launch, you can find your application package id that we saw in figure 1. Everything under Windows.Launch is organized by package ID as shown in the figure 2 below.

image

Fig 2: Registry settings showing the registered Extensions.

From figure 2, we can see our package HKEY_CURRENT_USER\Software\Classes\Extensions\ContractId\Windows.Launch\ PackageId\csharpapplicationcallingcppcomponent_1.0.0.0_x86_neutral_kb63pw67p0swp. This package has a  ActivatableClassId key . Under that we see App as shown in figure 3. This is the class registration for this extension. image

Fig 3: App registry settings for your application.

Let us see how the class registration for the applications looks like. First, We have extensions which say I implement this contract for ex I implement this launch and then we have classes. The extensions point to the classes. classes are actually the implementation. All applications are just Windows Runtime objects to the Windows OS, this is where all it starts. This is the windows runtime class that the OS knows about for your application.

The interesting part is in the class registration for the application. If we go up in the registry editor, we should see a registry key called ActivatableClasses at  HKEY_CURRENT_USER\Software\Classes\ActivatableClasses, this is where the class registrations are for all of our applications are. Here again we find package. All extensions, all classes are organized based on the package. That means our application or package has unique set of classes and they don’t share extension points or classes with other applications. They are all unique for our app. If we expand it, we see ActivatableClassId, the same name we saw in extensions. Here we should find the App classId. This is the WinRT class registration. This is the same for all types of applications, libraries etc.

Here we can see some registration attributes . The ActivationType is an important one. Windows Runtime supports two activation styles.

  1. InProcess activation
  2. Out of process activation

So Windows Runtime supports InProcess activation where we provide the DLL and windows load that into the process and it also supports out of process activation, where we will provide an exe and windows will launch the exe as your class implementation.

Registry key values:

ActivationType = 1 indicates its out of process activation class. out of process classes have a server. we have to know where the executable is, so there is a server registion here.

ActivationType = 0 indicates its in process activation

Out of process has a server and so there is a server registration here. Server with value App.AppXpdnr4x0evrk1yjmz5xfw2ksncfcjc5er.mca as shown in figure 4.image

Fig 4: Server registry values for your application.

In figure 3, below the ActivationType , we can find Server attribute and it contains the App.AppXpdnr4x0evrk1yjmz5xfw2ksncfcjc5er.mca we got from the above Server value.  The server registration, tells the windows runtime enough information about what code we actually need to get from the disk and start running to get the app up and running. The ExePath attribute gives the path to the exe.

Windows runtime supports two apartment models. MTA & STA. If you have worked in VC++ COM, COM+ earlier, then you might have programmed the components for Multi Threaded Apartment model & Single Threaded Apartment model.

Let us see some more ActivatableClassId entries for Windows Runtime present at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsRuntime as shown in figure 5.

image

Fig 5: Windows Runtime classes information.

Finally, the slide that caught my attention was the deployment pipeline process shown in Fig 6 that shows the overall view of the above mentioned information.

image

Figure 6 showing the role of the deployment engine @ Build Con.

"Only those who risk going too far can possibly find out how far they can go." – T.S. Eliot

Under the hood Part 2 : C++ WinRT Component DLL & C#.NET Metro application

We have developed a C++ WinRT Component DLL & C#.NET application in the post here Under the hood Part 1 : C++ WinRT Component DLL & C#.NET Metro application

The important point here is that the  C# application is accessing the C++ WinRT component through RCW mechanism. The same application can be developed with JavaScript also that can use the C++ DLL that we developed. Wow, cool right? 

To understand the simplicity of the new programming model, we created a C++ WinRT Component DLL in part 1, which is all the code you need to author a Windows Runtime component.

Please download the code and extract the files.

Code Snippet
#pragma once

using namespace Windows::Foundation;

namespace CppWinRTComponentDll
{

    public ref class CalculatorSample sealed
    {
    public:
        int Add(int x, int y);
        int Sub(int x, int y);
        int Mul(int x, int y);

    };
}

In this example, you will immediately notice some keywords that are not part of standard C++. Visual C++ defines a few Component Extensions that, in a Metro style app, are essentially syntactic sugar over the underlying COM calls involved in creating and consuming Windows Runtime types. You typically use these extensions in the public interfaces where your code is passing Windows Runtime types back and forth across the ABI to JavaScript, C#, or Visual Basic (or even another C++ module). Visual C++ provides a variety of implicit conversions between Windows Runtime types and standard C++ types. The typical pattern is to use standard C++ types and libraries internally as usual, and convert to Windows Runtime types in the public interfaces.

So how did the C++ component get pulled into .net application? When we build the CppWinRTComponentDll project, we see the following in the output window. Notice the highlighted CppWinRTComponentDll.winmd text. This means the compiler is generating a file of type windmd.

1>—— Build started: Project: CppWinRTComponentDll, Configuration: Debug Win32 ——
1>  CppWinRTComponentDll.vcxproj -> C:\Users\Kishore\Documents\Visual Studio 11\Projects\CppWinRTComponentDll With CSharp App\Debug\CppWinRTComponentDll\CppWinRTComponentDll.winmd
1>  LINK : C:\Users\kishore\Documents\Visual Studio 11\Projects\CppWinRTComponentDll With CSharp App\Debug\CppWinRTComponentDll\CppWinRTComponentDll.dll not found or not built by the last incremental link; performing full link
1>     Creating library C:\Users\kishore\Documents\Visual Studio 11\Projects\CppWinRTComponentDll With CSharp App\Debug\CppWinRTComponentDll\CppWinRTComponentDll.lib and object C:\Users\kishore\Documents\Visual Studio 11\Projects\CppWinRTComponentDll With CSharp App\Debug\CppWinRTComponentDll\CppWinRTComponentDll.exp
1>  CppWinRTComponentDll.vcxproj -> C:\Users\kishore\Documents\Visual Studio 11\Projects\CppWinRTComponentDll With CSharp App\Debug\CppWinRTComponentDll\CppWinRTComponentDll.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

You can notice the CppWinRTComponentDll.winmd file in the debug folder (CppWinRTComponentDll With CSharp App\Debug\CppWinRTComponentDll) as shown in Figure 1.

image

Fig 1: .WinMD File present in CppWinRTComponentDll folder inside the Debug folder.

This WinMD file is essentially a CLI meta data file and can be opened in ILDASM as shown in figure 2. CppWinRTComponentDll is exposed using API metadata present in CppWinRTComponentDll.winmd file. The format of WinMD file is Ecma-335 and this is the same format used by the .NET framework. It just used the ECMA-335 file format standard & the framework and nothing more than that. The underlying binary contract makes it easy for us to access the CppWinRTComponentDll APIs directly in the development language of our choice. The shape and structure of the CppWinRTComponentDll APIs can be understood by both static languages such as C# and dynamic languages such as JavaScript. IntelliSense is available in JavaScript, C#, Visual Basic, and C++ as you can see in the C# application (CSharpApplication project).

image

Fig 2: Opening CppWinRTComponentDll.winmd file using ILDASM.

This CppWinRTComponentDll.winmd file is created by c++ compiler and this can be seen as a cross language header file because c# cannot understand c++ header and neither JavaScript. so we need to have the file format that all languages understand and that is the .winmd file format. Although we authored a CalculatorSample class, what the compiler did for us is that, it also created a interface __ICalculatorSamplePublicNonVirtuals as shown in figure 3, which is the com interface used to talk to the calculator class. This adds it to the public surface.image

Fig 3: Interface ICalculatorSamplePublicNonVirtuals created by the compiler

Manifest of the CppWinRTComponentDll.winmd file can be seen in figure 4.image

Fig 4: Manifest of the CppWinRTComponentDll.WinMD File. Note the first entry, mscorlib.

we can see the Add method signature stored in the WinmD file in figure 5.image

Figure 5: Add method signature present in CppWinRTComponentDll.winmd file.

Code Snippet
.method public newslot abstract virtual instance int32
Add(int32 x,
int32 y) cil managed
{
} // end of method __ICalculatorSamplePublicNonVirtuals::Add

 

In the ILDASM, click on the .class interface private abstract auto ansi windowsruntime. The GUID attribute. this is like specifying the GUID of the interface as shown in figure 6. This is the GUID for the component.

image

Fig 6: GUID of the interface.

The WinMD file does not contain any IL. This is just like a header information so that other languages can understand. This makes the Projections to happen. The calculator is a ref class itself. The CppWinRTComponentDll.CalculatorSample class implements from .__ICalculatorSamplePublicNonVirtuals and it implements Add,Sub and Mul methods as shown in the following figure 7.

image

Fig 7: CppWinRTComponentDll.CalculatorSample class implements from __ICalculatorSamplePublicNonVirtuals Interface.

Note that every object inside WinRT is ref counted.

Details about the C++ WinRT Component DLL created in part 1 (MSDN): C++/CX (Component Extensions)

Visual C++ in Visual Studio 11 for has a new programming model for creating Metro style apps and components. One of the primary features of the new model is the abstract binary interface, or ABI, which defines an interface for inter-language communication. In Windows Developer Preview, native C++ can communicate across the ABI with JavaScript and with the managed .NET languages C# and Visual Basic. This means you can create high-performance components in native C++ and consume them directly from one of these other languages. It also means you can consume Windows Runtime types directly in native C++, without having to interop with a managed layer as when you consume .NET Framework types.

At a low level, the new programming model is based on an updated version of COM, but the way that you program against this new model is more simple and natural than old-style COM programming. When you create a consumable Windows Runtime components or Metro style apps in native C++ you work primarily with classes and members just as in standard C++. JavaScript or .NET code instantiates your object by using new (or New) and the object is destroyed according to the mechanisms of the client language. When native C++ consumes a Windows Runtime object, destruction is handled by means of reference counting.

Download the code and extract the files.

"Cultivate optimism by committing yourself to a cause, a plan or a value system. You’ll feel that you are growing in a meaningful direction which will help you rise above day-to-day setbacks." — Dr. Robert Conroy

Note: The code is developed using Windows 8 & Visual Studio 2011 developer preview, which might change when the actual versions are released.

Under the hood Part 1 : C++ WinRT Component DLL & C#.NET application

In order to better understand  the concepts of WinRT, C#.NET, C++, etc. in the new Windows 8 environment, let us write some code. Then we will explore what happens under the hood when we compile code and run the applications. This will be explained in many parts as we progress.

First let us understand what WinRT is and what makes a WinRT DLL or WinRT component. There is no better place to start other than creating a WinRT component ourselves and examining it. So lets get started.

Creating a WinRT Component DLL:

Step 1:

Open VS 2011 Developer preview. Click on New Project. In the New Project Dialog, from Installed section, select Visual C++ in the left hand side navigation tree. Select WinRT Component DLL from the project templates and name the component as CppWinRTComponentDll. Click OK as shown in Fig 1.image

Fig 1: Selecting Visual C++ template for WinRT Component DLL project.

Note: As a test, I tried to create a component with name C++WinRTComponentDll and VS 2011 C++ compiler shows many errors in the class files created by the wizard. So try to avoid ++ in the names.

Glimpse of new Visual Studio 2011 Developer preview edition:

In the new Solution Explorer, hover over the files and for each file you will find that there is an icon on the far right edge; View additional information (Ctrl+Right) icon.
When you select an item in Solution Explorer, whether it be a file or class or method, etc., the icon appears on the right edge of the selection. The tooltip says "View additional information (Ctrl+Right)". Clicking on the icon will invoke the "View Additional Information" menu which, for class files and members will provide relationships that you can view in Solution Explorer. Examples include "Base/Derived Types", "Find References", "Call Hierarchy", Calls, Is Called By, Is Used By etc. as shown in the following Fig 2.

image

Fig 2: Figure showing the View additional information (Ctrl+Right)icon.

Step 2:

Goto WinRTComponent.cpp file and delete the WinRTComponent definitions. Goto WinRTComponent.h and delete some of the default code. The code of the .h & .cpp files will look as shown in the following code snippets.

Code Snippet
// WinRTComponent.cpp

#include "pch.h"
#include "WinRTComponent.h"

using namespace CppWinRTComponentDll;

 

Code Snippet
#pragma once

using namespace Windows::Foundation;

namespace CppWinRTComponentDll
{

}
// WinRTComponent.h

 

We need the namespace CppWinRTComponentDll. Everything in WinRT has to be part of a namespace because the resolution of the DLL is based on a namespace that the class is in and that’s how other programming languages will find the class based on namespaces and DLL name.

Let us declare a sealed class called CalculatorSample in  WinRTComponent.h as shown in the following code snippet. The class is sealed as we don’t want others to derive from it. Sealed means no Inheritance.

Code Snippet
public ref class CalculatorSample sealed
{
public:
    int Add(int x, int y);
    int Sub(int x, int y);
    int Mul(int x, int y);

};

 

Why use Ref in front of the class:

Previously some of us worked on COM and created COM components. For that we have to create an interface, we have to specify that we are deriving from IUnknown (or derived) , put this in an MIDL file, use the MIDL Compiler to generate files, then go to C++ component, implement this interface, then create a class factory for it to create an instance and register this component. and the list goes on.. Well, all of this is done by using the keyword Ref in front of the class. So here we are creating WinRT Component that is accessible by dynamic languages as well. Here we are saying that CalculatorSample is a ref class, a class for WinRT. In other words, a ref class is a user-defined class that can be passed across the ABI boundary.

Step 3:

In the WinRTComponent.cpp, define the CalculatorSample  class member functions as shown in the following code snippet.

Code Snippet
int CalculatorSample::Add(int x, int y)
{
    return x+y;
}

int CalculatorSample::Sub(int x, int y)
{
    return x-y;
}

int CalculatorSample::Mul(int x, int y)
{
    return x*y;
}

 

So by now we have declared and defined the methods for the WinRT class called CalculatorSample. This class can be used by C++,C#.NET, VB.NET, JavaScript apps.

To sum it up, the WinRTComponent.h file should have the following code.

Code Snippet
#pragma once

using namespace Windows::Foundation;

namespace CppWinRTComponentDll
{

    public ref class CalculatorSample sealed
    {
    public:
        int Add(int x, int y);
        int Sub(int x, int y);
        int Mul(int x, int y);

    };
}
// WinRTComponent.h

WinRTComponent.cpp file contains the following code.

Code Snippet
// WinRTComponent.cpp

#include "pch.h"
#include "WinRTComponent.h"

using namespace CppWinRTComponentDll;

int CalculatorSample::Add(int x, int y)
{
    return x+y;
}

int CalculatorSample::Sub(int x, int y)
{
    return x-y;
}

int CalculatorSample::Mul(int x, int y)
{
    return x*y;
}

Step 4:

Do not Compile the project. pch.h and pch.cpp are like stdafx.h and stdafx.cpp in VC++ MFC.

This completes the creation of a WinRT Component DLL.

Let us create a new application and try to access the WinRT Component DLL that we just created. For that, I will use C#.NET, so that we can know how to call a WinRT Component DLL from C#.NET application.

Right Click on the Solution CppWinRTComponentDll, Click on Add and select the New Project menu item as shown in Fig 3.

image

Fig 3: Adding  a New project to the CppWinRTComponentDll solution.

Select Visual C# –> Application template and name the project as CSharpApplication as shown in Fig 4.

 

image

Fig 4: Creating a Visual C# Application project in VS 2011 Developer Preview.

Step 5:

Add a reference to the WinRT C++ calculator class we created to the C#.NET application as shown in the following figures.

image

Fig 5: Right click on References folder and Select Add Reference…

image

Fig 6: Select Solution tab in the left hand side navigation panel and select Projects. You should be able to see the CppWinRTComponentDll that we just created. Select CppWinRTComponentDll and click on Add button. click Close and go to step 6 if you have not encountered any error.

If you have compiled the C++ DLL by mistake before adding the reference, you will get a Failed to add reference dialog as shown below.

image

Fig 7: Failed to add reference dialog.

To fix the Failed to add reference dialog issue, clean up the CppWinRTComponentDll project as shown in the following figure 8.

image

Fig 8: Right Click on CppWinRTComponentDll  project, select Project Only, then select Clean Only CppWinRTComponentDll

Now repeat step 5 again to add a reference to the CppWinRTComponentDll and you should see the green circle icon with tick inside it as shown in Fig 9. This means the component is successfully referenced in the project.

image

Fig 9: Component successfully referenced in the project.

Click close.

Step 6:

Open MainPage.xaml file and add three text boxes to show the result of addition, subtraction and multiplication values returned from the C++ WinRT Component DLL.

Add the following XAML code.

Code Snippet
       <TextBox x:Name="txtAdd" HorizontalAlignment="Left" Text="TextBox" VerticalAlignment="Top" Margin="582,97,0,0" Height="36" Width="246" FontSize="20"/>
        <TextBox HorizontalAlignment="Left" Text="Calling Add method of C++ WinRT Component DLL" VerticalAlignment="Top" Margin="114,97,0,0"/>
       
        <TextBox x:Name="txtSub" HorizontalAlignment="Left" Text="TextBox" VerticalAlignment="Top" Margin="582,180,0,0" Height="36" Width="246" FontSize="20"/>
        <TextBox HorizontalAlignment="Left" Text="Calling Sub method of C++ WinRT Component DLL" VerticalAlignment="Top" Margin="114,180,0,0"/>
        
        <TextBox x:Name="txtMul" HorizontalAlignment="Left" Text="TextBox" VerticalAlignment="Top" Margin="582,260,0,0" Height="36" Width="246" FontSize="20">
        </TextBox>
        <TextBox HorizontalAlignment="Left" Text="Calling Mul method of C++ WinRT Component DLL" VerticalAlignment="Top" Margin="114,260,0,0"/>

 

Step 7:

Open MainPage.xaml.cs file and add the following code.

To use the C++ WinRT Component DLL that we just created we need to specify it in the C#.NET project by mentioning using CppWinRTComponentDll;

In the MainPage(), add the following code.

Code Snippet
CalculatorSample calcobj = new CalculatorSample();
            txtAdd.Text = calcobj.Add(10,20).ToString();
            txtMul.Text = calcobj.Mul(10, 20).ToString();
            txtSub.Text = calcobj.Sub(20, 10).ToString();

 

The complete MainPage.xaml file XAML code is

Code Snippet
<UserControl x:Class="CSharpApplication.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008&quot;
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
    mc:Ignorable="d"
    d:DesignHeight="768" d:DesignWidth="1366">
    
    <Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
        <TextBox x:Name="txtAdd" HorizontalAlignment="Left" Text="TextBox" VerticalAlignment="Top" Margin="582,97,0,0" Height="36" Width="246" FontSize="20"/>
        <TextBox HorizontalAlignment="Left" Text="Calling Add method of C++ WinRT Component DLL" VerticalAlignment="Top" Margin="114,97,0,0"/>
       
        <TextBox x:Name="txtSub" HorizontalAlignment="Left" Text="TextBox" VerticalAlignment="Top" Margin="582,180,0,0" Height="36" Width="246" FontSize="20"/>
        <TextBox HorizontalAlignment="Left" Text="Calling Sub method of C++ WinRT Component DLL" VerticalAlignment="Top" Margin="114,180,0,0"/>
        
        <TextBox x:Name="txtMul" HorizontalAlignment="Left" Text="TextBox" VerticalAlignment="Top" Margin="582,260,0,0" Height="36" Width="246" FontSize="20">
        </TextBox>
        <TextBox HorizontalAlignment="Left" Text="Calling Mul method of C++ WinRT Component DLL" VerticalAlignment="Top" Margin="114,260,0,0"/>

    </Grid>
    
</UserControl>

 

The complete MainPage.xaml.cs file C#.NET code is

Code Snippet
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using CppWinRTComponentDll;

namespace CSharpApplication
{
    partial class MainPage
    {
        public MainPage()
        {
            InitializeComponent();

            CalculatorSample calcobj = new CalculatorSample();
            txtAdd.Text = calcobj.Add(10,20).ToString();
            txtMul.Text = calcobj.Mul(10, 20).ToString();
            txtSub.Text = calcobj.Sub(20, 10).ToString();
            

        }
    }
}

 

Step 8: Build the solution.

The following information will be displayed in the output window. See the highlighted information. The Visual Studio 2011 is compiling the projects as well as deploying the projects. Later, we will see in detail what happens during deployment and how the applications is run by Windows 8.

1>—— Build started: Project: CSharpApplication, Configuration: Debug Any CPU ——
1>  CSharpApplication -> C:\Users\Prathima\Documents\Visual Studio 11\Projects\CppWinRTComponentDll With CSharp App\CSharpApplication\bin\Debug\csharpapplication.exe
1>  CSharpApplication -> C:\Users\Prathima\Documents\Visual Studio 11\Projects\CppWinRTComponentDll With CSharp App\CSharpApplication\bin\Debug\CSharpApplication.build.appxrecipe
2>—— Deploy started: Project: CSharpApplication, Configuration: Debug Any CPU ——
========== Build: 1 succeeded, 0 failed, 1 up-to-date, 0 skipped ==========
========== Deploy: 1 succeeded, 0 failed, 0 skipped ==========

 

The output of the programs is the application

image

Download the source code from here.

"The future belongs to those who see possibilities before they become obvious."  – John Scully

Note: This code is developed using Windows 8 & Visual Studio 2011 developer preview, which might change when the actual versions are released.

ABCs of Data Binding

Building the presentation (User Interface) applications is all about displaying and manipulation of data. Well, WPF has a powerful feature to display data in UI controls that can be bound to the data present in our control (business) or entity (data) classes or any class data for that matter.

Suppose you have a class called person and it has a property  public string PersonName that you want to display in a text box. How do we bind these two objects together? Well, WPF’s DataBinding comes to the rescue. Each binding has these four components:

  • A binding target object
  • A target property
  • A binding source
  • A path to the value in the binding source to use.

For example,if you want to bind the content of a TextBox to the Name property of an employee object, your target object is the TextBox, the target property is the Text property, the value to use is EmployeeName, and the source object is the employee object. The following figure illustrates the concepts of DataBinding.

 

image

Figure 1: Components of DataBinding

Mode Property:

You use the Mode property to specify the direction of the binding, i.e. source -> target or target <- source. The following enumeration list shows the available options for binding

  • Default causes the default Mode value of target property to be used.
  • OneTime updates the target property only when the application starts or when the DataContext undergoes a change.
  • OneWay updates the target property only when the source property changes.
  • TwoWay updates the target property or the property whenever either the target property or the source property changes.
  • OneWayToSource updates the source property when the target property changes.

UpdateSourceTrigger Property:

The UpdateSourceTrigger property of the binding determines what triggers the update of the source. If you a bind a variable to a control, then the data from the control can be transferred to the variable by using this property.

  • Default: Any of the following values (Depends on the control)
  • Explicit:The Source Value Gets Updated when the appications calls UpdateSource
  • LostFocus: The Source Value Gets Updated when the UIElement control loses focus
  • PropertyChanged:The Source Value Gets Updated when the user types in the UIElement control

Following is the code of the employee class that exposes a property called EmployeeName that we want to bind to the textbox control. To make binding happen, the following should be implemented on the data class.

  1. Derive the class exposing the properties from INotifyPropertChanged.
  2. Declare the event. Ex: public event PropertyChangedEventHandler PropertyChanged;
  3. Call OnPropertyChanged nd pass the property name whenever the property is updated Ex: OnPropertyChanged("EmployeeName");
  4. Create the OnPropertyChanged method to raise the event. Ex:
            protected void OnPropertyChanged(string name)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(name));
                }
            }
Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using System.Windows.Documents;
  9. using System.Windows.Input;
  10. using System.Windows.Media;
  11. using System.Windows.Media.Imaging;
  12. using System.Windows.Navigation;
  13. using System.Windows.Shapes;
  14. using System.ComponentModel;
  15.  
  16. namespace Bindingtoclasses
  17. {
  18.     public partial class MainWindow : Window
  19.     {
  20.         public MainWindow()
  21.         {
  22.             InitializeComponent();
  23.             Employee P = new Employee("Hello World");
  24.             this.DataContext = P;
  25.         }
  26.     }
  27.  
  28.     // This class implements INotifyPropertyChanged to support one-way and two-way bindings
  29.     // (such that the UI element updates when the source has been changed dynamically)
  30.     public class Employee : INotifyPropertyChanged
  31.     {
  32.         private string name;
  33.         // Declare the event
  34.         public event PropertyChangedEventHandler PropertyChanged;
  35.  
  36.         public Employee()
  37.         {
  38.         }
  39.  
  40.         public Employee(string value)
  41.         {
  42.             this.name = value;
  43.         }
  44.  
  45.         public string EmployeeName
  46.         {
  47.             get { return name; }
  48.             set
  49.             {
  50.                 name = value;
  51.                 // Call OnPropertyChanged whenever the property is updated
  52.                OnPropertyChanged("EmployeeName");
  53.             }
  54.         }
  55.  
  56.         //// Create the OnPropertyChanged method to raise the event
  57.         protected void OnPropertyChanged(string name)
  58.         {
  59.             PropertyChangedEventHandler handler = PropertyChanged;
  60.             if (handler != null)
  61.             {
  62.                 handler(this, new PropertyChangedEventArgs(name));
  63.             }
  64.         }
  65.     }
  66.  
  67. }

The XAML code to bind the class property to the textbox controls is as follows. To make binding happen, the following should be implemented in the XAML code.

  1. First we need to create an object of the employee class in XAML in the parent element. Ex:
    <Grid.Resources>
            <src:Employee x:Key="myDataSource" EmployeeName="Kishore1021"/>
    </Grid.Resources>

  2. Instead of creating an object in XAML, we can also use DataContext property, create an employee object in the code and assign it to the DataContext as follows
            public MainWindow()
            {
                InitializeComponent();
                Employee P = new Employee("Hello World");
                this.DataContext = P;
            }

  3. I used both in the following sample . Line 16 and 17 uses the local object created in XAML and line 18 uses the DataContext and so directly uses the property name. More info on DataContext in the coming blogs.
  4. Use the Binding Markup Extension “{Binding}” and key in the parameters. In Line 16, I am binding the TextBox.Text to myDataSource object and in that object, I am binding to EmployeeName and the source gets updated when the property gets changed. So as you type, the text in textbox2 also gets changed.
  5. Line 17 also uses the same concept as above except that it doesn’t update the source as the user types. Since the default value of updateSourceTrigger binding property is LostFocus, the textbox1 gets updated only when textbox2 loses focus.
  6. Line 18 uses DataContext and so uses the EmployeeName property directly and binds to textbox3.
    Code Snippet
    1. <Window x:Class="Bindingtoclasses.MainWindow"
    2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quot;
    4.         xmlns:src="clr-namespace:Bindingtoclasses"
    5.  
    6.         Title="MainWindow" Height="350" Width="525">
    7.     <Grid>
    8.         <Grid.Resources>
    9.                 <src:Employee x:Key="myDataSource" EmployeeName="Kishore1021"/>
    10.         </Grid.Resources>
    11.         <Grid.RowDefinitions>
    12.             <RowDefinition Height="*"></RowDefinition>
    13.             <RowDefinition Height="*"></RowDefinition>
    14.             <RowDefinition Height="*"></RowDefinition>
    15.         </Grid.RowDefinitions>
    16.         <TextBox Grid.Row="0" Text="{Binding Source={StaticResource myDataSource}, Path=EmployeeName, UpdateSourceTrigger=PropertyChanged}"/>
    17.         <TextBox Grid.Row="1" Text="{Binding Source= {StaticResource myDataSource}, Path=EmployeeName}"></TextBox>
    18.         <TextBox Grid.Row="2" Text="{Binding Path=EmployeeName}"></TextBox>
    19.         
    20.     </Grid>
    21. </Window>

The output of the program is as follows

image

Download code from Microsoft Skydrive :

Direct Link : https://skydrive.live.com/redir.aspx?cid=38ecce05b21b8b44&amp;resid=38ECCE05B21B8B44!394&amp;parid=38ECCE05B21B8B44!393

"If you’re riding ahead of the herd, take a look back every now and then to make sure it’s still there" – Will Rogers

Data Binding from the eyes of an VC++ developer

Having worked in VC++, MFC for more than a decade and getting to work on .NET WPF projects for a couple of years gave me an insight into the inner workings of data binding concepts in WPF.

Data binding in the user interface layer is nothing new. It has been around for quite some time, in various UI platforms, both for desktop and Web applications. The basic idea is that you "bind" the visual elements (controls) in a user interface to the data objects they are meant to display. The binding infrastructure then manages the data interactions from then on, so that modifications to the UI controls are reflected in the data objects, and vice versa. The major benefit of using data binding is that it reduces the amount of code the application developer needs to write.

Lets see how Data Binding is done in MFC:

In MFC, we have lot of great design concepts introduced like document/view, message mapping, dialog data routines and many more. DDX (Dialog Data Exchange) and DDV (Dialog Data Validation) are two great tools that allow us to easily set and access the values of MFC controls. DDX encapsulates the transfer of data between class member variables and dialog controls in a single place. Data Dialog Validation functions allow you to let Windows automatically restrict the values allowed within a control and is an easy way to validate data entry in the controls.

There are three main parts to DDX; UpdateData, DoDataExchange and the DDX-DDV functions (global functions) listed below from afxdd_.h.

  1. // simple text operations
  2. void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, BYTE& value);
  3. void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, short& value);
  4. void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, int& value);
  5. void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, UINT& value);
  6. void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, long& value);
  7. void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, DWORD& value);
  8. void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, LONGLONG& value);
  9. void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, ULONGLONG& value);
  10. void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, CString& value);
  11. void AFXAPI DDX_Text(_Inout_ CDataExchange* pDX, _In_ int nIDC, _Out_z_cap_(nMaxLen) LPTSTR value, _In_ int nMaxLen);
  12. void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, float& value);
  13. void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, double& value);
  14. void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, COleCurrency& value);
  15. void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, COleDateTime& value);
  16. void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, GUID& value);
  17. void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, DECIMAL& value);
  18. void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, FILETIME& value);
  19.  
  20. // special control types
  21. void AFXAPI DDX_Check(CDataExchange* pDX, int nIDC, int& value);
  22. void AFXAPI DDX_Radio(CDataExchange* pDX, int nIDC, int& value);
  23. void AFXAPI DDX_LBString(CDataExchange* pDX, int nIDC, CString& value);
  24. void AFXAPI DDX_CBString(CDataExchange* pDX, int nIDC, CString& value);
  25. void AFXAPI DDX_LBIndex(CDataExchange* pDX, int nIDC, int& index);
  26. void AFXAPI DDX_CBIndex(CDataExchange* pDX, int nIDC, int& index);
  27. void AFXAPI DDX_LBStringExact(CDataExchange* pDX, int nIDC, CString& value);
  28. void AFXAPI DDX_CBStringExact(CDataExchange* pDX, int nIDC, CString& value);
  29. void AFXAPI DDX_Scroll(CDataExchange* pDX, int nIDC, int& value);
  30. void AFXAPI DDX_Slider(CDataExchange* pDX, int nIDC, int& value);
  31.  
  32. void AFXAPI DDX_IPAddress(CDataExchange* pDX, int nIDC, DWORD& value);
  33.  
  34. void AFXAPI DDX_MonthCalCtrl(CDataExchange* pDX, int nIDC, CTime& value);
  35. void AFXAPI DDX_MonthCalCtrl(CDataExchange* pDX, int nIDC, COleDateTime& value);
  36. void AFXAPI DDX_MonthCalCtrl(CDataExchange* pDX, int nIDC, FILETIME& value);
  37. void AFXAPI DDX_DateTimeCtrl(CDataExchange* pDX, int nIDC, CString& value);
  38. void AFXAPI DDX_DateTimeCtrl(CDataExchange* pDX, int nIDC, CTime& value);
  39. void AFXAPI DDX_DateTimeCtrl(CDataExchange* pDX, int nIDC, COleDateTime& value);
  40. void AFXAPI DDX_DateTimeCtrl(CDataExchange* pDX, int nIDC, FILETIME& value);
  41.  
  42. // for getting access to the actual controls
  43. void AFXAPI DDX_Control(CDataExchange* pDX, int nIDC, CWnd& rControl);
  44.  
  45. /////////////////////////////////////////////////////////////////////////////
  46. // Standard Dialog Data Validation routines
  47.  
  48. // range – value must be >= minVal and <= maxVal
  49. // NOTE: you will require casts for 'minVal' and 'maxVal' to use the
  50. //   UINT, DWORD or float types
  51. void AFXAPI DDV_MinMaxByte(CDataExchange* pDX, BYTE value, BYTE minVal, BYTE maxVal);
  52. void AFXAPI DDV_MinMaxShort(CDataExchange* pDX, short value, short minVal, short maxVal);
  53. void AFXAPI DDV_MinMaxInt(CDataExchange* pDX, int value, int minVal, int maxVal);
  54. void AFXAPI DDV_MinMaxLong(CDataExchange* pDX, long value, long minVal, long maxVal);
  55. void AFXAPI DDV_MinMaxUInt(CDataExchange* pDX, UINT value, UINT minVal, UINT maxVal);
  56. void AFXAPI DDV_MinMaxDWord(CDataExchange* pDX, DWORD value, DWORD minVal, DWORD maxVal);
  57. void AFXAPI DDV_MinMaxLongLong(CDataExchange* pDX, LONGLONG value, LONGLONG minVal, LONGLONG maxVal);
  58. void AFXAPI DDV_MinMaxULongLong(CDataExchange* pDX, ULONGLONG value, ULONGLONG minVal, ULONGLONG maxVal);
  59. void AFXAPI DDV_MinMaxFloat(CDataExchange* pDX, float const& value, float minVal, float maxVal);
  60. void AFXAPI DDV_MinMaxDouble(CDataExchange* pDX, double const& value, double minVal, double maxVal);
  61.  
  62. // special control types
  63. void AFXAPI DDV_MinMaxSlider(CDataExchange* pDX, DWORD value, DWORD minVal, DWORD maxVal);
  64. void AFXAPI DDV_MinMaxDateTime(CDataExchange* pDX, CTime& refValue, const CTime* refMinRange, const CTime* refMaxRange);
  65. void AFXAPI DDV_MinMaxDateTime(CDataExchange* pDX, COleDateTime& refValue, const COleDateTime* refMinRange, const COleDateTime* refMaxRange);
  66. void AFXAPI DDV_MinMaxMonth(CDataExchange* pDX,    CTime& refValue, const CTime* pMinRange, const CTime* pMaxRange);
  67. void AFXAPI DDV_MinMaxMonth(CDataExchange* pDX, COleDateTime& refValue, const COleDateTime* refMinRange, const COleDateTime* refMaxRange);
  68.  
  69.  
  70. // number of characters
  71. void AFXAPI DDV_MaxChars(CDataExchange* pDX, CString const& value, int nChars);
  72.  
  73. /////////////////////////////////////////////////////////////////////////////

 

 

The framework calls CWnd::DoDataExchange to exchange and validate dialog data.

protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

** Note that DoDataExchange is a virtual function.

You need to override this member function DoDataExchange if you wish to utilize the framework’s automatic data exchange and validation. An implementation of DoDataExchange is shown below. I added a control variable and a data variable of type string to an edit control whose ID is IDC_EDIT1 .

void CMfcSampleDialog::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_EDIT1, controlvar);
    DDX_Text(pDX, IDC_EDIT1, strvariable);
}

It’s to be noted that DoDataExchange is never called directly, it’s called by the CWnd::UpdateData member function found in afxwin.h. UpdateData sets up an object called a CDataExchange that holds information about the direction of the transfer and so on and passes this to DoDataExchange to do the work. The body of DoDataExchange is generally just a whole lot of DDX (and DDV) calls.

Following is the declaration of CWnd::UpdateData member function found in afxwin.h

// Dialog Data support
public:
    BOOL UpdateData(BOOL bSaveAndValidate = TRUE);

UpdateData is called to initialize data in a dialog box, or to retrieve and validate dialog data. The bSaveAndValidate flag indicates whether a dialog box is being initialized (set bSaveAndValidate = FALSE) or data is being retrieved (set bSaveAndValidate = TRUE). The framework automatically calls UpdateData with bSaveAndValidate set to FALSE when a modal dialog box is created in the default implementation of CDialog::OnInitDialog. The call occurs before the dialog box is visible. The default implementation of CDialog::OnOK calls this member function with bSaveAndValidate set to TRUE to retrieve the data, and if successful, will close the dialog box.

To validate data, for ex, if the edit box should allow only 10 chars, then the following validation routine takes care of it.

DDV_MaxChars(pDX, m_streditcontrolvariable, 10);

DataBinding in WPF:

WPF provides a simple and powerful way to auto-update data between the user-data  and the user interface. This mechanism is called DataBinding. Every time when the data of your class model changes, it automatically reflects the updates to the user interface and vice versa. This is similar to UpdateData in c++ and in WPF it’s related to bringing data to the user interface. Data binding in WPF is ubiquitous and seamless. It is so powerful and flexible that it literally forces you to change the way you think about designing and developing user interfaces. With one simple API you can bind to domain/business objects, XML data, visual elements, ADO.NET data containers, collections, and basically anything else you can think of. You can use value converters to execute arbitrary data manipulation operations when bound values are passed back and forth. You can perform data validation by creating custom validation rules and applying them to a binding. The list goes on. Data binding in WPF is really a huge step forward.

Binding is a markup extension. When you use the binding extension to declare a binding, the declaration consists of a series of clauses following the Binding keyword and separated by commas (,).

<TextBox Grid.Row="0" Text="{Binding Source={StaticResource myDataSource}, Path=PONumber, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Grid.Row="1" Text="{Binding Source= {StaticResource myDataSource}, Path=PONumber}"></TextBox>
<TextBox Grid.Row="2" Text="{Binding Path=PONumber}"></TextBox>

The clauses in the binding declaration can be in any order and there are many possible combinations. The clauses are Name=Value pairs where Name is the name of the Binding property and Value is the value you are setting for the property. Data binding can also mean that if an outer representation of the data in an element changes, then the underlying data can be automatically updated to reflect the change. For example, if the user edits the value in a TextBox element, the underlying data value is automatically updated to reflect that change.

When creating binding declaration strings in markup, they must be attached to the specific dependency property of a target object. The above example shows how to bind the TextBox.Text property using the binding extension, specifying the Source and Path properties.

The source of a databinding can be a normal .NET property or a DependencyProperty. The target property of the binding must be a DependencyProperty.

To make the databinding properly work, both sides of a binding must provide a change notification that tells the binding when to update the target value. On normal .NET properties this is done by raising the PropertyChanged event of the INotifyPropertyChanged interface. On DependencyProperties it is done by the PropertyChanged callback of the property metadata

 

  

image

As illustrated by the above figure, data binding is essentially the bridge between the binding target and the binding source. The figure demonstrates the following fundamental WPF data binding concepts:

  • Typically, each binding has these four components: a binding target object, a target property, a binding source, and a path to the value in the binding source to use. For example, if you want to bind the content of a TextBox to the Name property of an PurchaseOrders object, your target object is the TextBox, the target property is the Text property, the value to use is PONumber, and the source object is the PurchaseOrders object.

  • The target property must be a dependency property. Most UIElement properties are dependency properties and most dependency properties, except read-only ones, support data binding by default. (Only DependencyObject types can define dependency properties and all UIElements derive from DependencyObject.)

  • Although not specified in the figure, it should be noted that the binding source object is not restricted to being a custom CLR object. WPF data binding supports data in the form of CLR objects and XML. To provide some examples, your binding source may be a UIElement, any list object, a CLR object that is associated with ADO.NET data or Web Services, or an XmlNode that contains your XML data.

Direction of the Data Flow

Databinding can be unidirectional (source -> target or target <- source), or bidirectional (source <-> target). As mentioned previously and as indicated by the arrow in the figure above, the data flow of a binding can go from the binding target to the binding source (for example, the source value changes when a user edits the value of a TextBox) and/or from the binding source to the binding target (for example, your TextBox content gets updated with changes in the binding source) if the binding source provides the proper notifications.

You may want your application to enable users to change the data and propagate it back to the source object. Or you may not want to enable users to update the source data. You can control this by setting the Mode property of your Binding object.

  • OneWay binding causes changes to the source property to automatically update the target property, but changes to the target property are not propagated back to the source property. This type of binding is appropriate if the control being bound is implicitly read-only. For instance, you may bind to a source such as a stock ticker or perhaps your target property has no control interface provided for making changes, such as a data-bound background color of a table. If there is no need to monitor the changes of the target property, using the OneWay binding mode avoids the overhead of the TwoWay binding mode.

  • TwoWay binding causes changes to either the source property or the target property to automatically update the other. This type of binding is appropriate for editable forms or other fully-interactive UI scenarios. Most properties default to OneWay binding, but some dependency properties (typically properties of user-editable controls such as the Text property of TextBox and the IsChecked property of CheckBox) default to TwoWay binding. A programmatic way to determine whether a dependency property binds one-way or two-way by default is to get the property metadata of the property using GetMetadata and then check the Boolean value of the BindsTwoWayByDefault property.

  • OneWayToSource is the reverse of OneWay binding; it updates the source property when the target property changes. One example scenario is if you only need to re-evaluate the source value from the UI.

  • OneTime binding, which causes the source property to initialize the target property, but subsequent changes do not propagate. This means that if the data context undergoes a change or the object in the data context changes, then the change is not reflected in the target property. This type of binding is appropriate if you are using data where either a snapshot of the current state is appropriate to use or the data is truly static. This type of binding is also useful if you want to initialize your target property with some value from a source property and the data context is not known in advance. This is essentially a simpler form of OneWay binding that provides better performance in cases where the source value does not change.

You use the Mode property to specify the direction of the binding. The following enumeration list shows the available options for binding updates (to be precise):

  • TwoWay updates the target property or the property whenever either the target property or the source property changes.

  • OneWay updates the target property only when the source property changes.

  • OneTime updates the target property only when the application starts or when the DataContext undergoes a change.

  • OneWayToSource updates the source property when the target property changes.

  • Default causes the default Mode value of target property to be used.

Note that to detect source changes (applicable to OneWay and TwoWay bindings), the source must implement a suitable property change notification mechanism such as INotifyPropertyChanged. To implement INotifyPropertyChanged you need to declare the PropertyChanged event and create the OnPropertyChanged method. Then for each property you want change notifications for, you call OnPropertyChanged whenever the property is updated.

What Triggers Source Updates

Bindings that are TwoWay or OneWayToSource listen for changes in the target property and propagate them back to the source. This is known as updating the source. For example, you may edit the text of a TextBox to change the underlying source value. As described in the last section, the direction of the data flow is determined by the value of the Mode property of the binding.

However, does your source value get updated while you are editing the text or after you finish editing the text and point your mouse away from the TextBox? The UpdateSourceTrigger property of the binding determines what triggers the update of the source. If the UpdateSourceTrigger value is PropertyChanged, then the value pointed to by the right arrow of TwoWay or the OneWayToSource bindings gets updated as soon as the target property changes. However, if the UpdateSourceTrigger value is LostFocus, then that value only gets updated with the new value when the target property loses focus.

Similar to the Mode property, different dependency properties have different default UpdateSourceTrigger values. The default value for most dependency properties is PropertyChanged, while the Text property has a default value of LostFocus. This means that source updates usually happen whenever the target property changes, which is fine for CheckBoxes and other simple controls. However, for text fields, updating after every keystroke can diminish performance and it denies the user the usual opportunity to backspace and fix typing errors before committing to the new value. That is why the Text property has a default value of LostFocus instead of PropertyChanged.

 

UpdateSourceTrigger value

When the Source Value Gets Updated

Example Scenario for TextBox

LostFocus (default for TextBox.Text)

When the TextBox control loses focus

A TextBox that is associated with validation logic

PropertyChanged

As you type into the TextBox

TextBox controls in a chat room window

Explicit

When the application calls UpdateSource

TextBox controls in an editable form (updates the source values only when the user clicks the submit button)

 

Databinding is typically done in XAML by using the {Binding} markup extension. The following example shows a simple binding between the text of a TextBox and a property of a class:

Download code from Microsoft Skydrive

Lead and inspire people. Don’t try to manage and manipulate people. Inventories can be managed but people must be lead. –Ross Perot