The CTreeCtrl supports several ways to sort its content:

  • InsertItem allows to insert the child item alphabetically, when specifying TVI_SORT for hInsertAfter
  • SortChildren performs an alphabetical sorting of the child items of the given parent item in a tree
  • SortChildrenCB performs a sort with a user-defined callback (hence the CB suffix) of the children of the specified item

Let’s consider this tree and investigate these two sorting methods.

Alphabetical sorting
SortChildren() does an alphabetical sorting. It is important to note that SortChildren() does not work recursively. It only sorts the children of the specified item. Therefore the following call would only sort the immediate children of the root item.

  m_tree.SortChildren(TVI_ROOT);

To sort the entire tree one needs to traverse the tree and call SortChildren for every item that has children (actually only items with more than one child need sorting). The following method performs a depth-first traversal and sorts all nodes that have children.

void CTreeSortDemoDlg::SortItem(HTREEITEM item)
{
   if(item != NULL)
   {
      if(item == TVI_ROOT || m_tree.ItemHasChildren(item))
      {
         HTREEITEM child = m_tree.GetChildItem(item);

         while(child != NULL)
         {
            SortItem(child);
            child = m_tree.GetNextItem(child, TVGN_NEXT);
         }

         m_tree.SortChildren(item);
      }
   }
}

// ...
SortItem(TVI_ROOT);

The result for the given tree is

User defined sorting
SortChildrenCB() allows the user to set a callback functions that the framework calls each time it needs to compare two items to perform the sorting. This allows to customize the sorting. Just like SortChildren() this method only sorts the children of the specified item, and does not perform a recursive sorting of the entire sub-tree.

This method has a single argument, a pointer to a TVSORTCB structure, that is defined like this:

typedef struct tagTVSORTCB {
  HTREEITEM    hParent;
  PFNTVCOMPARE lpfnCompare;
  LPARAM       lParam;
} TVSORTCB, *LPTVSORTCB;

The fields have the following meaning:

  • hParent: is the item whose children are to be sorted
  • lpfnCompare: a pointer to the user-defined callback function that does the sorting
  • lParam: is the value that is passed as to the 3rd parameter of the callback function, which looks like this:
    int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
    

    Usually, this parameter is a pointer to the tree itself, so that you can retrieve information about the items in the callback if necessary. However, it can be anything, including NULL.

    The lParam1 and lParam2 parameters correspond to the lParam member of the TVITEM structure for the two items being compared.

    The callback function must return a negative value if the first item should precede the second, a positive value if the first item should follow the second, or zero if the two items are equivalent.

Suppose we set for each item a pointer to a structure that looks like this:

struct ItemData
{
   CString  Name;
   int      Value;

   CString ToString() const
   {
      CString str;
      str.Format(_T("%s = %d"), Name, Value);
      return str;
   }
};

ItemData* data = MakeData(base, prefix);
HTREEITEM item = m_tree.InsertItem(data->ToString(), parent);
m_tree.SetItemData(item, (DWORD_PTR)data);

A user defined callback (a class method declared static) defines the precedence between two items based on the Value field.

int CALLBACK CTreeSortDemoDlg::CustomCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
   ItemData* data1 = reinterpret_cast<ItemData*>(lParam1);
   ItemData* data2 = reinterpret_cast<ItemData*>(lParam2);

   return (data1 != NULL && data2 != NULL) ? (data1->Value > data2->Value) : 0;
}

Sorting the entire tree with this callback is similar with the previous recursive method. The call to SortChildren() is replaced with a call to SortChildrenCB().

void CTreeSortDemoDlg::CustomSortItem(HTREEITEM item)
{
   if(item != NULL)
   {
      if(item == TVI_ROOT || m_tree.ItemHasChildren(item))
      {
         HTREEITEM child = m_tree.GetChildItem(item);

         while(child != NULL)
         {
            CustomSortItem(child);
            child = m_tree.GetNextItem(child, TVGN_NEXT);
         }

         TVSORTCB tvs;
         tvs.hParent = item;
         tvs.lpfnCompare = &CTreeSortDemoDlg::CustomCompare;
         tvs.lParam = reinterpret_cast<LPARAM>(&m_tree);

         m_tree.SortChildrenCB(&tvs);
      }
   }
}

// ...
CustomSortItem(TVI_ROOT);

The result on the given example is:

For a full sample see TreeSortDemo (55).

, , , , Hits for this post: 2423 .

Let’s say you have this VC++ project (or maybe more) targeting a 64-bit platform (x64 or IA64). You have the sources, everything is set. You build the solution and your project is skipped. You try again, maybe do a rebuild. The project is still skipped. You check the solution’s configuration manager, and the project is indeed checked for building. What could be wrong?

You open the project properties but the page doesn’t load. You get this error:

What’s happening?

What’s happening is that you are missing the x64/IA64 compiler and tools. You did not check them when you installed Visual Studio.



You have to go back to the setup and add this component. However, you must notice that if you have installed the service pack for Visual Studio (regardless the version and edition) you must remove the service pack first, run the original setup, add the x64/IA64 compiler and tools and then install the service pack back. Otherwise the original setup for Visual Studio will fail. The reason is the service pack installation overrides things, making the original setup unable to run again.

, , , , , Hits for this post: 3101 .

DocProject with Sandcastle are a great choice for creating MSDN-style documentation. You can author conceptual documentation using MAML (Microsoft Assistance Markup Language) and reference documentation from managed assemblies and XML comments. Here is the documentation for DocProject. Writing conceptual documentation I ran into some problems that were not straight forward to solve. Hopefully these tips will help you if you have the same problems.

Overloaded Methods
The codeEntityReference tag allows you to link to API reference documentation (namespaces, types, methods, properties, fields). You have to prefix the fully qualified name of the entity with N: for namespaces, T: for types, P: for properties, F: for fields and M: for methods. What if you have overloaded methods and you want to link to the page that displays all of them, not one particular method? The O: prefix Visual Studio is expecting (for XML comments) does not work. Sandcastle Help File Builder (SHFB) expects Overload: instead.

  <codeEntityReference>Overload:YourNamespace.YourClass.YouOverloadedMethod</codeEntityReference>

Methods with arguments
If you want to link to API reference documentation for a method that take some parameters you must specify those parameter’s type in parenthesis.

  <codeEntityReference>M:YourNamespace.YourClass.Function(System.String)</codeEntityReference>

However, if the method takes more than one parameter, you must separate the argument types with a comma and use no whitespaces between them. If you have whitespaces the API reference will not be resolved.

  <codeEntityReference>M:YourNamespace.YourClass.Function(System.String,System.Int32[])</codeEntityReference>

Constructors
Constructors are special methods so you must use a special notation for them: instead of using their name use the #ctor tag.

  <codeEntityReference>M:YourNamespace.YourClass.#ctor</codeEntityReference>

Of course, if the constructor has some arguments you must specify them in parenthesis:

  <codeEntityReference>M:YourNamespace.YourClass.#ctor(System.String)</codeEntityReference>

Generics
When it comes to generics you must use the special notation with ` (grave accent). The grave accent (`) indicates the level and the number after it is the number of the generic types. Here are the rules (as indicated in the ECMA specification ):

  • Arguments that define generic type parameters have an appended grave accent character followed by the number of type parameters (ex. T`1)
  • For nested types, the number is based upon the of new type parameters on the nested type(ex. T`1.Nested`2)
  • Arguments that refer to generic type parameters on types are encoded using a single grave accent character (`) followed by the zero-based index of the type parameter.
  • Arguments that use generic parameters on methods use double grave accent characters (“) followed by the zero-based index of the type-parameter instead of the single grave accent used for parameters on types.

For instance, let’s say your class looks like this:

namespace foo
{
   class bar<T>
   {
   }
}

If you want to link to the generic bar type you must do it like this:

  <codeEntityReference>T:foo.bar`1</codeEntityReference>

What if you had a generic method too?

namespace foo
{
   class bar<T>
   {
      public TR func1<TR>(string s)
      {
         return (default)TR; // just something dummy
      }

      public TR func2<TR;>(string s, TR arg)
      {
         return (default)TR; // just something dummy
      }

      public void func3<T1, T2>(T a, T1 b, T2 c)
      {
      }
   }
}

Then you must refer to the function as follows:

  // function is generic, but no generic argument is used
  <codeEntityReference>M:foo.bar`1.func1``1(System.String)</codeEntityReference>

  // function is generic and has a generic argument on the method => use `` + 0-based index of type
  <codeEntityReference>M:foo.bar`1.func2``1(System.String,``0)</codeEntityReference>

  // function is generic and has generic arguments on type and on the method
  // first argument type comes from the type => `0
  // second and third argument types come from the method, in the order they were declared => ``0 and ``1
  <codeEntityReference>M:foo.bar`1.func3``1(`0,``0,``1)</codeEntityReference>

API Reference Documentation
When you author documentation you probably want to put together conceptual documentation and API reference documentation. The later you build from external sources, i.e. assemblies and XML files with the XML-comments you wrote in the source code. Question is where and how do you insert this API reference? The answer was not very easy to find; luckily a colleague of mine was able to help me with the answer.

First of all, there is only one place in the hierarchy of your topics hierarchy where you can insert it. So no matter from how many sources you build this, it all goes into one place. To set the place you must edit the topics.xml file (under Help\Settings). This file looks like this (of course, this is a dummy sample):

<?xml version="1.0" encoding="utf-8"?>
<topics>
  <topic id="cec0ab12-05b5-4a00-ab8a-391d67625997" file="topic1.aml">
    <topic id="854aeed0-510e-4ca1-b2bb-12104ba9eada" file="topic1\topic11.aml">
  </topic>
</topics>

There is a special tag you can insert as a child of a topic. It’s called stoc and looks like this:

<?xml version="1.0" encoding="utf-8"?>
<topics>
  <topic id="cec0ab12-05b5-4a00-ab8a-391d67625997" file="topic1.aml">
    <stoc project="Project" />
  </topic>
</topics>

This will tell the builder to insert under topic1 all the API reference documentation.

, , , , Hits for this post: 1449 .

Visual Studio 11 Beta was made available today (See Jason Zander’s announcement). It can be downloaded from here. These are my first impressions after downloading and trying it.

The New UI
I have already talked about the new Chrome theme. I find it awful, you don’t know what’s enabled and what is not. I wish they change it, and at least give us the possibility to opt for this theme or the classic colored theme.

Startup time
It takes Visual Studio 2010 about a whole minute to start on my machines, so I didn’t have great expectations for Visual Studio 11. However, I am impressed with the startup time, which is about 3 seconds. Excellent.

Opening projects created with a previous version
When I opened a solution build with VS2010 it did not prompt me the classic question about upgrading to the new version. That’s because the project file schemas were not changed between VS2010 and VS11. This is the first time this happens. As for the solution file, it just updated the format version without prompting for anything.

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 11

Quick launch window
The first thing I do when I install Visual Studio is changing the fonts. But sometimes finding such windows or commands is cumbersome. A new window called Quick launch is now available in the top right corner. You can type for commands and it searches through menus, options, tool windows, etc. displaying a list of results. When you press on a result it executes the command.

Solution Explorer
This is now a hub for functionality previously available in Solution Explorer, Class View, Object Browser, Call Hierarchy, Navigate To, and Find References tool windows.

  

You can search in the solution explorer, view the call graph, hierarchy types etc. As you do this it creates new views kept in a stack. It is possible to navigate between these views with two buttons, Back and Forward that are available in the left side of the Solution Explorer toolbar.

The other buttons are:

  • Home: brings back to the home view of the solution explorer
  • Collapse all: collapses all the items in the Solution explorer three view
  • Sync with Active Document
  • Preview selected items: when this is enabled, as you select files in the tree they are displayed in a special document window, docked on the left of the documents bar. This is excellent because it helps viewing the file (or a method in a file) immediately, yet without opening lots of files (since they are all displayed, one at a time, in the same document window).
  • Properties: opens the properties window for the current item
  • Show all files: as in previous versions
  • View class diagram: shows the class diagram (or creates a new one if one does not exist) for the current item
  • Create a new window containing a copy of the content of this window: this duplicates the solution explorer window, just in case you want multiple views

If you want to quickly find something in the solution explorer, you can use the search control. As you type, the content is filtered to show only the elements that contained the type text. This includes source files, references, images and everything else in the tree.

Search and Replace
There is a new quick window for search and replace. This window is displayed in the top-right corner of the active document window. This window is specific for each document; when you switch to another document, it closes.

It is possible though to open the classic window, which looks like this:

Symbol selection
A nice IntelliSense feature is highlighting in the entire document the symbol under the cursors selection. This helps a lot figuring where else in the code the symbol is used. And also helps when you have variables with the same name in different scopes, because it only highlights the symbols that are visible in the scope of the block where the cursor is.

References Window
The window for adding references has also been redesign. You can see a list of the available components that can be referred. As you hover the mouse over them a check box is displayed on the left, so you can check that component for being added.

NuGet Package Manager
For .NET projects a NuGet package manager is available. You can open it from context menu for the solution or the project.

It opens a dialog where you can search for packages, install, update or remove.

XML Doc comments for VC++
A great feature that was finally added for VC++ is XML doc comments. You can add them to C++ types and methods and generate XML doc files. For generating the output file the /doc switch must be set.

For this sample

///<summary>
///This is a dummy type.
///</summary>
class foo
{
public:
	///<summary>This is a stub method.</summary>
	///<param name="a">This is a dummy parameter.</param>
	///<returns>This method returns a random integer.</returns>
	int bar(int a)
	{
	}
};

The following output file was generated:

<?xml version="1.0"?>
<doc>
  <assembly>"cpp2011demo"</assembly>
    <members>
      <member name="M:foo.bar(System.Int32)">
        <summary>This is a stub method.</summary>
        <param name="a">This is a dummy parameter.</param>
        <returns>This method returns a random integer.</returns>
      </member>
     <member name="T:foo">
       <summary>This is a dummy type.</summary>
     </member>
  </members>
</doc>

The gotcha is that so far it does not work in the automatic way as for C# or VB.NET. When you type /// it does not automatically generate the stubs, you have to add everything manually.

You can use these files to generate MSDN-style documentation using for instance the Sandcastle compiler.

Additional readings

, , , Hits for this post: 3644 .

Dear Microsoft,

I have recently read the two blog posts about the new “developer experience” with Visual Studio 11 (part 1 and part 2). I don’t have the IDE yet (since the beta will be made available on February 29), but from the blog posts I see that you once again changed the look and feel. Why do you have to do this all the time? Can’t you sell a new version without redesigning the UI? We don’t get used well with a version and you change the game again. And like it wasn’t bad enough to do such a big changed, you decided to go with a chrome theme. This is what I call “Windows disabled”; you can’t get a good feeling of what is enabled and what is not. Everything is in tones of gray and confusing.

Why do you have to invest all that time in redesigning the UI with each release? Why don’t you focus on making the current UI more responsible (for instance VS2010 takes 1 minute on my machines to start) and less buggy? Why don’t you invest that time in building features that make our lives easier? Like providing multiple windows for search results (not just two) or supporting auto completion (like it was in all versions until VS2010) in the folder selection fields in the New Project dialog?

So dear Microsoft, please

  1. make it possible for us to change the Chrome theme to the old colored theme
  2. don’t change the UI with each version

Sincerely,
A concerned developer

PS: I still can’t get out of my mind the horror or scrolling with the mouse on Windows 8 maybe 5 screens of colorful tiles to get to the app that I want to launch. Awful! As it stands I see big failures on the horizon.

, , , , Hits for this post: 3693 .

Visual Studio 11 brings many new things for native development, including support for new features from C++11 (unfortunately not all), or ability to write Metro apps with C++/CX including modeling the UI with XAML. In this post I will talk a bit about three favorite features that I noticed immediately after trying VS11 from Windows 8 Developer Preview.

Use of namespaces
Finally, I see namespaces promoted in native code. Yes, it’s C++/CX and they were probably forced to use namespaces for a consistent experience from the various languages that target the Windows Runtime, but it’s a very nice change to the default templates for C++ projects where everything is put in the global namespace. I can only hope they will improve that in this version or the next for standard C++ applications (whether Win32 console apps or MFC apps).

namespace Sample
{
    public ref class MainPage
    {
        public:
            MainPage();
            ~MainPage();
    };
}

UPDATE: looks like I wasn’t clear enough, I’m not saying namespaces is a new C++ feature (duh), I’m saying Visual Studio templates for C++ don’t promote that. Create a Win32 project, an MFC project, and ATL project, there are no namespaces. You’d have to code everything manually, but if you do it, you mess the wizards. So, what I’m saying is that I hope we can see namespaces promoted for other project and item templates too.

Partial classes
I already wrote about partial classes, but I want to reiterate this feature. Partial classes gives you the ability to define a class in several files. This is great because developers and code generator tools such as designers can edit different parts of the same class without interfering one with the other. This feature made it possible for supporting XAML user interfaces in C++/CX Metro applications.

I’m actually wondering why isn’t this already part of standard C++ and I can only wish that the next version (which hopefully will not take another decade to conclude) will include this feature.

Better Syntax Highlighting
Below is a comparison for the same piece of code highlighted by Visual Studio 2010 on the left, and Visual Studio.vNext (11) on the right.

There is hardly any formatting in VS10. However, on the other hand, the highlighting in VS11 is beautiful. User defined types (including library types) are displayed with another color than the built-in types (such as int), including in their definition. STL types (string, vector, etc.) are finally identified as types and displayed with the appropriate color. Also the name of parameters is displayed in italics which makes them easily identifiable. There are other things about the highlighting, but these striking changes.

, , , , , , Hits for this post: 7543 .

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 tool such as ILDASM or Reflector, or of course, through .NET Reflection.

If you look in C:\Windows\System32\WinMetadata folder you’ll find the WinMD files for the Windows Runtime. You can browse the content of these files with one of the aforementioned disassemblers.

Here are two dummy WinRT components, one developed in C++/CX and one in C#.

Native WinRT component in C++/CX Managed WinRT component in C#
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;
			}
		}
    };
}
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;
        }
    }
}

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 Class Library 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 WinMD File. 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.

Native WinRT component in C++/CX Managed WinRT component in C#

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

public static Assembly Load(AssemblyName assemblyRef);

Trying to load the winmd file fails with a FailLoadException with the message “Could not load file or assembly ‘Winmdreflection, ContentType=WindowsRuntime’ or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0×80131515)”.

try
{
    var assembly = Assembly.Load(
        new AssemblyName()
        {
            Name = "WinRTManagedComponent",
            ContentType = AssemblyContentType.WindowsRuntime
        });
}
catch (Exception ex)
{
}

It is possible though to read information for the types described in an winmd file in native code using the IMetaDataImport/IMetaDataImport2 COM interfaces. You can find an example here. But this has the drawback that you have to instantiate an object first and then query for its type information.

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’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’s property page and open the Common Properties > Frameworks and References page, or use the References command from the project’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.

Having done that you can instantiate the WinRT components.

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";
, , , , , , , Hits for this post: 9717 .

Not long ago I ran into a COM interop problem that was a bit tricky to fix. So I’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 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 “native” types, but custom structures.

These structures looked like this:

[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;
};

and the COM method signature:

[id(42)] HRESULT GetListOfStructs(SAFEARRAY(struct S)* arrRes);

When you add a COM reference to a .NET assembly, Visual Studio runs tlbimp.exe 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’s output folder, is called Interop.<comname>Lib.dll. For instance if the COM server is called NativeCOMServer, the interop assembly is called Interop.NativeCOMServerLib.dll.

The wrapper that was generated in the interop assembly had the following signature for the aforementioned method:

[DispId(42)]
void GetListOfStructs(ref Array arrRes);

and therefore used like this:

System.Array result = null;
obj.GetListOfStructs(ref result);

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 Hans Passant I figured the problem was rooted in the way Visual Studio generates the interop assembly. The generated RCW didn’t know how to handle the custom structure correctly. Probably different padding on the two sides generated the access violation.

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):

\TlbImp.exe $(TargetPath) /out:$(TargetDir)\NativeCOMLib.Interop.dll /primary  /keyfile:mykey.snk /machine:x86
\TlbImp.exe $(TargetPath) /out:$(TargetDir)\NativeCOMLib.Interop.dll /primary  /keyfile:mykey.snk /machine:x64

The result was a wrapper with methods like this:

[DispId(42)]
void GetListOfStructs(ref S[] arrRes);

which of course had to be called like this:

S[] result = null;
obj.GetListOfStructs(ref result);

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’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.

    <Reference Condition=" '$(Platform)' == 'x86' " Include="NativeCOMServer.Interop,
               Version=1.0.0.0, Culture=neutral, PublicKeyToken=f5b9312191a42d52, processorArchitecture=x86">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\Bin\NativeCOMServer.Interop.dll</HintPath>
    </Reference>
    <Reference Condition=" '$(Platform)' == 'x64' " Include="NativeCOMServer.Interop,
               Version=1.0.0.0, Culture=neutral, PublicKeyToken=f5b9312191a42d52, processorArchitecture=x64">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\Bin64\NativeCOMServer.Interop.dll</HintPath>
    </Reference>

But this time the wrappers were able to bridge the call and everything worked smoothly.

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.

, , , , , , Hits for this post: 8092 .

Partial classes are finally available to C++. Sort of. It’s not part of the new C++11 standard, it’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 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.

Partial classes:

  • are available only for ref classes; native classes are not supported
  • are introduced with the partial keyword in all definitions but one

Here is an example:

// foo.private.h
#pragma once

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

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

int foo::GetId() {return _id;}
Platform::String^ foo::GetName {return _name;}

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.

<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">

    <StackPanel Name="firstPanel">
        <Button Name="firstButon" />
    </StackPanel>

</UserControl>
//
// 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();
   };
}
//
// 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()
{
}

You can notice that the objects firstPanel and firstButton 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:

#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;
    };
}
//------------------------------------------------------------------------------
//     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<Windows::UI::Xaml::Controls::StackPanel^>(static_cast<IFrameworkElement^>(this)->FindName("firstPanel"));

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

}

void MainPage::Connect(int connectionId, Platform::Object^ pTarget)
{
}

The following image illustrates the grouping of these files:

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.

, , , , , , Hits for this post: 10032 .

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.

(source www.zdnet.com)

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 “immersive” 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.

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’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.

You can get a glimpse of the new system and the tools by downloading and installing the Windows Developer Preview with tools, that includes the following:

  • 64-bit Windows Developer Preview
  • Windows SDK for Metro style apps
  • Microsoft Visual Studio 11 Express for Windows Developer Preview
  • Microsoft Expression Blend 5 Developer Preview
  • 28 Metro style apps including the BUILD Conference app

Notice this is a pre-beta release and you might encounter various problems.

Before you start here are several additional articles that you might want to read:

There are also several new forums 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.

, , , , , , , , , Hits for this post: 13761 .