Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Cross-Platform .NET Development: Using Mono, Portable.NET, and Microsoft .NET - By Mark Easton, Jason King

0.00/5 (No votes)
2 Nov 2004 1  
Sample from the book - Chapter 5
Title Cross-Platform .NET Development: Using Mono, Portable.NET, and Microsoft .NET
Authors Mark Easton, Jason King
Publisher www.apress.com
Published Sep 2004
ISBN 1-59059-330-8
Price USD 49.99
Pages 560

The Spice of Life:

GUI Toolkits

�There are two major products that came out of Berkeley: LSD and UNIX. We don�t believe this to be a coincidence.� -Jeremy S. Anderson

SPAWNED IN THE EARLY 1970S, the decade of sartorial flamboyance that brought us sequined jump suits, ridiculously flared trousers, and the expression �Fat Elvis phase,� the graphical user interface (GUI) has grown from a hacker�s convenience tool into the public facade of the multibillion-dollar business that we all know and love. The impact that a good user interface has on an application should not be underestimated, and many projects, careers, and fortunes have been lost and found in the twinkling of a treeview.

So, the world is full of shallow aesthetes, but so what? It�s fun to pander to them, and the best thing about graphical interfaces is that they provide a chance to make manifest the underlying artistry that is software development. For those of you who don�t think that software is art, take a moment when you finish your next project to remind yourself that you�ve created something that didn�t previously exist. If creation-even when infused with logic-isn�t art, then call me a sandal-wearing, beard-chewing techie (brown kaftan and disastrous personal hygiene included).

TIP To read more about the history of the GUI, visit the excellent Web site http://www.toastytech.com/guis.

Philosophical ramblings aside, it�s time to delve into the exciting jumble of GUI tools that are available for .NET and that can help make the difference between a professional, cross-platform GUI application and a jarring profusion of pixel soup.

Topography of a .NET Graphical User Interface

Because this book deals with a variety of CLI implementations and operating systems, a good place to start is to figure out how an ideal managed GUI might work. After that, we�ll take a look at how each of the CLI implementations shapes up to the ideal implementation.

An Ideal Managed Windowing System

For the cross-platform developer dreaming of effortless portability, the ideal .NET rendering system would be written entirely in managed code.A sensible approach would involve the following steps:

  1. Creating a basic rendering system for displaying primitive items-such as lines and rectangles-on a device such as a screen, printer, or file.
  2. Developing a higher-level drawing library that encapsulates more-advanced functionality by using the basic rendering system.
  3. Designing a class hierarchy that uses the high-level rendering library and catches the user input to produce a windowing system.

Although there�s nothing wrong with this approach, it raises the question of when to leave the safe haven of managed code for the dangerous world of unsafe code and memory addresses. If this approach were taken to the extreme, the rendering system would depend on video drivers written to a managed interface, say IVideoDriver, and hardware vendors would release video drivers that conformed to the interface, as illustrated by Figure 5-1.

Of course, if hardware manufacturers wrote part of their video drivers in managed code, it wouldn�t just be a performance disaster but it would seriously overstep the boundaries of user code, and it might irreparably sour the relationship between kernel and user code.

In contrast to the managed approach, from a performance point of view, it would be ideal if all the code were tightly written assembler code, without a whiff of managed code.

Treading the fine line between these two approaches involves carefully separating functionality between managed and unmanaged code to deliver a compromise in performance and portability. Because device drivers are intrinsically linked to the host operating system and most operating systems provide some common rendering functionality, a more realistic split would use managed windowing and drawing systems, with an unmanaged rendering system calling to the device drivers, as shown in Figure 5-2.

While it�s one thing trying to balance tip-top performance with easily portable code, the main complaint against the managed approach that�s shown in Figure 5-2 is that it invariably leads to a standardized interface that is styled the same way on all platforms, but is contrary to each platform�s native look and feel.

Because some people prefer their applications to look the same across all platforms and others prefer their applications to fit in with the native feel of the operating system, frankly, a cross-platform GUI developer just can�t win.

The Basic .NET Windowing System

Having considered an ideal approach for implementing a cross-platform windowing system, it makes sense to root ourselves in the realities of .NET windowing systems and take a quick, conceptual look at the route taken by the different CLI implementations.

Because Microsoft .NET provides the System.Drawing.dll assembly for drawing and the System.Windows.Forms.dll assembly for windowing, it should come as no surprise that the other CLI implementations have also chosen to implement these assemblies. What�s interesting is to see how each CLI implementation has taken a significantly different approach to achieve this goal.

Microsoft .NET Framework

The .NET Framework currently implements both low-level rendering and higher-level controls by using Platform Invoke (P/Invoke) to call the Win32 API.

While it would be tempting to condemn Microsoft for reusing and extending the life of legacy technology, because the company�s approach helped achieve an early release of .NET and fits perfectly into the Windows user interface, it�s fair to say that Microsoft�s implementation demonstrates a shrewd use of technology. While Windows Longhorn looks set to break Microsoft�s reliance on the legacy Win32 API, in the meantime, the .NET Framework relies on the design that�s illustrated in Figure 5-3.

Because Microsoft .NET is only available for Windows, its use of Windows native functionality should come as no surprise, because it provides good performance with little concern for portability.

However, while it�s perfectly acceptable that Microsoft�s implementation isn�t portable, because System.Windows.Forms encapsulates the Windows GUI rather than a generic windowing system, one common complaint is that it should really be called Microsoft.Windows.Forms, with anything scoped within the System namespace being platform independent.

Mono

Mono�s approach to providing GUI functionality has evolved over time, and with multiple rendering back ends and multiple deployment platforms, the world of the GUI has been a tricky route to negotiate. It remains to be seen exactly where it will all end.

For its implementation of System.Drawing, Mono uses GDI+ on Windows, and Cairo on platforms running X Windows. As shown in Figure 5-4, while Platform Invoke is used to call directly into Gdiplus.dll on Windows, on non-Windows platforms, a library that mimics GDI+ is used. This library in turn passes all calls on to the Cairo library.

NOTE Cairo provides modern vector graphics functionality and features, including antialiased text rendering and mathematical transforms. Its ethos is to provide a uniform output on all media, although currently only X Windows and an in-memory image buffer implementation exist. Cairo plans to add support for the Portable Document Format (PDF) and PostScript outputs, which could elegantly lead into cross-platform printing support. See http://www.cairographics.org for more details.

While Mono�s implementation of System.Drawing is relatively straightforward, things are not so simple in regard to GUI toolkits. While we discuss a number of alternative GUI toolkits later in the chapter, three GUI implementations are currently directly related to Mono: System.Windows.Forms, implemented using Winelib; System.Windows.Forms, implemented using Gtk#; and Gtk#, a managed code wrapper for GTK+ that can be used as an alternative for System.Windows.Forms. Figure 5-5 shows these strategies in action.

Drowning Your Sorrows: Wine

While it often seems that a bottle is the answer to your cross-platform development woes, some help is at hand in the form of the Wine project.

Wine is an adaptability layer for Windows programs and provides an environment that allows Windows programs to be loaded on different operating systems and executed with varying degrees of success. Wine consists of the following two separate parts:

  • The wine program, which loads Windows binaries and marshals calls to the Windows API functions
  • The Winelib library, which implements an ever-increasing subset of the functions from the Win32 API libraries

Although the wine program only runs on x86 hardware and can only be used for running native Windows applications, the Winelib libraries can be used as replacements for their Windows counterparts and can be accessed from .NET applications by using Platform Invoke.

For more information on the Wine project, visit http://www.winehq.com.

TIP Because both of Mono�s System.Windows.Forms implementations are currently heavily in development, they aren�t as reliable as Gtk#, and therefore our advice is to use Gtk# where possible.

Because Gtk# has a strong following in the open source community, choosing between Gtk# and System.Windows.Forms is both a political and a practical dilemma, not made any easier by the fact that both namespaces will eventually work on a variety of platforms. As you would expect, the Gtk# namespace is not directly interchangeable with System.Windows.Forms. This means to effectively use Gtk#, you need to learn all about its types and peccadilloes, although that�s a small price to pay if System.Windows.Forms doesn�t meet your needs.

As you can see from Figure 5-6, a number of supporting assemblies are required for the Gtk# namespace. Each Gtk# assembly not only calls directly into the equivalent GTK+ shared library, but each Gtk# assembly also calls into a C shared library that acts as glue code and exposes some higher-level facilities that are not provided by the GTK+ libraries.

Portable.NET

Unlike Microsoft .NET and Mono, Portable.NET�s graphical architecture tends toward the linear design that was advocated in Figure 5-2, with System.Windows.Forms building on the rendering functionality that is provided by System.Drawing. This results in all the controls being written in managed code.

To provide a portable rendering system, System.Drawing uses a helper name-space, System.Drawing.Toolkit, that defines a number of interfaces that can be used when wrapping arbitrary rendering engines. To date, Portable.NET has created wrappers for Win32, which provides Windows portability, and for X Windows, which provides portability to GNU/Linux, Mac OS X, and other UNIX-based operating systems. This architecture is illustrated in Figure 5-7.

This architecture could well prove to be the purist�s choice, because it strives to accommodate a good, portable design. As other rendering systems are brought into the fold, the core of the System.Drawing and System.Windows.Forms namespaces will remain uncluttered, and the Portable.NET community has started discussing wrapping up the Mac OS X Cocoa APIs for a more Mac-native feel on Mac OS X.

TIP For those who are concerned with authoring controls or who have a general interest in how widgets work, the source code for Portable.NET�s implementation of System.Windows.Forms is an invaluable resource, although should you choose to use it as the basis for your own controls, the usual licensing rules apply.

Alternative GUI Toolkits

Having examined the standard graphical systems that are included with Mono, Portable.NET, and Microsoft .NET, it�s now time to investigate a range of alternative GUI toolkits, each of which provides its own set of features and challenges, while helping to spice up the already colorful life of the cross-platform developer. While developers from a stringent Windows background might be inclined to shun these toolkits and stick with System.Windows.Forms, you have a number of good reasons to embrace these alternative GUI toolkits. Not only are some of toolkits easily portable across different platforms, but they also offer different feature sets, and some of them can provide a native look and feel on any platform that they are deployed on. It�s also worth noting that when Microsoft releases Windows Longhorn in 2006, it will herald the arrival of a new Windows GUI system, Avalon, and will undoubtedly replace System.Windows.Forms as the preferred tool for developing Windows GUIs.

NOTE Promising the latest in vector graphics�based GUIs and using its own XML language, XAML, Avalon is set to be the future of GUI development on Windows. Luckily, an open source vector graphics library, VG.NET, is already available for .NET. While VG.NET is not identical to Avalon, it offers a number of similar features-such as exporting to MyXaml, an open source implementation XAML-and unlike Avalon, it�s available for use today. Downloads and more information on VG.NET are available from http://www.vgdotnet.org, and details of MyXaml can be found at http://www.myxaml.com.The one advantage of investing in System.Windows.Forms is that although its days are numbered, because Mono and PNET are both implementing their own version, System.Windows.Forms is likely to be the most popular .NET GUI toolkit for the foreseeable future.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here