DCSIMG
WPF For WinForms (and MFC) Developers, Part 1 - Pavel's Blog
Sign in | Join | Help

Pavel's Blog

Pavel is a software guy that is interested in almost everything
software related... way too much for too little time

WPF For WinForms (and MFC) Developers, Part 1

WPF has been around for more than 4 years now (since the release of Windows Vista), but only in the last couple of years there is increased move from Windows Forms to WPF. However, the transition is anything but easy. This is not just because WPF is relatively new, or because people are people, and as such don’t like change for the sake of change. I mean, WinForms is ok, isn’t it? MFC may be old, but it works, doesn’t it?

The term User Interface (UI) has served us for years. In recent years, this just isn’t enough. Now it’s all about User Experience (UX). Even if the application is a boring form entering system – now you want the user to actually like using the application, as boring as its various aspects may be.

In this series, I’ll introduce WPF to the skeptic, fearful or curious WinForms or MFC developer. It is not my intention to replace a good WPF book – and there are other tutorials on the web – my intention is to focus on the essentials, the core of WPF and especially why. Why is the question first asked by any WinForms or MFC developer when told about that new thing called WPF. Is WPF just another API for user interface development?

Why WPF?

So why WPF? What’s wrong with WinForms? What’s wrong with MFC? Granted, both are old, MFC is antiquity itself in computer time (created around 1989 if I’m not mistaken). Still, are they “bad” in any concrete way? Sure, both have their flaws. But then again all technologies / libraries have flaws. So, why WPF?

The basic problem with WinForms, MFC, VB6, WTL is the same: they are wrappers around the Win32 user interface API (in user32.dll or win32k.sys if you’re a kernel lover). Everything is centered around a handle to a window (HWND). An HWND is at the heart of the windowing system. It encapsulates a (usually) rectangular region that only one entity may control. Technically, a HWND doesn’t have to be rectangular – this can be changed with the SetWindowRgn Win32 function, but it’s awkward. Still, every pixel is controlled by a single entity, be that this HWND or that HWND. This means that transparency effects, such as blending of two HWNDs is difficult if not impossible.

The existence of these HWNDs makes other effects difficult to achieve. Moving HWNDs by changing their position, for example, is sluggish and usually flickers. They were simply not made for this.

One solution would be to redesign the windowing system. That would be a huge task, considering backwards compatibility would have to be maintained for years to come. I believe this is inevitable and will happen sooner or later. In the meantime, there is WPF.

That where WPF departs from the other technologies. In WPF, (barring a few minor exceptions) only a top level window has an HWND, so that the Windowing system recognizes it. The client are of the window is pure graphics to the windowing system. That means that buttons, list boxes and most other controls are “invisible” to windows, and veteran tools such as Spy++ wouldn’t find anything inside such a window.

Having given up on HWNDs opens up a world of possibilities in terms of graphic capabilities. And WPF takes the opportunity presented all the way.

So HWNDs are gone. So what?

Let’s take graphics as an example. How do you draw something in WinForms? There is GDI+ with classes such as Graphics, Pen, Brush and others. What’s wrong with those?

The first thing is that GDI+ is slow. In fact, it’s the slowest graphics API Microsoft has put out. It never undergoes hardware acceleration, which in today’s high powered graphic cards, is a real shame. Furthermore, it’s 2D only. Sometimes we need 3D, then what can we do? More on that later.

How do we do graphics with MFC? By using GDI (the original windows graphical API), and we can also use GDI+, as it’s a C++ graphic library. What’s wrong with GDI? It’s old and its API is primitive and unintuitive, for starters. It uses a device context (HDC, which is analogous to a GDI+ Graphics object), but that’s no better. Starting with Windows Vista, it’s not hardware accelerated either, although it’s faster that GDI+. What about 3D? Nothing like that.

With WinForms and MFC 3D graphics can be obtained using an external library such as DirecX (with its Direct3D component) or OpenGL. Both are native COM APIs, so for WinForms some wrapping is needed. There are a few around, such as SlimDX and Microsoft’s own wrappers found in the Windows API Code Pack. Although possible to use, it’s difficult and does not integrate well with WinForms (or MFC for that matter).

WPF renders everything using DirectX (Direct3D). This have several important benefits: first, all drawing is hardware accelerated, as DirectX works closely with the graphic hardware (technically through appropriate drivers). Second, mixing 2D and 3D is easy and natural. 3D can be used as easily as 2D (of course setting all the details is harder) but they are part of the same layout system and content model.

What about higher level multimedia, such as playing a video file? In WinForms or MFC we have to leverage an external library, such as DirectShow or the Windows Media Foundation. Again – native libraries, need to wrap somehow for .NET. And again – no integration.

WPF treats everything pretty much the same. Whether it’s a control, an image, a 3D scene, a video or whatever, everything can be mixed together any way we wish – we have great integration. No need to fish out to other libraries – everything is in the box.

This flexibility has other implications. A button in WPF, for example, does not have to contain text or an image or both. It can contain literally anything. It can contain a 3D moving scene, a playing video, text, image or any combination of the above. Yet it’s still a button, raising a Click event when pressed with the mouse, or the space bar is pressed when it’s in focus. WPF splits a control to have looks and behavior and the two can be kept separate most of the time. The same feat in WinForms would require deriving a new class from Button, overriding some OnPaint method and maybe others. With MFC it’s similar. WPF requires no such thing. If no new functionality is required, no new class is required, either. Just changing the content or more drastically, the control template does the trick. More on that in a future post.

What else?

WPF has many more features worth mentioning, such as data binding, flexible layout system, graphic capabilities and others. We’ll explore them in due course.

In the next part we’ll look at a new language that was created for WPF (but others use it today): XAML. We’ll ask the most important question: Why?

Comments List

# re: WPF For WinForms (and MFC) Developers, Part 1

Published at Wednesday, August 24, 2011 11:25 PM by Gruff  

I am the perfect canidate to use this information.  Long years with VB6 then VB.NET Winforms.  I've looked at WPF several times but found it too daunting to tackle.

Very nicely done.  Hope there are more Parts in the works.

Leave a Comment

(required) 
(
required
)
 
(optional)
(required) 

Enter the numbers above: