Click here to Skip to main content
15,884,099 members
Articles / Desktop Programming / Windows Forms
Article

Creating a non rectangular form using GDI+

Rate me:
Please Sign up or sign in to vote.
4.80/5 (40 votes)
22 Dec 20042 min read 106K   3.5K   88   13
This article descibes ways to creating a non rectangular form using GDI+.

Sample Image

Introduction

This is my first article for CodeProject where I spend a lot of time reading articles. Forgive me for any spelling mistakes because English is not my native language

In this article, I will show you different ways to create a non rectangular form which will make your application more attractive and will not waste your time because it's a very easy task.

Background

Although I don't know how to create a non rectangular form using Visual Studio 6, I am sure it is not an easy task. It will require a lot of API calls. But using the Visual Studio .NET, you will find that this is very easy and there are predefined steps to do so. There are two different ways:

  1. using the transparency key property in Windows Forms.
  2. using the GDI+ techniques

Using the transparency key property in Windows Forms

This is a trivial solution, just follow these steps:

  • set the FormBorderStyle property to None (which will remove the borders).
  • create a bitmap that will be set as the background image for your from.
  • fill the area that you want it to appear transparent with a specific color (e.g.: black).
  • set the BackgroundImage property to your bitmap.
  • set the TransparencyKey property to the specified color (black, for our example).

Because we remove the borders, you will find that we can't close or move our form, so we must create mouse events that I will discuss later in this article.

If this way didn't work and you can see the whole background, just check that the color quality of your monitor is less than 32 bit. If you change the BackColor property with a specific color and set the TransparencyKey property with the same color, you will find that your form disappears, since this way depends on some system settings. I searched the MSDN for an alternative way to make a nonrectangular form and I found what I wanted.

Using the GDI+ techniques

This is an easy way. It also depends on the TransparencyKey. It goes as follows:

  • set the FormBorderStyle to None
  • set the BackColor property with a specified color
  • set the TransparancyKey property with the same color
  • now the whole form is transparent
  • then use the GraphicsPath class to specify the visible region of your form
  • then call the SetClip method to replace the clipping region with the GraphicsPath region
  • fill the region with a color or an image
C#
// The namesapces used 
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

Then, we must override the onpaint event which is called when the window must be re-painted.

C#
protected override void OnPaint(PaintEventArgs e)
{
    // First we create a graphics object using
    // the PiantEventArgs e that will use the form
    Graphics grfx = e.Graphics;

    // Make Antialiasing which avoid stepped
    // look for circular path and curves you may 
    // use the SmoothingMode.AntiAlias
    grfx.SmoothingMode = SmoothingMode.HighQuality;

    // The GraphicsPath class is a sealed class
    // that Represents a series of connected 
    // lines and curves used to close
    // a path which will be tarnsparent
    GraphicsPath grfxPath1 = new GraphicsPath();

    // To make a circular form we will darw
    // an ellipse that is bounded inside a square which
    // will be simply a circle if it is bounded
    // to a rectangle it will draw an ellipse
    // i will make a form that is formed from 2 ellipses 
    Rectangle rec1 = new Rectangle(0,0,300,100);
    grfxPath1.AddEllipse(rec1);
    Rectangle rec2 = new Rectangle(120,99,60,40);
    grfxPath1.AddEllipse(rec2);

    // setclip Sets the clipping region of this
    // Graphics object to the result of the specified
    // operation combining the current clip region
    // and the specified  GraphicsPath object.
    grfx.SetClip(grfxPath1,CombineMode.Replace);

    // now we replace the clipping region with
    // the region specified in the graphicspath
    // we can fill this region with a color -even
    // the color specified in the TransparensyKey-
    // because the fill method is simply not detected by the TransparensyKey
    Brush b = new SolidBrush(Color.Green);
    grfx.FillEllipse(b,rec1);
    grfx.FillEllipse(b,rec2);

    // u may use the following 2 lines to put
    // an image instead the last four lines 
    // which fill the form with a normal color
    // note: the BackgrounImage can't be used because
    // it is detected by the TransparensyKey
    // Rectangle frmRectangle = new Rectangle(0,0,this.Width,this.Height);
    // grfx.DrawImage(Image.FromFile("zerosones.jpg"), frmRectangle);

    // then we may make a border to our from by using a thick pen
    Pen p = new Pen(Color.Yellow,5f);
    grfx.DrawPath(p,grfxPath1);
}

Mouse events

Because we remove the borders, we can't move our form, so we must add mouse handlers to replace the default.

C#
// points to hold the current position
// and the new position for the form and the mouse
Point MouseCurrrnetPos,MouseNewPos,formPos,formNewPos;

bool mouseDown=false;
private void Form1_MouseDown(object sender, 
             System.Windows.Forms.MouseEventArgs e)
{
    // when the mouse is down we must activate
    // a flag to say that the left button is down
    // and then store the current position
    // of the mouse and the form and we will 
    // use these posotions to calculate the offset
    // that must be added to the loaction
    if(e.Button==MouseButtons.Left)
    {
        mouseDown = true;
        MouseCurrrnetPos = Control.MousePosition;
        formPos = Location;
    }
}

// when the user release the mouse button we must update the flag
private void Form1_MouseUp(object sender, 
             System.Windows.Forms.MouseEventArgs e)
{
    if(e.Button==MouseButtons.Left)
        mouseDown=false;
}

// when the mouse moves we get its new position
// then calculate the new location that the form 
// should be moved to 
// and then set the current position of the form
// and the mouse with the new ones 
private void Form1_MouseMove(object sender, 
             System.Windows.Forms.MouseEventArgs e)
{
    if(mouseDown==true)
    {
        // get the position of the mouse in the screen
        MouseNewPos=Control.MousePosition;
        formNewPos.X=MouseNewPos.X-MouseCurrrnetPos.X+formPos.X;
        formNewPos.Y=MouseNewPos.Y-MouseCurrrnetPos.Y+formPos.Y;
        Location=formNewPos;
        formPos=formNewPos;
        MouseCurrrnetPos=MouseNewPos;
    }
}

Reference

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Egypt Egypt
Mina Fawzi
Faculty of engineering Ainshams university In CAIRO
intersted in .net technology and DirectX

Comments and Discussions

 
AnswerYou still can use the background image for transparency Pin
simo sabro28-Aug-08 3:31
simo sabro28-Aug-08 3:31 
GeneralRe: You still can use the background image for transparency Pin
Mark C Hagers10-Sep-08 3:13
Mark C Hagers10-Sep-08 3:13 
Generalabout the idea Pin
EIHABWADY15-Oct-06 10:43
EIHABWADY15-Oct-06 10:43 
GeneralMouse move event not Working Pin
Member 20976126-Jul-05 20:08
Member 20976126-Jul-05 20:08 
I am very thankful to u for the custamized form creation.
the artice is very helpful for a beginner to start custamizing the fors and controls.

if possible please cross check the mouse move code,that's not worked in my machine.

if anybody solves it please send me a copy

byeRose | [Rose]

GeneralRe: Mouse move event not Working Pin
mickeyfitzray17-Feb-06 6:19
mickeyfitzray17-Feb-06 6:19 
GeneralRe: Mouse move event not Working Pin
LatencyXXX25-Mar-12 2:15
LatencyXXX25-Mar-12 2:15 
GeneralVery good Pin
jlgbzh13-Jun-05 2:03
jlgbzh13-Jun-05 2:03 
GeneralRe: Very good Pin
liuyong13526-Sep-10 2:59
liuyong13526-Sep-10 2:59 
GeneralRe: Very good Pin
liuyong13526-Sep-10 3:00
liuyong13526-Sep-10 3:00 
GeneralColor Depth Pin
johnhidey23-Dec-04 5:12
johnhidey23-Dec-04 5:12 
GeneralExcellent work! Pin
AslFunky22-Dec-04 22:56
AslFunky22-Dec-04 22:56 
GeneralRe: Excellent work! Pin
ninjanear29-Dec-04 10:14
professionalninjanear29-Dec-04 10:14 
GeneralRe: Excellent work! Pin
MinaFawzi29-Dec-04 11:24
MinaFawzi29-Dec-04 11:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.