The non-client area is the border, where the icon, title, minimize button, maximize/restore button, and close button is located. Using some simple API's we can extend the glass into the client area.
Obviously you would want to use Windows Vista or Windows 7 for this. There is no point running this on XP or lower.
Section 1: Setting up Project and Creating the Vista API Class
1) Create a Windows Forms Application in Visual Studio using C#.
2) Go to the Solution Explorer and add a class to the current project. Name it Vista API.cs.
3) Remove the class so you end up with this.
Code: Select all
namespace <Don't Change>
{
}
5) add an Internal Class named VistaAPI.
Code: Select all
namespace GlassTutorial
{
internal class VistaAPI
{
}
}
Code: Select all
internal struct Margins
{
public int Left, Right, Top, Bottom;
}
Code: Select all
internal class VistaAPI
{
internal struct Margins
{
public int Left, Right, Top, Bottom;
}
}
7) Now we need to use "Using System.Runtime.InteropServices"
Code: Select all
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
Code: Select all
internal class VistaAPI
{
[DllImport("dwmapi.dll")]
internal static extern void DwmExtendFrameIntoClientArea(
System.IntPtr hWnd, ref Margins pMargins);
[DllImport("dwmapi.dll")]
public extern static int DwmIsCompositionEnabled(ref bool isEnabled);
}
You also might want to add a summary above the DLL Imports.
Code: Select all
internal class VistaAPI
{
/// <summary>
/// Extending frame into the Margins
/// </summary>
/// <param name="hWnd"></param>
/// <param name="pMargins"></param>
[DllImport("dwmapi.dll")]
internal static extern void DwmExtendFrameIntoClientArea(
System.IntPtr hWnd, ref Margins pMargins);
/// <summary>
/// Checking if Desktop Composition is Enabled
/// </summary>
/// <param name="isEnabled"></param>
/// <returns></returns>
[DllImport("dwmapi.dll")]
public extern static int DwmIsCompositionEnabled(ref bool isEnabled);
/// <summary>
/// Setting up the Margins that DwmExtendFrameIntoClientArea will use
/// </summary>
internal struct Margins
{
public int Left, Right, Top, Bottom;
}
}
Code: Select all
internal const int WM_NCHITTEST = 0x84;
internal const int HTCLIENT = 1;
internal const int HTCAPTION = 2;
Section 2: Setting up the Form to use Extended Frame
1) Don't add any controls to Form1 yet. First we just want to view the code. So right click and press View code.
2) You should only see the Constructor and the partial class.
3) Add these lines above the Constructor.
Code: Select all
//Margins API Call
private VistaAPI.Margins marg;
//Creating Glass Rectangle
private Rectangle toprect = Rectangle.Empty;
Code: Select all
public partial class Form1 : Form
{
//Margins API Call
private VistaAPI.Margins marg;
//Creating Glass Rectangle
private Rectangle toprect = Rectangle.Empty;
public Form1()
{
InitializeComponent();
}
}
But first, we need a Boolean to tell whether glass is enabled or not.
Code: Select all
private bool IsGlassEnabled()
{
if (Environment.OSVersion.Version.Major < 6)
{
return false;
}
bool IsGlassSupported = false;
VistaAPI.DwmIsCompositionEnabled(ref IsGlassSupported);
return IsGlassSupported;
}
5) Add this code to the Constructor.
Code: Select all
if (!this.IsGlassEnabled())
{
return;
}
marg.Top = <Number of Pixels you want from the top>;
marg.Bottom = <Number of Pixels you want from the bottom>;
marg.Left = <Number of Pixels you want from the left>;
marg.Right = <Number of Pixels you want from the right>;
VistaAPI.DwmExtendFrameIntoClientArea(this.Handle, ref marg);
Code: Select all
public partial class Form1 : Form
{
//Margins API Call
private VistaAPI.Margins marg;
//Creating Glass Rectangle
private Rectangle toprect = Rectangle.Empty;
public Form1()
{
InitializeComponent();
if (!this.IsGlassEnabled())
{
return;
}
marg.Top = 20;
marg.Bottom = 20;
marg.Left = 20;
marg.Right = 20;
VistaAPI.DwmExtendFrameIntoClientArea(this.Handle, ref marg);
}
private bool IsGlassEnabled()
{
if (Environment.OSVersion.Version.Major < 6)
{
return false;
}
bool IsGlassSupported = false;
VistaAPI.DwmIsCompositionEnabled(ref IsGlassSupported);
return IsGlassSupported;
}
}
If we are to debug our program now, you will see the border extended, but glass won't show up.

If it shows white where you extended the frame, you are doing everything correct so far!
Now we need to create a paint method. So in the constructor we need to override the OnPaint method.
Just type this.Paint, then press the space bar and press "+" then "=" and press tab twice. It will create the method.
Section 3: Painting the Glass
1) Remove the line of code telling it to throw the exception.
2) Create a new Solid Brush.
Code: Select all
//Creating a New Solid Black Brush
SolidBrush BlackBrush = new SolidBrush(Color.Black);
Code: Select all
//Creating a New Solid Black Brush
SolidBrush BlackBrush = new SolidBrush(Color.Black);
//Referencing Graphics
Graphics g = e.Graphics;
//Checking if Glass is enabled
if (this.IsGlassEnabled())
{
}
4) Add this Inside the If Statement.
Code: Select all
//Create rectangle to match Glass Area
toprect =
new Rectangle(0, 0, this.ClientSize.Width, marg.Top);
//Filling the Rectangle with Black Brush
g.FillRectangle(BlackBrush, toprect);

Section 4: Moving Window by Clicking on Glass
Congratulations! You can now extend the glass frame as far into the form as you want, But now we need to make it so when you click on the glass, you can move it.
I copied this code from a video, I don't really know how exactly it works, but I understand what it does.
Code: Select all
#region Dragging the Window
// make windows do the work for us by lieing to it about where the user clicked
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == VistaAPI.WM_NCHITTEST // if this is a click
&& m.Result.ToInt32() == VistaAPI.HTCLIENT // ...and it is on the client
&& this.IsOnGlass(m.LParam.ToInt32())) // ...and specifically in the glass area
{
m.Result = new IntPtr(VistaAPI.HTCAPTION); // lie and say they clicked on the title bar
}
}
private bool IsOnGlass(int lParam)
{
if (!this.IsGlassEnabled())
{
return false;
}
// get screen coordinates
int x = (lParam << 16) >> 16; // lo order word
int y = lParam >> 16; // hi order word
// translate screen coordinates to client area
Point p = this.PointToClient(new Point(x, y));
// work out if point clicked is on glass
if (toprect.Contains(p))
return true;
return false;
}
#endregion
That concludes how to extend the glass frame into the non client area. In my next tutorial, I will teach you how to draw text on it without any problems.
Right Click and Save or Just go to the URL.