How to: Create Nonrectangular Windows Forms

Previously, creating non-rectangular forms was a time-consuming and labor-intensive process that involved API calls and extensive programming efforts. This is no longer the case.

Note

This process involves a great deal of graphics processing for the hardware involved; as a result, computers will perform differently based on memory and graphics cards present. When applications involve custom drawing, always test on a variety of video cards to ensure satisfactory performance before deploying to users.

The process of creating non-rectangular forms has two elements: creating the shaped form, and coding some programming logic to allow the form to be moved and closed. This second step is necessary because a form with a custom shape has no title bar and none of the functionality inherent in it, such as the ability to move the form around the screen and close it. Thus, it is necessary to write code to replicate these features. For a more information about creating both forms and controls of non-rectangular shapes, see How to: Create a Shaped Windows Form.

Creating a non-rectangular form consists of three steps:

  • Create a bitmap that will act as the form's surface. (Effectively, you will "cut out" the desired shape of the form from a rectangle.)

  • Create a Windows Application project and set its properties to get rid of the title bar and use the bitmap as the background of the form.

  • Enter code that recreates the functionality that the title bar provided, such as moving the form and closing it.

Note

The dialog boxes and menu commands you see might differ from those described in Help depending on your active settings or edition. To change your settings, choose Import and Export Settings on the Tools menu. For more information, see Visual Studio Settings.

To create a shaped form

  1. Create a bitmap of a non-rectangular shape of one color with a distinct background of another color. Use any paint program you like. The shape you draw will ultimately be your form, so be sure to draw it large enough to be useful.

    Note

    Choose an easy-to-remember background color, such as blue, as this will be important later on.

  2. In Visual Studio, create a new Windows Application project. For more information, see How to: Create a Windows Application Project.

  3. In the Properties window:

    • Set the FormBorderStyle property to None.

      This property removes the title bar from the form. (It also removes the functionality that is provided by a title bar, including the ability to close the form and move the form. However, this shortcoming is addressed below in code.)

    • Set the BackgroundImage property of the form to the bitmap file you created earlier. There is no need to add the file to the project system; this will be done automatically when you specify it as the background image.

      This property sets the bitmap image to be the background of the form. (When used in tandem with the TransparencyKey property specified below, this property defines the shape of the form.)

    • Set the TransparencyKey property to the background color of the bitmap file.

      This property tells the application which parts of the form you want to see through.

      Note

      Monitors set to a color depth of greater than 24-bit can have display problems with certain parts of the form not being transparent, despite setting of the TransparencyKey property. To avoid this problem, ensure that the monitor's color depth is set to less than 24-bit in the Display control panel. When developing applications that feature this transparency, keep in mind that you will have to make your users aware of this issue.

To write code to close the form

  1. Add a Button control to the form. For more information, see How to: Add Controls to Windows Forms.

  2. Add code that will allow the user to close the form by invoking its Close method.

    The following example shows how you can add a button that, when clicked, will close the form.

    Private Sub Button1_Click(ByVal sender As System.Object, _
       ByVal e As System.EventArgs) Handles Button1.Click
       Me.Close()
    End Sub
    
    private void button1_Click(object sender, System.EventArgs e)
    {
       this.Close();
    }
    
    C# noteC# Note:

    Be sure to add code to enable the event handler. Using the code from the following example, it would look like:

    this.Button1.Click += new System.EventHandler(this.button1_Click);
    

To write code to move the form (optional)

  1. Create a procedure to move the form when it is dragged. Enter code similar to the following to create a new Point object. This will act as a variable when you calculate how to move the form. The isMouseDown field is used to track whether the user is holding the mouse button down. The form should move only when the mouse is held down.

    Private mouseOffset As Point
    Private isMouseDown As Boolean = False
    
    private Point mouseOffset;
    private bool isMouseDown = false;
    
  2. Create an event handler for the form's MouseDown event. In the handler, add code that allows a user to click anywhere on the form to drag it. For details about creating event handlers, see How to: Create Event Handlers Using the Designer.

    Enter code similar to the following to assign coordinates to the mouseOffset variable based on the current position of the mouse pointer. In the code below, notice that the offset position is calculated using system information about the border size (FrameBorderSize.Width) and title bar height(CaptionHeight). These must be taken into account when testing the offset, because some measurements are made with the client area and some are made with screen coordinates. Thus, the offset is equal to the border width plus the caption height plus the offset into the client area of the form.

    Private Sub Form1_MouseDown(ByVal sender As Object, _
        ByVal e As MouseEventArgs) Handles MyBase.MouseDown
        Dim xOffset As Integer
        Dim yOffset As Integer
    
        If e.Button = MouseButtons.Left Then
            xOffset = -e.X - SystemInformation.FrameBorderSize.Width
            yOffset = -e.Y - SystemInformation.CaptionHeight - _
                    SystemInformation.FrameBorderSize.Height
            mouseOffset = New Point(xOffset, yOffset)
            isMouseDown = True
        End If
    End Sub
    
    private void Form1_MouseDown(object sender, 
        System.Windows.Forms.MouseEventArgs e)
    {
        int xOffset;
        int yOffset;
    
        if (e.Button == MouseButtons.Left) 
        {
            xOffset = -e.X - SystemInformation.FrameBorderSize.Width;
            yOffset = -e.Y - SystemInformation.CaptionHeight - 
                SystemInformation.FrameBorderSize.Height;
            mouseOffset = new Point(xOffset, yOffset);
            isMouseDown = true;
        }    
    }
    
    C# noteC# Note:

    Be sure to add code to enable the event handler. Using the code from the following example, it would look like:

    this.MouseDown += new
       System.Windows.Forms.MouseEventHandler
       (this.Form1_MouseDown);
    
  3. Create an event handler for the form's MouseMove event.

    Enter code similar to the following. When the left mouse button is clicked and the mouse is dragged, the form's Location property is set to the new position.

    Private Sub Form1_MouseMove(ByVal sender As Object, _
        ByVal e As MouseEventArgs) Handles MyBase.MouseMove
        If isMouseDown Then
            Dim mousePos As Point = Control.MousePosition
            mousePos.Offset(mouseOffset.X, mouseOffset.Y)
            Location = mousePos
        End If
    End Sub
    
    private void Form1_MouseMove(object sender, 
        System.Windows.Forms.MouseEventArgs e)
    {
        if (isMouseDown) 
        {
            Point mousePos = Control.MousePosition;
            mousePos.Offset(mouseOffset.X, mouseOffset.Y);
            Location = mousePos;
        }
    }
    
    C# noteC# Note:

    Be sure to add code to enable the event handler. Using the code from the following example, it would look like:

    this.MouseMove += new
       System.Windows.Forms.MouseEventHandler
       (this.Form1_MouseMove);
    
  4. Create an event handler for the form's MouseUp event. Enter code similar to the following.

    Private Sub Form1_MouseUp(ByVal sender As Object, _
        ByVal e As MouseEventArgs) Handles MyBase.MouseUp
        ' Changes the isMouseDown field so that the form does
        ' not move unless the user is pressing the left mouse button.
        If e.Button = MouseButtons.Left Then
            isMouseDown = False
        End If
    End Sub
    
    private void Form1_MouseUp(object sender, 
        System.Windows.Forms.MouseEventArgs e)
    {
        // Changes the isMouseDown field so that the form does
        // not move unless the user is pressing the left mouse button.
        if (e.Button == MouseButtons.Left) 
        {
            isMouseDown = false;
        }
    }
    
    C# noteC# Note:

    Be sure to add code to enable the event handler. Using the code from the following example, it would look like:

    this.MouseUp += new
       System.Windows.Forms.MouseEventHandler
       (this.Form1_MouseUp);
    

See Also

Tasks

How to: Create a Shaped Windows Form

How to: Create Transparent Windows Forms

Reference

Windows Forms Overview

Change History

Date

History

Reason

October 2008

Added code to enable MouseUp event handler.

Customer feedback.