Click here to Skip to main content
Licence 
First Posted 5 Mar 2007
Views 45,221
Downloads 1,665
Bookmarked 60 times

Custom shaped form with a drop down in C#

By | 5 Mar 2007 | Article
A simple way to create custom forms in C#

Introduction

This is a simple project that demonstrates how easy it is to create a custom shaped form that has a drop down in .NET using very little code.

This is a VS2003 project but it should work in VS2005 or C# Express with few modifications.

I had found code that demonstrated the basic principle, but I needed something with the potential to be dynamic. Transparency did not work for most of the samples I found in 32 bit mode so I went searching on MSDN and found a code snippet that loaded images with transparency, and it was all done in C#.

Screenshot - customshapeimage1.gif

What you see above is the initial screen when the program loads. What you don't see is the actual size of the form which is actually 300 pixels by 200 pixels, much larger than the image above. Also when you run it, clicking around the image will either bring up the window behind the image, or in this case do nothing since there is no window behind it. When you mouse over it, you will see a drop down which is also click-able.

Some of you may recognize the images. In fact this started out as an older VB7 project created by somebody else (I can't remember who) which demonstrated what this project does. However, transparency did not work in 32 bit mode plus it had an additional class to handle the clipping and graphics, most of which I discovered you don't need.

Using the code

To start with, create a borderless form of any size. It must be big enough to hold the largest image. Borderless allows for invisibility.

Set the transparency key of the form to some color you won't be using elsewhere. It is not necessary to set it to the same transparency color as the image(s).

The heart of the code is 5 lines as shown below (excluding comments) executed in the paint event.

bmp is a private bitmap variable declared at the class level.

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        ImageAttributes attr = new ImageAttributes();
        // Set the transparency color key based on the upper-left pixel
        // of the image.  This sets transparency for the image only.
        attr.SetColorKey(bmp.GetPixel(0, 0), bmp.GetPixel(0, 0));
        //Fill the form with the transparent color set in the 
        //transparencykey attribute of the form.
        //This also makes the form invisible to the mouse
        e.Graphics.FillRectangle(Brushes.Transparent,this.DisplayRectangle);
        //Paint the image
        //Now mouse events will occur only in the visible image area, 
        //effectively reshaping the form to the image.
        GraphicsUnit pu = GraphicsUnit.Pixel;
        //need to convert from RectangleF 
        e.Graphics.DrawImage((Image)bmp, Rectangle.Truncate( 
            bmp.GetBounds(ref pu)), 0F, 0F, (float)bmp.Width, 
            (float)bmp.Height,
            GraphicsUnit.Pixel, attr);
    }

To make the drop down, I actually load a different image that includes the original image. I do this with the MouseEnter event of the form.

private void Form1_MouseEnter(object sender , EventArgs e )
    {
        bmp = (Bitmap)Bitmap.FromFile("Sonique Small Extended.bmp");
        this.Invalidate();
    }
Screenshot - customshapeimage2.gif

I then switch back to the original image on the MouseLeave event of the form.

private void Form1_MouseLeave(object sender , EventArgs e )
    {
        bmp = (Bitmap)Bitmap.FromFile("Sonique Small.bmp");
        this.Invalidate();
    }

I also included some code to simulate an exit button, which is the "x" button on the drop down image.

private void Form1_MouseUp(object sender, 

System.Windows.Forms.MouseEventArgs e)
    {
        Point p=new Point(e.X,e.Y);
        if (ExitButton(p))
            this.Close();
    }
    private bool ExitButton(Point p)
    {
        int left = 157;
        int right = 168;
        int top = 28;
        int bottom = 39;
        return (p.X >= left && p.X <= right
            && p.Y >= top && p.Y <= bottom);
    }

Points of Interest

Comment out the line that draws the image. When you run it, you will never see the form plus you can't click on it, as if it didn't exist.

Also notice I don't have any code to set the region and clipping - it's not needed. Moreover, I don't use any calls to the Win32 api - it is all C#.

Possible Improvements

There is a lot missing here. My point was to show how to create a custom form, but you will undoubtedly need more controls. You could add custom controls, examples of which you can find on CodeProject, or make use of my example here. I also included a simple project to determine the mouse boundaries needed for this example.

If you do add custom controls, you need to modify either the MouseLeave or MouseEnter events so the particular image will stay put while you process control events.

I load the images in real time, and you will see it is pretty snappy.

If, when you experiment, you find it slows down because of large images or too many images, try creating a bitmap array on Form_load and keep them in memory, and if needed use double buffering. There is a lot you can do to improve this.

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

About the Author

mredlon

Web Developer

United States United States

Member

I have been programming since 1986, in c, c++,basic, Visual Basic and now Dotnet.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralA question PinmemberMember 11115320:42 5 Nov '09  
GeneralPaint event vs OnPaint method PinmemberEddy A21:25 8 Aug '07  
AnswerRe: Paint event vs OnPaint method Pinmembermredlon3:37 9 Aug '07  
GeneralGreat Article! Pinmemberimxuf6:13 2 Jul '07  
GeneralLove Sonique!! Pinmemberhanda296:06 12 Mar '07  
GeneralRe: Love Sonique!! Pinmembermredlon10:57 12 Mar '07  
GeneralRe: Love Sonique!! PinmemberRoberto Collina5:50 13 Apr '08  

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

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

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120517.1 | Last Updated 5 Mar 2007
Article Copyright 2007 by mredlon
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid