Lorenz Cuno Klopfenstein

Articles from July 2010

Aero in Windows Vista introduced the new glass windows and a nice set of APIs that allow developers to change glass and blur settings. One of the options allows to extend the glass frame from the “non-client” area to the inner parts of the window. This effect is used by many applications of Windows itself (Windows and Internet Explorer for instance, or Media Player — before they dropped the glass in Windows 7).

To understand how this works, firstly let's take a look to how a standard window is structured in Windows:

Windows areas.

A window is composed of many separate areas. The most important one in our case is the non-client area which includes many other parts (for instance the caption, i.e. the title and icon of the window). This area surrounds the central rectangular client area, which is the space where the application draws its own contents.

The whole non-client area is composed of glass in Aero: when extending the glass frame, you are effectively allowing Windows to draw its glass effect inside the client area where you too are drawing the contents of the window. Combining what you and Windows draw together can be tricky (you must draw using GDI and not GDI+ in order to handle alpha transparency and the background of your windows must be black on the glassy area), but it isn't too hard.

However, most applications that extend the glass frame allow you to drag and move the window if you click anywhere on the glass. This makes sense for the users but doesn't work out of the box: after all, even if clicking on glass, the clicks still end in your client area and must be handled by the application. To let Windows handle the clicks and enable dragging, you essentially must not only extend the glass area, but also the whole caption area inside your window (since the caption is the part of window usually in charge of handling mouse dragging). The resulting layout would look like this:

Windows areas.

How do you tell Windows that what was your client area should be considered part of the caption? Windows has a simple way of determining which parts are what: it sends WM_NCHITTEST messages asking your window directly. The message stands for “non-client hit testing” and the result you pass back to the window manager describes the area the mouse pointer is currently hovering on.

protected override void WndProc(ref Message m) {
	base.WndProc(ref m);

	if (m.Msg == WM_NCHITTEST && m.Result.ToInt32() == HTCLIENT) {
		uint lparam = (uint)m.LParam.ToInt32();
		ushort x = (ushort)lparam;
		ushort y = (ushort)(lparam >> 16);

		if(PointerOnGlass(x, y)){
			m.Result = (IntPtr)HTCAPTION;
			return;
		}
	}
}

const int WM_NCHITTEST = 0x84;
const int HTCLIENT = 1;
const int HTCAPTION = 2;

By putting this snippet of code in your WndProc method you'll tell the Window Manager to consider the pixels on glass of your client area as part of the window's caption area instead. This will automatically enable dragging, Aero Snap and so on.

If you use the WindowsFormsAero library, you can simply use the GlassForm helper class and derive from it. The form handles all glass-related stuff automagically (you simply have to set the glass margins you want). It also allows you to hide the window's title and icon in a simple way. Check it out!

Posted on Thursday, July 01, 2010
1011 Views
12 comments posted

When trying to build graphical interfaces on Linux with Mono, you have lots of choice. If you want maximum portability you can use Windows Forms (which don't look so great on Mono) or Gtk# (way better for multi-platform stuff). Both have a pretty standard look, even if WinForms look native only on Windows and Gtk does so on Gnome, and both work very well for standard desktop apps.

However, when doing more advanced graphics or targeting embedded systems, both fall short: WinForms runs OK on Windows CE (even if it is very limited), while Gtk looks pretty boring and may not be the ideal choice on resource constrained systems. The next multiplatform GUI choices that come to mind are Nokia's Qt or Intel's Clutter. Clutter is still a young project, but both frameworks unfortunately lack some good .NET bindings in essence.

In my case I'm starting to use Qt, through the Qyoto bindings. The latest Ubuntu distro already includes the package, which makes getting started pretty easy — at last if it weren't for the lack of documentation.

Qyoto provides a quite complete mapping of the Qt interface, but unfortunately mantains a lot of the original C++ “smell”: many enumerations are given as simple integers, events (the signal/slot system in Qt) don't rely on .NET events but require you to bind methods to signals by their untyped name. Less of a problem, but still not very pretty: in many points Qyoto doesn't respect the common .NET naming conventions and some Qt methods should really be mapped to properties.

Anyway, these minor criticisms notwithstanding, Qyoto provides a simple and complete way to use Qt's power from C#. Let's take a look to a simple example application.

More...

Posted on Wednesday, July 07, 2010
3827 Views
105 comments posted
Back to Klopfenstein.net
Clemens Klopfenstein Serena Kiefer Lukas Tiberio Klopfenstein Lorenz Cuno Klopfenstein
English German