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:
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:
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!



