Create custom UI appearance for WinForms Layered Form - part 5
By ganton ~ July 30th, 2008. Filed under: WinForms.
In my previous posts in the series I described how to create custom CheckBox, RadioButton and Button controls. They are completely customizable during design time in Visual Studio WinForms designer.
(All posts in this series: Post 1, Post 2, Post 3, Post 4, Post 5, Post 6, Source Code)
This post presents a creation of a layered window in order to have a custom form and to be able to create a form with a form of a png image file. If you are not familiar with layered window you can have a look at http://msdn.microsoft.com/en-us/library/ms997507.aspx. It is an old post but I found it very useful.
In order to make a window layered we will use several functions from Windows API. Functions used are UpdateLayeredWindow, SetWindowLong, GetDC, CreateCompatibleDC, ReleaseDC, DeleteDC, SelectObject and DeleteObject. In addition we will create some structures used to cnfigure our form. They are equivalent to those in Windows API. Here are they POINT, SIZE and BLENDFUNCTION. All of them will be wrapped in a separate class named Win32Helper. In order to call Win32 API Dlls we will use P/Invoke. If you are not familiar with it there is a nice article at http://msdn.microsoft.com/en-us/magazine/cc164123.aspx and you also can visit pinvoke.net.
Click to expand Win32Helper class implementation.
Now we are ready to create a custom form which will allow us to have a layered window. The name of our class is LayeredForm and it provides two pubic properties and one method. IsLayered property indicates where the window should be a layered one and IsTransparent property indicates where the window should be transparent for the mouse events. The second property will be used in my next post where I’ll explain how to create shadow of a window.
The public method is SetBitmap. It accepts a Bitmap object as its only parameter. It allows us to update the form according to provided bitmap. Below you can review the code which is commented and I think it is easy to get into it.
Click to expand SetBitmap method implementation.
Now we are ready with all preparation work and we are able to create a form named TestLayeredWindowForm which will inherit from LayeredForm and will call its SetBitmap method providing a simple png image in form’s Load event handler. It also contains event handlers for MouseMove, MouseDown and MouseDoubleClick events. Their implementation allow us to click on the window and to move it and to close it when double clicking.
private void TestLayeredWindowForm_Load(object sender, EventArgs e)
{
// retrieve executing directory
string directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName);
SetBitmap((Bitmap) Bitmap.FromFile(directory + "\\circle window.png"));
}
private void TestLayeredWindowForm_MouseMove(object sender, MouseEventArgs e)
{
// if the left button is clicked and it is still held move the form
if (e.Button == MouseButtons.Left)
{
Top += e.Y - _startPoint.Y;
Left += e.X - _startPoint.X;
}
}
private void TestLayeredWindowForm_MouseDown(object sender, MouseEventArgs e)
{
// store started point into private variable in order to use it in mouse move event handler
if (e.Button == MouseButtons.Left)
{
_startPoint = new Point(e.X, e.Y);
}
}
private void TestLayeredWindowForm_MouseDoubleClick(object sender, MouseEventArgs e)
{
// if left mouse button is double clicked the form is closed
if (e.Button == MouseButtons.Left)
{
Close();
}
}
The result layered form is shown in the picture below.
That is all for today. next time I’ll provide a sample how to implement a form with shadow.

