Friday, September 24, 2010

Windows Presentation Foundation

The Windows Presentation Foundation (WPF) is a graphical display system for Windows. WPF is designed for .NET, influenced by modern display technologies such as HTML and Flash, and hardware accelerated. It’s also the most radical change to hit Windows user interfaces since Windows 95.

THE EVOLUTION OF WINDOWS GRAPHICS

It’s hard to appreciate how dramatic WPF is without realizing that Windows developers have been using essentially the same display technology for more than 15 years. A standard Windows application relies on two well-worn parts of the Windows operating system to create its user interface:

* User32. This provides the familiar Windows look and feel for elements such as windows, buttons, text boxes, and so on.
* GDI/GDI+. This provides drawing support for rendering shapes, text, and images at the cost of additional complexity (and often lackluster performance).

Over the years, both technologies have been refined, and the APIs that developers use to interact with them have changed dramatically. But whether you’re crafting an application with .NET and Windows Forms or lingering in the past with Visual Basic 6 or MFC-based C++ code, behind the scenes the same parts of the Windows operating system are at work. Newer frameworks simply deliver better wrappers for interacting with User32 and GDI/GDI+. They can provide improvements in efficiency, reduce complexity, and add prebaked features so you don’t have to code them yourself; but they can’t remove the fundamental limitations of a system component that was designed more than a decade ago.

DIRECTX: THE NEW GRAPHICS ENGINE

Microsoft created one way around the limitations of the User32 and GDI/GDI+ libraries: DirectX. Over the years since it was first introduced (shortly after Windows 95), DirectX has matured. It’s now an integral part of Windows, with support for all modern video cards. But because of its raw complexity, DirectX was almost never used in traditional types of Windows applications (such as business software).

WPF changes all this. In WPF, the underlying graphics technology isn’t GDI/GDI+. Instead, it’s DirectX. Remarkably, WPF applications use DirectX no matter what type of user interface you create. That means that whether you’re designing complex three-dimensional graphics (DirectX’s forte) or just drawing buttons and plain text, all the drawing work travels through the DirectX pipeline. As a result, even the most mundane business applications can use rich effects such as transparency and anti-aliasing. You also benefit from hardware acceleration, which simply means DirectX hands off as much work as possible to the graphics processing unit (GPU), which is the dedicated processor on the video card.


THE NEW THINGS WPF BRINGS IN

* A web-like layout model
* A rich drawing model
* A rich text model
* Animation as a first-class programming concept
* Support for audio and video media
* Styles and templates
* Commands
* Declarative user interface
* Page based applications


RESOLUTION INDEPENDENCE

Traditional Windows applications are bound by certain assumptions about resolution. Developers usually assume a standard monitor resolution (such as 1024 by 768 pixels), design their windows with that in mind, and try to ensure reasonable resizing behavior for smaller and larger dimensions. The problem is that the user interface in traditional Windows applications isn’t scalable. As a result, if you use a high monitor resolution that crams pixels in more densely, your application windows become smaller and more difficult to read. This is particularly a problem with newer monitors that have high pixel densities and run at correspondingly high resolutions. For example, it’s common to find consumer monitors (particularly on laptops) that have pixel densities of 120 dpi or 144 dpi (dots per inch), rather than the more traditional 96 dpi. At their native resolution, these displays pack the pixels in much more tightly, creating eye-squinting small controls and text.

Ideally, applications would use higher pixel densities to show more detail. For example, a high resolution monitor could display similarly sized toolbar icons but use the extra pixels to render sharper graphics. That way, you could keep the same basic layout but offer increased clarity and detail. For a variety of reasons, this solution hasn’t been possible in the past. Although you can resize graphical content that’s drawn with GDI/GDI+, User32 (which generates the visuals for common controls) doesn’t support true scaling.

WPF doesn’t suffer from this problem because it renders all user interface elements itself, from simple shapes to common controls such as buttons. As a result, if you create a button that’s 1 inch wide on your computer monitor, it can remain 1 inch wide on a high-resolution monitor—WPF will simply render it in greater detail and with more pixels.

This is the big picture, but it glosses over a few details. Most importantly, you need to realize that WPF bases its scaling on the system DPI setting, not the DPI of your physical display device. This makes perfect sense—after all, if you’re displaying your application on a 100-inch projector, you’re probably standing several feet back and expecting to see a jumbo-size version of your windows. You don’t want WPF to suddenly scale down your application to “normal” size. Similarly, if you’re using a laptop with a high-resolution display, you probably expect to have slightly smaller windows—it’s the price you pay to fit all your information onto a smaller screen. Furthermore, different users have different preferences. Some want richer detail, while others prefer to cram in more content. So, how does WPF determine how big an application window should be? The short answer is that WPF uses the system DPI setting when it calculates sizes. But to understand how this really works, it helps to take a closer look at the WPF measurement system.

WPF UNITS

A WPF window and all the elements inside it are measured using device-independent units. A single device-independent unit is defined as 1/96 of an inch. To understand what this means in practice, you’ll need to consider an example.

Imagine that you create a small button in WPF that’s 96 by 96 units in size. If you’re using the standard Windows DPI setting (96 dpi), each device-independent unit corresponds to one real, physical pixel. That’s because WPF uses this calculation:

[Physical Unit Size] = [Device-Independent Unit Size] × [System DPI]
= 1/96 inch × 96 dpi
= 1 pixel

Essentially, WPF assumes it takes 96 pixels to make an inch because Windows tells it that through the system DPI setting. However, the reality depends on your display device.

THE ARCHITECTURE OF WPF

WPF uses a multilayered architecture. At the top, your application interacts with a high-level set of services that are completely written in managed C# code. The actual work of translating .NET objects into Direct3D textures and triangles happens behind the scenes, using a lower-level unmanaged component called milcore.dll. Milcore.dll is implemented in unmanaged code because it needs tight integration with Direct3D and because it’s extremely performance-sensitive.

* PresentationFramework.dll: This holds the top-level WPF types, including those that represent windows, panels, and other types of controls. It also implements higher-level programming abstractions such as styles. Most of the classes you’ll use directly come from this assembly.

* PresentationCore.dll: This holds base types, such as UIElement and Visual, from which all shapes and controls derive. If you don’t need the full window and control abstraction layer, you can drop down to this level and still take advantage of WPF’s rendering engine.

* WindowsBase.dll: This holds even more basic ingredients that have the potential to be reused outside of WPF, such as DispatcherObject and DependencyObject, which introduces the plumbing for dependency properties.

* milcore.dll: This is the core of the WPF rendering system and the foundation of the Media Integration Layer (MIL). Its composition engine translates visual elements into the triangle and textures that Direct3D expects. Although milcore.dll is considered part of WPF, it’s also an essential system component for Windows Vista and Windows 7. In fact, the Desktop Window Manager (DWM) uses milcore.dll to render the desktop.


THE LAST WORD

WPF is the beginning of the future of Windows development. In time, it will become a system like User32 and GDI/GDI+, on top of which more enhancements and higher-level features are added. Eventually, WPF will allow you to design applications that would be impossible (or at least thoroughly impractical) using Windows Forms.