Wednesday, 30 July 2014

Going Beyond the Limits of Windows Forms

One of the things I explore in my Windows Forms Best Practices course on Pluralsight (soon to be released) is how you can go beyond the limitations of the Windows Forms platform, and integrate newer technologies into your legacy applications. Here are three ways you can extend the capabilities of your Windows Forms applications.

1. Use Platform Invoke to harness the full power of the Windows Operating System

Because Windows Forms has not been significantly updated for several years now, many of the newer capabilities of Windows are not directly supported. For example, Windows Forms controls do not provide you with touch events representing your gestures on a touch screen.

However, this does not mean you are limited to using only what the System.Windows.Forms namespace has to offer. For example, with a bit of Platform Invoke, you can register to receive WM_TOUCH messages in your application with a call into the RegisterTouchWindow API in your Form load event. Then you can override the WndProc method on your form to detect the WM_TOUCH messages, and use another Windows API, GetTouchInputInfo, to interpret the message parameters.

This may sound a little complicated to you, but there is a great demo application that is part of the Windows 7 SDK which you can read about here. Of course it would be much nicer if Windows Forms had built-in touch screen support, but don’t let the fact that it doesn’t stop you from taking advantage of operating system features like this. Anything the Windows API can do, your Windows Forms application can do, thanks to P/Invoke.

2. Use the WebBrowser control to host Web Content

Many existing Windows Forms line of business applications are being gradually replaced over time with newer HTML 5 applications, allowing them to be accessed from a much broader set of devices. But the transition can be a slow process, and sometimes the time required to rewrite the entire application is prohibitive. However, with the WebBrowser Windows Forms control, you can host any web content you like, meaning that you could incrementally migrate certain parts of your application to web pages.

The WebBrowser control is essentially Internet Explorer hosted inside a Windows Forms control, and will use whatever version of IE you have installed. Frustratingly, it defaults to IE 7 compatibility mode, and there isn’t an easy programmatic way to change that. However, if you are in control of the HTML that is rendered, or are able to write a registry key, then you can use one of the two techniques described here to fix it.

The WebBrowser control actually has a few cool properties, such as the ability to let you explore and manipulate the DOM as a HtmlDocument using the WebBrowser’s Document property. You can even provide a .NET object that can be manipulated using JavaScript with the ObjectForScripting property. So two way communication from the your .NET code to the webpage, and vice versa are possible.

Obviously composing your application partly out of Windows Forms controls and partly out of hosted web pages won’t be a completely seamless user experience, but it may provide a way for you to incrementally retire various parts of a large legacy Windows Forms application and replace them with HTML 5.

3. Use the ElementHost control to host WPF content

Alternatively, you may wish to move away from Windows Forms towards WPF and XAML. Not all applications are suited to being web applications, and the WPF platform offers many advantages in terms of rendering capabilities that Windows Forms developers may wish to take advantage of. It also provides a possible route towards supporting other XAML based platforms such as Windows Store apps or Windows Phone apps.

The ElementHost control allows you to host any WPF control inside a Windows Forms application. It’s extremely simple to use, and with the exception of a few quirks here and there, works very well. If you made use of a Model View Presenter pattern, where your Views are entirely passive, then migrating your application to WPF from Windows Forms is not actually as big a task as you might imagine. You simply need to re-implement your view interfaces with WPF components instead of Windows Forms. In my Pluralsight course I show how easy this is, simply swapping out part of the interface for the demo application with a WPF replacement.

So if you are working on a Windows Forms application and find yourself frustrated by the limitations of the platform, remember that you aren’t limited to what Windows Forms itself has to offer. Consider one of these three techniques to push the boundaries of what is possible, and start to migrate towards more modern UI development technologies at the same time.

No comments: