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: 2592 .

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: 3379 .

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: 2994 .

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: 3922 .

Many of you have requested an update of the game, with new elements and challenges. After lot of time in coordinating the translations, the latest update is finally ready, with the exception of the German translation which is not available for the new elements (if anyone interested in helping there, please drop a comment). Alchemy 2.1 adds 56 new elements, bringing the total to 500. The game is now also available in Polish and Bulgarian, bringing the total number of languages to 16.

The list of the 56 new elements is:



Airport Dollar Physics
Artist Economics Plastic
Astronaut Economy Pound
Astronomy Euro Product
Bank Europe Safe
Basket Factory School
Basketball Geek School bus
Biology Geology Science
Blackboard Gift Sound mixer
Blowfish Giftbox Sound of Music
Box Hail Speakers
Cargo Helmet Student
Chalk Language Toolbox
Charles Darwin Linguistics Vault
Chemistry Linux Work
Christmas Moby Dick Worker
Company Money
Container Musician
Creditcard Nerd
Deposit box Paleontology

The entire list of elements (500) is available here.

Starting with this version, when you unlock all the available elements a notification is displayed, which looks like this:

In addition to these, some fixes were implemented. The most important is about the Wiki button, which used to always search in the English version of the encyclopedia. Now, it searches articles in the language selected in the game. That means if you use English it will continue to search in en.wikipedia.org, but if you use French for example it will search at fr.wikipedia.org.

I want to thank again to the people that translated the game. Your work is appreciated. If anyone else wants to translate Alchemy to a language not yet available please drop a comment so I can contact you.

Any feedback or suggestion is welcomed.

You can download the latest version of the game from this page.

, , Hits for this post: 4634 .

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: 6629 .

Earlier this year I published a series of articles on Codeguru about WP7 Silverlight development. Later on I have remastered them a bit and merged them together with a couple of articles by Vipul Patel into a small eBook that was published on internet.com, called Windows Phone 7 Quick Start Developer Guide. There is also a ZIP archive with the source code for all the sample projects presented throughout the book. While you can still find the articles online on the site, I recommend the eBook as a better learning material as it puts the various topics together.

The eBook is intended for developers with a fair knowledge of .NET programming that want to start developing Silverlight applications for Windows Phone 7. However, it is not a complete guide to Silverlight development for Windows Phone 7. The eBook covers a smaller set of Silverlight topics that is intended to prepare the reader for the most common challenges a Windows Phone 7 developer faces.

Here is the table of contents of the eBook.

  • Preface
  • Where to Start
  • Creating a Simple Windows Phone Application: “Hello World!”
  • The Application Bar
  • Page Navigation
  • Tombstoning and Data Persistence
  • Pivot and Panorama
  • Launchers and Choosers
  • Touch
  • Using Bing Maps Control
  • App Hub: Application Submission Walkthrough
  • References
  • About the Authors

Download the eBook from here.

, , , Hits for this post: 3033 .

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 an image (specific to the key) to appear on the screen. For example, let’s say if I press the “O” key, an image of Earth appears on my screen.

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.

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.


A good option for loading PNG files is using Windows Imaging Component. 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 blog. This is how it looks, except that I made some slight modifications to LoadImageFromResources (called LoadSplashImage on his blog).

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, &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<void**>(&ipDecoder))))
      goto Return;

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

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

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

   WICConvertBitmapSource(GUID_WICPixelFormat32bppPBGRA, ipFrame, &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(&width, &height)) || width == 0 || height == 0)
      goto Return;

   BITMAPINFO bminfo;

   ZeroMemory(&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, &bminfo, DIB_RGB_COLORS, &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<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;
}

However for this to work the following are necessary:

#include <Objidl.h>
#include <Wincodec.h>

#pragma comment (lib, "windowscodecs.lib")

Objidl.h is required for IStream, while Wincodec.h and windowscodecs.lib for WIC.

I have created a Win32 Project, called TypePictures. The wizard generates the backbone for the app, but I’ll not talk about that part. Besides adding the functions listed above, I also added the following:

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

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.

RegisterPictureWindowClass registers the window class for the picture window. It uses the c_szPictureClass defined earlier for the class name.

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(&wcex);
}

This will be called in the main function before the call to InitInstance.

RegisterPictureWindowClass(hInstance);

CreatePictureWindow is a function that creates the picture window. This will be a layered window that we’ll later update with UpdateLayeredWindow when displayined the picture.

BOOL CreatePictureWindow(HINSTANCE hInstance, HWND hOwner)
{
   if(g_hPictureWnd != NULL)
      return FALSE;

   RECT rcwin;
   GetWindowRect(hOwner, &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;
}

DestroyPictureWindow does what the name implies, it destroys the layered window that displays the picture.

BOOL DestroyPictureWindow()
{
   if(g_hPictureWnd == NULL)
      return FALSE;

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

   return ret;
}

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.

BOOL SetPicture(HBITMAP hbmp)
{
   if(g_hPictureWnd == NULL)
      return FALSE;

   BITMAP bm;
   GetObject(hbmp, sizeof(bm), &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, &rcwin);

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

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

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

   return TRUE;
}

PictureTimerProc is the timer procedure we use to destroy the window after a specified interval since the last typed key elapsed.

VOID CALLBACK PictureTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
   if(idEvent == g_timer)
   {
      ::KillTimer(hwnd, idEvent);
      g_timer = 0;

      DestroyPictureWindow();
   }
}

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.

WndProc is the function where the messages sent to the main window are processed. We’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:

   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;

And basically that is all. Just run the application and type E, M and S. You’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).

You can download the source code from here: TypePictures (154).

, , , Hits for this post: 3081 .

I recently ran across a bug with an application ported to the x64 platform. After debugging the application the error turned to be due to integrals layout and casting. I think this is a typical example worth mentioning.

It starts with this definition:

#define COMBO_VALUE -99

which is used for a combo box with SetItemData:

pCombo->SetItemData(index, (DWORD)COMBO_VALUE);

Notice the cast to DWORD, which is an integral type represented on 32-bits both on x86 and x64. At a later point this value was retrieved and tested against COMBO_VALUE:

if (pCombo->GetItemData(pCombo->GetCurSel()) == COMBO_VALUE)

They key here is how the value of -99 is represented:

  32-bit platform 64-bit platform
-99 FFFFFF9D FFFFFFFFFFFFFF9D
(DWORD)-99 FFFFFF9D FFFFFF9D
(DWORD_PTR)-99 FFFFFF9D FFFFFFFFFFFFFF9D
(DWORD_PTR)(DWORD)-99 FFFFFF9D 00000000FFFFFF9D

GetItemData returns a DWORD_PTR, so FFFFFF9D becomes 00000000FFFFFF9D on x64. Then -99 is also interpreted as a DWORD. Thus the condition in the above if statement resolves to 00000000FFFFFF9D == FFFFFFFFFFFFFF9D on x64, which of course is false.

To fix the problem, the if statement should be re-written like this:

if ((DWORD)pCombo->GetItemData(pCombo->GetCurSel()) == COMBO_VALUE)

A very simply fix, but not so simple to spot the root of the problem when just reading the code.

, , , Hits for this post: 3741 .

Version 2.0.3 of Alchemy (released today) is available in 14 languages: Czech, Danish, Dutch, English, French, German, Hebrew, Hungarian, Indonesian, Italian, Portuguese, Romanian, Slovak and Spanish. According to Wikipedia this sums up to 1.1 – 1.4 billion native speakers. Here is a map with the countries where at least one of these languages is a native/official language.

I want to thank again to the volunteers from around the world that translated the game to these languages and made the game available for more than one billion native speakers. Great job, thank you. Here is the list of the translators:

  • Ruud van der Eem (Dutch)
  • Lukas Juda “LKJ” (Czech)
  • Bruno Silva (Portuguese)
  • Zoltán Perge (Hungarian)
  • Fabien Celier “Lord of Dark” (French)
  • Jeppe Uhd (Danish)
  • Martin (German)
  • Leandro Papi (Italian)
  • Erez Segall (Hebrew)
  • Jozef Krsak (Slovak)
  • Pamungkas Atma Saputra (Indonesian)
  • Luis Rolando Rodríguez Daza (Spanish)

If anyone wants to help translate the game to some other language, please drop a comment on my blog so I can contact you.

Download the latest version of the game from here.

, , Hits for this post: 4939 .