<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Marius Bancila's Blog &#187; C++</title>
	<atom:link href="http://mariusbancila.ro/blog/tag/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://mariusbancila.ro/blog</link>
	<description>Sharing my opinions and ideas!</description>
	<lastBuildDate>Mon, 14 Nov 2011 07:19:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>WinRT and winmd Files</title>
		<link>http://mariusbancila.ro/blog/2011/10/30/winrt-and-winmd-files/</link>
		<comments>http://mariusbancila.ro/blog/2011/10/30/winrt-and-winmd-files/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 19:15:40 +0000</pubDate>
		<dc:creator>Marius Bancila</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[CTPs & Betas]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[WinRT]]></category>
		<category><![CDATA[C++/CX]]></category>
		<category><![CDATA[ildasm]]></category>
		<category><![CDATA[managed]]></category>
		<category><![CDATA[native]]></category>
		<category><![CDATA[win8]]></category>
		<category><![CDATA[winmd]]></category>
		<category><![CDATA[winrt]]></category>

		<guid isPermaLink="false">http://mariusbancila.ro/blog/?p=1162</guid>
		<description><![CDATA[If you tried the Win8 Developer Preview and built WinRT components (native or managed) you noticed the .winmd files. The name stands for Windows Meta Data and the format of these files is the same used by the .NET framework for the CLI, i.e. ECMA-335. That means you can actually read these files with a [...]]]></description>
			<content:encoded><![CDATA[<p>If you tried the Win8 Developer Preview and built WinRT components (native or managed) you noticed the <strong>.winmd</strong> files. The name stands for Windows Meta Data and the format of these files is the same used by the .NET framework for the CLI, i.e. <a href="http://www.ecma-international.org/publications/standards/Ecma-335.htm">ECMA-335</a>. That means you can actually read these files with a tool such as ILDASM or Reflector, or of course, through .NET Reflection.</p>
<p>If you look in C:\Windows\System32\WinMetadata folder you&#8217;ll find the WinMD files for the Windows Runtime. You can browse the content of these files with one of the aforementioned disassemblers.<br />
<img alt="" src="/blog/wp-content/uploads/2011/10/winmetadatafolder.png" title="WinMetadata folder" class="alignnone" width="856" height="601" /></p>
<p>Here are two dummy WinRT components, one developed in C++/CX and one in C#.</p>
<table>
<tr>
<td>Native WinRT component in C++/CX</td>
<td>Managed WinRT component in C#</td>
</tr>
<tr valign="top">
<td>
<pre class="cpp" name="code">
namespace WinRTNativeComponent
{
    public ref class MyWinRTComponent sealed
    {
        int _id;
		String^ _name;

    public:
		MyWinRTComponent () {}
		~MyWinRTComponent () {}

        property int Id
        {
            int get() { return _id; }
            void set(int value) { _id = value; }
        }

		property String^ Name
		{
			String^ get() {return _name;}
			void set(String^ value) { _name= value; }
		}

        bool Update(int id, String^ name)
		{
			{
				if(_id == id)
				{
					_name = name;
					return true;
				}

				return false;
			}
		}
    };
}
</pre>
</td>
<td>
<pre class="csharp" name="code">
namespace WinRTManagedComponent
{
    public sealed class MyWinRTComponent
    {
        public int Id { get; set; }
        public string Name { get; set; }

        bool Update(int id, string name)
        {
            if (Id == id)
            {
                Name = name;
                return true;
            }

            return false;
        }
    }
}
</pre>
</td>
</tr>
</table>
<p>In the case of the native component, the output includes a DLL and a WINMD file (and of course a PDB file). In the case of the managed component, the output is either a DLL only or a WINMD only (plus the associated PDB file), depending on the Output type as defined in the project properties. If the type is <strong>Class Library</strong> the output is a DLL; this is enough if your component is supposed to be consumed from a managed language. However, if the component should be consumed from C++/CX or Javascript, then the project type must be set to <strong>WinMD File</strong>. In this case the DLL is replaced by a WinMD file, that contains, at least in the current version, both the matadata (as implied by the name) and the implementation.</p>
<table>
<tr>
<td>Native WinRT component in C++/CX</td>
<td>Managed WinRT component in C#</td>
</tr>
<tr valign="top">
<td><img alt="" src="/blog/wp-content/uploads/2011/10/winmdnative.png" title="WinMD for native component" class="alignnone" width="419" height="600" /></td>
<td><img alt="" src="/blog/wp-content/uploads/2011/10/winmdmanaged.png" title="WinMD for managed component" class="alignnone" width="419" height="600" /></td>
</tr>
</table>
<p>It should be possible to use reflection with winmd files. However, the reflection capabilities of .NET 4.5 in this developer preview seem to be very limited. The only available Load method in the Assembly class is</p>
<pre class="csharp" name="code">
public static Assembly Load(AssemblyName assemblyRef);
</pre>
<p>Trying to load the winmd file fails with a FailLoadException with the message &#8220;Could not load file or assembly &#8216;Winmdreflection, ContentType=WindowsRuntime&#8217; or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0&#215;80131515)&#8221;.</p>
<pre class="csharp" name="code">
try
{
    var assembly = Assembly.Load(
        new AssemblyName()
        {
            Name = "WinRTManagedComponent",
            ContentType = AssemblyContentType.WindowsRuntime
        });
}
catch (Exception ex)
{
}
</pre>
<p>It is possible though to read information for the types described in an winmd file in native code using the  <a href="http://msdn.microsoft.com/en-us/library/ms230172.aspx">IMetaDataImport</a>/<a href="http://msdn.microsoft.com/en-us/library/ms232953.aspx">IMetaDataImport2</a> COM interfaces. You can find an example <a href="http://social.msdn.microsoft.com/Forums/en-AU/winappswithnativecode/thread/211ef583-db11-4e55-926b-6d9ab53dbdb4">here</a>. But this has the drawback that you have to instantiate an object first and then query for its type information.</p>
<p>To use a Windows Runtime component in a Metro application (managed or native) you have to add a reference to it. That is pretty straight forward. In the following example I&#8217;m adding a reference in a C++ Metro application to the two WinRT components, one native and one managed, shown earlier. To do this, you can go to the project&#8217;s property page and open the Common Properties > Frameworks and References page, or use the References command from the project&#8217;s context menu which opens that page directly. You can add a reference to a project from the same solution, to a Windows component or you can browse for the winmd file.<br />
<img alt="" src="/blog/wp-content/uploads/2011/10/winmdreference.png" title="Adding a references to an winmd file" class="alignnone" width="800" height="556" /></p>
<p>Having done that you can instantiate the WinRT components.</p>
<pre class="cpp" name="code">
auto obj1 = ref new WinRTManagedComponent::MyWinRTComponent();
obj1->Id = 1;
obj1->Name = L"marius";

auto obj2 = ref new WinRTNativeComponent::MyWinRTComponent();
obj2->Id = 1;
obj2->Name = L"marius";
</pre>
]]></content:encoded>
			<wfw:commentRss>http://mariusbancila.ro/blog/2011/10/30/winrt-and-winmd-files/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Accessing 64-bit Native COM Server From a Managed Client</title>
		<link>http://mariusbancila.ro/blog/2011/10/19/accessing-64-bit-native-com-server-from-a-managed-client/</link>
		<comments>http://mariusbancila.ro/blog/2011/10/19/accessing-64-bit-native-com-server-from-a-managed-client/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 07:26:43 +0000</pubDate>
		<dc:creator>Marius Bancila</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[64bit]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[interop]]></category>
		<category><![CDATA[managed]]></category>
		<category><![CDATA[native]]></category>
		<category><![CDATA[tlbimp]]></category>
		<category><![CDATA[VisualStudio]]></category>

		<guid isPermaLink="false">http://mariusbancila.ro/blog/?p=1147</guid>
		<description><![CDATA[Not long ago I ran into a COM interop problem that was a bit tricky to fix. So I&#8217;m sharing the problem and the solution here in case others encounter the same problem. I had this native in-proc COM server that initially was built only for x86. It was used in a native MFC application [...]]]></description>
			<content:encoded><![CDATA[<p>Not long ago I ran into a COM interop problem that was a bit tricky to fix. So I&#8217;m sharing the problem and the solution here in case others encounter the same problem.</p>
<p>I had this native in-proc COM server that initially was built only for x86. It was used in a native MFC application as well as a C# Windows Forms application, where it was added as a COM reference. Both worked nicely. But then I needed to port the MFC app to the x64 platform, so I had to do the same with the in-proc COM server. They both worked correctly, but the managed app, which had to be available also both as 64-bit and 32-bit (even on 64-bit machines), was broken. Eventually I traced the problem to some COM method calls which were a bit atypical, because the arguments to the methods were not COM &#8220;native&#8221; types, but custom structures.</p>
<p>These structures looked like this:</p>
<pre class="cpp" name="code">
[uuid(6F13C84D-0E01-48cd-BFD4-F7071A32B49F)] struct S
{
      long a;
      BSTR b;
      long c;
      BSTR d;
      long e;
      BSTR f;
      BSTR g;
      BSTR h;
      BSTR i;
      long j;
      BSTR k;
      long l;
      BSTR m;
      long n;
};
</pre>
<p>and the COM method signature:</p>
<pre class="cpp" name="code">
[id(42)] HRESULT GetListOfStructs(SAFEARRAY(struct S)* arrRes);
</pre>
<p>When you add a COM reference to a .NET assembly, Visual Studio runs <a href="http://msdn.microsoft.com/en-us/library/tt0cf3sx.aspx">tlbimp.exe</a> to generate a .NET assembly with equivalent definitions to the type definitions found in the COM type library. This interop assembly is used to access the COM server. It contains Runtime Callable Wrappers that bridge the two worlds together. By default, the interop assembly, generated in the project&#8217;s output folder, is called <strong>Interop.&lt;comname&gt;Lib.dll</strong>. For instance if the COM server is called NativeCOMServer, the interop assembly is called Interop.NativeCOMServerLib.dll.</p>
<p>The wrapper that was generated in the interop assembly had the following signature for the aforementioned method:</p>
<pre class="cpp" name="code">
[DispId(42)]
void GetListOfStructs(ref Array arrRes);
</pre>
<p>and therefore used like this:</p>
<pre class="cpp" name="code">
System.Array result = null;
obj.GetListOfStructs(ref result);
</pre>
<p>The call was performed correctly, the native code was executing, but as soon as it was returning an access violation exception was occurring. Thanks to <a href="http://stackoverflow.com/questions/7517474/accessing-64-bit-com-server-from-managed-assembly-fails">Hans Passant</a> I figured the problem was rooted in the way Visual Studio generates the interop assembly. The generated RCW didn&#8217;t know how to handle the custom structure correctly. Probably different padding on the two sides generated the access violation. </p>
<p>The trick was to generate the interop assembly directly, as a custom build step in the COM server project, and include it as an assembly reference in the managed project. Here are the commands for the custom build (must to make sure you have the correct path to the 32-bit and the 64-bit version of tlbimp.exe):</p>
<pre>
<pathto32bittool>\TlbImp.exe $(TargetPath) /out:$(TargetDir)\NativeCOMLib.Interop.dll /primary  /keyfile:mykey.snk /machine:x86
<pathto64bittool>\TlbImp.exe $(TargetPath) /out:$(TargetDir)\NativeCOMLib.Interop.dll /primary  /keyfile:mykey.snk /machine:x64
</pre>
<p>The result was a wrapper with methods like this:</p>
<pre class="cpp" name="code">
[DispId(42)]
void GetListOfStructs(ref S[] arrRes);
</pre>
<p>which of course had to be called like this:</p>
<pre class="cpp" name="code">
S[] result = null;
obj.GetListOfStructs(ref result);
</pre>
<p>To include either one or the other in the C# project I had to manually change the project file, since Visual Studio does not know conditional references, a feature available in MSBuild. I didn&#8217;t build the managed app for Any CPU because it had to be able to run as 32-bit on 64-bit machines, so I had two configurations, one for x86 and one fore x64.</p>
<pre class="xml" name="code">
    &lt;Reference Condition=" '$(Platform)' == 'x86' " Include="NativeCOMServer.Interop,
               Version=1.0.0.0, Culture=neutral, PublicKeyToken=f5b9312191a42d52, processorArchitecture=x86">
      &lt;SpecificVersion>False&lt;/SpecificVersion>
      &lt;HintPath>..\Bin\NativeCOMServer.Interop.dll&lt;/HintPath>
    &lt;/Reference>
    &lt;Reference Condition=" '$(Platform)' == 'x64' " Include="NativeCOMServer.Interop,
               Version=1.0.0.0, Culture=neutral, PublicKeyToken=f5b9312191a42d52, processorArchitecture=x64">
      &lt;SpecificVersion>False&lt;/SpecificVersion>
      &lt;HintPath>..\Bin64\NativeCOMServer.Interop.dll&lt;/HintPath>
    &lt;/Reference>
</pre>
<p>But this time the wrappers were able to bridge the call and everything worked smoothly. </p>
<p>The lesson learned is that when you have COM custom structures you should not rely on the way Visual Studio generates the interop assembly. You should build the interop explicitly (maybe as a custom build step, like I did) and include it as an assembly reference to your managed project.</p>
]]></content:encoded>
			<wfw:commentRss>http://mariusbancila.ro/blog/2011/10/19/accessing-64-bit-native-com-server-from-a-managed-client/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C++, WinRT and Partial Classes</title>
		<link>http://mariusbancila.ro/blog/2011/10/13/cpp-winrt-and-partial-classes/</link>
		<comments>http://mariusbancila.ro/blog/2011/10/13/cpp-winrt-and-partial-classes/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 20:46:05 +0000</pubDate>
		<dc:creator>Marius Bancila</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[WinRT]]></category>
		<category><![CDATA[XAML]]></category>
		<category><![CDATA[C++/CX]]></category>
		<category><![CDATA[partial classes]]></category>
		<category><![CDATA[VisualStudio]]></category>
		<category><![CDATA[VS11]]></category>
		<category><![CDATA[winrt]]></category>

		<guid isPermaLink="false">http://mariusbancila.ro/blog/?p=1131</guid>
		<description><![CDATA[Partial classes are finally available to C++. Sort of. It&#8217;s not part of the new C++11 standard, it&#8217;s part of the C++/CX language developed by Microsoft for targeting WinRT on Windows 8. Partial classes mean that you can define a class spanned across several files. Why is this great? Because it allows developers and automatic [...]]]></description>
			<content:encoded><![CDATA[<p>Partial classes are finally available to C++. Sort of. It&#8217;s not part of the new C++11 standard, it&#8217;s part of the C++/CX language developed by Microsoft for targeting WinRT on Windows 8.</p>
<p>Partial classes mean that you can define a class spanned across several files. Why is this great? Because it allows developers and automatic code generator tools (such as designers) to edit parts of the same class without interfering one with another. WinRT allows C++ developers to write UI in XAML. This could not have been possible without the support for partial classes. </p>
<p>Partial classes:</p>
<ul>
<li>are available only for ref classes; native classes are not supported</li>
<li>are introduced with the <strong>partial</strong> keyword in all definitions but one</li>
</ul>
<p>Here is an example:</p>
<pre class="cpp" name="code">
// foo.private.h
#pragma once

partial ref class foo // <- here the partial keyword is used
{
private:
   int _id;
   Platform::String^ _name;
};
</pre>
<pre class="cpp" name="code">
// foo.public.h
#pragma once
#include "foo.private.h"

ref class foo // <- partial keyword is not used here
{
public:
   int GetId();
   Platform::String^ GetName();
};
</pre>
<pre class="cpp" name="code">
// foo.cpp
#include "pch.h"
#include "foo.public.h"

int foo::GetId() {return _id;}
Platform::String^ foo::GetName {return _name;}
</pre>
<p>What happens when you add a new page to a C++ Metro style application? The wizard generates three files: a XAML file and a header and cpp file as the code behind. Let's say the page is called MainPage. In this case the three files are MainPage.xaml (code below is a dummy example), MainPage.xaml.h and MainPage.xaml.cpp.</p>
<pre class="cpp" name="code">
&lt;UserControl x:Class="DemoApp.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="768" d:DesignWidth="1366"&gt;

    &lt;StackPanel Name="firstPanel"&gt;
        &lt;Button Name="firstButon" /&gt;
    &lt;/StackPanel&gt;

&lt;/UserControl&gt;
</pre>
<pre class="cpp" name="code">
//
// MainPage.xaml.h
// Declaration of the MainPage.xaml class.
//

#pragma once

#include "pch.h"
#include "MainPage.g.h"

namespace DemoApp
{
   public ref class MainPage
   {
      public:
         MainPage();
         ~MainPage();
   };
}
</pre>
<pre class="cpp" name="code">
//
// 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 DemoApp;

MainPage::MainPage()
{
   InitializeComponent();
}

MainPage::~MainPage()
{
}
</pre>
<p>You can notice that the objects <em>firstPanel</em> and <em>firstButton</em> are not defined in the header for MainPage and second, MainPage.xaml.h includes MainPage.g.h. So what is this? This is a designer generated file, which together with MainPage.g.cpp completes the definition of the MainPage ref class. These files are not generated until you start a build. After you do that you can find them in the output folder (Debug or Release for instance). This is how they look:</p>
<pre class="cpp" name="code">
#pragma once
//------------------------------------------------------------------------------
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
//------------------------------------------------------------------------------

namespace Windows {
    namespace UI {
        namespace Xaml {
            namespace Controls {
                ref class StackPanel;
                ref class Button;
            }
        }
    }
}

namespace DemoApp
{
    partial ref class MainPage : public Windows::UI::Xaml::Controls::UserControl,
                                                     public Windows::UI::Xaml::Markup::IComponentConnector
    {
    public:
        void InitializeComponent();
        void Connect(int connectionId, Platform::Object^ pTarget);

    private:
        Windows::UI::Xaml::Controls::StackPanel^ firstPanel;
        Windows::UI::Xaml::Controls::Button^ firstButon;
    };
}
</pre>
<pre class="cpp" name="code">
//------------------------------------------------------------------------------
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
//------------------------------------------------------------------------------
#include "pch.h"

#include "MainPage.xaml.h"

using namespace Windows::Foundation;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Markup;
using namespace MyDemoApplication1;

void MainPage::InitializeComponent()
{
    // Call LoadComponent on ms-resource://DemoApp/Files/MainPage.xaml
    Windows::UI::Xaml::Application::LoadComponent(this, ref new Windows::Foundation::Uri("ms-resource://DemoApp/Files/MainPage.xaml"));

    // Get the StackPanel named 'firstPanel'
    firstPanel = safe_cast&lt;Windows::UI::Xaml::Controls::StackPanel^&gt;(static_cast&lt;IFrameworkElement^&gt;(this)->FindName("firstPanel"));

    // Get the Button named 'firstButon'
    firstButon = safe_cast&lt;Windows::UI::Xaml::Controls::Button^&gt;(static_cast&lt;IFrameworkElement^&gt;(this)->FindName("firstButon"));

}

void MainPage::Connect(int connectionId, Platform::Object^ pTarget)
{
}
</pre>
<p>The following image illustrates the grouping of these files:<br />
<img alt="" src="/blog/wp-content/uploads/2011/10/cpppartialclass.png" title="C++/CX partial classes" class="alignnone" width="771" height="410" /><br />
MainPage.xaml is a XAML files, which can be edited both by the designer or manually by the developer (basically with the designer is still the developer that models the UI). The other files are C++/CX files. MainPage.xaml.h and MainPage.xaml.cpp are the files the developer writes, while MainPage.g.h and MainPage.g.cpp are edited by the designer. Do not modify the code in these files, because you could either mess up the designer, or all your changes would get lost when the file is regenerated.</p>
]]></content:encoded>
			<wfw:commentRss>http://mariusbancila.ro/blog/2011/10/13/cpp-winrt-and-partial-classes/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Windows Runtime</title>
		<link>http://mariusbancila.ro/blog/2011/09/15/windows-runtime/</link>
		<comments>http://mariusbancila.ro/blog/2011/09/15/windows-runtime/#comments</comments>
		<pubDate>Thu, 15 Sep 2011 20:54:16 +0000</pubDate>
		<dc:creator>Marius Bancila</dc:creator>
				<category><![CDATA[64bit]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[CTPs & Betas]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Windows Programming]]></category>
		<category><![CDATA[WinRT]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[metro]]></category>
		<category><![CDATA[MSDN]]></category>
		<category><![CDATA[runtime]]></category>
		<category><![CDATA[win32]]></category>
		<category><![CDATA[winrt]]></category>

		<guid isPermaLink="false">http://mariusbancila.ro/blog/?p=1116</guid>
		<description><![CDATA[Windows Runtime, or shortly WinRT, is a new runtime (siting on top of the Windows kernel) that allows developers to write Metro style applications for Windows 8, using a variety of languages including C/C++, C#, VB.NET or JavaScript/HTML5. Microsoft has started rolling out information about Windows 8 and the new runtime at BUILD. WinRT is [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://msdn.microsoft.com/en-us/library/windows/apps/br211377%28v=VS.85%29.aspx">Windows Runtime</a>, or shortly WinRT, is a new runtime (siting on top of the Windows kernel) that allows developers to write Metro style applications for Windows 8, using a variety of languages including C/C++, C#, VB.NET or JavaScript/HTML5. Microsoft has started rolling out information about Windows 8 and the new runtime at <a href="http://www.buildwindows.com/">BUILD</a>.</p>
<div class="wp-caption alignnone" style="width: 643px"><img alt="" src="http://i.zdnet.com/blogs/archslide.png" title="Windows 8" width="633" height="427" /><p class="wp-caption-text">(source www.zdnet.com)</p></div>
<p>WinRT is a native layer (written in C++ and being COM-based) that is intended as a replacement, or alternative, to Win32, and enables development of &#8220;immersive&#8221; applications, using the Metro style. Its API is object oriented and can be consumed both from native or managed languages, as well as JavaScript. At the same time the old Win32 applications will continue to run just as before and you can still (and most certainly will) develop Win32 applications.</p>
<p>Microsoft has created a new language called C++ Component Extension, or simply C++/CX. While the syntax is very similar to C++/CLI, the language is not managed, it&#8217;s still native. WinRT components built in C++/CX do not compile to managed code, but to 100% native code. A good news for C++ developers is that they can use XAML now to build the UI for immersive applications. However, this is not available for classical, Win32 applications.</p>
<p>You can get a glimpse of the new system and the tools by downloading and installing the <a href="http://msdn.microsoft.com/en-us/windows/apps/br229516">Windows Developer Preview with tools</a>, that includes the following:</p>
<ul>
<li>64-bit Windows Developer Preview</li>
<li>Windows SDK for Metro style apps</li>
<li>Microsoft Visual Studio 11 Express for Windows Developer Preview</li>
<li>Microsoft Expression Blend 5 Developer Preview</li>
<li>28 Metro style apps including the BUILD Conference app</li>
</ul>
<p>Notice this is a pre-beta release and you might encounter various problems.</p>
<p>Before you start here are several additional articles that you might want to read:</p>
<ul>
<li><a href="http://www.infoq.com/news/2011/09/WinRT-API">WinRT: An Object Orientated Replacement for Win32</a></li>
<li><a href="http://www.infoq.com/news/2011/09/C-Component-Extensions">C++ Component Extensions: The New Face of COM</a></li>
<li><a href="http://www.infoq.com/news/2011/09/DotNet-On-WinRT">C# and Visual Basic on the WinRT API</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh441569%28v=VS.85%29.aspx">Creating Windows Runtime Components in C++</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh441589%28v=VS.85%29.aspx">Tutorial: Creating and using extension SDKs</a></li>
<li><a href="http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-532T">Using the Windows Runtime from C++</a></li>
</ul>
<p>There are also several <a href="http://social.msdn.microsoft.com/Forums/en-US/category/windowsapps">new forums</a> available on MSDN forums for developing Metro style applications, which you can use for addressing technical questions. Hopefully thee will be answers from Microsoft people working in this area.</p>
]]></content:encoded>
			<wfw:commentRss>http://mariusbancila.ro/blog/2011/09/15/windows-runtime/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Display images as you type in C++</title>
		<link>http://mariusbancila.ro/blog/2011/08/04/display-images-as-you-type-in-cpp/</link>
		<comments>http://mariusbancila.ro/blog/2011/08/04/display-images-as-you-type-in-cpp/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 16:28:18 +0000</pubDate>
		<dc:creator>Marius Bancila</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[WIC]]></category>
		<category><![CDATA[winapi]]></category>

		<guid isPermaLink="false">http://mariusbancila.ro/blog/?p=1101</guid>
		<description><![CDATA[There was a question on Stackoverflow about a C++ project displaying an image as you type. Here is the original question: I am writing a very simple program in C++ that listens to keyboard input, but what I want to output is much more difficult than I expected. For every key I press, I want [...]]]></description>
			<content:encoded><![CDATA[<p>There was a <a href="http://stackoverflow.com/questions/6924597/how-do-i-link-c-visual-studio-2010-to-an-image-outputting-event-listener">question on Stackoverflow</a> about a C++ project displaying an image as you type. Here is the original question:</p>
<blockquote><p>I am writing a very simple program in C++ that listens to keyboard input, but what I want to output is much more difficult than I expected. For every key I press, I want an image (specific to the key) to appear on the screen. For example, let&#8217;s say if I press the &#8220;O&#8221; key, an image of Earth appears on my screen.</p></blockquote>
<p>It sounded like a fun exercise to do in C++ using Windows API. So here is my quick answer, a simple solution to the problem.</p>
<p>I wanted to display three different images, an earth, a moon and a sun, when the user types E, M or S in the window. The images should use transparency, so I decided to use PNG files. Here is how the images look.<br />
<img alt="" src="/blog/wp-content/uploads/2011/08/earth.png" title="earth" class="alignnone" width="128" height="128" /><br />
<img alt="" src="/blog/wp-content/uploads/2011/08/moon.png" title="moon" class="alignnone" width="128" height="128" /><br />
<img alt="" src="/blog/wp-content/uploads/2011/08/sun.png" title="sun" class="alignnone" width="128" height="128" /></p>
<p>A good option for loading PNG files is using <a href="http://msdn.microsoft.com/en-us/library/ee719654.aspx">Windows Imaging Component</a>. The point would be to add the PNG files to the project resources, then use WIC to load them and create an HBITMAP that would be used later to display the image. Bradley Grainger had just the right code on his <a href="http://code.logos.com/blog/2008/09/displaying_a_splash_screen_with_c_part_i.html">blog</a>. This is how it looks, except that I made some slight modifications to LoadImageFromResources (called LoadSplashImage on his blog).</p>
<pre name="code" class="cpp">
IStream* CreateStreamOnResource(LPCTSTR lpName, LPCTSTR lpType)
{
   IStream * ipStream = NULL;

   HRSRC hrsrc = FindResource(NULL, lpName, lpType);
   if (hrsrc == NULL)
      goto Return;

   DWORD dwResourceSize = SizeofResource(NULL, hrsrc);
   HGLOBAL hglbImage = LoadResource(NULL, hrsrc);
   if (hglbImage == NULL)
      goto Return;

   LPVOID pvSourceResourceData = LockResource(hglbImage);
   if (pvSourceResourceData == NULL)
      goto Return;

   HGLOBAL hgblResourceData = GlobalAlloc(GMEM_MOVEABLE, dwResourceSize);
   if (hgblResourceData == NULL)
      goto Return;

   LPVOID pvResourceData = GlobalLock(hgblResourceData);

   if (pvResourceData == NULL)
      goto FreeData;

   CopyMemory(pvResourceData, pvSourceResourceData, dwResourceSize);

   GlobalUnlock(hgblResourceData);

   if (SUCCEEDED(CreateStreamOnHGlobal(hgblResourceData, TRUE, &#038;ipStream)))
      goto Return;

FreeData:
   GlobalFree(hgblResourceData);

Return:
   return ipStream;
}

IWICBitmapSource* LoadBitmapFromStream(IStream * ipImageStream)
{
   IWICBitmapSource* ipBitmap = NULL;

   IWICBitmapDecoder* ipDecoder = NULL;
   if (FAILED(CoCreateInstance(CLSID_WICPngDecoder, NULL, CLSCTX_INPROC_SERVER,
                               __uuidof(ipDecoder), reinterpret_cast&lt;void**&gt;(&#038;ipDecoder))))
      goto Return;

   if (FAILED(ipDecoder->Initialize(ipImageStream, WICDecodeMetadataCacheOnLoad)))
      goto ReleaseDecoder;

   UINT nFrameCount = 0;
   if (FAILED(ipDecoder->GetFrameCount(&#038;nFrameCount)) || nFrameCount != 1)
      goto ReleaseDecoder;

   IWICBitmapFrameDecode* ipFrame = NULL;
   if (FAILED(ipDecoder->GetFrame(0, &#038;ipFrame)))
      goto ReleaseDecoder;

   WICConvertBitmapSource(GUID_WICPixelFormat32bppPBGRA, ipFrame, &#038;ipBitmap);
   ipFrame->Release();

ReleaseDecoder:
   ipDecoder->Release();
Return:
   return ipBitmap;
}

HBITMAP CreateHBITMAP(IWICBitmapSource* ipBitmap)
{
   HBITMAP hbmp = NULL;

   UINT width = 0;
   UINT height = 0;
   if (FAILED(ipBitmap->GetSize(&#038;width, &#038;height)) || width == 0 || height == 0)
      goto Return;

   BITMAPINFO bminfo;

   ZeroMemory(&#038;bminfo, sizeof(bminfo));
   bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
   bminfo.bmiHeader.biWidth = width;
   bminfo.bmiHeader.biHeight = -((LONG) height);
   bminfo.bmiHeader.biPlanes = 1;
   bminfo.bmiHeader.biBitCount = 32;
   bminfo.bmiHeader.biCompression = BI_RGB;

   void * pvImageBits = NULL;
   HDC hdcScreen = GetDC(NULL);
   hbmp = CreateDIBSection(hdcScreen, &#038;bminfo, DIB_RGB_COLORS, &#038;pvImageBits, NULL, 0);
   ReleaseDC(NULL, hdcScreen);
   if (hbmp == NULL)
      goto Return;

   const UINT cbStride = width * 4;
   const UINT cbImage = cbStride * height;
   if (FAILED(ipBitmap->CopyPixels(NULL, cbStride, cbImage, static_cast&lt;BYTE*>(pvImageBits))))
   {
      DeleteObject(hbmp);
      hbmp = NULL;
   }

Return:
   return hbmp;
}

HBITMAP LoadImageFromResources(LPCTSTR lpName, LPCTSTR lpType)
{
   HBITMAP hbmpSplash = NULL;

   IStream* ipImageStream = CreateStreamOnResource(lpName, lpType);
   if (ipImageStream == NULL)
      goto Return;

   IWICBitmapSource* ipBitmap = LoadBitmapFromStream(ipImageStream);
   if (ipBitmap == NULL)
      goto ReleaseStream;

   hbmpSplash = CreateHBITMAP(ipBitmap);
   ipBitmap->Release();

ReleaseStream:
   ipImageStream->Release();

Return:
   return hbmpSplash;
}
</pre>
<p>However for this to work the following are necessary:</p>
<pre name="code" class="cpp">
#include &lt;Objidl.h>
#include &lt;Wincodec.h>

#pragma comment (lib, "windowscodecs.lib")
</pre>
<p>Objidl.h is required for IStream, while Wincodec.h and windowscodecs.lib for WIC.</p>
<p>I have created a Win32 Project, called TypePictures. The wizard generates the backbone for the app, but I&#8217;ll not talk about that part. Besides adding the functions listed above, I also added the following:</p>
<pre name="code" class="cpp">
HWND g_hPictureWnd = NULL;
HBITMAP g_hbmp;
UINT_PTR g_timer = 0;
const TCHAR c_szPictureClass[] = _T("myPictureWindow");

ATOM RegisterPictureWindowClass(HINSTANCE hInstance);
BOOL CreatePictureWindow(HINSTANCE hInstance, HWND hOwner);
BOOL DestroyPictureWindow();
BOOL SetPicture(HBITMAP hbmp);
VOID CALLBACK PictureTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
</pre>
<p>hPictureWnd is the handle to the window that displays the image, g_timer is a timer used for automatically closing the window after a desire interval, and g_hbmp is the handle to the current loaded image.</p>
<p>RegisterPictureWindowClass registers the window class for the picture window. It uses the c_szPictureClass defined earlier for the class name.</p>
<pre name="code" class="cpp">
ATOM RegisterPictureWindowClass(HINSTANCE hInstance)
{
   WNDCLASSEX wcex = {0};

   wcex.cbSize = sizeof(WNDCLASSEX);

   wcex.lpfnWndProc	= DefWindowProc;
   wcex.cbClsExtra	= 0;
   wcex.cbWndExtra	= 0;
   wcex.hInstance	= hInstance;
   wcex.hIcon		= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TYPEPICTURES));
   wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
   wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
   wcex.lpszClassName	= c_szPictureClass;
   wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

   return RegisterClassEx(&#038;wcex);
}
</pre>
<p>This will be called in the main function before the call to InitInstance.</p>
<pre name="code" class="cpp">
RegisterPictureWindowClass(hInstance);
</pre>
<p>CreatePictureWindow is a function that creates the picture window. This will be a layered window that we&#8217;ll later update with <a href="http://msdn.microsoft.com/en-us/library/ms633556%28VS.85%29.aspx">UpdateLayeredWindow</a> when displayined the picture.</p>
<pre name="code" class="cpp">
BOOL CreatePictureWindow(HINSTANCE hInstance, HWND hOwner)
{
   if(g_hPictureWnd != NULL)
      return FALSE;

   RECT rcwin;
   GetWindowRect(hOwner, &#038;rcwin);

   g_hPictureWnd = ::CreateWindowEx(
      WS_EX_LAYERED,
      c_szPictureClass,
      NULL,
      WS_POPUP | WS_VISIBLE,
      rcwin.right+1, rcwin.top, 128, 128,
      hOwner,
      NULL,
      hInstance,
      NULL);

   return g_hPictureWnd != NULL;
}
</pre>
<p>DestroyPictureWindow does what the name implies, it destroys the layered window that displays the picture.</p>
<pre name="code" class="cpp">
BOOL DestroyPictureWindow()
{
   if(g_hPictureWnd == NULL)
      return FALSE;

   BOOL ret = DestroyWindow(g_hPictureWnd);
   g_hPictureWnd = NULL;

   return ret;
}
</pre>
<p>SetPicture is a key function that displays a bitmap in the layered window. It takes the bitmap that was loaded from an PNG with LoadImageFromResources and displays it in the layered window. As mentioned earlier it calls UpdateLayeredWindow to update the window.</p>
<pre name="code" class="cpp">
BOOL SetPicture(HBITMAP hbmp)
{
   if(g_hPictureWnd == NULL)
      return FALSE;

   BITMAP bm;
   GetObject(hbmp, sizeof(bm), &#038;bm);
   SIZE sizebmp = {bm.bmWidth, bm.bmHeight};

   HDC hdcScreen = GetDC(g_hPictureWnd);
   HDC hdcMem = CreateCompatibleDC(hdcScreen);
   HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcMem, hbmp);

   BLENDFUNCTION blend = { 0 };
   blend.BlendOp = AC_SRC_OVER;
   blend.SourceConstantAlpha = 255;
   blend.AlphaFormat = AC_SRC_ALPHA;

   RECT rcwin;
   GetWindowRect(g_hPictureWnd, &#038;rcwin);

   POINT ptSrc = {0};
   POINT ptDest = {rcwin.left, rcwin.top};

   UpdateLayeredWindow(
      g_hPictureWnd,
      hdcScreen,
      &#038;ptDest,
      &#038;sizebmp,
      hdcMem,
      &#038;ptSrc,
      RGB(0, 0, 0),
      &#038;blend,
      ULW_ALPHA);

   SelectObject(hdcMem, hbmpOld);
   DeleteDC(hdcMem);
   ReleaseDC(g_hPictureWnd, hdcScreen);

   return TRUE;
}
</pre>
<p>PictureTimerProc is the timer procedure we use to destroy the window after a specified interval since the last typed key elapsed.</p>
<pre name="code" class="cpp">
VOID CALLBACK PictureTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
   if(idEvent == g_timer)
   {
      ::KillTimer(hwnd, idEvent);
      g_timer = 0;

      DestroyPictureWindow();
   }
}
</pre>
<p>Make sure you call CoInitialize() to initialize the COM library for the main thread before the message loop begins in function main. Also make sure to call CoUninitialize() before the program ends.</p>
<p>WndProc is the function where the messages sent to the main window are processed. We&#8217;ll handle WM_CHAR, and when E, M or S are pressed we load the appropriate image, create the layered window for the picture if not already created, and set the picture in the window. This is how the code looks:</p>
<pre name="code" class="cpp">
   case WM_CHAR:
      {
         HBITMAP hbmp = NULL;
         switch((char)wParam)
         {
         case 'E': case 'e':
            hbmp = LoadImageFromResources(MAKEINTRESOURCE(IDB_PNG1), _T("PNG"));
            break;
         case 'M': case 'm':
            hbmp = LoadImageFromResources(MAKEINTRESOURCE(IDB_PNG2), _T("PNG"));
            break;
         case 'S': case 's':
            hbmp = LoadImageFromResources(MAKEINTRESOURCE(IDB_PNG3), _T("PNG"));
            break;
         default:
            break;
         }

         if(hbmp != NULL)
         {
            if(g_hbmp != NULL)
               DeleteObject(g_hbmp);
            g_hbmp = hbmp;

            if(g_hPictureWnd == NULL)
            {
               CreatePictureWindow(hInst, hWnd);
            }

            if(g_hPictureWnd != NULL)
            {
               if(SetPicture(hbmp))
               {
                  g_timer = SetTimer(hWnd, 1, 2000, PictureTimerProc);
                  SetFocus(hWnd);
               }
            }
         }
      }
      break;
</pre>
<p>And basically that is all. Just run the application and type E, M and S. You&#8217;ll see the images changing and 2 seconds after the last key is pressed the image is automatically hidden (as the layered window is destroyed).</p>
<p>You can download the source code from here: <a class="downloadlink" href="http://mariusbancila.ro/blog/wp-content/plugins/download-monitor/download.php?id=8" title="Version1.0 downloaded 154 times" >TypePictures (154)</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://mariusbancila.ro/blog/2011/08/04/display-images-as-you-type-in-cpp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Redefinition of &#8216;BOOKMARK&#8217;</title>
		<link>http://mariusbancila.ro/blog/2011/06/22/redefinition-of-bookmark/</link>
		<comments>http://mariusbancila.ro/blog/2011/06/22/redefinition-of-bookmark/#comments</comments>
		<pubDate>Wed, 22 Jun 2011 15:22:35 +0000</pubDate>
		<dc:creator>Marius Bancila</dc:creator>
				<category><![CDATA[64bit]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[MAPI]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[x64]]></category>

		<guid isPermaLink="false">http://mariusbancila.ro/blog/?p=1036</guid>
		<description><![CDATA[If you include in a VC++ project &#60;mapidefs.h&#62; and &#60;sqltypes.h&#62; and build for the x64 platform you get a redefinition error. #include &#60;Windows.h> #include &#60;MAPIDefS.h> #include &#60;sqltypes.h> int _tmain(int argc, _TCHAR* argv[]) { return 0; } 1>C:\Program Files\Microsoft SDKs\Windows\v6.0A\include\sqltypes.h(283) : error C2371: &#8216;BOOKMARK&#8217; : redefinition; different basic types 1> C:\Program Files\Microsoft SDKs\Windows\v6.0A\include\MAPIDefS.h(1142) : see declaration [...]]]></description>
			<content:encoded><![CDATA[<p>If you include in a VC++ project &lt;mapidefs.h&gt; and &lt;sqltypes.h&gt; and build for the x64 platform you get a redefinition error.</p>
<pre name="code" class="cpp">
#include &lt;Windows.h>
#include &lt;MAPIDefS.h>
#include &lt;sqltypes.h>

int _tmain(int argc, _TCHAR* argv[])
{
	return 0;
}
</pre>
<blockquote><p>1>C:\Program Files\Microsoft SDKs\Windows\v6.0A\include\sqltypes.h(283) : error C2371: &#8216;BOOKMARK&#8217; : redefinition; different basic types<br />
1>        C:\Program Files\Microsoft SDKs\Windows\v6.0A\include\MAPIDefS.h(1142) : see declaration of &#8216;BOOKMARK&#8217;
</p></blockquote>
<p>The reason is that BOOKMARK is defined in both files.</p>
<p>This is mapidefs.h</p>
<pre name="code" class="cpp">
typedef ULONG 		BOOKMARK;
</pre>
<p>This is sqltypes.h</p>
<pre name="code" class="cpp">
typedef SQLULEN         BOOKMARK;
</pre>
<p>On x86, both ULONG and SQLULEN are an unsigned long. However, on x64, ULONG is still unsigned long, but SQLULEN is an UINT64, which is different than unsigned long. Hence the error.</p>
<p>There is a Connect bug report called <a href="http://connect.microsoft.com/VisualStudio/feedback/details/100721/using-x64-with-mapidefs-h-and-sqltypes-h-causes-c2371">Using x64 with mapidefs.h and sqltypes.h causes C2371</a> filed by Martin Richter 6 years ago (!), with no fix yet. Martin proposed the following workaround:</p>
<pre name="code" class="cpp">
#undef BOOMARK
#define BOOMARK MAPI_BOOKMARK
#include &lt;mapidefs.h>
#undef BOOMARK
#define BOOMARK SQL_BOOKMARK
#include &lt;sqltypes.h>
#undef
</pre>
<p>However, it doesn&#8217;t work for me. I get the very same error. To get rid of the error you have to use namespaces. Define two namespaces, let&#8217;s call them MAPI and SQL and include each header in one of them. Then you can use the using namespace directive so that you don&#8217;t have to prefix everything with MAPI:: or SQL::. However, you&#8217;ll have to use the fully qualified name when you want to use one or the other BOOKMARK, as shown in the following example:</p>
<pre name="code" class="cpp">
#include &lt;Windows.h>

namespace MAPI
{
#include &lt;mapidefs.h>
}

namespace SQL
{
#include &lt;sqltypes.h>
}

using namespace MAPI;
using namespace SQL;

int _tmain(int argc, _TCHAR* argv[])
{
   SQL::BOOKMARK bookmark = 0;

   return 0;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://mariusbancila.ro/blog/2011/06/22/redefinition-of-bookmark/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C++ Renaissance at Microsoft</title>
		<link>http://mariusbancila.ro/blog/2011/06/20/cpp-renaissance-at-microsoft/</link>
		<comments>http://mariusbancila.ro/blog/2011/06/20/cpp-renaissance-at-microsoft/#comments</comments>
		<pubDate>Mon, 20 Jun 2011 08:59:27 +0000</pubDate>
		<dc:creator>Marius Bancila</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Parallel Programming]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Windows Programming]]></category>
		<category><![CDATA[renaissance]]></category>
		<category><![CDATA[resources]]></category>
		<category><![CDATA[VisualStudio]]></category>

		<guid isPermaLink="false">http://mariusbancila.ro/blog/?p=1019</guid>
		<description><![CDATA[At the beginning of this year, Microsoft announced a &#8220;C++ renaissance&#8221;. Quoting from the description of a Channel 9 video with Craig Symonds and Mohsen Agsen: C++ is currently undergoing a renaissance. This means that, by definition, the language, compilers and compositional tooling are evolving and coalescing into a state that maximizes native developer efficiency, [...]]]></description>
			<content:encoded><![CDATA[<p>At the beginning of this year, Microsoft announced a &#8220;C++ renaissance&#8221;. Quoting from the description of a <a href="http://channel9.msdn.com/">Channel 9</a> video with Craig Symonds and Mohsen Agsen:</p>
<blockquote><p>C++ is currently undergoing a renaissance. This means that, by definition, the language, compilers and compositional tooling are evolving and coalescing into a state that maximizes native developer efficiency, productivity, and creativity across hardware and software domains.</p></blockquote>
<p>Everybody agrees that Microsoft made C++ a sort of second class citizen in the past years, while the company invested a lot in the .NET framework. Many developers have switched from native development to managed (.NET) simply because it offers a more productive environment. And the postponing of the ISO standard committee in releasing the new C++0x standard only made things worse. </p>
<p>However, with the completion of the new C++ standard this year, Microsoft, apparently, plans to change that, and make C++ again appealing to developers. They already made C++0x features available in the VS2010 C++ compiler and are working on implementing most of the rest for Visual Studio vNext. They are also investing in tools (now labeled Application Lifecycle Management), and for instance are bringing intellisence to C++/CLI. One of the most important areas of development is parallelism, where they are developing the PPL and Agents libraries and now the C++ AMP that they just announced. And also recently the Kinect for Windows SDK beta that provides Kinect capabilities to developers who build applications with C++ (and other laguanges). And in the mean time <a href="http://blogs.msdn.com/b/jasonz/archive/2011/06/06/welcome-erich-gamma-to-the-visual-studio-team.aspx">they hired Erich Gamma in the Visual Studio team</a>.</p>
<p>But this is not enough in my opinion. Improvements in language and tools are an important part, but not everything. It is equally necessary for Microsoft to evangelize it, using any necessary means. Unless they can spread the word, the work might pass unnoticed. To be honest, I was very reluctant about this part, half an year ago, when they announced the &#8220;renaissance&#8221;. However, looking back at what they done I&#8217;d say they are on the right track. Of course, there is still a lot of work to match the &#8220;advertising&#8221; effort put into .NET. But right now C++ is getting more attention at conferences such as PDC or TechEd, or their publishing assets, such as Channel 9, MSDN or their team blogs. So I tried to assemble a collection of videos, blogs, books and code samples related to C++ or native development that they published since the announcement of the renaissance. So far it looks good, in my opinion.</p>
<p>Channel 9<br />
<a href="http://channel9.msdn.com/Shows/Going+Deep/E2E-Herb-Sutter-and-Erik-Meijer-Perspectives-on-C">E2E: Herb Sutter and Erik Meijer &#8211; Perspectives on C++</a><br />
<a href="http://channel9.msdn.com/Shows/Going+Deep/Craig-Symonds-and-Mohsen-Agsen-C-Renaissance">Craig Symonds and Mohsen Agsen: C++ Renaissance</a><br />
<a href="http://channel9.msdn.com/posts/Windows-7-Taskbar-Integration-for-MFC-Applications">Windows 7 Taskbar Integration for MFC Applications</a><br />
<a href="http://channel9.msdn.com/Blogs/Charles/Tony-Goodhew-VC-Developer-Communication-Questions-and-Answers">Tony Goodhew: VC++ Developer Communication &#8211; Questions and Answers</a><br />
<a href="http://channel9.msdn.com/Blogs/Charles/VC-MVP-Summit-Kate-Gregory">Talkin&#8217; C++ with Kate Gregory</a><br />
<a href="http://channel9.msdn.com/Blogs/Charles/MVP-Summit-2011-Meet-C-MVPs-Angel-PJ-Tom-and-Sheng">MVP Summit 2011: Meet C++ MVPs Angel, PJ, Tom and Sheng</a><br />
<a href="http://channel9.msdn.com/Blogs/Charles/MVP-Summit-2011-Meet-C-MVPs-Alon-Marius-Bruno-and-Jim">Talkin&#8217; C++ with Alon, Marius, Bruno, and Jim</a><br />
<a href="http://channel9.msdn.com/posts/Talkin-C-with-Boris-Jabes-C-Intellisense-Game-Development-and-Boris-Faces-His-Demons">Talkin&#8217; C++ with Boris Jabes: C++ Intellisense, Game Development, and Boris Faces His Demons</a><br />
<a href="http://channel9.msdn.com/posts/Application-Restart-and-Recovery-on-Windows-7-in-Native-Code">Application Restart and Recovery on Windows 7 in Native Code</a><br />
<a href="http://channel9.msdn.com/Shows/Going+Deep/Parallel-Programming-in-Native-Code-Tasks-and-Continuations-Part-1-of-2">Parallel Programming for C++ Developers: Tasks and Continuations, Part 1 of 2</a><br />
<a href="http://channel9.msdn.com/Shows/Going+Deep/Parallel-Programming-for-C-Developers-Tasks-and-Continuations-Part-2-of-2">Parallel Programming for C++ Developers: Tasks and Continuations, Part 2 of 2</a><br />
<a href="http://channel9.msdn.com/Shows/Going+Deep/Conversation-with-Herb-Sutter-Perspectives-on-Modern-C0x11">Conversation with Herb Sutter: Perspectives on Modern C++(0x/11)</a><br />
<a href="http://channel9.msdn.com/posts/C-ALM--Architecture-Tools-and-Unit-Testing-for-Visual-C-Developers">First Look: New ALM Tools for VC++ Developers</a><br />
<a href="http://channel9.msdn.com/Events/TechEd/NorthAmerica/2011/DEV303">Modern Native C++ Development for Maximum Productivity</a><br />
<a href="http://channel9.msdn.com/Shows/Going+Deep/Mohsen-Agsen-C-Today-and-Tomorrow">Mohsen Agsen &#8211; C++ Today and Tomorrow</a><br />
<a href="http://channel9.msdn.com/Shows/Going+Deep/Herb-Sutter-C-Questions-and-Answers">Herb Sutter: C++ Questions and Answers</a><br />
<a href="http://channel9.msdn.com/posts/AFDS-Keynote-Herb-Sutter-Heterogeneous-Computing-and-C-AMP">Herb Sutter &#8211; Heterogeneous Computing and C++ AMP</a><br />
<a href="http://channel9.msdn.com/posts/Daniel-Moth-Blazing-fast-code-using-GPUs-and-more-with-C-AMP">Daniel Moth: Blazing-fast code using GPUs and more, with C++ AMP</a><br />
<a href="http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Stephan-T-Lavavej-Advanced-STL-1-of-n">C9 Lectures: Stephan T Lavavej &#8211; Advanced STL, 1 of n</a><br />
<a href="http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Stephan-T-Lavavej-Advanced-STL-2-of-n">C9 Lectures: Stephan T Lavavej &#8211; Advanced STL, 2 of n</a><br />
<a href="http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Stephan-T-Lavavej-Advanced-STL-3-of-n">C9 Lectures: Stephan T Lavavej &#8211; Advanced STL, 3 of n</a><br />
<a href="http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Stephan-T-Lavavej-Advanced-STL-4-of-n">C9 Lectures: Stephan T Lavavej &#8211; Advanced STL, 4 of n</a><br />
<a href="http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Stephan-T-Lavavej-Advanced-STL-5-of-n">C9 Lectures: Stephan T Lavavej &#8211; Advanced STL, 5 of n</a></p>
<p>Visual C++ Team Blog<br />
<a href="http://blogs.msdn.com/b/vcblog/archive/2011/01/05/damn-my-vc-project-is-building-slower-in-vs2010-what-do-i-do-now-a-step-by-step-guide.aspx">Grr&#8230; My VC++ Project Is Building Slower in VS2010. What Do I Do Now? (A Step by Step Guide)</a><br />
<a href="http://blogs.msdn.com/b/vcblog/archive/2011/03/03/10136696.aspx">C++/CLI IntelliSense in Visual Studio vNext</a><br />
<a href="http://blogs.msdn.com/b/vcblog/archive/2011/03/22/10143956.aspx">Exception Boundaries: Working With Multiple Error Handling Mechanisms</a><br />
<a href="http://blogs.msdn.com/b/vcblog/archive/2011/03/29/10146895.aspx">Troubleshooting Tips for IntelliSense Slowness</a><br />
<a href="http://blogs.msdn.com/b/vcblog/archive/2011/04/05/10149742.aspx">Build Related Improvement in VS2010 SP1</a><br />
<a href="http://blogs.msdn.com/b/vcblog/archive/2011/05/04/10161066.aspx">Converting An MFC Ribbon To Designer Format</a><br />
<a href="http://blogs.msdn.com/b/vcblog/archive/2011/05/26/10168887.aspx">Enforcing Correct Concurrent Access of Class Data</a></p>
<p>Parallel Programming in Native Code Blog<br />
<a href="http://blogs.msdn.com/b/nativeconcurrency/archive/2011/01/15/sorting-in-ppl.aspx">Sorting in PPL</a><br />
<a href="http://blogs.msdn.com/b/nativeconcurrency/archive/2011/01/26/how-to-pick-your-parallel-sort.aspx">How to pick your parallel sort?</a><br />
<a href="http://blogs.msdn.com/b/nativeconcurrency/archive/2011/02/21/the-concurrency-runtime-and-visual-c-2010-lambda-expressions.aspx">The Concurrency Runtime and Visual C++ 2010: Lambda Expressions</a><br />
<a href="http://blogs.msdn.com/b/nativeconcurrency/archive/2011/02/28/the-concurrency-runtime-and-visual-c-2010-automatic-type-deduction.aspx">The Concurrency Runtime and Visual C++ 2010: Automatic Type Deduction</a><br />
<a href="http://blogs.msdn.com/b/nativeconcurrency/archive/2011/03/07/the-concurrency-runtime-and-visual-c-2010-the-decltype-type-specifier.aspx">The Concurrency Runtime and Visual C++ 2010: The decltype Type Specifier</a><br />
<a href="http://blogs.msdn.com/b/nativeconcurrency/archive/2011/03/14/the-concurrency-runtime-and-visual-c-2010-rvalue-references.aspx">The Concurrency Runtime and Visual C++ 2010: Rvalue References</a><br />
<a href="http://blogs.msdn.com/b/nativeconcurrency/archive/2011/03/24/the-concurrency-runtime-and-visual-c-2010-transporting-exceptions-between-threads.aspx">The Concurrency Runtime and Visual C++ 2010: Transporting Exceptions between Threads</a><br />
<a href="http://blogs.msdn.com/b/nativeconcurrency/archive/2011/03/23/building-responsive-gui-applications-with-ppl-tasks.aspx">Building Responsive GUI Applications with PPL Tasks</a></p>
<p>MSDN Magazine<br />
<a href="http://msdn.microsoft.com/en-us/magazine/gg650659.aspx">Writing a Debugging Tools for Windows Extension</a><br />
<a href="http://msdn.microsoft.com/en-us/magazine/hh148143.aspx">Writing a Debugging Tools for Windows Extension, Part 2: Output</a><br />
<a href="http://msdn.microsoft.com/en-us/magazine/hh205613.aspx">Writing a Debugging Tools for Windows Extension, Part 3: Clients and Callbacks</a><br />
<a href="http://msdn.microsoft.com/en-us/magazine/hh205645.aspx">Agile C++ Development and Testing with Visual Studio and TFS</a></p>
<p>Books &#038; Publications<br />
<a href="http://parallelpatternscpp.codeplex.com/">Parallel Programming with Microsoft Visual C++</a><br />
<a href="http://paper.li/visualc/news">The Visual C++ Weekly</a></p>
<p>Code &#038; Samples<br />
<a href="http://archive.msdn.microsoft.com/concrtextras">Code samples for the Concurrency Runtime and Parallel Pattern Library in Visual Studio 2010</a><br />
<a href="http://code.msdn.microsoft.com/Bing-Maps-Trip-Optimizer-003021ae">Bing Maps Trip Optimizer</a><br />
<a href="http://msdn.microsoft.com/en-us/library/ff708696.aspx">Hilo: Developing C++ Applications for Windows 7</a><br />
<a href="http://1code.codeplex.com/">All-in-One Code Framework</a></p>
]]></content:encoded>
			<wfw:commentRss>http://mariusbancila.ro/blog/2011/06/20/cpp-renaissance-at-microsoft/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>C++ Accelerated Massive Parallelism</title>
		<link>http://mariusbancila.ro/blog/2011/06/16/c-accelerated-massive-parallelism/</link>
		<comments>http://mariusbancila.ro/blog/2011/06/16/c-accelerated-massive-parallelism/#comments</comments>
		<pubDate>Thu, 16 Jun 2011 07:55:05 +0000</pubDate>
		<dc:creator>Marius Bancila</dc:creator>
				<category><![CDATA[Parallel Programming]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[parallel]]></category>
		<category><![CDATA[VisualStudio]]></category>

		<guid isPermaLink="false">http://mariusbancila.ro/blog/?p=1011</guid>
		<description><![CDATA[Microsoft has recently announced at the AMD Fusion Developer Summit the introduction of a new technology called C++ Accelerated Massive Parallelism or shortly C++ AMP that helps C++ developers use the GPU for parallel programming. The new technology will be part of Visual C++, integrated with full support (edit, build, debug, profile) in the next [...]]]></description>
			<content:encoded><![CDATA[<p>Microsoft has recently announced at the AMD Fusion Developer Summit the introduction of a new technology called <strong>C++ Accelerated Massive Parallelism</strong> or shortly <strong>C++ AMP</strong> that helps C++ developers use the GPU for parallel programming. The new technology will be part of Visual C++, integrated with full support (edit, build, debug, profile) in the next version of Visual Studio. It is built in modern C++ on top of DirectX. It will provide an STL-like library, part of the Concurrency namespace, delivered in a amp.h header.</p>
<p>S.Somasegar (Senior Vice President of the Developer Division) said:</p>
<blockquote><p>By building on the Windows DirectX platform, our implementation of C++ AMP allows you to target hardware from all the major hardware vendors. We expect that it will be part of the next Visual C++ compiler and fully integrated in the next release of Visual Studio experience. </p></blockquote>
<p>You can read more about it here:</p>
<ul>
<li><a href="http://blogs.msdn.com/b/somasegar/archive/2011/06/15/targeting-heterogeneity-with-c-amp-and-ppl.aspx">Targeting Heterogeneity with C++ AMP and PPL</a></li>
<li><a href="http://www.danielmoth.com/Blog/C-Accelerated-Massive-Parallelism.aspx">C++ Accelerated Massive Parallelism</a></li>
<li><a href="http://blogs.msdn.com/b/vcblog/archive/2011/06/15/introducing-amp.aspx">Introducing C++ Accelerated Massive Parallelism (C++ AMP)</a></li>
</ul>
<p>Looking forward for the first CTP and samples.</p>
<p>UPDATE<br />
Herb Sutter introduces C++ AMP at the AMD Fusion Developer Summit 11<br />
<iframe style="height:288px;width:512px" src="http://channel9.msdn.com/posts/AFDS-Keynote-Herb-Sutter-Heterogeneous-Computing-and-C-AMP/player?w=512&#038;h=288" frameBorder="0" scrolling="no" ></iframe></p>
<p>Daniel Moth digs deeper into C++ AMP with code samples and more<br />
<iframe style="height:288px;width:512px" src="http://channel9.msdn.com/posts/Daniel-Moth-Blazing-fast-code-using-GPUs-and-more-with-C-AMP/player?w=512&#038;h=288" frameBorder="0" scrolling="no" ></iframe></p>
<p>Herb Sutter</p>
<blockquote><p>How long is your password? How long it will take a 100,000,000 GPU cores running at what, a million attempts per second to crack your password just by brute force? That where almost a kid can write that. An that is just a tiny example of how game changing this is.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://mariusbancila.ro/blog/2011/06/16/c-accelerated-massive-parallelism/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finding Installed Applications with VC++</title>
		<link>http://mariusbancila.ro/blog/2011/05/01/finding-installed-applications-with-vc/</link>
		<comments>http://mariusbancila.ro/blog/2011/05/01/finding-installed-applications-with-vc/#comments</comments>
		<pubDate>Sun, 01 May 2011 21:32:43 +0000</pubDate>
		<dc:creator>Marius Bancila</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Windows Programming]]></category>
		<category><![CDATA[install]]></category>
		<category><![CDATA[MSI]]></category>
		<category><![CDATA[registry]]></category>
		<category><![CDATA[WMI]]></category>

		<guid isPermaLink="false">http://mariusbancila.ro/blog/?p=909</guid>
		<description><![CDATA[Finding applications installed on a machine (the ones that you see in Control Panel Add/Remove programs) could be a little bit tricky, because there isn&#8217;t a bulletproof API or method. Each of the available methods has its own weak points. WMI is slow and can actually be disabled on a machine. MSI API only shows [...]]]></description>
			<content:encoded><![CDATA[<p>Finding applications installed on a machine (the ones that you see in Control Panel Add/Remove programs) could be a little bit tricky, because there isn&#8217;t a bulletproof API or method. Each of the available methods has its own weak points. WMI is slow and can actually be disabled on a machine. MSI API only shows applications installed with an MSI, and reading directly from the Windows Registry is not an officially supported alternative. Thus it is an open point which one is the most appropriate, though the official answer will probably be MSI API.</p>
<p>In this post I will go through all of these three methods and show how to query for the installed applications and display the name, publisher, vendor and installation location (if available). Notice these are just some samples, and if you want to use this in your applications you&#8217;ll probably want to do additional things like better error checking. Because I want the code to work both with ANSI and UNICODE I will use the following defines</p>
<pre name="code" class="cpp">
#include <iostream >
#include <string>

#ifdef _UNICODE
#define tcout       wcout
#define tstring     wstring
#else
#define tcout       cout
#define tstring     string
#endif
</pre>
<p><strong>WMI</strong><br />
<a href="http://msdn.microsoft.com/en-us/library/aa394378.aspx">Win32_Product</a> is a WMI class that represents a product installed by Windows Installer. For fetching the list of installed applications with WMI I will reuse the WMIQuery class I first shown in this <a href="http://mariusbancila.ro/blog/2011/01/05/finding-if-a-computer-is-a-laptop/">post</a>. You need to include <strong>Wbemidl.h</strong> and link with <strong>wbemuuid.lib</strong>. </p>
<p>In the code shown below WmiQueryValue() is a function that reads a property from the current record and returns it as an STL string (UNICODE or ANSI). WmiEnum() is a function that fetches and displays in the console all the installed applications.</p>
<pre name="code" class="cpp">
class WMIQuery
{
   IWbemLocator* m_pLocator;
   IWbemServices* m_pServices;

public:
   WMIQuery():
      m_pLocator(NULL),
      m_pServices(NULL)
   {
   }

   bool Initialize()
   {
      // Obtain the initial locator to WMI
      HRESULT hr = ::CoCreateInstance(
         CLSID_WbemLocator,
         0,
         CLSCTX_INPROC_SERVER,
         IID_IWbemLocator, (LPVOID *) &#038;m_pLocator);

      if (FAILED(hr))
      {
         cerr &lt;&lt; "Failed to create IWbemLocator object. Err code = 0x" &lt;&lt; hex &lt;&lt; hr &lt;&lt; endl;
         return false;
      }

      // Connect to WMI through the IWbemLocator::ConnectServer method
      // Connect to the root\cimv2 namespace with the current user
      hr = m_pLocator->ConnectServer(
         _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
         NULL,                    // User name. NULL = current user
         NULL,                    // User password. NULL = current
         0,                       // Locale. NULL indicates current
         NULL,                    // Security flags.
         0,                       // Authority (e.g. Kerberos)
         0,                       // Context object
         &#038;m_pServices             // pointer to IWbemServices proxy
         );

      if (FAILED(hr))
      {
         cerr &lt;&lt; "Could not connect. Error code = 0x" &lt;&lt; hex &lt;&lt; hr &lt;&lt; endl;
         m_pLocator->Release();
         m_pLocator = NULL;
         return false;
      }

      // Set security levels on the proxy
      hr = ::CoSetProxyBlanket(
         m_pServices,                 // Indicates the proxy to set
         RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
         RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
         NULL,                        // Server principal name
         RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx
         RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
         NULL,                        // client identity
         EOAC_NONE                    // proxy capabilities
         );

      if (FAILED(hr))
      {
         cerr &lt;&lt; "Could not set proxy blanket. Error code = 0x" &lt;&lt; hex &lt;&lt; hr &lt;&lt; endl;
         m_pServices->Release();
         m_pServices = NULL;
         m_pLocator->Release();
         m_pLocator = NULL;
         return false;
      }

      return true;
   }

   IEnumWbemClassObject* Query(LPCTSTR strquery)
   {
      IEnumWbemClassObject* pEnumerator = NULL;
      HRESULT hr = m_pServices->ExecQuery(
         bstr_t("WQL"),
         bstr_t(strquery),
         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
         NULL,
         &#038;pEnumerator);

      if (FAILED(hr))
      {
         cerr &lt;&lt; "Query for operating system name failed. Error code = 0x" &lt;&lt; hex &lt;&lt; hr &lt; endl;
         return NULL;
      }

      return pEnumerator;
   }

   ~WMIQuery()
   {
      if(m_pServices != NULL)
      {
         m_pServices->Release();
         m_pServices = NULL;
      }

      if(m_pLocator != NULL)
      {
         m_pLocator->Release();
         m_pLocator = NULL;
      }
   }
};

tstring WmiQueryValue(IWbemClassObject* pclsObj,
                      LPCWSTR szName)
{
    tstring value;

    if(pclsObj != NULL &#038;&#038; szName != NULL)
    {
        VARIANT vtProp;

        HRESULT hr = pclsObj->Get(szName, 0, &#038;vtProp, 0, 0);
        if(SUCCEEDED(hr))
        {
            if(vtProp.vt == VT_BSTR &#038;&#038; ::SysStringLen(vtProp.bstrVal) > 0)
            {
#ifdef _UNICODE
                value = vtProp.bstrVal;
#else
                int len = ::SysStringLen(vtProp.bstrVal)+1;
                if(len > 0)
                {
                    value.resize(len);
                    ::WideCharToMultiByte(CP_ACP,
                                          0,
                                          vtProp.bstrVal,
                                          -1,
                                          &#038;value[0],
                                          len,
                                          NULL,
                                          NULL);
                }
#endif
            }
        }
    }

    return value;
}

void WmiEnum()
{
    HRESULT hres;

    // Initialize COM.
    hres =  ::CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres))
    {
        cout &lt;&lt; "Failed to initialize COM library. Error code = 0x" &lt;&lt; hex &lt;&lt; hres &lt;&lt; endl;
        return;
    }

    // Set general COM security levels
    hres =  ::CoInitializeSecurity(
        NULL,
        -1,                          // COM authentication
        NULL,                        // Authentication services
        NULL,                        // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication
        RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
        NULL,                        // Authentication info
        EOAC_NONE,                   // Additional capabilities
        NULL                         // Reserved
        );

    if (FAILED(hres))
    {
        cout &lt;&lt; "Failed to initialize security. Error code = 0x" &lt;&lt; hex &lt;&lt; hres &lt;&lt; endl;
        ::CoUninitialize();
        return;
    }
    else
    {
        WMIQuery query;
        if(query.Initialize())
        {
            IEnumWbemClassObject* pEnumerator = query.Query(_T("SELECT * FROM Win32_Product"));

            if(pEnumerator != NULL)
            {
                // Get the data from the query
                IWbemClassObject *pclsObj;
                ULONG uReturn = 0;

                while (pEnumerator)
                {
                    HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &#038;pclsObj, &#038;uReturn);

                    if(0 == uReturn)
                    {
                        break;
                    }

                    // find the values of the properties we are interested in
                    tstring name = WmiQueryValue(pclsObj, L"Name");
                    tstring publisher = WmiQueryValue(pclsObj, L"Vendor");
                    tstring version = WmiQueryValue(pclsObj, L"Version");
                    tstring location = WmiQueryValue(pclsObj, L"InstallLocation");

                    if(!name.empty())
                    {
                        tcout &lt;&lt; name &lt;&lt; endl;
                        tcout &lt;&lt; "  - " &lt;&lt; publisher &lt;&lt; endl;
                        tcout &lt;&lt; "  - " &lt;&lt; version &lt;&lt; endl;
                        tcout &lt;&lt; "  - " &lt;&lt; location &lt;&lt; endl;
                        tcout &lt;&lt; endl;
                    }

                    pclsObj->Release();
                }

                pEnumerator->Release();
            }
        }
    }

    // unintializa COM
    ::CoUninitialize();
}
</pre>
<p>A sample from the output of this WmiEnum() function looks like this:</p>
<blockquote><p>
Java(TM) 6 Update 25<br />
  &#8211; Oracle<br />
  &#8211; 6.0.250<br />
  &#8211; C:\Program Files\Java\jre6\</p>
<p>Java(TM) SE Development Kit 6 Update 25<br />
  &#8211; Oracle<br />
  &#8211; 1.6.0.250<br />
  &#8211; C:\Program Files\Java\jdk1.6.0_25\</p>
<p>Microsoft .NET Framework 4 Client Profile<br />
  &#8211; Microsoft Corporation<br />
  &#8211; 4.0.30319<br />
  -</p>
<p>Microsoft Sync Framework Services v1.0 SP1 (x86)<br />
  &#8211; Microsoft Corporation<br />
  &#8211; 1.0.3010.0<br />
  -</p>
<p>Microsoft ASP.NET MVC 2 &#8211; Visual Studio 2010 Tools<br />
  &#8211; Microsoft Corporation<br />
  &#8211; 2.0.50217.0<br />
  -</p>
<p>Adobe Reader X (10.0.1)<br />
  &#8211; Adobe Systems Incorporated<br />
  &#8211; 10.0.1<br />
  &#8211; C:\Program Files\Adobe\Reader 10.0\Reader\
</p></blockquote>
<p>One can notice that the code is relatively long, but most important it is very slow.</p>
<p><strong>MSI API</strong><br />
Two of the <a href="http://msdn.microsoft.com/en-us/library/aa369426.aspx">MSI API functions</a> can help fetching the list of installed applications:</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/aa370102.aspx">MsiUnumProductsEx</a>: enumerates through one or all the instances of products that are currently advertised or installed (requires Windows Installer 3.0 or newer)</li>
<li><a href="http://msdn.microsoft.com/en-us/library/aa370131.aspx">MsiGetProductInfoEx</a>: returns product information for advertised and installed products</li>
</ul>
<p>In order to use these functions you need to include <strong>msi.h</strong> and link to <strong>msi.lib</strong>.</p>
<p>In the code below, MsiQueryProperty() is a function that returns the value of product property (as a tstring as defined above) by calling MsiGetProductInfoEx. MsiEnum() is a function that iterates through all the installed applications and prints in the console the name, publisher, version and installation location.</p>
<pre name="code" class="cpp">
tstring MsiQueryProperty(LPCTSTR szProductCode,
                         LPCTSTR szUserSid,
                         MSIINSTALLCONTEXT dwContext,
                         LPCTSTR szProperty)
{
    tstring value;

    DWORD cchValue = 0;
    UINT ret2 = ::MsiGetProductInfoEx(
        szProductCode,
        szUserSid,
        dwContext,
        szProperty,
        NULL,
        &#038;cchValue);

    if(ret2 == ERROR_SUCCESS)
    {
        cchValue++;
        value.resize(cchValue);

        ret2 = ::MsiGetProductInfoEx(
            szProductCode,
            szUserSid,
            dwContext,
            szProperty,
            (LPTSTR)&#038;value[0],
            &#038;cchValue);
    }

    return value;
}

void MsiEnum()
{
    UINT ret = 0;
    DWORD dwIndex = 0;
    TCHAR szInstalledProductCode[39] = {0};
    TCHAR szSid[128] = {0};
    DWORD cchSid;
    MSIINSTALLCONTEXT dwInstalledContext;

    do
    {
        memset(szInstalledProductCode, 0, sizeof(szInstalledProductCode));
        cchSid = sizeof(szSid)/sizeof(szSid[0]);

        ret = ::MsiEnumProductsEx(
            NULL,           // all the products in the context
            _T("s-1-1-0"),  // i.e.Everyone, all users in the system
            MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED | MSIINSTALLCONTEXT_MACHINE,
            dwIndex,
            szInstalledProductCode,
            &#038;dwInstalledContext,
            szSid,
            &#038;cchSid);

        if(ret == ERROR_SUCCESS)
        {
            tstring name = MsiQueryProperty(
                szInstalledProductCode,
                cchSid == 0 ? NULL : szSid,
                dwInstalledContext,
                INSTALLPROPERTY_INSTALLEDPRODUCTNAME);

            tstring publisher = MsiQueryProperty(
                szInstalledProductCode,
                cchSid == 0 ? NULL : szSid,
                dwInstalledContext,
                INSTALLPROPERTY_PUBLISHER);                

            tstring version = MsiQueryProperty(
                szInstalledProductCode,
                cchSid == 0 ? NULL : szSid,
                dwInstalledContext,
                INSTALLPROPERTY_VERSIONSTRING);

            tstring location = MsiQueryProperty(
                szInstalledProductCode,
                cchSid == 0 ? NULL : szSid,
                dwInstalledContext,
                INSTALLPROPERTY_INSTALLLOCATION);            

            tcout &lt;&lt; name &lt;&lt; endl;
            tcout &lt;&lt; "  - " &lt;&lt; publisher &lt;&lt; endl;
            tcout &lt;&lt; "  - " &lt;&lt; version &lt;&lt; endl;
            tcout &lt;&lt; "  - " &lt;&lt; location &lt;&lt; endl;
            tcout &lt;&lt; endl;

            dwIndex++;
        }

    } while(ret == ERROR_SUCCESS);
}
</pre>
<p>And this is a sample for the WmiEnum() function.</p>
<blockquote><p>
Java(TM) 6 Update 25<br />
  &#8211; Oracle<br />
  &#8211; 6.0.250<br />
  &#8211; C:\Program Files\Java\jre6\</p>
<p>Java(TM) SE Development Kit 6 Update 25<br />
  &#8211; Oracle<br />
  &#8211; 1.6.0.250<br />
  &#8211; C:\Program Files\Java\jdk1.6.0_25\</p>
<p>Microsoft .NET Framework 4 Client Profile<br />
  &#8211; Microsoft Corporation<br />
  &#8211; 4.0.30319<br />
  -</p>
<p>Microsoft Sync Framework Services v1.0 SP1 (x86)<br />
  &#8211; Microsoft Corporation<br />
  &#8211; 1.0.3010.0<br />
  -</p>
<p>Microsoft ASP.NET MVC 2 &#8211; Visual Studio 2010 Tools<br />
  &#8211; Microsoft Corporation<br />
  &#8211; 2.0.50217.0<br />
  -</p>
<p>Adobe Reader X (10.0.1)<br />
  &#8211; Adobe Systems Incorporated<br />
  &#8211; 10.0.1<br />
  &#8211; C:\Program Files\Adobe\Reader 10.0\Reader\
</p></blockquote>
<p><strong>Windows Registry</strong><br />
Installed applications are listed in Windows Registry under <strong>HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall</strong>. The <a href="http://support.microsoft.com/kb/247501">KB247501</a> article explains the structure of the information under this Registry key. Make sure you read it if you decide to use this approach. </p>
<p>In the code shown below, RegistryQueryValue() is a function that queries the value of a name/value pair in the registry and returns the value as a tstring. RegistryEnum() is a function that prints to the console all the installed application as found in the registry.</p>
<pre name="code" class="cpp">
tstring RegistryQueryValue(HKEY hKey,
                           LPCTSTR szName)
{
    tstring value;

    DWORD dwType;
    DWORD dwSize = 0;

    if (::RegQueryValueEx(
        hKey,                   // key handle
        szName,                 // item name
        NULL,                   // reserved
        &#038;dwType,                // type of data stored
        NULL,                   // no data buffer
        &#038;dwSize                 // required buffer size
        ) == ERROR_SUCCESS &#038;&#038; dwSize > 0)
    {
        value.resize(dwSize);

        ::RegQueryValueEx(
            hKey,                   // key handle
            szName,                 // item name
            NULL,                   // reserved
            &#038;dwType,                // type of data stored
            (LPBYTE)&#038;value[0],      // data buffer
            &#038;dwSize                 // available buffer size
            );
    }

    return value;
}

void RegistryEnum()
{
    HKEY hKey;
    LONG ret = ::RegOpenKeyEx(
        HKEY_LOCAL_MACHINE,     // local machine hive
        _T("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"), // uninstall key
        0,                      // reserved
        KEY_READ,               // desired access
        &#038;hKey                   // handle to the open key
        );

    if(ret != ERROR_SUCCESS)
        return;

    DWORD dwIndex = 0;
    DWORD cbName = 1024;
    TCHAR szSubKeyName[1024];

    while ((ret = ::RegEnumKeyEx(
        hKey,
        dwIndex,
        szSubKeyName,
        &#038;cbName,
        NULL,
        NULL,
        NULL,
        NULL)) != ERROR_NO_MORE_ITEMS)
    {
        if (ret == ERROR_SUCCESS)
        {
            HKEY hItem;
            if (::RegOpenKeyEx(hKey, szSubKeyName, 0, KEY_READ, &#038;hItem) != ERROR_SUCCESS)
                continue;

            tstring name = RegistryQueryValue(hItem, _T("DisplayName"));
            tstring publisher = RegistryQueryValue(hItem, _T("Publisher"));
            tstring version = RegistryQueryValue(hItem, _T("DisplayVersion"));
            tstring location = RegistryQueryValue(hItem, _T("InstallLocation"));

            if(!name.empty())
            {
                tcout &lt;&lt; name &lt;&lt; endl;
                tcout &lt;&lt; "  - " &lt;&lt; publisher &lt;&lt; endl;
                tcout &lt;&lt; "  - " &lt;&lt; version &lt;&lt; endl;
                tcout &lt;&lt; "  - " &lt;&lt; location &lt;&lt; endl;
                tcout &lt;&lt; endl;
            }

            ::RegCloseKey(hItem);
        }
        dwIndex++;
        cbName = 1024;
    }
    ::RegCloseKey(hKey);
}
</pre>
<p>And a sample output of the RegistryEnum() function:</p>
<blockquote><p>
Java(TM) SE Development Kit 6 Update 25</p>
<p>  &#8211; Oracle<br />
  &#8211; 1.6.0.250<br />
  &#8211; C:\Program Files\Java\jdk1.6.0_25\</p>
<p>Microsoft Visual Studio 2005 Tools for Office Runtime</p>
<p>  &#8211; Microsoft Corporation<br />
  &#8211; 8.0.60940.0<br />
  -</p>
<p>MSDN Library for Visual Studio 2008 &#8211; ENU</p>
<p>  &#8211; Microsoft<br />
  &#8211; 9.0.21022<br />
  &#8211; C:\Program Files\MSDN\MSDN9.0\</p>
<p>Microsoft SQL Server Compact 3.5 SP2 ENU</p>
<p>  &#8211; Microsoft Corporation<br />
  &#8211; 3.5.8080.0<br />
  &#8211; C:\Program Files\Microsoft SQL Server Compact Edition\</p>
<p>Microsoft .NET Framework 4 Client Profile</p>
<p>  &#8211; Microsoft Corporation<br />
  &#8211; 4.0.30319<br />
  -
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://mariusbancila.ro/blog/2011/05/01/finding-installed-applications-with-vc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MVP Global Summit 2011</title>
		<link>http://mariusbancila.ro/blog/2011/03/16/mvp-global-summit-2011/</link>
		<comments>http://mariusbancila.ro/blog/2011/03/16/mvp-global-summit-2011/#comments</comments>
		<pubDate>Wed, 16 Mar 2011 20:14:29 +0000</pubDate>
		<dc:creator>Marius Bancila</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[MVP]]></category>
		<category><![CDATA[channel9]]></category>
		<category><![CDATA[summit]]></category>

		<guid isPermaLink="false">http://mariusbancila.ro/blog/?p=881</guid>
		<description><![CDATA[The MVP Global Summit 2011 took place in Redmond and Bellevue at the beginning of March. This year I attended for the fifth time, and as usual it was a great time. Fellow MVPs, discussions with the Microsoft product groups, parties, everything made it worth it. And this year it was also a little bit [...]]]></description>
			<content:encoded><![CDATA[<p>The MVP Global Summit 2011 took place in Redmond and Bellevue at the beginning of March. This year I attended for the fifth time, and as usual it was a great time. Fellow MVPs, discussions with the Microsoft product groups, parties, everything made it worth it. And this year it was also a little bit special because I was named C++ MVP of the Year, a distinction shared with <a href="https://mvp.support.microsoft.com/profile=E66C573D-9CEA-408D-BF8D-1C1A9EA062F2">Kate Gregory</a>. A 3rd C++ MVP, <a href="https://mvp.support.microsoft.com/profile=53E2CF19-EA8C-48B1-8941-A7AB174DA98A">Sheng Jiang</a>, was also named MVP of the Year as top answerer in the MSDN forums. As an MVP of the Year I was invited to attend a dinner held by <a href="http://blogs.msdn.com/b/somasegar/">S. Somasegar</a>, senior vice president of the Developer Division at Microsoft, where I joined the other MVPs of the year in the awarded categories (such as C#, VB, ASP.NET, etc.), but also top figures from Microsoft, such as Scott Guthrie, Jason Zander, Anders Hejlsberg or Scott Hanselman and the Microsoft community leads. This is a picture from the event, showing, from left to right, Sheng Jiang, myself, Diego Dagum &#8211; Windows C++ community PM, and Kate Gregory. </p>
<p><img alt="" src="/blog/wp-content/uploads/2011/03/mvpdinner.jpg" title="C++ MVPs of the Year" class="alignnone" width="600" height="450" /></p>
<p>Another special moment at this summit was being interviewed by Charles Torre for <a href="http://channel9.msdn.com/">channel9</a>. He did several interviews with C++ MVPs and these interviews were posted on channel9 recently. <a href="http://channel9.msdn.com/Blogs/Charles/MVP-Summit-2011-Meet-C-MVPs-Alon-Marius-Bruno-and-Jim">Here</a> you can find the original post for the interview with <a href="https://mvp.support.microsoft.com/profile=A70BA339-1B2E-4280-9E15-6114CE653398">Alon Fliess</a>, <a href="https://mvp.support.microsoft.com/profile=5945C666-42F4-4147-848B-6B0DDDAE140C">Bruno Boucard</a>, <a href="http://qualapps.blogspot.com/">Jim Berveridge</a> and myself. We talked mostly about C++, but also the MVP program.</p>
<p><object type="application/x-silverlight-2" data="data:application/x-silverlight-2," width="512" height="288"><param name="minRuntimeVersion" value="4.0.50401.0"/><param name="source" value="http://channel9.msdn.com/scripts/Channel9.xap?v=1.5"/><param name="initParams" value="mediaurl=http://files.ch9.ms/ch9/8ef5/c88f54f8-87ef-402c-af41-9e9f012d8ef5/VCMVPSummit11Roundtable1.ism/manifest,thumbnail=http://media.ch9.ms/ch9/8ef5/c88f54f8-87ef-402c-af41-9e9f012d8ef5/VCMVPSummit11Roundtable1_512_ch9.jpg,deliverymethod=adaptivestreaming,autoplay=false,entryid=c88f54f887ef402caf419e9f012d8ef5"/></object></p>
<p>The other interviews that I mentioned can be found here:</p>
<ul>
<li><a href="http://channel9.msdn.com/Blogs/Charles/MVP-Summit-2011-Meet-C-MVPs-Angel-PJ-Tom-and-Sheng">MVP Summit 2011: Meet C++ MVPs Angel, PJ, Tom and Sheng</a></li>
<li><a href="http://channel9.msdn.com/Blogs/Charles/VC-MVP-Summit-Kate-Gregory">Talkin&#8217; C++ with Kate Gregory</a></li>
</ul>
<p>Looking forward for the next summit experience.</p>
]]></content:encoded>
			<wfw:commentRss>http://mariusbancila.ro/blog/2011/03/16/mvp-global-summit-2011/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

